/* DiaCanvas -- A technical drawing canvas.
 * Copyright (C) 1999, Arjan Molenaar
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/* Original license:
 * Dia -- an diagram creation/manipulation program
 * Copyright (C) 1998 Alexander Larsson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#ifndef __DIA_RENDERER_H__
#define __DIA_RENDERER_H__

#include <diacanvas/geometry.h>
#include <diacanvas/diacolor.h>
#include <diacanvas/diafont.h>
#include <diacanvas/diaimage.h>

DIA_OPEN

#define DIA_RENDERER(ren) ((DiaRenderer*) ren)

typedef struct _DiaRenderOps DiaRenderOps;
typedef struct _DiaInteractiveRenderOps DiaInteractiveRenderOps;
typedef struct _DiaRenderer DiaRenderer;

typedef enum
{
  DIA_LINE_CAPS_BUTT,
  DIA_LINE_CAPS_ROUND,
  DIA_LINE_CAPS_PROJECTING
} DiaLineCaps;

typedef enum {
  DIA_LINE_JOIN_MITER,
  DIA_LINE_JOIN_ROUND,
  DIA_LINE_JOIN_BEVEL
} DiaLineJoin;

typedef enum {
  DIA_LINE_STYLE_SOLID,
  DIA_LINE_STYLE_DASHED,
  DIA_LINE_STYLE_DASH_DOT,
  DIA_LINE_STYLE_DASH_DOT_DOT,
  DIA_LINE_STYLE_DOTTED
} DiaLineStyle;

typedef enum {
  DIA_FILL_STYLE_SOLID
} DiaFillStyle;

/******************************************************
 **  Functions defined for every Renderer
 **
 ******************************************************/

/* Called before rendering begins.
   Can be used to do various pre-rendering setup. */
typedef void (*DiaBeginRenderFunc) (DiaRenderer *renderer);

/* Called after all rendering is done.
   Used to do various clean-ups.*/
typedef void (*DiaEndRenderFunc) (DiaRenderer *renderer);

/* Set the origin. This is a point to which the objects will refer as their
   origin */ 
typedef void (*DiaSetOriginFunc) (DiaRenderer *renderer, gfloat x, gfloat y);

/* Set the current line width
   if linewidth==0, the line will be an 'hairline' */
typedef void (*DiaSetLineWidthFunc) (DiaRenderer *renderer, gfloat linewidth);

/* Set the current linecap (the way lines are ended) */
typedef void (*DiaSetLineCapsFunc) (DiaRenderer *renderer, DiaLineCaps mode);

/* Set the current linejoin (the way two lines are joined together) */
typedef void (*DiaSetLineJoinFunc) (DiaRenderer *renderer, DiaLineJoin mode);

/* Set the current line style */
typedef void (*DiaSetLineStyleFunc) (DiaRenderer *renderer, DiaLineStyle mode);

/* Set the dash length, when the style is not SOLID
   A dot will be 10% of length */
typedef void (*DiaSetDashLengthFunc) (DiaRenderer *renderer, gfloat length);

/* Set the fill style */
typedef void (*DiaSetFillStyleFunc) (DiaRenderer *renderer, DiaFillStyle mode);

/* Set the current font */
typedef void (*DiaSetFontFunc) (DiaRenderer *renderer,
				DiaFont *font, gfloat height);

/* Draw a line from start to end, using color and the current line style */
typedef void (*DiaDrawLineFunc) (DiaRenderer *renderer,
			      Point *start, Point *end,
			      DiaColor *color);

/* Draw a line joining multiple points, using color and the current
   line style */
typedef void (*DiaDrawPolyLineFunc) (DiaRenderer *renderer,
				     Point *points, gint num_points,
				     DiaColor *color);

/* Draw a polygone, using the current line style
   The polygon is closed even if the first point is not the same as the
   last point */
typedef void (*DiaDrawPolygonFunc) (DiaRenderer *renderer,
				    Point *points, gint num_points,
				    DiaColor *color);

/* Same a DrawPolygonFunc, expect the polygon is filled using the current
   fill type */
