aboutsummaryrefslogtreecommitdiffstats
path: root/libgnomecanvas
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2010-10-09 11:27:05 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-10-30 01:49:58 +0800
commit9c9cbddd06100aebe0341bb8b0a632fd5ff5a2b3 (patch)
treea731d0b97d8306bfebb445feb6f18a092a969a98 /libgnomecanvas
parent6b75dd581c0f72f1114bc37afa1d51e9a806df50 (diff)
downloadgsoc2013-evolution-9c9cbddd06100aebe0341bb8b0a632fd5ff5a2b3.tar.gz
gsoc2013-evolution-9c9cbddd06100aebe0341bb8b0a632fd5ff5a2b3.tar.zst
gsoc2013-evolution-9c9cbddd06100aebe0341bb8b0a632fd5ff5a2b3.zip
gnome-canvas: Port GnomeCanvasLine to use Cairo for drawing
Diffstat (limited to 'libgnomecanvas')
-rw-r--r--libgnomecanvas/gnome-canvas-line.c202
-rw-r--r--libgnomecanvas/gnome-canvas-line.h5
-rw-r--r--libgnomecanvas/gnome-canvas.c30
-rw-r--r--libgnomecanvas/gnome-canvas.h1
4 files changed, 100 insertions, 138 deletions
diff --git a/libgnomecanvas/gnome-canvas-line.c b/libgnomecanvas/gnome-canvas-line.c
index a1e278450b..4e6364d7e0 100644
--- a/libgnomecanvas/gnome-canvas-line.c
+++ b/libgnomecanvas/gnome-canvas-line.c
@@ -71,7 +71,6 @@ enum {
PROP_WIDTH_UNITS,
PROP_CAP_STYLE,
PROP_JOIN_STYLE,
- PROP_LINE_STYLE,
PROP_FIRST_ARROWHEAD,
PROP_LAST_ARROWHEAD,
PROP_SMOOTH,
@@ -94,8 +93,6 @@ static void gnome_canvas_line_get_property (GObject *object,
GParamSpec *pspec);
static void gnome_canvas_line_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags);
-static void gnome_canvas_line_realize (GnomeCanvasItem *item);
-static void gnome_canvas_line_unrealize (GnomeCanvasItem *item);
static void gnome_canvas_line_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
gint x, gint y, gint width, gint height);
static gdouble gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
@@ -184,22 +181,15 @@ gnome_canvas_line_class_init (GnomeCanvasLineClass *class)
(gobject_class,
PROP_CAP_STYLE,
g_param_spec_enum ("cap_style", NULL, NULL,
- GDK_TYPE_CAP_STYLE,
- GDK_CAP_BUTT,
+ 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,
- GDK_TYPE_JOIN_STYLE,
- GDK_JOIN_MITER,
- (G_PARAM_READABLE | G_PARAM_WRITABLE)));
- g_object_class_install_property
- (gobject_class,
- PROP_LINE_STYLE,
- g_param_spec_enum ("line_style", NULL, NULL,
- GDK_TYPE_LINE_STYLE,
- GDK_LINE_SOLID,
+ G_TYPE_UINT, /* XXX */
+ CAIRO_LINE_JOIN_MITER,
(G_PARAM_READABLE | G_PARAM_WRITABLE)));
g_object_class_install_property
(gobject_class,
@@ -246,8 +236,6 @@ gnome_canvas_line_class_init (GnomeCanvasLineClass *class)
item_class->destroy = gnome_canvas_line_destroy;
item_class->update = gnome_canvas_line_update;
- item_class->realize = gnome_canvas_line_realize;
- item_class->unrealize = gnome_canvas_line_unrealize;
item_class->draw = gnome_canvas_line_draw;
item_class->point = gnome_canvas_line_point;
item_class->bounds = gnome_canvas_line_bounds;
@@ -257,9 +245,8 @@ static void
gnome_canvas_line_init (GnomeCanvasLine *line)
{
line->width = 0.0;
- line->cap = GDK_CAP_BUTT;
- line->join = GDK_JOIN_MITER;
- line->line_style = GDK_LINE_SOLID;
+ 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;
@@ -346,7 +333,7 @@ get_bounds (GnomeCanvasLine *line, gdouble *bx1, gdouble *by1, gdouble *bx2, gdo
* the two miter vertex points and add them to the bounding box.
*/
- if (line->join == GDK_JOIN_MITER)
+ 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;
@@ -561,40 +548,6 @@ reconfigure_arrows (GnomeCanvasLine *line)
}
}
-/* Convenience function to set the line's GC's foreground color */
-static void
-set_line_gc_foreground (GnomeCanvasLine *line)
-{
- GdkColor c;
-
- if (!line->gc)
- return;
-
- c.pixel = line->fill_pixel;
- gdk_gc_set_foreground (line->gc, &c);
-}
-
-/* Recalculate the line's width and set it in its GC */
-static void
-set_line_gc_width (GnomeCanvasLine *line)
-{
- gint width;
-
- if (!line->gc)
- return;
-
- if (line->width_pixels)
- width = (gint) line->width;
- else
- width = (gint) (line->width * line->item.canvas->pixels_per_unit + 0.5);
-
- gdk_gc_set_line_attributes (line->gc,
- width,
- line->line_style,
- (line->first_arrow || line->last_arrow) ? GDK_CAP_BUTT : line->cap,
- line->join);
-}
-
static void
gnome_canvas_line_set_property (GObject *object,
guint param_id,
@@ -690,14 +643,12 @@ gnome_canvas_line_set_property (GObject *object,
case PROP_WIDTH_PIXELS:
line->width = g_value_get_uint (value);
line->width_pixels = TRUE;
- set_line_gc_width (line);
gnome_canvas_item_request_update (item);
break;
case PROP_WIDTH_UNITS:
line->width = fabs (g_value_get_double (value));
line->width_pixels = FALSE;
- set_line_gc_width (line);
gnome_canvas_item_request_update (item);
break;
@@ -711,12 +662,6 @@ gnome_canvas_line_set_property (GObject *object,
gnome_canvas_item_request_update (item);
break;
- case PROP_LINE_STYLE:
- line->line_style = g_value_get_enum (value);
- set_line_gc_width (line);
- 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);
@@ -762,8 +707,6 @@ gnome_canvas_line_set_property (GObject *object,
line->fill_pixel = gnome_canvas_get_color_pixel (item->canvas,
line->fill_rgba);
- set_line_gc_foreground (line);
-
gnome_canvas_item_request_redraw_svp (item, line->fill_svp);
if (line->first_svp)
@@ -873,10 +816,6 @@ gnome_canvas_line_get_property (GObject *object,
g_value_set_enum (value, line->join);
break;
- case PROP_LINE_STYLE:
- g_value_set_enum (value, line->line_style);
- break;
-
case PROP_FIRST_ARROWHEAD:
g_value_set_boolean (value, line->first_arrow);
break;
@@ -924,56 +863,18 @@ gnome_canvas_line_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_p
reconfigure_arrows (line);
- set_line_gc_foreground (line);
- set_line_gc_width (line);
-
get_bounds_canvas (line, &x1, &y1, &x2, &y2, affine);
gnome_canvas_update_bbox (item, x1, y1, x2, y2);
}
static void
-gnome_canvas_line_realize (GnomeCanvasItem *item)
-{
- GtkLayout *layout;
- GnomeCanvasLine *line;
- GdkWindow *bin_window;
-
- line = GNOME_CANVAS_LINE (item);
-
- if (parent_class->realize)
- (* parent_class->realize) (item);
-
- layout = GTK_LAYOUT (item->canvas);
- bin_window = gtk_layout_get_bin_window (layout);
- line->gc = gdk_gc_new (bin_window);
-
-#if 0
- (* GNOME_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0);
-#endif
-}
-
-static void
-gnome_canvas_line_unrealize (GnomeCanvasItem *item)
-{
- GnomeCanvasLine *line;
-
- line = GNOME_CANVAS_LINE (item);
-
- g_object_unref (line->gc);
- line->gc = NULL;
-
- if (parent_class->unrealize)
- (* parent_class->unrealize) (item);
-}
-
-static void
item_to_canvas (GnomeCanvas *canvas, gdouble *item_coords, GdkPoint *canvas_coords, gint num_points,
- gint *num_drawn_points, gdouble i2c[6], gint x, gint y)
+ gint *num_drawn_points, const cairo_matrix_t *matrix)
{
gint i;
gint old_cx, old_cy;
gint cx, cy;
- ArtPoint pi, pc;
+ double x, y;
#ifdef VERBOSE
{
@@ -985,11 +886,11 @@ item_to_canvas (GnomeCanvas *canvas, gdouble *item_coords, GdkPoint *canvas_coor
/* the first point is always drawn */
- pi.x = item_coords[0];
- pi.y = item_coords[1];
- art_affine_point (&pc, &pi, i2c);
- cx = floor (pc.x + 0.5);
- cy = floor (pc.y + 0.5);
+ 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++;
@@ -998,11 +899,11 @@ item_to_canvas (GnomeCanvas *canvas, gdouble *item_coords, GdkPoint *canvas_coor
*num_drawn_points = 1;
for (i = 1; i < num_points; i++) {
- pi.x = item_coords[i * 2];
- pi.y = item_coords[i * 2 + 1];
- art_affine_point (&pc, &pi, i2c);
- cx = floor (pc.x + 0.5);
- cy = floor (pc.y + 0.5);
+ 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;
@@ -1022,13 +923,37 @@ gnome_canvas_line_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
GdkPoint static_points[NUM_STATIC_POINTS];
GdkPoint *points;
gint actual_num_points_drawn;
- gdouble i2c[6];
+ 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)
@@ -1036,12 +961,13 @@ gnome_canvas_line_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
else
points = g_new (GdkPoint, line->num_points);
- gnome_canvas_item_i2c_affine (item, i2c);
-
item_to_canvas (item->canvas, line->coords, points, line->num_points,
- &actual_num_points_drawn, i2c, x, y);
+ &actual_num_points_drawn, &matrix);
- gdk_draw_lines (drawable, line->gc, points, actual_num_points_drawn);
+ 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);
@@ -1052,14 +978,20 @@ gnome_canvas_line_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
if (line->first_arrow) {
item_to_canvas (item->canvas, line->first_coords, points, NUM_ARROW_POINTS,
- &actual_num_points_drawn, i2c, x, y);
- gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn );
+ &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, i2c, x, y);
- gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn );
+ &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);
}
}
@@ -1116,8 +1048,8 @@ gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
* point and the first point.
*/
- if (((line->cap == GDK_CAP_ROUND) && (i == num_points))
- || ((line->join == GDK_JOIN_ROUND) && (i != num_points))) {
+ 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;
@@ -1134,9 +1066,9 @@ gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
if (i == num_points)
gnome_canvas_get_butt_points (coords[2], coords[3], coords[0], coords[1],
- width, (line->cap == GDK_CAP_PROJECTING),
+ width, (line->cap == CAIRO_LINE_CAP_SQUARE),
poly, poly + 1, poly + 2, poly + 3);
- else if ((line->join == GDK_JOIN_MITER) && !changed_miter_to_bevel) {
+ else if ((line->join == CAIRO_LINE_JOIN_MITER) && !changed_miter_to_bevel) {
poly[0] = poly[6];
poly[1] = poly[7];
poly[2] = poly[4];
@@ -1151,7 +1083,7 @@ gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
* from this polygon; this checks the wedges that fill the mitered point.
*/
- if ((line->join == GDK_JOIN_BEVEL) || changed_miter_to_bevel) {
+ if ((line->join == CAIRO_LINE_JOIN_BEVEL) || changed_miter_to_bevel) {
poly[8] = poly[0];
poly[9] = poly[1];
@@ -1168,9 +1100,9 @@ gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
if (i == 2)
gnome_canvas_get_butt_points (coords[0], coords[1], coords[2], coords[3],
- width, (line->cap == GDK_CAP_PROJECTING),
+ width, (line->cap == CAIRO_LINE_CAP_SQUARE),
poly + 4, poly + 5, poly + 6, poly + 7);
- else if (line->join == GDK_JOIN_MITER) {
+ 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],
@@ -1199,7 +1131,7 @@ gnome_canvas_line_point (GnomeCanvasItem *item, gdouble x, gdouble y,
/* If caps are rounded, check the distance to the cap around the final end point of the line */
- if (line->cap == GDK_CAP_ROUND) {
+ if (line->cap == CAIRO_LINE_CAP_ROUND) {
dx = coords[0] - x;
dy = coords[1] - y;
dist = sqrt (dx * dx + dy * dy) - width / 2.0;
diff --git a/libgnomecanvas/gnome-canvas-line.h b/libgnomecanvas/gnome-canvas-line.h
index 5dbeecd07e..749478ff72 100644
--- a/libgnomecanvas/gnome-canvas-line.h
+++ b/libgnomecanvas/gnome-canvas-line.h
@@ -113,9 +113,8 @@ struct _GnomeCanvasLine {
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 */
- GdkCapStyle cap; /* Cap style for line */
- GdkJoinStyle join; /* Join style for line */
- GdkLineStyle line_style;/* Style for the line */
+ cairo_line_cap_t cap; /* Cap style for line */
+ cairo_line_join_t join; /* Join style for line */
gulong fill_pixel; /* Color for line */
diff --git a/libgnomecanvas/gnome-canvas.c b/libgnomecanvas/gnome-canvas.c
index 4f84b9e8ab..f89133c9ad 100644
--- a/libgnomecanvas/gnome-canvas.c
+++ b/libgnomecanvas/gnome-canvas.c
@@ -414,6 +414,18 @@ gnome_canvas_item_update (GnomeCanvasItem *item,
item->flags &= ~GNOME_CANVAS_ITEM_NEED_VIS;
}
+static void
+gnome_canvas_matrix_from_affine (cairo_matrix_t *matrix,
+ double affine[6])
+{
+ matrix->xx = affine[0];
+ matrix->yx = affine[1];
+ matrix->xy = affine[2];
+ matrix->yy = affine[3];
+ matrix->x0 = affine[4];
+ matrix->y0 = affine[5];
+}
+
#define noHACKISH_AFFINE
/*
@@ -1106,6 +1118,24 @@ gnome_canvas_item_i2c_affine (GnomeCanvasItem *item, gdouble affine[6])
art_affine_multiply (affine, i2w, w2c);
}
+/**
+ * gnome_canvas_item_i2c_matrix:
+ * @item: A canvas item.
+ * @matrix: Matrix to take the resulting transformation matrix (return value).
+ *
+ * Gets the affine transform that converts from item-relative coordinates to
+ * canvas pixel coordinates.
+ **/
+void
+gnome_canvas_item_i2c_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix)
+{
+ gdouble affine;
+
+ gnome_canvas_item_i2c_affine (item, &affine);
+
+ gnome_canvas_matrix_from_affine (matrix, &affine);
+}
+
/* Returns whether the item is an inferior of or is equal to the parent. */
static gint
is_descendant (GnomeCanvasItem *item, GnomeCanvasItem *parent)
diff --git a/libgnomecanvas/gnome-canvas.h b/libgnomecanvas/gnome-canvas.h
index fa51400073..c698c833aa 100644
--- a/libgnomecanvas/gnome-canvas.h
+++ b/libgnomecanvas/gnome-canvas.h
@@ -282,6 +282,7 @@ void gnome_canvas_item_i2w_affine (GnomeCanvasItem *item, gdouble affine[6]);
* canvas pixel coordinates.
*/
void gnome_canvas_item_i2c_affine (GnomeCanvasItem *item, gdouble affine[6]);
+void gnome_canvas_item_i2c_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix);
/* Remove the item from its parent group and make the new group its parent. The
* item will be put on top of all the items in the new group. The item's