aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libgnomecanvas/Makefile.am2
-rw-r--r--libgnomecanvas/gnome-canvas-line.c1191
-rw-r--r--libgnomecanvas/gnome-canvas-line.h143
-rw-r--r--libgnomecanvas/gnome-canvas-util.c21
-rw-r--r--libgnomecanvas/gnome-canvas-util.h3
-rw-r--r--libgnomecanvas/libgnomecanvas.h1
6 files changed, 24 insertions, 1337 deletions
diff --git a/libgnomecanvas/Makefile.am b/libgnomecanvas/Makefile.am
index 5069052309..14b44a0d07 100644
--- a/libgnomecanvas/Makefile.am
+++ b/libgnomecanvas/Makefile.am
@@ -25,7 +25,6 @@ libgnomecanvasinclude_HEADERS = \
gailcanvaswidgetfactory.h \
gnome-canvas-clipgroup.h \
gnome-canvas-i18n.h \
- gnome-canvas-line.h \
gnome-canvas-path-def.h \
gnome-canvas-pixbuf.h \
gnome-canvas-rect-ellipse.h \
@@ -48,7 +47,6 @@ libgnomecanvas_la_SOURCES = \
gailcanvaswidget.c \
gailcanvaswidgetfactory.c \
gnome-canvas-clipgroup.c \
- gnome-canvas-line.c \
gnome-canvas-path-def.c \
gnome-canvas-pixbuf.c \
gnome-canvas-rect-ellipse.c \
diff --git a/libgnomecanvas/gnome-canvas-line.c b/libgnomecanvas/gnome-canvas-line.c
deleted file mode 100644
index 20cde8a6d9..0000000000
--- a/libgnomecanvas/gnome-canvas-line.c
+++ /dev/null
@@ -1,1191 +0,0 @@
-/*
- * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
- * All rights reserved.
- *
- * This file is part of the Gnome Library.
- *
- * The Gnome 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.
- *
- * The Gnome 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 the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/*
- @NOTATION@
- */
-
-/* Line/curve item type for GnomeCanvas widget
- *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is
- * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
- *
- *
- * Author: Federico Mena <federico@nuclecu.unam.mx>
- */
-
-#include <config.h>
-#include <math.h>
-#include <string.h>
-#include <libart_lgpl/art_vpath.h>
-#include <libart_lgpl/art_svp.h>
-#include <libart_lgpl/art_svp_vpath.h>
-#include <libart_lgpl/art_svp_vpath_stroke.h>
-#include "libgnomecanvas.h"
-
-#define noVERBOSE
-
-#define DEFAULT_SPLINE_STEPS 12 /* this is what Tk uses */
-#define NUM_ARROW_POINTS 6 /* number of points in an arrowhead */
-#define NUM_STATIC_POINTS 256 /* number of static points to use to avoid allocating arrays */
-
-#define GROW_BOUNDS(bx1, by1, bx2, by2, x, y) { \
- if (x < bx1) \
- bx1 = x; \
- \
- if (x > bx2) \
- bx2 = x; \
- \
- if (y < by1) \
- by1 = y; \
- \
- if (y > by2) \
- by2 = y; \
-}
-
-enum {
- PROP_0,
- PROP_POINTS,
- PROP_FILL_COLOR,
- PROP_FILL_COLOR_GDK,
- PROP_FILL_COLOR_RGBA,
- PROP_WIDTH_PIXELS,
- PROP_WIDTH_UNITS,
- PROP_CAP_STYLE,
- PROP_JOIN_STYLE,
- PROP_FIRST_ARROWHEAD,
- PROP_LAST_ARROWHEAD,
- PROP_SMOOTH,
- PROP_SPLINE_STEPS,
- PROP_ARROW_SHAPE_A,
- PROP_ARROW_SHAPE_B,
- PROP_ARROW_SHAPE_C
-};
-
-static void gnome_canvas_line_class_init (GnomeCanvasLineClass *class);
-static void gnome_canvas_line_init (GnomeCanvasLine *line);
-static void gnome_canvas_line_destroy (GnomeCanvasItem *object);
-static void gnome_canvas_line_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gnome_canvas_line_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void gnome_canvas_line_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags);
-static void gnome_canvas_line_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
- gint x, gint y, gint width, gint height);
-static GnomeCanvasItem *gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
- gint cx, gint cy);
-static void gnome_canvas_line_bounds (GnomeCanvasItem *item, gdouble *x1, gdouble *y1, gdouble *x2, gdouble *y2);
-
-static GnomeCanvasItemClass *parent_class;
-
-GType
-gnome_canvas_line_get_type (void)
-{
- static GType line_type;
-
- if (!line_type) {
- const GTypeInfo object_info = {
- sizeof (GnomeCanvasLineClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) gnome_canvas_line_class_init,
- (GClassFinalizeFunc) NULL,
- NULL, /* class_data */
- sizeof (GnomeCanvasLine),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gnome_canvas_line_init,
- NULL /* value_table */
- };
-
- line_type = g_type_register_static (GNOME_TYPE_CANVAS_ITEM, "GnomeCanvasLine",
- &object_info, 0);
- }
-
- return line_type;
-}
-
-static void
-gnome_canvas_line_class_init (GnomeCanvasLineClass *class)
-{
- GObjectClass *gobject_class;
- GnomeCanvasItemClass *item_class;
-
- gobject_class = (GObjectClass *) class;
- item_class = (GnomeCanvasItemClass *) class;
-
- parent_class = g_type_class_peek_parent (class);
-
- gobject_class->set_property = gnome_canvas_line_set_property;
- gobject_class->get_property = gnome_canvas_line_get_property;
-
- g_object_class_install_property
- (gobject_class,
- PROP_POINTS,
- g_param_spec_boxed ("points", NULL, NULL,
- GNOME_TYPE_CANVAS_POINTS,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_FILL_COLOR,
- g_param_spec_string ("fill_color", NULL, NULL,
- NULL,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_FILL_COLOR_GDK,
- g_param_spec_boxed ("fill_color_gdk", NULL, NULL,
- GDK_TYPE_COLOR,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_FILL_COLOR_RGBA,
- g_param_spec_uint ("fill_color_rgba", NULL, NULL,
- 0, G_MAXUINT, 0,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_WIDTH_PIXELS,
- g_param_spec_uint ("width_pixels", NULL, NULL,
- 0, G_MAXUINT, 0,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_WIDTH_UNITS,
- g_param_spec_double ("width_units", NULL, NULL,
- 0.0, G_MAXDOUBLE, 0.0,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_CAP_STYLE,
- g_param_spec_enum ("cap_style", NULL, NULL,
- G_TYPE_UINT, /* XXX */
- CAIRO_LINE_CAP_BUTT,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_JOIN_STYLE,
- g_param_spec_enum ("join_style", NULL, NULL,
- G_TYPE_UINT, /* XXX */
- CAIRO_LINE_JOIN_MITER,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_FIRST_ARROWHEAD,
- g_param_spec_boolean ("first_arrowhead", NULL, NULL,
- FALSE,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_LAST_ARROWHEAD,
- g_param_spec_boolean ("last_arrowhead", NULL, NULL,
- FALSE,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_SMOOTH,
- g_param_spec_boolean ("smooth", NULL, NULL,
- FALSE,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_SPLINE_STEPS,
- g_param_spec_uint ("spline_steps", NULL, NULL,
- 0, G_MAXUINT, DEFAULT_SPLINE_STEPS,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_ARROW_SHAPE_A,
- g_param_spec_double ("arrow_shape_a", NULL, NULL,
- -G_MAXDOUBLE, G_MAXDOUBLE, 0,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_ARROW_SHAPE_B,
- g_param_spec_double ("arrow_shape_b", NULL, NULL,
- -G_MAXDOUBLE, G_MAXDOUBLE, 0,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_ARROW_SHAPE_C,
- g_param_spec_double ("arrow_shape_c", NULL, NULL,
- -G_MAXDOUBLE, G_MAXDOUBLE, 0,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
-
- item_class->destroy = gnome_canvas_line_destroy;
- item_class->update = gnome_canvas_line_update;
- item_class->draw = gnome_canvas_line_draw;
- item_class->point = gnome_canvas_line_point;
- item_class->bounds = gnome_canvas_line_bounds;
-}
-
-static void
-gnome_canvas_line_init (GnomeCanvasLine *line)
-{
- line->width = 0.0;
- line->cap = CAIRO_LINE_CAP_BUTT;
- line->join = CAIRO_LINE_JOIN_MITER;
- line->shape_a = 0.0;
- line->shape_b = 0.0;
- line->shape_c = 0.0;
- line->spline_steps = DEFAULT_SPLINE_STEPS;
-}
-
-static void
-gnome_canvas_line_destroy (GnomeCanvasItem *object)
-{
- GnomeCanvasLine *line;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GNOME_IS_CANVAS_LINE (object));
-
- line = GNOME_CANVAS_LINE (object);
-
- /* remember, destroy can be run multiple times! */
-
- if (line->coords)
- g_free (line->coords);
- line->coords = NULL;
-
- if (line->first_coords)
- g_free (line->first_coords);
- line->first_coords = NULL;
-
- if (line->last_coords)
- g_free (line->last_coords);
- line->last_coords = NULL;
-
- if (line->fill_svp)
- art_svp_free (line->fill_svp);
- line->fill_svp = NULL;
-
- if (line->first_svp)
- art_svp_free (line->first_svp);
- line->first_svp = NULL;
-
- if (line->last_svp)
- art_svp_free (line->last_svp);
- line->last_svp = NULL;
-
- if (GNOME_CANVAS_ITEM_CLASS (parent_class)->destroy)
- GNOME_CANVAS_ITEM_CLASS (parent_class)->destroy (object);
-}
-
-/* Computes the bounding box of the line, including its arrow points. Assumes that the number of
- * points in the line is not zero.
- */
-static void
-get_bounds (GnomeCanvasLine *line, gdouble *bx1, gdouble *by1, gdouble *bx2, gdouble *by2)
-{
- gdouble *coords;
- gdouble x1, y1, x2, y2;
- gdouble width;
- gint i;
-
- if (!line->coords) {
- *bx1 = *by1 = *bx2 = *by2 = 0.0;
- return;
- }
-
- /* Find bounding box of line's points */
-
- x1 = x2 = line->coords[0];
- y1 = y2 = line->coords[1];
-
- for (i = 1, coords = line->coords + 2; i < line->num_points; i++, coords += 2)
- GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
-
- /* Add possible over-estimate for wide lines */
-
- if (line->width_pixels)
- width = line->width / line->item.canvas->pixels_per_unit;
- else
- width = line->width;
-
- x1 -= width;
- y1 -= width;
- x2 += width;
- y2 += width;
-
- /* For mitered lines, make a second pass through all the points. Compute the location of
- * the two miter vertex points and add them to the bounding box.
- */
-
- if (line->join == CAIRO_LINE_JOIN_MITER)
- for (i = line->num_points, coords = line->coords; i >= 3; i--, coords += 2) {
- gdouble mx1, my1, mx2, my2;
-
- if (gnome_canvas_get_miter_points (coords[0], coords[1],
- coords[2], coords[3],
- coords[4], coords[5],
- width,
- &mx1, &my1, &mx2, &my2)) {
- GROW_BOUNDS (x1, y1, x2, y2, mx1, my1);
- GROW_BOUNDS (x1, y1, x2, y2, mx2, my2);
- }
- }
-
- /* Add the arrow points, if any */
-
- if (line->first_arrow && line->first_coords)
- for (i = 0, coords = line->first_coords; i < NUM_ARROW_POINTS; i++, coords += 2)
- GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
-
- if (line->last_arrow && line->last_coords)
- for (i = 0, coords = line->last_coords; i < NUM_ARROW_POINTS; i++, coords += 2)
- GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
-
- /* Done */
-
- *bx1 = x1;
- *by1 = y1;
- *bx2 = x2;
- *by2 = y2;
-}
-
-/* Computes the bounding box of the line, in canvas coordinates. Assumes that the number of points in the polygon is
- * not zero. Affine is the i2c transformation.
- */
-static void
-get_bounds_canvas (GnomeCanvasLine *line, gdouble *bx1, gdouble *by1, gdouble *bx2, gdouble *by2, gdouble affine[6])
-{
- /* It would be possible to tighten the bounds somewhat by transforming the individual points before
- aggregating them into the bbox. But it hardly seems worth it. */
- ArtDRect bbox_world;
- ArtDRect bbox_canvas;
-
- get_bounds (line, &bbox_world.x0, &bbox_world.y0, &bbox_world.x1, &bbox_world.y1);
-
- art_drect_affine_transform (&bbox_canvas, &bbox_world, affine);
- /* include 1 pixel of fudge */
- *bx1 = bbox_canvas.x0 - 1;
- *by1 = bbox_canvas.y0 - 1;
- *bx2 = bbox_canvas.x1 + 1;
- *by2 = bbox_canvas.y1 + 1;
-}
-
-/* Recalculates the arrow polygons for the line */
-static void
-reconfigure_arrows (GnomeCanvasLine *line)
-{
- gdouble *poly, *coords;
- gdouble dx, dy, length;
- gdouble sin_theta, cos_theta, tmp;
- gdouble frac_height; /* Line width as fraction of arrowhead width */
- gdouble backup; /* Distance to backup end points so the line ends in the middle of the arrowhead */
- gdouble vx, vy; /* Position of arrowhead vertex */
- gdouble shape_a, shape_b, shape_c;
- gdouble width;
- gint i;
-
- if (line->num_points == 0)
- return;
-
- /* Set up things */
-
- if (line->first_arrow) {
- if (line->first_coords) {
- line->coords[0] = line->first_coords[0];
- line->coords[1] = line->first_coords[1];
- } else
- line->first_coords = g_new (double, 2 * NUM_ARROW_POINTS);
- } else if (line->first_coords) {
- line->coords[0] = line->first_coords[0];
- line->coords[1] = line->first_coords[1];
-
- g_free (line->first_coords);
- line->first_coords = NULL;
- }
-
- i = 2 * (line->num_points - 1);
-
- if (line->last_arrow) {
- if (line->last_coords) {
- line->coords[i] = line->last_coords[0];
- line->coords[i + 1] = line->last_coords[1];
- } else
- line->last_coords = g_new (double, 2 * NUM_ARROW_POINTS);
- } else if (line->last_coords) {
- line->coords[i] = line->last_coords[0];
- line->coords[i + 1] = line->last_coords[1];
-
- g_free (line->last_coords);
- line->last_coords = NULL;
- }
-
- if (!line->first_arrow && !line->last_arrow)
- return;
-
- if (line->width_pixels)
- width = line->width / line->item.canvas->pixels_per_unit;
- else
- width = line->width;
-
- /* Add fudge value for better-looking results */
-
- shape_a = line->shape_a;
- shape_b = line->shape_b;
- shape_c = line->shape_c + width / 2.0;
-
- if (line->width_pixels) {
- shape_a /= line->item.canvas->pixels_per_unit;
- shape_b /= line->item.canvas->pixels_per_unit;
- shape_c /= line->item.canvas->pixels_per_unit;
- }
-
- shape_a += 0.001;
- shape_b += 0.001;
- shape_c += 0.001;
-
- /* Compute the polygon for the first arrowhead and adjust the first point in the line so
- * that the line does not stick out past the leading edge of the arrowhead.
- */
-
- frac_height = (line->width / 2.0) / shape_c;
- backup = frac_height * shape_b + shape_a * (1.0 - frac_height) / 2.0;
-
- if (line->first_arrow) {
- poly = line->first_coords;
- poly[0] = poly[10] = line->coords[0];
- poly[1] = poly[11] = line->coords[1];
-
- dx = poly[0] - line->coords[2];
- dy = poly[1] - line->coords[3];
- length = sqrt (dx * dx + dy * dy);
- if (length < GNOME_CANVAS_EPSILON)
- sin_theta = cos_theta = 0.0;
- else {
- sin_theta = dy / length;
- cos_theta = dx / length;
- }
-
- vx = poly[0] - shape_a * cos_theta;
- vy = poly[1] - shape_a * sin_theta;
-
- tmp = shape_c * sin_theta;
-
- poly[2] = poly[0] - shape_b * cos_theta + tmp;
- poly[8] = poly[2] - 2.0 * tmp;
-
- tmp = shape_c * cos_theta;
-
- poly[3] = poly[1] - shape_b * sin_theta - tmp;
- poly[9] = poly[3] + 2.0 * tmp;
-
- poly[4] = poly[2] * frac_height + vx * (1.0 - frac_height);
- poly[5] = poly[3] * frac_height + vy * (1.0 - frac_height);
- poly[6] = poly[8] * frac_height + vx * (1.0 - frac_height);
- poly[7] = poly[9] * frac_height + vy * (1.0 - frac_height);
-
- /* Move the first point towards the second so that the corners at the end of the
- * line are inside the arrowhead.
- */
-
- line->coords[0] = poly[0] - backup * cos_theta;
- line->coords[1] = poly[1] - backup * sin_theta;
- }
-
- /* Same process for last arrowhead */
-
- if (line->last_arrow) {
- coords = line->coords + 2 * (line->num_points - 2);
- poly = line->last_coords;
- poly[0] = poly[10] = coords[2];
- poly[1] = poly[11] = coords[3];
-
- dx = poly[0] - coords[0];
- dy = poly[1] - coords[1];
- length = sqrt (dx * dx + dy * dy);
- if (length < GNOME_CANVAS_EPSILON)
- sin_theta = cos_theta = 0.0;
- else {
- sin_theta = dy / length;
- cos_theta = dx / length;
- }
-
- vx = poly[0] - shape_a * cos_theta;
- vy = poly[1] - shape_a * sin_theta;
-
- tmp = shape_c * sin_theta;
-
- poly[2] = poly[0] - shape_b * cos_theta + tmp;
- poly[8] = poly[2] - 2.0 * tmp;
-
- tmp = shape_c * cos_theta;
-
- poly[3] = poly[1] - shape_b * sin_theta - tmp;
- poly[9] = poly[3] + 2.0 * tmp;
-
- poly[4] = poly[2] * frac_height + vx * (1.0 - frac_height);
- poly[5] = poly[3] * frac_height + vy * (1.0 - frac_height);
- poly[6] = poly[8] * frac_height + vx * (1.0 - frac_height);
- poly[7] = poly[9] * frac_height + vy * (1.0 - frac_height);
-
- coords[2] = poly[0] - backup * cos_theta;
- coords[3] = poly[1] - backup * sin_theta;
- }
-}
-
-static void
-gnome_canvas_line_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GnomeCanvasItem *item;
- GnomeCanvasLine *line;
- GnomeCanvasPoints *points;
- GdkColor color = { 0, 0, 0, 0, };
- GdkColor *pcolor;
- gboolean color_changed;
- gint have_pixel;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GNOME_IS_CANVAS_LINE (object));
-
- item = GNOME_CANVAS_ITEM (object);
- line = GNOME_CANVAS_LINE (object);
-
- color_changed = FALSE;
- have_pixel = FALSE;
-
- switch (param_id) {
- case PROP_POINTS:
- points = g_value_get_boxed (value);
-
- if (line->coords) {
- g_free (line->coords);
- line->coords = NULL;
- }
-
- if (!points)
- line->num_points = 0;
- else {
- line->num_points = points->num_points;
- line->coords = g_new (double, 2 * line->num_points);
- memcpy (line->coords, points->coords, 2 * line->num_points * sizeof (gdouble));
- }
-
- /* Drop the arrowhead polygons if they exist -- they will be regenerated */
-
- if (line->first_coords) {
- g_free (line->first_coords);
- line->first_coords = NULL;
- }
-
- if (line->last_coords) {
- g_free (line->last_coords);
- line->last_coords = NULL;
- }
-
- /* Since the line's points have changed, we need to re-generate arrowheads in
- * addition to recalculating the bounds.
- */
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_FILL_COLOR:
- if (g_value_get_string (value))
- gdk_color_parse (g_value_get_string (value), &color);
- line->fill_rgba = ((color.red & 0xff00) << 16 |
- (color.green & 0xff00) << 8 |
- (color.blue & 0xff00) |
- 0xff);
- color_changed = TRUE;
- break;
-
- case PROP_FILL_COLOR_GDK:
- pcolor = g_value_get_boxed (value);
- if (pcolor) {
- GdkColormap *colormap;
- color = *pcolor;
-
- colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
- gdk_rgb_find_color (colormap, &color);
-
- have_pixel = TRUE;
- }
-
- line->fill_rgba = ((color.red & 0xff00) << 16 |
- (color.green & 0xff00) << 8 |
- (color.blue & 0xff00) |
- 0xff);
- color_changed = TRUE;
- break;
-
- case PROP_FILL_COLOR_RGBA:
- line->fill_rgba = g_value_get_uint (value);
- color_changed = TRUE;
- break;
-
- case PROP_WIDTH_PIXELS:
- line->width = g_value_get_uint (value);
- line->width_pixels = TRUE;
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_WIDTH_UNITS:
- line->width = fabs (g_value_get_double (value));
- line->width_pixels = FALSE;
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_CAP_STYLE:
- line->cap = g_value_get_enum (value);
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_JOIN_STYLE:
- line->join = g_value_get_enum (value);
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_FIRST_ARROWHEAD:
- line->first_arrow = g_value_get_boolean (value);
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_LAST_ARROWHEAD:
- line->last_arrow = g_value_get_boolean (value);
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_SMOOTH:
- /* FIXME */
- break;
-
- case PROP_SPLINE_STEPS:
- /* FIXME */
- break;
-
- case PROP_ARROW_SHAPE_A:
- line->shape_a = fabs (g_value_get_double (value));
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_ARROW_SHAPE_B:
- line->shape_b = fabs (g_value_get_double (value));
- gnome_canvas_item_request_update (item);
- break;
-
- case PROP_ARROW_SHAPE_C:
- line->shape_c = fabs (g_value_get_double (value));
- gnome_canvas_item_request_update (item);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-
- if (color_changed) {
- if (have_pixel)
- line->fill_pixel = color.pixel;
- else
- line->fill_pixel = gnome_canvas_get_color_pixel (item->canvas,
- line->fill_rgba);
-
- gnome_canvas_item_request_redraw_svp (item, line->fill_svp);
-
- if (line->first_svp)
- gnome_canvas_item_request_redraw_svp (item, line->first_svp);
-
- if (line->last_svp)
- gnome_canvas_item_request_redraw_svp (item, line->last_svp);
-
- }
-}
-
-/* Returns a copy of the line's points without the endpoint adjustments for
- * arrowheads.
- */
-static GnomeCanvasPoints *
-get_points (GnomeCanvasLine *line)
-{
- GnomeCanvasPoints *points;
- gint start_ofs, end_ofs;
-
- if (line->num_points == 0)
- return NULL;
-
- start_ofs = end_ofs = 0;
-
- points = gnome_canvas_points_new (line->num_points);
-
- /* Invariant: if first_coords or last_coords exist, then the line's
- * endpoints have been adjusted.
- */
-
- if (line->first_coords) {
- start_ofs = 1;
-
- points->coords[0] = line->first_coords[0];
- points->coords[1] = line->first_coords[1];
- }
-
- if (line->last_coords) {
- end_ofs = 1;
-
- points->coords[2 * (line->num_points - 1)] = line->last_coords[0];
- points->coords[2 * (line->num_points - 1) + 1] = line->last_coords[1];
- }
-
- memcpy (points->coords + 2 * start_ofs,
- line->coords + 2 * start_ofs,
- 2 * (line->num_points - (start_ofs + end_ofs)) * sizeof (gdouble));
-
- return points;
-}
-
-static void
-gnome_canvas_line_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GnomeCanvasLine *line;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GNOME_IS_CANVAS_LINE (object));
-
- line = GNOME_CANVAS_LINE (object);
-
- switch (param_id) {
- case PROP_POINTS:
- /* get_points returns a copy */
- g_value_take_boxed (value, get_points (line));
- break;
-
- case PROP_FILL_COLOR:
- g_value_take_string (value,
- g_strdup_printf ("#%02x%02x%02x",
- line->fill_rgba >> 24,
- (line->fill_rgba >> 16) & 0xff,
- (line->fill_rgba >> 8) & 0xff));
- break;
-
- case PROP_FILL_COLOR_GDK: {
- GnomeCanvas *canvas = GNOME_CANVAS_ITEM (line)->canvas;
- GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas));
- GdkColor color;
-
- gdk_colormap_query_color (colormap, line->fill_pixel, &color);
- g_value_set_boxed (value, &color);
- break;
- }
-
- case PROP_FILL_COLOR_RGBA:
- g_value_set_uint (value, line->fill_rgba);
- break;
-
- case PROP_WIDTH_PIXELS:
- g_value_set_uint (value, line->width);
- break;
-
- case PROP_WIDTH_UNITS:
- g_value_set_double (value, line->width);
- break;
-
- case PROP_CAP_STYLE:
- g_value_set_enum (value, line->cap);
- break;
-
- case PROP_JOIN_STYLE:
- g_value_set_enum (value, line->join);
- break;
-
- case PROP_FIRST_ARROWHEAD:
- g_value_set_boolean (value, line->first_arrow);
- break;
-
- case PROP_LAST_ARROWHEAD:
- g_value_set_boolean (value, line->last_arrow);
- break;
-
- case PROP_SMOOTH:
- g_value_set_boolean (value, line->smooth);
- break;
-
- case PROP_SPLINE_STEPS:
- g_value_set_uint (value, line->spline_steps);
- break;
-
- case PROP_ARROW_SHAPE_A:
- g_value_set_double (value, line->shape_a);
- break;
-
- case PROP_ARROW_SHAPE_B:
- g_value_set_double (value, line->shape_b);
- break;
-
- case PROP_ARROW_SHAPE_C:
- g_value_set_double (value, line->shape_c);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-gnome_canvas_line_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags)
-{
- GnomeCanvasLine *line;
- gdouble x1, y1, x2, y2;
-
- line = GNOME_CANVAS_LINE (item);
-
- if (parent_class->update)
- (* parent_class->update) (item, affine, clip_path, flags);
-
- reconfigure_arrows (line);
-
- get_bounds_canvas (line, &x1, &y1, &x2, &y2, affine);
- gnome_canvas_update_bbox (item, x1, y1, x2, y2);
-}
-
-static void
-item_to_canvas (GnomeCanvas *canvas, gdouble *item_coords, GdkPoint *canvas_coords, gint num_points,
- gint *num_drawn_points, const cairo_matrix_t *matrix)
-{
- gint i;
- gint old_cx, old_cy;
- gint cx, cy;
- double x, y;
-
-#ifdef VERBOSE
- {
- gchar str[128];
- art_affine_to_string (str, i2c);
- g_print ("line item_to_canvas %s\n", str);
- }
-#endif
-
- /* the first point is always drawn */
-
- x = item_coords[0];
- y = item_coords[1];
- cairo_matrix_transform_point (matrix, &x, &y);
- cx = floor (x + 0.5);
- cy = floor (y + 0.5);
- canvas_coords->x = cx - x;
- canvas_coords->y = cy - y;
- canvas_coords++;
- old_cx = cx;
- old_cy = cy;
- *num_drawn_points = 1;
-
- for (i = 1; i < num_points; i++) {
- x = item_coords[i * 2];
- y = item_coords[i * 2 + 1];
- cairo_matrix_transform_point (matrix, &x, &y);
- cx = floor (x + 0.5);
- cy = floor (y + 0.5);
- if (old_cx != cx || old_cy != cy) {
- canvas_coords->x = cx - x;
- canvas_coords->y = cy - y;
- old_cx = cx;
- old_cy = cy;
- canvas_coords++;
- (*num_drawn_points)++;
- }
- }
-}
-
-static void
-gnome_canvas_line_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
- gint x, gint y, gint width, gint height)
-{
- GnomeCanvasLine *line;
- GdkPoint static_points[NUM_STATIC_POINTS];
- GdkPoint *points;
- gint actual_num_points_drawn;
- cairo_matrix_t matrix;
- cairo_t *cr;
- int i;
-
- line = GNOME_CANVAS_LINE (item);
-
- if (line->num_points == 0)
- return;
-
- cr = gdk_cairo_create (drawable);
- cairo_translate (cr, -x, -y);
-
- /* points are always centered */
- cairo_translate (cr, 0.5, 0.5);
-
- cairo_set_source_rgba (cr,
- ((line->fill_pixel >> 24) & 0xff) / 255.0,
- ((line->fill_pixel >> 16) & 0xff) / 255.0,
- ((line->fill_pixel >> 8) & 0xff) / 255.0,
- ((line->fill_pixel >> 0) & 0xff) / 255.0);
- if (line->width_pixels)
- cairo_set_line_width (cr, (gint) line->width);
- else
- cairo_set_line_width (cr, (gint) (line->width * line->item.canvas->pixels_per_unit + 0.5));
- if (line->first_arrow || line->last_arrow)
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
- else
- cairo_set_line_cap (cr, line->cap);
- cairo_set_line_join (cr, line->join);
-
- gnome_canvas_item_i2c_matrix (item, &matrix);
- /* Build array of canvas pixel coordinates */
-
- if (line->num_points <= NUM_STATIC_POINTS)
- points = static_points;
- else
- points = g_new (GdkPoint, line->num_points);
-
- item_to_canvas (item->canvas, line->coords, points, line->num_points,
- &actual_num_points_drawn, &matrix);
-
- cairo_move_to (cr, points[0].x, points[0].y);
- for (i = 1; i < actual_num_points_drawn; i++)
- cairo_line_to (cr, points[i].x, points[i].y);
- cairo_stroke (cr);
-
- if (points != static_points)
- g_free (points);
-
- /* Draw arrowheads */
-
- points = static_points;
-
- if (line->first_arrow) {
- item_to_canvas (item->canvas, line->first_coords, points, NUM_ARROW_POINTS,
- &actual_num_points_drawn, &matrix);
- cairo_move_to (cr, points[0].x, points[0].y);
- for (i = 1; i < actual_num_points_drawn; i++)
- cairo_line_to (cr, points[i].x, points[i].y);
- cairo_fill (cr);
- }
-
- if (line->last_arrow) {
- item_to_canvas (item->canvas, line->last_coords, points, NUM_ARROW_POINTS,
- &actual_num_points_drawn, &matrix);
- cairo_move_to (cr, points[0].x, points[0].y);
- for (i = 1; i < actual_num_points_drawn; i++)
- cairo_line_to (cr, points[i].x, points[i].y);
- cairo_fill (cr);
- }
-}
-
-static GnomeCanvasItem *
-gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
- gint cx, gint cy)
-{
- GnomeCanvasLine *line;
- gdouble *line_points = NULL, *coords;
- gdouble static_points[2 * NUM_STATIC_POINTS];
- gdouble poly[10];
- gdouble best, dist;
- gdouble dx, dy;
- gdouble width;
- gint num_points = 0, i;
- gint changed_miter_to_bevel;
-
-#ifdef VERBOSE
- g_print ("gnome_canvas_line_point x, y = (%g, %g); cx, cy = (%d, %d)\n", x, y, cx, cy);
-#endif
-
- line = GNOME_CANVAS_LINE (item);
-
- best = 1.0e36;
-
- /* Handle smoothed lines by generating an expanded set ot points */
-
- if (line->smooth && (line->num_points > 2)) {
- /* FIXME */
- } else {
- num_points = line->num_points;
- line_points = line->coords;
- }
-
- /* Compute a polygon for each edge of the line and test the point against it. The effective
- * width of the line is adjusted so that it will be at least one pixel thick (so that zero
- * pixel-wide lines can be pickedup as well).
- */
-
- if (line->width_pixels)
- width = line->width / item->canvas->pixels_per_unit;
- else
- width = line->width;
-
- if (width < (1.0 / item->canvas->pixels_per_unit))
- width = 1.0 / item->canvas->pixels_per_unit;
-
- changed_miter_to_bevel = 0;
-
- for (i = num_points, coords = line_points; i >= 2; i--, coords += 2) {
- /* If rounding is done around the first point, then compute distance between the
- * point and the first point.
- */
-
- if (((line->cap == CAIRO_LINE_CAP_ROUND) && (i == num_points))
- || ((line->join == CAIRO_LINE_JOIN_ROUND) && (i != num_points))) {
- dx = coords[0] - x;
- dy = coords[1] - y;
- dist = sqrt (dx * dx + dy * dy) - width / 2.0;
- if (dist < GNOME_CANVAS_EPSILON) {
- best = 0.0;
- goto done;
- } else if (dist < best)
- best = dist;
- }
-
- /* Compute the polygonal shape corresponding to this edge, with two points for the
- * first point of the edge and two points for the last point of the edge.
- */
-
- if (i == num_points)
- gnome_canvas_get_butt_points (coords[2], coords[3], coords[0], coords[1],
- width, (line->cap == CAIRO_LINE_CAP_SQUARE),
- poly, poly + 1, poly + 2, poly + 3);
- else if ((line->join == CAIRO_LINE_JOIN_MITER) && !changed_miter_to_bevel) {
- poly[0] = poly[6];
- poly[1] = poly[7];
- poly[2] = poly[4];
- poly[3] = poly[5];
- } else {
- gnome_canvas_get_butt_points (coords[2], coords[3], coords[0], coords[1],
- width, FALSE,
- poly, poly + 1, poly + 2, poly + 3);
-
- /* If this line uses beveled joints, then check the distance to a polygon
- * comprising the last two points of the previous polygon and the first two
- * from this polygon; this checks the wedges that fill the mitered point.
- */
-
- if ((line->join == CAIRO_LINE_JOIN_BEVEL) || changed_miter_to_bevel) {
- poly[8] = poly[0];
- poly[9] = poly[1];
-
- dist = gnome_canvas_polygon_to_point (poly, 5, x, y);
- if (dist < GNOME_CANVAS_EPSILON) {
- best = 0.0;
- goto done;
- } else if (dist < best)
- best = dist;
-
- changed_miter_to_bevel = FALSE;
- }
- }
-
- if (i == 2)
- gnome_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3],
- width, (line->cap == CAIRO_LINE_CAP_SQUARE),
- poly + 4, poly + 5, poly + 6, poly + 7);
- else if (line->join == CAIRO_LINE_JOIN_MITER) {
- if (!gnome_canvas_get_miter_points (coords[0], coords[1],
- coords[2], coords[3],
- coords[4], coords[5],
- width,
- poly + 4, poly + 5, poly + 6, poly + 7)) {
- changed_miter_to_bevel = TRUE;
- gnome_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3],
- width, FALSE,
- poly + 4, poly + 5, poly + 6, poly + 7);
- }
- } else
- gnome_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3],
- width, FALSE,
- poly + 4, poly + 5, poly + 6, poly + 7);
-
- poly[8] = poly[0];
- poly[9] = poly[1];
-
- dist = gnome_canvas_polygon_to_point (poly, 5, x, y);
- if (dist < GNOME_CANVAS_EPSILON) {
- best = 0.0;
- goto done;
- } else if (dist < best)
- best = dist;
- }
-
- /* If caps are rounded, check the distance to the cap around the final end point of the line */
-
- if (line->cap == CAIRO_LINE_CAP_ROUND) {
- dx = coords[0] - x;
- dy = coords[1] - y;
- dist = sqrt (dx * dx + dy * dy) - width / 2.0;
- if (dist < GNOME_CANVAS_EPSILON) {
- best = 0.0;
- goto done;
- } else
- best = dist;
- }
-
- /* sometimes the GnomeCanvasItem::update signal will not have
- been processed between deleting the arrow points and a call
- to this routine -- this can cause a segfault here */
- if ((line->first_arrow && !line->first_coords) ||
- (line->last_arrow && !line->last_coords))
- reconfigure_arrows (line);
-
- /* If there are arrowheads, check the distance to them */
-
- if (line->first_arrow) {
- dist = gnome_canvas_polygon_to_point (line->first_coords, NUM_ARROW_POINTS, x, y);
- if (dist < GNOME_CANVAS_EPSILON) {
- best = 0.0;
- goto done;
- } else
- best = dist;
- }
-
- if (line->last_arrow) {
- dist = gnome_canvas_polygon_to_point (line->last_coords, NUM_ARROW_POINTS, x, y);
- if (dist < GNOME_CANVAS_EPSILON) {
- best = 0.0;
- goto done;
- } else
- best = dist;
- }
-
-done:
-
- if ((line_points != static_points) && (line_points != line->coords))
- g_free (line_points);
-
- return best == 0.0 ? item : NULL;
-}
-
-static void
-gnome_canvas_line_bounds (GnomeCanvasItem *item, gdouble *x1, gdouble *y1, gdouble *x2, gdouble *y2)
-{
- GnomeCanvasLine *line;
-
- line = GNOME_CANVAS_LINE (item);
-
- if (line->num_points == 0) {
- *x1 = *y1 = *x2 = *y2 = 0.0;
- return;
- }
-
- get_bounds (line, x1, y1, x2, y2);
-}
diff --git a/libgnomecanvas/gnome-canvas-line.h b/libgnomecanvas/gnome-canvas-line.h
deleted file mode 100644
index 749478ff72..0000000000
--- a/libgnomecanvas/gnome-canvas-line.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
- * All rights reserved.
- *
- * This file is part of the Gnome Library.
- *
- * The Gnome 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.
- *
- * The Gnome 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 the Gnome Library; see the file COPYING.LIB. If not,
- * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-/*
- @NOTATION@
- */
-
-/* Line/curve item type for GnomeCanvas widget
- *
- * GnomeCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is
- * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
- *
- *
- * Author: Federico Mena <federico@nuclecu.unam.mx>
- */
-
-#ifndef GNOME_CANVAS_LINE_H
-#define GNOME_CANVAS_LINE_H
-
-#include <libgnomecanvas/gnome-canvas.h>
-
-G_BEGIN_DECLS
-
-/* Line item for the canvas. This is a polyline with configurable width, cap/join styles, and arrowheads.
- * If arrowheads are enabled, then three values are used to specify their shape:
- *
- * arrow_shape_a: Distance from tip of arrowhead to the center point.
- * arrow_shape_b: Distance from tip of arrowhead to trailing point, measured along the shaft.
- * arrow_shape_c: Distance of trailing point from outside edge of shaft.
- *
- * The following object arguments are available:
- *
- * name type read/write description
- * ------------------------------------------------------------------------------------------
- * points GnomeCanvasPoints* RW Pointer to a GnomeCanvasPoints structure.
- * This can be created by a call to
- * gnome_canvas_points_new() (in gnome-canvas-util.h).
- * X coordinates are in the even indices of the
- * points->coords array, Y coordinates are in
- * the odd indices.
- * fill_color string W X color specification for line
- * fill_color_gdk GdkColor* RW Pointer to an allocated GdkColor
- * width_pixels uint R Width of the line in pixels. The line width
- * will not be scaled when the canvas zoom factor changes.
- * width_units gdouble R Width of the line in canvas units. The line width
- * will be scaled when the canvas zoom factor changes.
- * cap_style GdkCapStyle RW Cap ("endpoint") style for the line.
- * join_style GdkJoinStyle RW Join ("vertex") style for the line.
- * line_style GdkLineStyle RW Line dash style
- * first_arrowhead boolean RW Specifies whether to draw an arrowhead on the
- * first point of the line.
- * last_arrowhead boolean RW Specifies whether to draw an arrowhead on the
- * last point of the line.
- * smooth boolean RW Specifies whether to smooth the line using
- * parabolic splines.
- * spline_steps uint RW Specifies the number of steps to use when rendering curves.
- * arrow_shape_a gdouble RW First arrow shape specifier.
- * arrow_shape_b gdouble RW Second arrow shape specifier.
- * arrow_shape_c gdouble RW Third arrow shape specifier.
- */
-
-#define GNOME_TYPE_CANVAS_LINE (gnome_canvas_line_get_type ())
-#define GNOME_CANVAS_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_CANVAS_LINE, GnomeCanvasLine))
-#define GNOME_CANVAS_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_CANVAS_LINE, GnomeCanvasLineClass))
-#define GNOME_IS_CANVAS_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_CANVAS_LINE))
-#define GNOME_IS_CANVAS_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_CANVAS_LINE))
-#define GNOME_CANVAS_LINE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_CANVAS_LINE, GnomeCanvasLineClass))
-
-typedef struct _GnomeCanvasLine GnomeCanvasLine;
-typedef struct _GnomeCanvasLineClass GnomeCanvasLineClass;
-
-struct _GnomeCanvasLine {
- GnomeCanvasItem item;
-
- gdouble *coords; /* Array of coordinates for the line's points. X coords are in the
- * even indices, Y coords are in the odd indices. If the line has
- * arrowheads then the first and last points have been adjusted to
- * refer to the necks of the arrowheads rather than their tips. The
- * actual endpoints are stored in the first_arrow and last_arrow
- * arrays, if they exist.
- */
-
- gdouble *first_coords; /* Array of points describing polygon for the first arrowhead */
- gdouble *last_coords; /* Array of points describing polygon for the last arrowhead */
-
- GdkGC *gc; /* GC for drawing line */
-
- ArtSVP *fill_svp; /* The SVP for the outline shape */ /*AA*/
- ArtSVP *first_svp; /* The SVP for the first arrow */ /*AA*/
- ArtSVP *last_svp; /* The SVP for the last arrow */ /*AA*/
-
- gdouble width; /* Width of the line */
-
- gdouble shape_a; /* Distance from tip of arrowhead to center */
- gdouble shape_b; /* Distance from tip of arrowhead to trailing point, measured along shaft */
- gdouble shape_c; /* Distance of trailing points from outside edge of shaft */
-
- cairo_line_cap_t cap; /* Cap style for line */
- cairo_line_join_t join; /* Join style for line */
-
- gulong fill_pixel; /* Color for line */
-
- guint32 fill_rgba; /* RGBA color for outline */ /*AA*/
-
- gint num_points; /* Number of points in the line */
- guint fill_color; /* Fill color, RGBA */
-
- gint spline_steps; /* Number of steps in each spline segment */
-
- guint width_pixels : 1; /* Is the width specified in pixels or units? */
- guint first_arrow : 1; /* Draw first arrowhead? */
- guint last_arrow : 1; /* Draw last arrowhead? */
- guint smooth : 1; /* Smooth line (with parabolic splines)? */
-};
-
-struct _GnomeCanvasLineClass {
- GnomeCanvasItemClass parent_class;
-};
-
-/* Standard Gtk function */
-GType gnome_canvas_line_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif
diff --git a/libgnomecanvas/gnome-canvas-util.c b/libgnomecanvas/gnome-canvas-util.c
index 8a21c548c7..bc6b1ba968 100644
--- a/libgnomecanvas/gnome-canvas-util.c
+++ b/libgnomecanvas/gnome-canvas-util.c
@@ -616,3 +616,24 @@ gnome_canvas_cap_gdk_to_art (GdkCapStyle gdk_cap)
return ART_PATH_STROKE_CAP_BUTT; /* shut up the compiler */
}
}
+
+/**
+ * gnome_canvas_cairo_create_scratch:
+ *
+ * Create a scratch #cairo_t. This is useful for measuring purposes or
+ * calling functions like cairo_in_fill().
+ *
+ * Returns: A new cairo_t. Destroy with cairo_destroy() after use.
+ **/
+cairo_t *
+gnome_canvas_cairo_create_scratch (void)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ return cr;
+}
diff --git a/libgnomecanvas/gnome-canvas-util.h b/libgnomecanvas/gnome-canvas-util.h
index 1c43b65596..74e112f0fd 100644
--- a/libgnomecanvas/gnome-canvas-util.h
+++ b/libgnomecanvas/gnome-canvas-util.h
@@ -141,6 +141,9 @@ ArtPathStrokeJoinType gnome_canvas_join_gdk_to_art (GdkJoinStyle gdk_join);
/* Convert from GDK line cap specifier to libart. */
ArtPathStrokeCapType gnome_canvas_cap_gdk_to_art (GdkCapStyle gdk_cap);
+/* Create a scratch cairo_t for measuring purposes */
+cairo_t *gnome_canvas_cairo_create_scratch (void);
+
G_END_DECLS
#endif
diff --git a/libgnomecanvas/libgnomecanvas.h b/libgnomecanvas/libgnomecanvas.h
index 8ddd2c541e..6dff7de8dd 100644
--- a/libgnomecanvas/libgnomecanvas.h
+++ b/libgnomecanvas/libgnomecanvas.h
@@ -27,7 +27,6 @@
#define LIBGNOMECANVAS_H
#include <libgnomecanvas/gnome-canvas.h>
-#include <libgnomecanvas/gnome-canvas-line.h>
#include <libgnomecanvas/gnome-canvas-text.h>
#include <libgnomecanvas/gnome-canvas-rich-text.h>
#include <libgnomecanvas/gnome-canvas-pixbuf.h>