typedef void (*DiaFillPolygonFunc) (DiaRenderer *renderer,
				    Point *points, gint num_points,
				    DiaColor *color);

/* Draw a rectangle, given its upper-left and lower-right corners */
typedef void (*DiaDrawRectangleFunc) (DiaRenderer *renderer,
				      Point *ul_corner, Point *lr_corner,
				      DiaColor *color);

/* Same a DrawRectangleFunc, except the rectangle is filled using the
   current fill style */
typedef void (*DiaFillRectangleFunc) (DiaRenderer *renderer,
				      Point *ul_corner, Point *lr_corner,
				      DiaColor *color);

/* Draw an arc, given its center, the bounding box (widget, height),
   the start angle and the end angle */
typedef void (*DiaDrawArcFunc) (DiaRenderer *renderer,
				Point *center,
				gfloat width, gfloat height,
				gfloat angle1, gfloat angle2,
				DiaColor *color);

/* Same a DrawArcFunc except the arc is filled (a pie-chart) */
typedef void (*DiaFillArcFunc) (DiaRenderer *renderer,
				Point *center,
				gfloat width, gfloat height,
				gfloat angle1, gfloat angle2,
				DiaColor *color);

/* Draw an ellipse, given its center and the bounding box */
typedef void (*DiaDrawEllipseFunc) (DiaRenderer *renderer,
				    Point *center,
				    gfloat width, gfloat height,
				    DiaColor *color);

/* Same a DrawEllipse, except the ellips is filled */
typedef void (*DiaFillEllipseFunc) (DiaRenderer *renderer,
				    Point *center,
				    gfloat width, gfloat height,
				    DiaColor *color);

/* Draw a bezier curve, given it's control points.
   numpoints must be of the form :   numpoints = 4 + 3 * n, n >= 0 */
typedef void (*DiaDrawBezierFunc) (DiaRenderer *renderer,
				   Point *points,
				   gint numpoints,
				   DiaColor *color);

/* Same as DrawBezierFunc, except the last point must be the same as the
   first point, and the resulting shape is filled */
typedef void (*DiaFillBezierFunc) (DiaRenderer *renderer,
				   Point *points,
				   gint numpoints,
				   DiaColor *color);

/* Print a string at pos, using the current font */
typedef void (*DiaDrawStringFunc) (DiaRenderer *renderer,
				   const char *text,
				   Point *pos,
/* 				   DiaHAlignment halign, */
/* 				   DiaVAlignment valign, */
				   DiaColor *color);

/* Draw an image, given its bounding box */
typedef void (*DiaDrawImageFunc) (DiaRenderer *renderer,
				  Point *point,
				  gfloat width, gfloat height,
				  DiaImage *image);

/* This function will draw a standard handle at POSITION.
 */
typedef void (*DiaDrawHandleFunc) (DiaRenderer *renderer,
				   Point *position, DiaColor *color,
				   gboolean is_connectable);
/* Idem for ConnectionPoints.
 */
typedef void (*DiaDrawConnectionPointFunc) (DiaRenderer *renderer,
					    Point *position, DiaColor *color);

/******************************************************
 **  Functions defined for every Interactive Renderer
 **  Interactive renderers are renderers that render
 **  to pixels on the screen.
 ******************************************************/

/* Returns the EXACT width of text in pixels, using the current font
   This operation just has to be defined for renderers that are
   interactive, (ie. the screen). As you can't generally calculate
   exact widths otherwise.
 */
typedef gfloat (*DiaGetTextWidthFunc) (DiaRenderer *renderer,
				     const gchar *text, gint length);

/* convenience function that return the bounding box size (absolute)
 * of a handle or CP
 */
typedef void (*DiaGetHandleBoundingBoxFunc) (DiaRenderer *renderer,
					     Point *pos, Rectangle *bb);
typedef void (*DiaGetCPBoundingBoxFunc) (DiaRenderer *renderer,
					 Point *pos,
					 Rectangle *bb);

