goocanvas r24 - in trunk: . demo docs src
- From: damon svn gnome org
- To: svn-commits-list gnome org
- Subject: goocanvas r24 - in trunk: . demo docs src
- Date: Mon, 3 Nov 2008 11:31:46 +0000 (UTC)
Author: damon
Date: Mon Nov 3 11:31:46 2008
New Revision: 24
URL: http://svn.gnome.org/viewvc/goocanvas?rev=24&view=rev
Log:
2008-11-03 Damon Chaplin <damon gnome org>
* src/goocanvasgrid.[hc]: new grid item.
* demo/mv-demo.c (setup_grids):
* demo/demo.c (setup_grids): added a grid.
* src/Makefile.am: added grid.
* src/goocanvas.[hc] (goo_canvas_convert_bounds_to_item_space): new
function to convert a bounding box in device space to a bounding box
in item space. Useful in paint() methods to optimize painting.
* src/goocanvasutils.c (goo_canvas_convert_colors_to_rgba)
(goo_canvas_get_rgba_value_from_pattern)
(goo_canvas_set_style_property_from_pattern)
(goo_canvas_create_pattern_from_color_value)
(goo_canvas_create_pattern_from_rgba_value)
(goo_canvas_create_pattern_from_pixbuf_value): new private utility
functions taken out of goocanvasitemsimple.c code.
* src/goocanvasitemsimple.c: use above utility functions.
Added:
trunk/src/goocanvasgrid.c
trunk/src/goocanvasgrid.h
Modified:
trunk/ChangeLog
trunk/demo/demo.c
trunk/demo/mv-demo.c
trunk/docs/goocanvas-docs.sgml
trunk/docs/goocanvas-sections.txt
trunk/docs/goocanvas.types
trunk/src/Makefile.am
trunk/src/goocanvas.c
trunk/src/goocanvas.h
trunk/src/goocanvasitemsimple.c
trunk/src/goocanvasprivate.h
trunk/src/goocanvasutils.c
Modified: trunk/demo/demo.c
==============================================================================
--- trunk/demo/demo.c (original)
+++ trunk/demo/demo.c Mon Nov 3 11:31:46 2008
@@ -1438,6 +1438,25 @@
#endif
}
+
+static void
+setup_grids (GooCanvasItem *root)
+{
+ GooCanvasItem *item;
+
+ item = goo_canvas_grid_new (root, 80, 310, 90, 90, 10, 10, 5, 5,
+ "stroke-color", "yellow",
+ "fill-color", "pink",
+ "border-width", 2.0,
+ "border-color", "red",
+ "vert-grid-line-color", "lightblue",
+ "horz-grid-line-width", 1.0,
+ "vert-grid-line-width", 1.0,
+ "vert-grid-lines-on-top", TRUE,
+ NULL);
+}
+
+
static void
setup_canvas (GooCanvas *canvas)
{
@@ -1458,6 +1477,7 @@
setup_images (root);
setup_invisible_texts (root);
setup_static_items (canvas);
+ setup_grids (root);
#endif
test_color_properties (root);
Modified: trunk/demo/mv-demo.c
==============================================================================
--- trunk/demo/mv-demo.c (original)
+++ trunk/demo/mv-demo.c Mon Nov 3 11:31:46 2008
@@ -1292,6 +1292,24 @@
}
+static void
+setup_grids (GooCanvasItemModel *root)
+{
+ GooCanvasItemModel *item;
+
+ item = goo_canvas_grid_model_new (root, 80, 310, 90, 90, 10, 10, 5, 5,
+ "stroke-color", "yellow",
+ "fill-color", "pink",
+ "border-width", 2.0,
+ "border-color", "red",
+ "vert-grid-line-color", "lightblue",
+ "horz-grid-line-width", 1.0,
+ "vert-grid-line-width", 1.0,
+ "vert-grid-lines-on-top", TRUE,
+ NULL);
+}
+
+
static GooCanvasItemModel*
create_model (void)
{
@@ -1309,6 +1327,7 @@
setup_texts (root);
setup_images (root);
setup_invisible_texts (root);
+ setup_grids (root);
#endif
#if 0
setup_widgets (root);
Modified: trunk/docs/goocanvas-docs.sgml
==============================================================================
--- trunk/docs/goocanvas-docs.sgml (original)
+++ trunk/docs/goocanvas-docs.sgml Mon Nov 3 11:31:46 2008
@@ -31,6 +31,7 @@
<title>Standard Canvas Items</title>
<xi:include href="xml/goocanvasgroup.xml"/>
<xi:include href="xml/goocanvasellipse.xml"/>
+ <xi:include href="xml/goocanvasgrid.xml"/>
<xi:include href="xml/goocanvasimage.xml"/>
<xi:include href="xml/goocanvaspath.xml"/>
<xi:include href="xml/goocanvaspolyline.xml"/>
@@ -44,6 +45,7 @@
<title>Standard Canvas Item Models</title>
<xi:include href="xml/goocanvasgroupmodel.xml"/>
<xi:include href="xml/goocanvasellipsemodel.xml"/>
+ <xi:include href="xml/goocanvasgridmodel.xml"/>
<xi:include href="xml/goocanvasimagemodel.xml"/>
<xi:include href="xml/goocanvaspathmodel.xml"/>
<xi:include href="xml/goocanvaspolylinemodel.xml"/>
Modified: trunk/docs/goocanvas-sections.txt
==============================================================================
--- trunk/docs/goocanvas-sections.txt (original)
+++ trunk/docs/goocanvas-sections.txt Mon Nov 3 11:31:46 2008
@@ -387,6 +387,7 @@
goo_canvas_convert_from_pixels
goo_canvas_convert_to_item_space
goo_canvas_convert_from_item_space
+goo_canvas_convert_bounds_to_item_space
<SUBSECTION>
goo_canvas_pointer_grab
@@ -592,6 +593,45 @@
</SECTION>
<SECTION>
+<FILE>goocanvasgrid</FILE>
+<TITLE>GooCanvasGrid</TITLE>
+GooCanvasGrid
+goo_canvas_grid_new
+
+<SUBSECTION Standard>
+GOO_CANVAS_GRID
+GOO_IS_CANVAS_GRID
+GOO_TYPE_CANVAS_GRID
+goo_canvas_grid_get_type
+GOO_CANVAS_GRID_CLASS
+GOO_IS_CANVAS_GRID_CLASS
+GOO_CANVAS_GRID_GET_CLASS
+
+<SUBSECTION Private>
+GooCanvasGridData
+GooCanvasGridClass
+</SECTION>
+
+<SECTION>
+<FILE>goocanvasgridmodel</FILE>
+<TITLE>GooCanvasGridModel</TITLE>
+GooCanvasGridModel
+goo_canvas_grid_model_new
+
+<SUBSECTION Standard>
+GOO_CANVAS_GRID_MODEL
+GOO_IS_CANVAS_GRID_MODEL
+GOO_TYPE_CANVAS_GRID_MODEL
+goo_canvas_grid_model_get_type
+GOO_CANVAS_GRID_MODEL_CLASS
+GOO_IS_CANVAS_GRID_MODEL_CLASS
+GOO_CANVAS_GRID_MODEL_GET_CLASS
+
+<SUBSECTION Private>
+GooCanvasGridModelClass
+</SECTION>
+
+<SECTION>
<FILE>goocanvaswidget</FILE>
<TITLE>GooCanvasWidget</TITLE>
GooCanvasWidget
Modified: trunk/docs/goocanvas.types
==============================================================================
--- trunk/docs/goocanvas.types (original)
+++ trunk/docs/goocanvas.types Mon Nov 3 11:31:46 2008
@@ -37,3 +37,5 @@
goo_canvas_image_model_get_type
goo_canvas_table_get_type
goo_canvas_table_model_get_type
+goo_canvas_grid_get_type
+goo_canvas_grid_model_get_type
Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am (original)
+++ trunk/src/Makefile.am Mon Nov 3 11:31:46 2008
@@ -29,6 +29,7 @@
libgoocanvas_public_headers = \
goocanvasellipse.h \
+ goocanvasgrid.h \
goocanvasgroup.h \
goocanvasimage.h \
goocanvasitem.h \
@@ -49,6 +50,7 @@
goocanvasatk.c \
goocanvasellipse.c \
goocanvasenumtypes.c \
+ goocanvasgrid.c \
goocanvasgroup.c \
goocanvasimage.c \
goocanvasitem.c \
Modified: trunk/src/goocanvas.c
==============================================================================
--- trunk/src/goocanvas.c (original)
+++ trunk/src/goocanvas.c Mon Nov 3 11:31:46 2008
@@ -3486,22 +3486,9 @@
}
-/**
- * goo_canvas_convert_to_item_space:
- * @canvas: a #GooCanvas.
- * @item: a #GooCanvasItem.
- * @x: a pointer to the x coordinate to convert.
- * @y: a pointer to the y coordinate to convert.
- *
- * Converts a coordinate from the canvas coordinate space to the given
- * item's coordinate space, applying all transformation matrices including the
- * item's own transformation matrix, if it has one.
- **/
-void
-goo_canvas_convert_to_item_space (GooCanvas *canvas,
- GooCanvasItem *item,
- gdouble *x,
- gdouble *y)
+static void
+get_transform_to_item_space (GooCanvasItem *item,
+ cairo_matrix_t *transform)
{
GooCanvasItem *tmp = item, *parent, *child;
GList *list = NULL, *l;
@@ -3530,8 +3517,31 @@
}
g_list_free (list);
- /* Now convert the coordinates. */
- cairo_matrix_transform_point (&inverse, x, y);
+ *transform = inverse;
+}
+
+
+/**
+ * goo_canvas_convert_to_item_space:
+ * @canvas: a #GooCanvas.
+ * @item: a #GooCanvasItem.
+ * @x: a pointer to the x coordinate to convert.
+ * @y: a pointer to the y coordinate to convert.
+ *
+ * Converts a coordinate from the canvas coordinate space to the given
+ * item's coordinate space, applying all transformation matrices including the
+ * item's own transformation matrix, if it has one.
+ **/
+void
+goo_canvas_convert_to_item_space (GooCanvas *canvas,
+ GooCanvasItem *item,
+ gdouble *x,
+ gdouble *y)
+{
+ cairo_matrix_t transform;
+
+ get_transform_to_item_space (item, &transform);
+ cairo_matrix_transform_point (&transform, x, y);
}
@@ -3583,6 +3593,56 @@
}
+/**
+ * goo_canvas_convert_bounds_to_item_space:
+ * @canvas: a #GooCanvas.
+ * @item: a #GooCanvasItem.
+ * @bounds: the bounds in device space.
+ *
+ * Converts the bound in device space to a bounding box in item space.
+ * This is useful in the item paint() methods to convert the bounds to be
+ * painted to the item's coordinate space.
+ **/
+void
+goo_canvas_convert_bounds_to_item_space (GooCanvas *canvas,
+ GooCanvasItem *item,
+ GooCanvasBounds *bounds)
+{
+ GooCanvasBounds tmp_bounds = *bounds, tmp_bounds2 = *bounds;
+ cairo_matrix_t transform;
+
+ get_transform_to_item_space (item, &transform);
+
+ /* Convert the top-left and bottom-right corners to device coords. */
+ cairo_matrix_transform_point (&transform, &tmp_bounds.x1, &tmp_bounds.y1);
+ cairo_matrix_transform_point (&transform, &tmp_bounds.x2, &tmp_bounds.y2);
+
+ /* Now convert the top-right and bottom-left corners. */
+ cairo_matrix_transform_point (&transform, &tmp_bounds2.x1, &tmp_bounds2.y2);
+ cairo_matrix_transform_point (&transform, &tmp_bounds2.x2, &tmp_bounds2.y1);
+
+ /* Calculate the minimum x coordinate seen and put in x1. */
+ bounds->x1 = MIN (tmp_bounds.x1, tmp_bounds.x2);
+ bounds->x1 = MIN (bounds->x1, tmp_bounds2.x1);
+ bounds->x1 = MIN (bounds->x1, tmp_bounds2.x2);
+
+ /* Calculate the maximum x coordinate seen and put in x2. */
+ bounds->x2 = MAX (tmp_bounds.x1, tmp_bounds.x2);
+ bounds->x2 = MAX (bounds->x2, tmp_bounds2.x1);
+ bounds->x2 = MAX (bounds->x2, tmp_bounds2.x2);
+
+ /* Calculate the minimum y coordinate seen and put in y1. */
+ bounds->y1 = MIN (tmp_bounds.y1, tmp_bounds.y2);
+ bounds->y1 = MIN (bounds->y1, tmp_bounds2.y1);
+ bounds->y1 = MIN (bounds->y1, tmp_bounds2.y2);
+
+ /* Calculate the maximum y coordinate seen and put in y2. */
+ bounds->y2 = MAX (tmp_bounds.y1, tmp_bounds.y2);
+ bounds->y2 = MAX (bounds->y2, tmp_bounds2.y1);
+ bounds->y2 = MAX (bounds->y2, tmp_bounds2.y2);
+}
+
+
/*
* Keyboard focus navigation.
*/
Modified: trunk/src/goocanvas.h
==============================================================================
--- trunk/src/goocanvas.h (original)
+++ trunk/src/goocanvas.h Mon Nov 3 11:31:46 2008
@@ -10,6 +10,7 @@
#include <gtk/gtk.h>
#include <goocanvasenumtypes.h>
#include <goocanvasellipse.h>
+#include <goocanvasgrid.h>
#include <goocanvasgroup.h>
#include <goocanvasimage.h>
#include <goocanvaspath.h>
@@ -272,6 +273,9 @@
GooCanvasItem *item,
gdouble *x,
gdouble *y);
+void goo_canvas_convert_bounds_to_item_space (GooCanvas *canvas,
+ GooCanvasItem *item,
+ GooCanvasBounds *bounds);
/*
Added: trunk/src/goocanvasgrid.c
==============================================================================
--- (empty file)
+++ trunk/src/goocanvasgrid.c Mon Nov 3 11:31:46 2008
@@ -0,0 +1,1075 @@
+/*
+ * GooCanvas. Copyright (C) 2005-8 Damon Chaplin.
+ * Released under the GNU LGPL license. See COPYING for details.
+ *
+ * goocanvasgrid.c - a grid item.
+ */
+
+/**
+ * SECTION:goocanvasgrid
+ * @Title: GooCanvasGrid
+ * @Short_Description: a grid item.
+ *
+ * GooCanvasGrid represents a grid item.
+ *
+ * It is a subclass of #GooCanvasItemSimple and so inherits all of the style
+ * properties such as "stroke-color", "fill-color" and "line-width".
+ *
+ * It also implements the #GooCanvasItem interface, so you can use the
+ * #GooCanvasItem functions such as goo_canvas_item_raise() and
+ * goo_canvas_item_rotate().
+ *
+ * To create a #GooCanvasGrid use goo_canvas_grid_new().
+ *
+ * To get or set the properties of an existing #GooCanvasGrid, use
+ * g_object_get() and g_object_set().
+ */
+#include <config.h>
+#include <math.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include "goocanvasprivate.h"
+#include "goocanvas.h"
+
+
+enum {
+ PROP_0,
+
+ PROP_X,
+ PROP_Y,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_X_STEP,
+ PROP_Y_STEP,
+ PROP_X_OFFSET,
+ PROP_Y_OFFSET,
+ PROP_HORZ_GRID_LINE_WIDTH,
+ PROP_VERT_GRID_LINE_WIDTH,
+ PROP_HORZ_GRID_LINE_PATTERN,
+ PROP_VERT_GRID_LINE_PATTERN,
+ PROP_BORDER_WIDTH,
+ PROP_BORDER_PATTERN,
+ PROP_VERT_GRID_LINES_ON_TOP,
+
+ /* Convenience properties. */
+ PROP_HORZ_GRID_LINE_COLOR,
+ PROP_HORZ_GRID_LINE_COLOR_RGBA,
+ PROP_HORZ_GRID_LINE_PIXBUF,
+ PROP_VERT_GRID_LINE_COLOR,
+ PROP_VERT_GRID_LINE_COLOR_RGBA,
+ PROP_VERT_GRID_LINE_PIXBUF,
+ PROP_BORDER_COLOR,
+ PROP_BORDER_COLOR_RGBA,
+ PROP_BORDER_PIXBUF
+};
+
+
+GooCanvasItemIface *goo_canvas_grid_parent_iface;
+
+static void canvas_item_interface_init (GooCanvasItemIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasGrid, goo_canvas_grid,
+ GOO_TYPE_CANVAS_ITEM_SIMPLE,
+ G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM,
+ canvas_item_interface_init))
+
+
+static void
+goo_canvas_grid_install_common_properties (GObjectClass *gobject_class)
+{
+ g_object_class_install_property (gobject_class, PROP_X,
+ g_param_spec_double ("x",
+ "X",
+ _("The x coordinate of the grid"),
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE, 0.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_Y,
+ g_param_spec_double ("y",
+ "Y",
+ _("The y coordinate of the grid"),
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE, 0.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_WIDTH,
+ g_param_spec_double ("width",
+ _("Width"),
+ _("The width of the grid"),
+ 0.0, G_MAXDOUBLE, 0.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_HEIGHT,
+ g_param_spec_double ("height",
+ _("Height"),
+ _("The height of the grid"),
+ 0.0, G_MAXDOUBLE, 0.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_X_STEP,
+ g_param_spec_double ("x-step",
+ "X Step",
+ _("The distance between the vertical grid lines"),
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_Y_STEP,
+ g_param_spec_double ("y-step",
+ "Y Step",
+ _("The distance between the horizontal grid lines"),
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_X_OFFSET,
+ g_param_spec_double ("x-offset",
+ "X Offset",
+ _("The distance before the first vertical grid line"),
+ 0.0, G_MAXDOUBLE, 0.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_Y_OFFSET,
+ g_param_spec_double ("y-offset",
+ "Y Offset",
+ _("The distance before the first horizontal grid line"),
+ 0.0, G_MAXDOUBLE, 0.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_WIDTH,
+ g_param_spec_double ("horz-grid-line-width",
+ _("Horizontal Grid Line Width"),
+ _("The width of the horizontal grid lines"),
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE, -1.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_WIDTH,
+ g_param_spec_double ("vert-grid-line-width",
+ _("Vertical Grid Line Width"),
+ _("The width of the vertical grid lines"),
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE, -1.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_PATTERN,
+ g_param_spec_boxed ("horz-grid-line-pattern",
+ _("Horizontal Grid Line Pattern"),
+ _("The cairo pattern to paint the horizontal grid lines with"),
+ GOO_TYPE_CAIRO_PATTERN,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_PATTERN,
+ g_param_spec_boxed ("vert-grid-line-pattern",
+ _("Vertical Grid Line Pattern"),
+ _("The cairo pattern to paint the vertical grid lines with"),
+ GOO_TYPE_CAIRO_PATTERN,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_BORDER_WIDTH,
+ g_param_spec_double ("border-width",
+ _("Border Width"),
+ _("The width of the border around the grid"),
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE, -1.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_BORDER_PATTERN,
+ g_param_spec_boxed ("border-pattern",
+ _("Border Pattern"),
+ _("The cairo pattern to paint the border with"),
+ GOO_TYPE_CAIRO_PATTERN,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINES_ON_TOP,
+ g_param_spec_boolean ("vert-grid-lines-on-top",
+ _("Vertical Grid Lines On Top"),
+ _("If the vertical grid lines are painted above the horizontal grid lines"),
+ FALSE,
+ G_PARAM_READWRITE));
+
+
+ /* Convenience properties - some are writable only. */
+ g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_COLOR,
+ g_param_spec_string ("horz-grid-line-color",
+ _("Horizontal Grid Line Color"),
+ _("The color to use for the horizontal grid lines"),
+ NULL,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_COLOR_RGBA,
+ g_param_spec_uint ("horz-grid-line-color-rgba",
+ _("Horizontal Grid Line Color RGBA"),
+ _("The color to use for the horizontal grid lines, specified as a 32-bit integer value"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_HORZ_GRID_LINE_PIXBUF,
+ g_param_spec_object ("horz-grid-line-pixbuf",
+ _("Horizontal Grid Line Pixbuf"),
+ _("The pixbuf to use to draw the horizontal grid lines"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_COLOR,
+ g_param_spec_string ("vert-grid-line-color",
+ _("Vertical Grid Line Color"),
+ _("The color to use for the vertical grid lines"),
+ NULL,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_COLOR_RGBA,
+ g_param_spec_uint ("vert-grid-line-color-rgba",
+ _("Vertical Grid Line Color RGBA"),
+ _("The color to use for the vertical grid lines, specified as a 32-bit integer value"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_VERT_GRID_LINE_PIXBUF,
+ g_param_spec_object ("vert-grid-line-pixbuf",
+ _("Vertical Grid Line Pixbuf"),
+ _("The pixbuf to use to draw the vertical grid lines"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_BORDER_COLOR,
+ g_param_spec_string ("border-color",
+ _("Border Color"),
+ _("The color to use for the border"),
+ NULL,
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_BORDER_COLOR_RGBA,
+ g_param_spec_uint ("border-color-rgba",
+ _("Border Color RGBA"),
+ _("The color to use for the border, specified as a 32-bit integer value"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, PROP_BORDER_PIXBUF,
+ g_param_spec_object ("border-pixbuf",
+ _("Border Pixbuf"),
+ _("The pixbuf to use to draw the border"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_WRITABLE));
+}
+
+
+/* This initializes the common grid data. */
+static void
+goo_canvas_grid_init_data (GooCanvasGridData *grid_data)
+{
+ grid_data->x = 0.0;
+ grid_data->y = 0.0;
+ grid_data->width = 0.0;
+ grid_data->height = 0.0;
+ grid_data->x_step = 10.0;
+ grid_data->y_step = 10.0;
+ grid_data->x_offset = 0.0;
+ grid_data->y_offset = 0.0;
+ grid_data->horz_grid_line_width = -1.0;
+ grid_data->vert_grid_line_width = -1.0;
+ grid_data->horz_grid_line_pattern = NULL;
+ grid_data->vert_grid_line_pattern = NULL;
+ grid_data->border_width = -1.0;
+ grid_data->border_pattern = NULL;
+ grid_data->vert_grid_lines_on_top = FALSE;
+}
+
+
+/* This frees the contents of the grid data, but not the struct itself. */
+static void
+goo_canvas_grid_free_data (GooCanvasGridData *grid_data)
+{
+
+}
+
+
+static void
+goo_canvas_grid_init (GooCanvasGrid *grid)
+{
+ grid->grid_data = g_slice_new0 (GooCanvasGridData);
+ goo_canvas_grid_init_data (grid->grid_data);
+}
+
+
+/**
+ * goo_canvas_grid_new:
+ * @parent: the parent item, or %NULL. If a parent is specified, it will assume
+ * ownership of the item, and the item will automatically be freed when it is
+ * removed from the parent. Otherwise call g_object_unref() to free it.
+ * @x: the x coordinate of the left of the grid.
+ * @y: the y coordinate of the top of the grid.
+ * @width: the width of the grid.
+ * @height: the height of the grid.
+ * @x_step: the distance between the vertical grid lines.
+ * @y_step: the distance between the horizontal grid lines.
+ * @x_offset: the distance before the first vertical grid line.
+ * @y_offset: the distance before the first horizontal grid line.
+ * @...: optional pairs of property names and values, and a terminating %NULL.
+ *
+ * Creates a new grid item.
+ *
+ * <!--PARAMETERS-->
+ *
+ * Here's an example showing how to create a grid:
+ *
+ * <informalexample><programlisting>
+ * GooCanvasItem *grid = goo_canvas_grid_new (mygroup, 100.0, 100.0, 400.0, 200.0,
+ * 20.0, 20.0, 10.0, 10.0,
+ * "horz-grid-line-width", 4.0,
+ * "horz-grid-line-color", "yellow",
+ * "vert-grid-line-width", 2.0,
+ * "vert-grid-line-color", "red",
+ * "border-width", 3.0,
+ * "border-color", "white",
+ * "fill-color", "blue",
+ * NULL);
+ * </programlisting></informalexample>
+ *
+ * Returns: a new grid item.
+ **/
+GooCanvasItem*
+goo_canvas_grid_new (GooCanvasItem *parent,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ gdouble x_step,
+ gdouble y_step,
+ gdouble x_offset,
+ gdouble y_offset,
+ ...)
+{
+ GooCanvasItem *item;
+ GooCanvasGrid *grid;
+ GooCanvasGridData *grid_data;
+ va_list var_args;
+ const char *first_property;
+
+ item = g_object_new (GOO_TYPE_CANVAS_GRID, NULL);
+ grid = (GooCanvasGrid*) item;
+
+ grid_data = grid->grid_data;
+ grid_data->x = x;
+ grid_data->y = y;
+ grid_data->width = width;
+ grid_data->height = height;
+ grid_data->x_step = x_step;
+ grid_data->y_step = y_step;
+ grid_data->x_offset = x_offset;
+ grid_data->y_offset = y_offset;
+
+ va_start (var_args, y_offset);
+ first_property = va_arg (var_args, char*);
+ if (first_property)
+ g_object_set_valist (G_OBJECT (item), first_property, var_args);
+ va_end (var_args);
+
+ if (parent)
+ {
+ goo_canvas_item_add_child (parent, item, -1);
+ g_object_unref (item);
+ }
+
+ return item;
+}
+
+
+static void
+goo_canvas_grid_finalize (GObject *object)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasGrid *grid = (GooCanvasGrid*) object;
+
+ /* Free our data if we didn't have a model. (If we had a model it would
+ have been reset in dispose() and simple_data will be NULL.) */
+ if (simple->simple_data)
+ {
+ goo_canvas_grid_free_data (grid->grid_data);
+ g_slice_free (GooCanvasGridData, grid->grid_data);
+ }
+ grid->grid_data = NULL;
+
+ G_OBJECT_CLASS (goo_canvas_grid_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_grid_get_common_property (GObject *object,
+ GooCanvasGridData *grid_data,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_X:
+ g_value_set_double (value, grid_data->x);
+ break;
+ case PROP_Y:
+ g_value_set_double (value, grid_data->y);
+ break;
+ case PROP_WIDTH:
+ g_value_set_double (value, grid_data->width);
+ break;
+ case PROP_HEIGHT:
+ g_value_set_double (value, grid_data->height);
+ break;
+ case PROP_X_STEP:
+ g_value_set_double (value, grid_data->x_step);
+ break;
+ case PROP_Y_STEP:
+ g_value_set_double (value, grid_data->y_step);
+ break;
+ case PROP_X_OFFSET:
+ g_value_set_double (value, grid_data->x_offset);
+ break;
+ case PROP_Y_OFFSET:
+ g_value_set_double (value, grid_data->y_offset);
+ break;
+ case PROP_HORZ_GRID_LINE_WIDTH:
+ g_value_set_double (value, grid_data->horz_grid_line_width);
+ break;
+ case PROP_VERT_GRID_LINE_WIDTH:
+ g_value_set_double (value, grid_data->vert_grid_line_width);
+ break;
+ case PROP_HORZ_GRID_LINE_PATTERN:
+ g_value_set_boxed (value, grid_data->horz_grid_line_pattern);
+ break;
+ case PROP_VERT_GRID_LINE_PATTERN:
+ g_value_set_boxed (value, grid_data->vert_grid_line_pattern);
+ break;
+ case PROP_BORDER_WIDTH:
+ g_value_set_double (value, grid_data->border_width);
+ break;
+ case PROP_BORDER_PATTERN:
+ g_value_set_boxed (value, grid_data->border_pattern);
+ break;
+ case PROP_VERT_GRID_LINES_ON_TOP:
+ g_value_set_boolean (value, grid_data->vert_grid_lines_on_top);
+ break;
+
+ /* Convenience properties. */
+ case PROP_HORZ_GRID_LINE_COLOR_RGBA:
+ goo_canvas_get_rgba_value_from_pattern (grid_data->horz_grid_line_pattern, value);
+ break;
+ case PROP_VERT_GRID_LINE_COLOR_RGBA:
+ goo_canvas_get_rgba_value_from_pattern (grid_data->vert_grid_line_pattern, value);
+ break;
+ case PROP_BORDER_COLOR_RGBA:
+ goo_canvas_get_rgba_value_from_pattern (grid_data->border_pattern, value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+goo_canvas_grid_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasGrid *grid = (GooCanvasGrid*) object;
+
+ goo_canvas_grid_get_common_property (object, grid->grid_data,
+ prop_id, value, pspec);
+}
+
+
+static void
+goo_canvas_grid_set_common_property (GObject *object,
+ GooCanvasGridData *grid_data,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_X:
+ grid_data->x = g_value_get_double (value);
+ break;
+ case PROP_Y:
+ grid_data->y = g_value_get_double (value);
+ break;
+ case PROP_WIDTH:
+ grid_data->width = g_value_get_double (value);
+ break;
+ case PROP_HEIGHT:
+ grid_data->height = g_value_get_double (value);
+ break;
+ case PROP_X_STEP:
+ grid_data->x_step = g_value_get_double (value);
+ break;
+ case PROP_Y_STEP:
+ grid_data->y_step = g_value_get_double (value);
+ break;
+ case PROP_X_OFFSET:
+ grid_data->x_offset = g_value_get_double (value);
+ break;
+ case PROP_Y_OFFSET:
+ grid_data->y_offset = g_value_get_double (value);
+ break;
+ case PROP_HORZ_GRID_LINE_WIDTH:
+ grid_data->horz_grid_line_width = g_value_get_double (value);
+ break;
+ case PROP_VERT_GRID_LINE_WIDTH:
+ grid_data->vert_grid_line_width = g_value_get_double (value);
+ break;
+ case PROP_HORZ_GRID_LINE_PATTERN:
+ cairo_pattern_destroy (grid_data->horz_grid_line_pattern);
+ grid_data->horz_grid_line_pattern = g_value_get_boxed (value);
+ cairo_pattern_reference (grid_data->horz_grid_line_pattern);
+ break;
+ case PROP_VERT_GRID_LINE_PATTERN:
+ cairo_pattern_destroy (grid_data->vert_grid_line_pattern);
+ grid_data->vert_grid_line_pattern = g_value_get_boxed (value);
+ cairo_pattern_reference (grid_data->vert_grid_line_pattern);
+ break;
+ case PROP_BORDER_WIDTH:
+ grid_data->border_width = g_value_get_double (value);
+ break;
+ case PROP_BORDER_PATTERN:
+ cairo_pattern_destroy (grid_data->border_pattern);
+ grid_data->border_pattern = g_value_get_boxed (value);
+ cairo_pattern_reference (grid_data->border_pattern);
+ break;
+ case PROP_VERT_GRID_LINES_ON_TOP:
+ grid_data->vert_grid_lines_on_top = g_value_get_boolean (value);
+ break;
+
+ /* Convenience properties. */
+ case PROP_HORZ_GRID_LINE_COLOR:
+ cairo_pattern_destroy (grid_data->horz_grid_line_pattern);
+ grid_data->horz_grid_line_pattern = goo_canvas_create_pattern_from_color_value (value);
+ break;
+ case PROP_HORZ_GRID_LINE_COLOR_RGBA:
+ cairo_pattern_destroy (grid_data->horz_grid_line_pattern);
+ grid_data->horz_grid_line_pattern = goo_canvas_create_pattern_from_rgba_value (value);
+ break;
+ case PROP_HORZ_GRID_LINE_PIXBUF:
+ cairo_pattern_destroy (grid_data->horz_grid_line_pattern);
+ grid_data->horz_grid_line_pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
+ break;
+
+ case PROP_VERT_GRID_LINE_COLOR:
+ cairo_pattern_destroy (grid_data->vert_grid_line_pattern);
+ grid_data->vert_grid_line_pattern = goo_canvas_create_pattern_from_color_value (value);
+ break;
+ case PROP_VERT_GRID_LINE_COLOR_RGBA:
+ cairo_pattern_destroy (grid_data->vert_grid_line_pattern);
+ grid_data->vert_grid_line_pattern = goo_canvas_create_pattern_from_rgba_value (value);
+ break;
+ case PROP_VERT_GRID_LINE_PIXBUF:
+ cairo_pattern_destroy (grid_data->vert_grid_line_pattern);
+ grid_data->vert_grid_line_pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
+ break;
+
+ case PROP_BORDER_COLOR:
+ cairo_pattern_destroy (grid_data->border_pattern);
+ grid_data->border_pattern = goo_canvas_create_pattern_from_color_value (value);
+ break;
+ case PROP_BORDER_COLOR_RGBA:
+ cairo_pattern_destroy (grid_data->border_pattern);
+ grid_data->border_pattern = goo_canvas_create_pattern_from_rgba_value (value);
+ break;
+ case PROP_BORDER_PIXBUF:
+ cairo_pattern_destroy (grid_data->border_pattern);
+ grid_data->border_pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+goo_canvas_grid_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object;
+ GooCanvasGrid *grid = (GooCanvasGrid*) object;
+
+ if (simple->model)
+ {
+ g_warning ("Can't set property of a canvas item with a model - set the model property instead");
+ return;
+ }
+
+ goo_canvas_grid_set_common_property (object, grid->grid_data,
+ prop_id, value, pspec);
+ goo_canvas_item_simple_changed (simple, TRUE);
+}
+
+
+static void
+goo_canvas_grid_update (GooCanvasItemSimple *simple,
+ cairo_t *cr)
+{
+ GooCanvasGrid *grid = (GooCanvasGrid*) simple;
+ GooCanvasGridData *grid_data = grid->grid_data;
+ gdouble border_width = 0.0;
+
+ /* We can quickly compute the bounds as being just the grid's size
+ plus the border width around each edge. */
+ if (grid_data->border_width > 0.0)
+ border_width = grid_data->border_width;
+
+ simple->bounds.x1 = grid_data->x - border_width;
+ simple->bounds.y1 = grid_data->y - border_width;
+ simple->bounds.x2 = grid_data->x + grid_data->width + border_width;
+ simple->bounds.y2 = grid_data->y + grid_data->height + border_width;
+}
+
+
+static gdouble
+calculate_start_position (gdouble start_pos,
+ gdouble step,
+ gdouble redraw_start_pos,
+ gdouble line_width)
+{
+ gdouble n, result;
+
+ /* We want the first position where pos + line_width/2 >= redraw_start_pos.
+ i.e. start_pos + (n * step) + (line_width / 2) >= redraw_start_pos,
+ or (n * step) >= redraw_start_pos - start_pos - (line_width / 2),
+ or n >= (redraw_start_pos - start_pos - (line_width / 2) / step). */
+ n = ceil (((redraw_start_pos - start_pos - (line_width / 2.0))) / step);
+
+ if (n <= 0)
+ result = start_pos;
+ else
+ result = start_pos + (n * step);
+
+ return result;
+}
+
+
+static void
+paint_vertical_lines (GooCanvasItemSimple *simple,
+ cairo_t *cr,
+ const GooCanvasBounds *bounds)
+{
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+ GooCanvasGrid *grid = (GooCanvasGrid*) simple;
+ GooCanvasGridData *grid_data = grid->grid_data;
+ double x, max_x, max_y, max_bounds_x, line_width;
+ gboolean has_stroke;
+
+ max_x = grid_data->x + grid_data->width;
+ max_y = grid_data->y + grid_data->height;
+
+ has_stroke = goo_canvas_style_set_stroke_options (simple_data->style, cr);
+ line_width = goo_canvas_item_simple_get_line_width (simple);
+
+ /* If the grid's vertical grid line pattern/color has been set, use that.
+ If not, and we don't have a stroke color just return. */
+ if (grid_data->vert_grid_line_pattern)
+ cairo_set_source (cr, grid_data->vert_grid_line_pattern);
+ else if (!has_stroke)
+ return;
+
+ /* If the grid's vertical grid line width has been set, use that. */
+ if (grid_data->vert_grid_line_width > 0.0)
+ {
+ line_width = grid_data->vert_grid_line_width;
+ cairo_set_line_width (cr, line_width);
+ }
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+
+ /* Calculate the first grid line that intersects the bounds to redraw. */
+ x = calculate_start_position (grid_data->x + grid_data->x_offset,
+ grid_data->x_step, bounds->x1, line_width);
+
+ /* Calculate the last possible line position. */
+ max_bounds_x = bounds->x2 + (line_width / 2.0);
+ max_x = MIN (max_x, max_bounds_x);
+
+ /* Add on a tiny fraction of step to avoid any double comparison issues. */
+ max_x += grid_data->x_step * 0.00001;
+
+ while (x <= max_x)
+ {
+ cairo_move_to (cr, x, grid_data->y);
+ cairo_line_to (cr, x, max_y);
+ cairo_stroke (cr);
+
+ x += grid_data->x_step;
+ }
+}
+
+
+static void
+paint_horizontal_lines (GooCanvasItemSimple *simple,
+ cairo_t *cr,
+ const GooCanvasBounds *bounds)
+{
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+ GooCanvasGrid *grid = (GooCanvasGrid*) simple;
+ GooCanvasGridData *grid_data = grid->grid_data;
+ double y, max_x, max_y, max_bounds_y, line_width;
+ gboolean has_stroke;
+
+ max_x = grid_data->x + grid_data->width;
+ max_y = grid_data->y + grid_data->height;
+
+ has_stroke = goo_canvas_style_set_stroke_options (simple_data->style, cr);
+ line_width = goo_canvas_item_simple_get_line_width (simple);
+
+ /* If the grid's horizontal grid line pattern/color has been set, use that.
+ If not, and we don't have a stroke color just return. */
+ if (grid_data->horz_grid_line_pattern)
+ cairo_set_source (cr, grid_data->horz_grid_line_pattern);
+ else if (!has_stroke)
+ return;
+
+ /* If the grid's horizontal grid line width has been set, use that. */
+ if (grid_data->horz_grid_line_width > 0.0)
+ {
+ line_width = grid_data->horz_grid_line_width;
+ cairo_set_line_width (cr, grid_data->horz_grid_line_width);
+ }
+
+ cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+
+ /* Calculate the first grid line that intersects the bounds to redraw. */
+ y = calculate_start_position (grid_data->y + grid_data->y_offset,
+ grid_data->y_step, bounds->y1, line_width);
+
+ /* Calculate the last possible line position. */
+ max_bounds_y = bounds->y2 + (line_width / 2.0);
+ max_y = MIN (max_y, max_bounds_y);
+
+ /* Add on a tiny fraction of step to avoid any double comparison issues. */
+ max_y += grid_data->y_step * 0.00001;
+
+ while (y <= max_y)
+ {
+ cairo_move_to (cr, grid_data->x, y);
+ cairo_line_to (cr, max_x, y);
+ cairo_stroke (cr);
+
+ y += grid_data->y_step;
+ }
+}
+
+
+static void
+goo_canvas_grid_paint (GooCanvasItemSimple *simple,
+ cairo_t *cr,
+ const GooCanvasBounds *bounds)
+{
+ GooCanvasItemSimpleData *simple_data = simple->simple_data;
+ GooCanvasGrid *grid = (GooCanvasGrid*) simple;
+ GooCanvasGridData *grid_data = grid->grid_data;
+ GooCanvasBounds redraw_bounds = *bounds;
+ gdouble half_border_width;
+
+ /* Paint the background in the fill pattern/color, if one is set. */
+ if (goo_canvas_style_set_fill_options (simple_data->style, cr))
+ {
+ cairo_rectangle (cr, grid_data->x, grid_data->y,
+ grid_data->width, grid_data->height);
+ cairo_fill (cr);
+ }
+
+ /* Clip to the grid's area while painting the grid lines. */
+ cairo_save (cr);
+ cairo_rectangle (cr, grid_data->x, grid_data->y,
+ grid_data->width, grid_data->height);
+ cairo_clip (cr);
+
+ /* Convert the bounds to be redrawn from device space to item space. */
+ goo_canvas_convert_bounds_to_item_space (simple->canvas,
+ (GooCanvasItem*) simple,
+ &redraw_bounds);
+
+ /* Paint the grid lines, in the required order. */
+ if (grid_data->vert_grid_lines_on_top)
+ {
+ paint_horizontal_lines (simple, cr, &redraw_bounds);
+ paint_vertical_lines (simple, cr, &redraw_bounds);
+ }
+ else
+ {
+ paint_vertical_lines (simple, cr, &redraw_bounds);
+ paint_horizontal_lines (simple, cr, &redraw_bounds);
+ }
+
+ cairo_restore (cr);
+
+ /* Paint the border. */
+ if (grid_data->border_width > 0)
+ {
+ if (grid_data->border_pattern)
+ cairo_set_source (cr, grid_data->border_pattern);
+ else
+ goo_canvas_style_set_stroke_options (simple_data->style, cr);
+
+ cairo_set_line_width (cr, grid_data->border_width);
+ half_border_width = grid_data->border_width / 2.0;
+ cairo_rectangle (cr, grid_data->x - half_border_width,
+ grid_data->y - half_border_width,
+ grid_data->width + grid_data->border_width,
+ grid_data->height + grid_data->border_width);
+ cairo_stroke (cr);
+ }
+}
+
+
+static void
+goo_canvas_grid_set_model (GooCanvasItem *item,
+ GooCanvasItemModel *model)
+{
+ GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+ GooCanvasGrid *grid = (GooCanvasGrid*) item;
+ GooCanvasGridModel *gmodel = (GooCanvasGridModel*) model;
+
+ /* If our grid_data was allocated, free it. */
+ if (!simple->model)
+ {
+ goo_canvas_grid_free_data (grid->grid_data);
+ g_slice_free (GooCanvasGridData, grid->grid_data);
+ }
+
+ /* Now use the new model's grid_data instead. */
+ grid->grid_data = &gmodel->grid_data;
+
+ /* Let the parent class do the rest. */
+ goo_canvas_grid_parent_iface->set_model (item, model);
+}
+
+
+static void
+canvas_item_interface_init (GooCanvasItemIface *iface)
+{
+ iface->set_model = goo_canvas_grid_set_model;
+}
+
+
+static void
+goo_canvas_grid_class_init (GooCanvasGridClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+ GooCanvasItemSimpleClass *simple_class = (GooCanvasItemSimpleClass*) klass;
+
+ goo_canvas_grid_parent_iface = g_type_interface_peek (goo_canvas_grid_parent_class, GOO_TYPE_CANVAS_ITEM);
+
+ gobject_class->finalize = goo_canvas_grid_finalize;
+
+ gobject_class->get_property = goo_canvas_grid_get_property;
+ gobject_class->set_property = goo_canvas_grid_set_property;
+
+ simple_class->simple_update = goo_canvas_grid_update;
+ simple_class->simple_paint = goo_canvas_grid_paint;
+
+ goo_canvas_grid_install_common_properties (gobject_class);
+}
+
+
+
+/**
+ * SECTION:goocanvasgridmodel
+ * @Title: GooCanvasGridModel
+ * @Short_Description: a model for grid items.
+ *
+ * GooCanvasGridModel represents a model for grid items.
+ *
+ * It is a subclass of #GooCanvasItemModelSimple and so inherits all of the
+ * style properties such as "stroke-color", "fill-color" and "line-width".
+ *
+ * It also implements the #GooCanvasItemModel interface, so you can use the
+ * #GooCanvasItemModel functions such as goo_canvas_item_model_raise() and
+ * goo_canvas_item_model_rotate().
+ *
+ * To create a #GooCanvasGridModel use goo_canvas_grid_model_new().
+ *
+ * To get or set the properties of an existing #GooCanvasGridModel, use
+ * g_object_get() and g_object_set().
+ *
+ * To respond to events such as mouse clicks on the grid you must connect
+ * to the signal handlers of the corresponding #GooCanvasGrid objects.
+ * (See goo_canvas_get_item() and #GooCanvas::item-created.)
+ */
+
+GooCanvasItemModelIface *goo_canvas_grid_model_parent_iface;
+
+static void item_model_interface_init (GooCanvasItemModelIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GooCanvasGridModel, goo_canvas_grid_model,
+ GOO_TYPE_CANVAS_ITEM_MODEL_SIMPLE,
+ G_IMPLEMENT_INTERFACE (GOO_TYPE_CANVAS_ITEM_MODEL,
+ item_model_interface_init))
+
+
+static void
+goo_canvas_grid_model_init (GooCanvasGridModel *gmodel)
+{
+ goo_canvas_grid_init_data (&gmodel->grid_data);
+}
+
+
+/**
+ * goo_canvas_grid_model_new:
+ * @parent: the parent model, or %NULL. If a parent is specified, it will assume
+ * ownership of the item, and the item will automatically be freed when it is
+ * removed from the parent. Otherwise call g_object_unref() to free it.
+ * @x: the x coordinate of the left of the grid.
+ * @y: the y coordinate of the top of the grid.
+ * @width: the width of the grid.
+ * @height: the height of the grid.
+ * @x_step: the distance between the vertical grid lines.
+ * @y_step: the distance between the horizontal grid lines.
+ * @x_offset: the distance before the first vertical grid line.
+ * @y_offset: the distance before the first horizontal grid line.
+ * @...: optional pairs of property names and values, and a terminating %NULL.
+ *
+ * Creates a new grid model.
+ *
+ * <!--PARAMETERS-->
+ *
+ * Here's an example showing how to create a grid:
+ *
+ * <informalexample><programlisting>
+ * GooCanvasItemModel *grid = goo_canvas_grid_model_new (mygroup, 100.0, 100.0, 400.0, 200.0,
+ * 20.0, 20.0, 10.0, 10.0,
+ * "horz-grid-line-width", 4.0,
+ * "horz-grid-line-color", "yellow",
+ * "vert-grid-line-width", 2.0,
+ * "vert-grid-line-color", "red",
+ * "border-width", 3.0,
+ * "border-color", "white",
+ * "fill-color", "blue",
+ * NULL);
+ * </programlisting></informalexample>
+ *
+ * Returns: a new grid model.
+ **/
+GooCanvasItemModel*
+goo_canvas_grid_model_new (GooCanvasItemModel *parent,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ gdouble x_step,
+ gdouble y_step,
+ gdouble x_offset,
+ gdouble y_offset,
+ ...)
+{
+ GooCanvasItemModel *model;
+ GooCanvasGridModel *gmodel;
+ GooCanvasGridData *grid_data;
+ const char *first_property;
+ va_list var_args;
+
+ model = g_object_new (GOO_TYPE_CANVAS_GRID_MODEL, NULL);
+ gmodel = (GooCanvasGridModel*) model;
+
+ grid_data = &gmodel->grid_data;
+ grid_data->x = x;
+ grid_data->y = y;
+ grid_data->width = width;
+ grid_data->height = height;
+ grid_data->x_step = x_step;
+ grid_data->y_step = y_step;
+ grid_data->x_offset = x_offset;
+ grid_data->y_offset = y_offset;
+
+ va_start (var_args, y_offset);
+ first_property = va_arg (var_args, char*);
+ if (first_property)
+ g_object_set_valist ((GObject*) model, first_property, var_args);
+ va_end (var_args);
+
+ if (parent)
+ {
+ goo_canvas_item_model_add_child (parent, model, -1);
+ g_object_unref (model);
+ }
+
+ return model;
+}
+
+
+static void
+goo_canvas_grid_model_finalize (GObject *object)
+{
+ GooCanvasGridModel *gmodel = (GooCanvasGridModel*) object;
+
+ goo_canvas_grid_free_data (&gmodel->grid_data);
+
+ G_OBJECT_CLASS (goo_canvas_grid_model_parent_class)->finalize (object);
+}
+
+
+static void
+goo_canvas_grid_model_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasGridModel *gmodel = (GooCanvasGridModel*) object;
+
+ goo_canvas_grid_get_common_property (object, &gmodel->grid_data,
+ prop_id, value, pspec);
+}
+
+
+static void
+goo_canvas_grid_model_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GooCanvasGridModel *gmodel = (GooCanvasGridModel*) object;
+
+ goo_canvas_grid_set_common_property (object, &gmodel->grid_data,
+ prop_id, value, pspec);
+ g_signal_emit_by_name (gmodel, "changed", TRUE);
+}
+
+
+static GooCanvasItem*
+goo_canvas_grid_model_create_item (GooCanvasItemModel *model,
+ GooCanvas *canvas)
+{
+ GooCanvasItem *item;
+
+ item = g_object_new (GOO_TYPE_CANVAS_GRID, NULL);
+ goo_canvas_item_set_model (item, model);
+
+ return item;
+}
+
+
+static void
+item_model_interface_init (GooCanvasItemModelIface *iface)
+{
+ iface->create_item = goo_canvas_grid_model_create_item;
+}
+
+
+static void
+goo_canvas_grid_model_class_init (GooCanvasGridModelClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass*) klass;
+
+ goo_canvas_grid_model_parent_iface = g_type_interface_peek (goo_canvas_grid_model_parent_class, GOO_TYPE_CANVAS_ITEM_MODEL);
+
+ gobject_class->finalize = goo_canvas_grid_model_finalize;
+
+ gobject_class->get_property = goo_canvas_grid_model_get_property;
+ gobject_class->set_property = goo_canvas_grid_model_set_property;
+
+ goo_canvas_grid_install_common_properties (gobject_class);
+}
+
+
Added: trunk/src/goocanvasgrid.h
==============================================================================
--- (empty file)
+++ trunk/src/goocanvasgrid.h Mon Nov 3 11:31:46 2008
@@ -0,0 +1,149 @@
+/*
+ * GooCanvas. Copyright (C) 2005-8 Damon Chaplin.
+ * Released under the GNU LGPL license. See COPYING for details.
+ *
+ * goocanvasgrid.h - a grid item.
+ */
+#ifndef __GOO_CANVAS_GRID_H__
+#define __GOO_CANVAS_GRID_H__
+
+#include <gtk/gtk.h>
+#include "goocanvasitemsimple.h"
+
+G_BEGIN_DECLS
+
+
+/* This is the data used by both model and view classes. */
+typedef struct _GooCanvasGridData GooCanvasGridData;
+struct _GooCanvasGridData
+{
+ /* The area that the grid covers. */
+ gdouble x, y, width, height;
+
+ /* The distance between grid lines. */
+ gdouble x_step, y_step;
+
+ /* The offset before the first grid line. */
+ gdouble x_offset, y_offset;
+
+ /* The widths of the grid lines, or -ve to use item's stroke width. */
+ gdouble horz_grid_line_width, vert_grid_line_width;
+
+ /* The color/pattern for the grid lines, or NULL to use the stroke color. */
+ cairo_pattern_t *horz_grid_line_pattern, *vert_grid_line_pattern;
+
+ /* The width of the border around the grid, or -1 for no border. */
+ gdouble border_width;
+
+ /* The color/pattern for the border, or NULL to use the stroke color. */
+ cairo_pattern_t *border_pattern;
+
+ /* If vertical grid lines are drawn on top. */
+ guint vert_grid_lines_on_top : 1;
+};
+
+
+#define GOO_TYPE_CANVAS_GRID (goo_canvas_grid_get_type ())
+#define GOO_CANVAS_GRID(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_GRID, GooCanvasGrid))
+#define GOO_CANVAS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_GRID, GooCanvasGridClass))
+#define GOO_IS_CANVAS_GRID(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_GRID))
+#define GOO_IS_CANVAS_GRID_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_GRID))
+#define GOO_CANVAS_GRID_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_GRID, GooCanvasGridClass))
+
+
+typedef struct _GooCanvasGrid GooCanvasGrid;
+typedef struct _GooCanvasGridClass GooCanvasGridClass;
+
+/**
+ * GooCanvasGrid
+ *
+ * The #GooCanvasGrid-struct struct contains private data only.
+ */
+struct _GooCanvasGrid
+{
+ GooCanvasItemSimple parent_object;
+
+ GooCanvasGridData *grid_data;
+};
+
+struct _GooCanvasGridClass
+{
+ GooCanvasItemSimpleClass parent_class;
+
+ /*< private >*/
+
+ /* Padding for future expansion */
+ void (*_goo_canvas_reserved1) (void);
+ void (*_goo_canvas_reserved2) (void);
+ void (*_goo_canvas_reserved3) (void);
+ void (*_goo_canvas_reserved4) (void);
+};
+
+
+GType goo_canvas_grid_get_type (void) G_GNUC_CONST;
+GooCanvasItem* goo_canvas_grid_new (GooCanvasItem *parent,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ gdouble x_step,
+ gdouble y_step,
+ gdouble x_offset,
+ gdouble y_offset,
+ ...);
+
+
+
+#define GOO_TYPE_CANVAS_GRID_MODEL (goo_canvas_grid_model_get_type ())
+#define GOO_CANVAS_GRID_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GOO_TYPE_CANVAS_GRID_MODEL, GooCanvasGridModel))
+#define GOO_CANVAS_GRID_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GOO_TYPE_CANVAS_GRID_MODEL, GooCanvasGridModelClass))
+#define GOO_IS_CANVAS_GRID_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOO_TYPE_CANVAS_GRID_MODEL))
+#define GOO_IS_CANVAS_GRID_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GOO_TYPE_CANVAS_GRID_MODEL))
+#define GOO_CANVAS_GRID_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GOO_TYPE_CANVAS_GRID_MODEL, GooCanvasGridModelClass))
+
+
+typedef struct _GooCanvasGridModel GooCanvasGridModel;
+typedef struct _GooCanvasGridModelClass GooCanvasGridModelClass;
+
+/**
+ * GooCanvasGridModel
+ *
+ * The #GooCanvasGridModel-struct struct contains private data only.
+ */
+struct _GooCanvasGridModel
+{
+ GooCanvasItemModelSimple parent_object;
+
+ GooCanvasGridData grid_data;
+};
+
+struct _GooCanvasGridModelClass
+{
+ GooCanvasItemModelSimpleClass parent_class;
+
+ /*< private >*/
+
+ /* Padding for future expansion */
+ void (*_goo_canvas_reserved1) (void);
+ void (*_goo_canvas_reserved2) (void);
+ void (*_goo_canvas_reserved3) (void);
+ void (*_goo_canvas_reserved4) (void);
+};
+
+
+GType goo_canvas_grid_model_get_type (void) G_GNUC_CONST;
+GooCanvasItemModel* goo_canvas_grid_model_new (GooCanvasItemModel *parent,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ gdouble height,
+ gdouble x_step,
+ gdouble y_step,
+ gdouble x_offset,
+ gdouble y_offset,
+ ...);
+
+
+G_END_DECLS
+
+#endif /* __GOO_CANVAS_GRID_H__ */
Modified: trunk/src/goocanvasitemsimple.c
==============================================================================
--- trunk/src/goocanvasitemsimple.c (original)
+++ trunk/src/goocanvasitemsimple.c Mon Nov 3 11:31:46 2008
@@ -432,27 +432,6 @@
}
-static guint
-convert_color (double red, double green, double blue, double alpha)
-{
- guint red_byte, green_byte, blue_byte, alpha_byte;
-
- red_byte = red * 256;
- red_byte -= red_byte >> 8;
-
- green_byte = green * 256;
- green_byte -= green_byte >> 8;
-
- blue_byte = blue * 256;
- blue_byte -= blue_byte >> 8;
-
- alpha_byte = alpha * 256;
- alpha_byte -= alpha_byte >> 8;
-
- return (red_byte << 24) + (green_byte << 16) + (blue_byte << 8) + alpha_byte;
-}
-
-
static void
goo_canvas_item_simple_get_common_property (GObject *object,
GooCanvasItemSimpleData *simple_data,
@@ -465,9 +444,6 @@
GValue *svalue;
gdouble line_width = 2.0;
gchar *font = NULL;
- cairo_pattern_t *pattern;
- double red, green, blue, alpha;
- guint rgba = 0;
switch (prop_id)
{
@@ -539,29 +515,15 @@
/* Convenience properties. */
case PROP_STROKE_COLOR_RGBA:
svalue = goo_canvas_style_get_property (style, goo_canvas_style_stroke_pattern_id);
- if (svalue && svalue->data[0].v_pointer)
- {
- pattern = svalue->data[0].v_pointer;
- if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
- {
- cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha);
- rgba = convert_color (red, green, blue, alpha);
- }
- }
- g_value_set_uint (value, rgba);
+ if (svalue)
+ goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer,
+ value);
break;
case PROP_FILL_COLOR_RGBA:
svalue = goo_canvas_style_get_property (style, goo_canvas_style_fill_pattern_id);
- if (svalue && svalue->data[0].v_pointer)
- {
- pattern = svalue->data[0].v_pointer;
- if (cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
- {
- cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha);
- rgba = convert_color (red, green, blue, alpha);
- }
- }
- g_value_set_uint (value, rgba);
+ if (svalue)
+ goo_canvas_get_rgba_value_from_pattern (svalue->data[0].v_pointer,
+ value);
break;
/* Other properties. */
@@ -630,10 +592,6 @@
GParamSpec *pspec)
{
GooCanvasStyle *style;
- GdkColor color = { 0, 0, 0, 0, };
- guint rgba, red, green, blue, alpha;
- GdkPixbuf *pixbuf;
- cairo_surface_t *surface;
cairo_pattern_t *pattern;
gboolean recompute_bounds = FALSE;
cairo_matrix_t *transform;
@@ -722,74 +680,29 @@
/* Convenience properties. */
case PROP_STROKE_COLOR:
- if (g_value_get_string (value))
- gdk_color_parse (g_value_get_string (value), &color);
- pattern = cairo_pattern_create_rgb (color.red / 65535.0,
- color.green / 65535.0,
- color.blue / 65535.0);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, &tmpval);
- g_value_unset (&tmpval);
+ pattern = goo_canvas_create_pattern_from_color_value (value);
+ goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
break;
case PROP_STROKE_COLOR_RGBA:
- rgba = g_value_get_uint (value);
- red = (rgba >> 24) & 0xFF;
- green = (rgba >> 16) & 0xFF;
- blue = (rgba >> 8) & 0xFF;
- alpha = (rgba) & 0xFF;
- pattern = cairo_pattern_create_rgba (red / 255.0, green / 255.0,
- blue / 255.0, alpha / 255.0);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, &tmpval);
- g_value_unset (&tmpval);
+ pattern = goo_canvas_create_pattern_from_rgba_value (value);
+ goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
break;
case PROP_STROKE_PIXBUF:
- pixbuf = g_value_get_object (value);
- surface = goo_canvas_cairo_surface_from_pixbuf (pixbuf);
- pattern = cairo_pattern_create_for_surface (surface);
- cairo_surface_destroy (surface);
- cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, goo_canvas_style_stroke_pattern_id, &tmpval);
- g_value_unset (&tmpval);
+ pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
+ goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_stroke_pattern_id, pattern);
break;
+
case PROP_FILL_COLOR:
- if (g_value_get_string (value))
- gdk_color_parse (g_value_get_string (value), &color);
- pattern = cairo_pattern_create_rgb (color.red / 65535.0,
- color.green / 65535.0,
- color.blue / 65535.0);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, &tmpval);
- g_value_unset (&tmpval);
+ pattern = goo_canvas_create_pattern_from_color_value (value);
+ goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
break;
case PROP_FILL_COLOR_RGBA:
- rgba = g_value_get_uint (value);
- red = (rgba >> 24) & 0xFF;
- green = (rgba >> 16) & 0xFF;
- blue = (rgba >> 8) & 0xFF;
- alpha = (rgba) & 0xFF;
- pattern = cairo_pattern_create_rgba (red / 255.0, green / 255.0,
- blue / 255.0, alpha / 255.0);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, &tmpval);
- g_value_unset (&tmpval);
+ pattern = goo_canvas_create_pattern_from_rgba_value (value);
+ goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
break;
case PROP_FILL_PIXBUF:
- pixbuf = g_value_get_object (value);
- surface = goo_canvas_cairo_surface_from_pixbuf (pixbuf);
- pattern = cairo_pattern_create_for_surface (surface);
- cairo_surface_destroy (surface);
- cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
- g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
- g_value_take_boxed (&tmpval, pattern);
- goo_canvas_style_set_property (style, goo_canvas_style_fill_pattern_id, &tmpval);
- g_value_unset (&tmpval);
+ pattern = goo_canvas_create_pattern_from_pixbuf_value (value);
+ goo_canvas_set_style_property_from_pattern (style, goo_canvas_style_fill_pattern_id, pattern);
break;
/* Other properties. */
Modified: trunk/src/goocanvasprivate.h
==============================================================================
--- trunk/src/goocanvasprivate.h (original)
+++ trunk/src/goocanvasprivate.h Mon Nov 3 11:31:46 2008
@@ -8,6 +8,7 @@
#define __GOO_CANVAS_PRIVATE_H__
#include <gtk/gtk.h>
+#include "goocanvasstyle.h"
G_BEGIN_DECLS
@@ -30,6 +31,22 @@
cairo_pattern_t* goo_canvas_cairo_pattern_from_pixbuf (GdkPixbuf *pixbuf);
cairo_surface_t* goo_canvas_cairo_surface_from_pixbuf (GdkPixbuf *pixbuf);
+guint goo_canvas_convert_colors_to_rgba (double red,
+ double green,
+ double blue,
+ double alpha);
+
+void goo_canvas_get_rgba_value_from_pattern (cairo_pattern_t *pattern,
+ GValue *value);
+
+void goo_canvas_set_style_property_from_pattern (GooCanvasStyle *style,
+ GQuark property_id,
+ cairo_pattern_t *pattern);
+
+cairo_pattern_t* goo_canvas_create_pattern_from_color_value (const GValue *value);
+cairo_pattern_t* goo_canvas_create_pattern_from_rgba_value (const GValue *value);
+cairo_pattern_t* goo_canvas_create_pattern_from_pixbuf_value (const GValue *value);
+
gboolean goo_canvas_boolean_handled_accumulator (GSignalInvocationHint *ihint,
GValue *return_accu,
Modified: trunk/src/goocanvasutils.c
==============================================================================
--- trunk/src/goocanvasutils.c (original)
+++ trunk/src/goocanvasutils.c Mon Nov 3 11:31:46 2008
@@ -1192,3 +1192,103 @@
}
+/* Converts red, green, blue and alpha doubles to an RGBA guint. */
+guint
+goo_canvas_convert_colors_to_rgba (double red,
+ double green,
+ double blue,
+ double alpha)
+{
+ guint red_byte, green_byte, blue_byte, alpha_byte;
+
+ red_byte = red * 256;
+ red_byte -= red_byte >> 8;
+
+ green_byte = green * 256;
+ green_byte -= green_byte >> 8;
+
+ blue_byte = blue * 256;
+ blue_byte -= blue_byte >> 8;
+
+ alpha_byte = alpha * 256;
+ alpha_byte -= alpha_byte >> 8;
+
+ return (red_byte << 24) + (green_byte << 16) + (blue_byte << 8) + alpha_byte;
+}
+
+
+void
+goo_canvas_get_rgba_value_from_pattern (cairo_pattern_t *pattern,
+ GValue *value)
+{
+ double red, green, blue, alpha;
+ guint rgba = 0;
+
+ if (pattern && cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
+ {
+ cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha);
+ rgba = goo_canvas_convert_colors_to_rgba (red, green, blue, alpha);
+ }
+ g_value_set_uint (value, rgba);
+}
+
+
+/* Sets a style property to the given pattern, taking ownership of it. */
+void
+goo_canvas_set_style_property_from_pattern (GooCanvasStyle *style,
+ GQuark property_id,
+ cairo_pattern_t *pattern)
+{
+ GValue tmpval = { 0 };
+
+ g_value_init (&tmpval, GOO_TYPE_CAIRO_PATTERN);
+ g_value_take_boxed (&tmpval, pattern);
+ goo_canvas_style_set_property (style, property_id, &tmpval);
+ g_value_unset (&tmpval);
+}
+
+
+cairo_pattern_t*
+goo_canvas_create_pattern_from_color_value (const GValue *value)
+{
+ GdkColor color = { 0, 0, 0, 0, };
+
+ if (g_value_get_string (value))
+ gdk_color_parse (g_value_get_string (value), &color);
+
+ return cairo_pattern_create_rgb (color.red / 65535.0,
+ color.green / 65535.0,
+ color.blue / 65535.0);
+}
+
+
+cairo_pattern_t*
+goo_canvas_create_pattern_from_rgba_value (const GValue *value)
+{
+ guint rgba, red, green, blue, alpha;
+
+ rgba = g_value_get_uint (value);
+ red = (rgba >> 24) & 0xFF;
+ green = (rgba >> 16) & 0xFF;
+ blue = (rgba >> 8) & 0xFF;
+ alpha = (rgba) & 0xFF;
+
+ return cairo_pattern_create_rgba (red / 255.0, green / 255.0,
+ blue / 255.0, alpha / 255.0);
+}
+
+
+cairo_pattern_t*
+goo_canvas_create_pattern_from_pixbuf_value (const GValue *value)
+{
+ GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+
+ pixbuf = g_value_get_object (value);
+ surface = goo_canvas_cairo_surface_from_pixbuf (pixbuf);
+ pattern = cairo_pattern_create_for_surface (surface);
+ cairo_surface_destroy (surface);
+ cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+ return pattern;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]