/* Clear the current clipping region.
   This function needs only be defined for interactive
   renderers.
*/
typedef void (*DiaClipRegionClearFunc) (DiaRenderer *renderer);

/* Add a rectangle to the current clipping region.
   This function needs only be defined for interactive
   renderers.
*/
typedef void (*DiaClipRegionAddRectangleFunc) (DiaRenderer *renderer,
					       Rectangle *rect);

/* Draw a line from start to end, using color and the current line style */
typedef void (*DiaDrawPixelLineFunc) (DiaRenderer *renderer,
				      gint x1, gint y1,
				      gint x2, gint y2,
				      DiaColor *color);

/* Draw a rectangle, given its upper-left and lower-right corners
   in pixels.
*/
typedef void (*DiaDrawPixelRectangleFunc) (DiaRenderer *renderer,
					   gint x, gint y,
					   gint width, gint height,
					   DiaColor *color);

/* Same a DrawPixelRectangleFunc, except the rectangle is filled using the
   current fill style */
typedef void (*DiaFillPixelRectangleFunc) (DiaRenderer *renderer,
					   gint x, gint y,
					   gint width, gint height,
					   DiaColor *color);


struct _DiaRenderOps {
  /* Control ops: */
  DiaBeginRenderFunc   begin_render;
  DiaEndRenderFunc     end_render;
  
  DiaSetOriginFunc     set_origin; /* NEW!!! */
  
  /* Line attributes: */
  DiaSetLineWidthFunc  set_linewidth;
  DiaSetLineCapsFunc   set_linecaps;
  DiaSetLineJoinFunc   set_linejoin;
  DiaSetLineStyleFunc  set_linestyle;
  DiaSetDashLengthFunc set_dashlength;
  /* Fill attributes: */
  DiaSetFillStyleFunc  set_fillstyle;
  /* Font stuff: */
  DiaSetFontFunc       set_font;
  
  /* Lines: */
  DiaDrawLineFunc      draw_line;
  DiaDrawPolyLineFunc  draw_polyline;

  /* Polygons: */
  DiaDrawPolygonFunc   draw_polygon;
  DiaFillPolygonFunc   fill_polygon;

  /* Rectangles: */
  DiaDrawRectangleFunc draw_rect;
  DiaFillRectangleFunc fill_rect;
  
  /* Arcs: */
  DiaDrawArcFunc       draw_arc;
  DiaFillArcFunc       fill_arc;
  
  /* Ellipses: */
  DiaDrawEllipseFunc   draw_ellipse;
  DiaFillEllipseFunc   fill_ellipse;

  /* Bezier curves: */
  DiaDrawBezierFunc    draw_bezier;
  DiaFillBezierFunc    fill_bezier;
  
  /* Text: */
  DiaDrawStringFunc    draw_string;

  /* Images: */
  DiaDrawImageFunc     draw_image; /* Not really supported yet */

  /* Object specific functions: */
  DiaDrawHandleFunc draw_handle;
  DiaDrawConnectionPointFunc draw_cp;
  
};

struct _DiaInteractiveRenderOps {
  DiaGetTextWidthFunc get_text_width;

  /* convenience functions that return the _absolute_ bounding box of a 
   * handle or connection point
   */
  DiaGetHandleBoundingBoxFunc get_handle_bb;
  DiaGetCPBoundingBoxFunc get_cp_bb;

  DiaClipRegionClearFunc clip_region_clear;
  DiaClipRegionAddRectangleFunc clip_region_add_rect;

  DiaDrawPixelLineFunc draw_pixel_line;
  DiaDrawPixelRectangleFunc draw_pixel_rect;
  DiaFillPixelRectangleFunc fill_pixel_rect;
};

struct _DiaRenderer {
  DiaRenderOps *ops;
  Point origin;
  
  gboolean is_interactive;
  DiaInteractiveRenderOps *interactive_ops;
  gint pixel_width; /* Only needed for interactive renderers.*/
  gint pixel_height; /* Only needed for interactive renderers.*/
};

DIA_CLOSE

#endif /* __DIA_RENDERER_H__ */





