[anjuta] foocanvas, class-inheritance: Use cairo to render canvas; gdk draw is butt ugly



commit 71bb87d00641045c76a392c858e1940139860f9f
Author: Naba Kumar <naba gnome org>
Date:   Sat May 15 01:33:07 2010 +0300

    foocanvas, class-inheritance: Use cairo to render canvas; gdk draw is butt ugly

 libfoocanvas/foo-canvas-line.c              |  241 ++++-----------
 libfoocanvas/foo-canvas-line.h              |    9 +-
 libfoocanvas/foo-canvas-polygon.c           |  172 ++++-------
 libfoocanvas/foo-canvas-polygon.h           |    6 +-
 libfoocanvas/foo-canvas-rect-ellipse.c      |  439 ++++++++-------------------
 libfoocanvas/foo-canvas-rect-ellipse.h      |    4 +-
 libfoocanvas/foo-canvas-text.c              |    4 -
 libfoocanvas/foo-canvas.c                   |   42 +--
 libfoocanvas/foo-canvas.h                   |   10 -
 plugins/class-inheritance/class-callbacks.c |   12 +-
 plugins/class-inheritance/class-inherit.c   |   16 +-
 11 files changed, 272 insertions(+), 683 deletions(-)
---
diff --git a/libfoocanvas/foo-canvas-line.c b/libfoocanvas/foo-canvas-line.c
index 5a1600e..34cddf0 100644
--- a/libfoocanvas/foo-canvas-line.c
+++ b/libfoocanvas/foo-canvas-line.c
@@ -42,7 +42,8 @@
 #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 GDK_TO_CAIRO_LINE_CAP(cap) ((cap == GDK_CAP_NOT_LAST)? CAIRO_LINE_CAP_BUTT : cap - 1)
+#define GDK_TO_CAIRO_LINE_JOIN(join) (join)
 
 #define GROW_BOUNDS(bx1, by1, bx2, by2, x, y) {	\
 	if (x < bx1)				\
@@ -58,7 +59,6 @@
 		by2 = y;			\
 }
 
-
 enum {
 	PROP_0,
 	PROP_POINTS,
@@ -74,6 +74,7 @@ enum {
 	PROP_FIRST_ARROWHEAD,
 	PROP_LAST_ARROWHEAD,
 	PROP_SMOOTH,
+	PROP_AA,
 	PROP_SPLINE_STEPS,
 	PROP_ARROW_SHAPE_A,
 	PROP_ARROW_SHAPE_B,
@@ -209,10 +210,10 @@ foo_canvas_line_class_init (FooCanvasLineClass *klass)
 				       G_PARAM_READWRITE));
         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_READWRITE));
+                 PROP_AA,
+                 g_param_spec_boolean ("aa", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
         g_object_class_install_property
                 (gobject_class,
                  PROP_ARROW_SHAPE_A,
@@ -253,8 +254,8 @@ foo_canvas_line_init (FooCanvasLine *line)
 	line->shape_a = 0.0;
 	line->shape_b = 0.0;
 	line->shape_c = 0.0;
-	line->spline_steps = DEFAULT_SPLINE_STEPS;
-	line->line_smoothed = FALSE;
+	line->aa = FALSE;
+	line->smooth = FALSE;
 }
 
 static void
@@ -553,60 +554,6 @@ reconfigure_arrows (FooCanvasLine *line)
 	}
 }
 
-/* Convenience function to set the line's GC's foreground color */
-static void
-set_line_gc_foreground (FooCanvasLine *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 (FooCanvasLine *line)
-{
-	int width;
-
-	if (!line->gc)
-		return;
-
-	if (line->width_pixels)
-		width = (int) line->width;
-	else
-		width = (int) (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);
-}
-
-/* Sets the stipple pattern for the line */
-static void
-set_stipple (FooCanvasLine *line, GdkBitmap *stipple, int reconfigure)
-{
-	if (line->stipple && !reconfigure)
-		g_object_unref (line->stipple);
-
-	line->stipple = stipple;
-	if (stipple && !reconfigure)
-		g_object_ref (stipple);
-
-	if (line->gc) {
-		if (stipple) {
-			gdk_gc_set_stipple (line->gc, stipple);
-			gdk_gc_set_fill (line->gc, GDK_STIPPLED);
-		} else
-			gdk_gc_set_fill (line->gc, GDK_SOLID);
-	}
-}
-
 static void
 foo_canvas_line_set_property (GObject              *object,
 				guint                 param_id,
@@ -662,7 +609,6 @@ foo_canvas_line_set_property (GObject              *object,
 		/* Since the line's points have changed, we need to re-generate arrowheads in
 		 * addition to recalculating the bounds.
 		 */
-		line->line_smoothed = FALSE;
 		foo_canvas_item_request_update (item);
 		break;
 
@@ -701,21 +647,20 @@ foo_canvas_line_set_property (GObject              *object,
 		break;
 
 	case PROP_FILL_STIPPLE:
-		set_stipple (line, (GdkBitmap *) g_value_get_object (value), FALSE);
+		line->stipple = (GdkBitmap *) g_value_get_object (value);
+		g_object_ref (line->stipple);
 		foo_canvas_item_request_redraw (item);		
 		break;
 
 	case PROP_WIDTH_PIXELS:
 		line->width = g_value_get_uint (value);
 		line->width_pixels = TRUE;
-		set_line_gc_width (line);
 		foo_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);
 		foo_canvas_item_request_update (item);
 		break;
 
@@ -731,7 +676,6 @@ foo_canvas_line_set_property (GObject              *object,
 
 	case PROP_LINE_STYLE:
 		line->line_style = g_value_get_enum (value);
-		set_line_gc_width (line);
 		foo_canvas_item_request_update (item);
 		break;
 
@@ -747,13 +691,11 @@ foo_canvas_line_set_property (GObject              *object,
 
 	case PROP_SMOOTH:
 		line->smooth = g_value_get_boolean (value);
-		line->line_smoothed = FALSE;
 		foo_canvas_item_request_update (item);
 		break;
 
-	case PROP_SPLINE_STEPS:
-		line->spline_steps = g_value_get_int (value);
-		line->line_smoothed = FALSE;
+	case PROP_AA:
+		line->aa = g_value_get_boolean (value);
 		foo_canvas_item_request_update (item);
 		break;
 
@@ -784,8 +726,6 @@ foo_canvas_line_set_property (GObject              *object,
 			line->fill_pixel = foo_canvas_get_color_pixel (item->canvas,
 									 line->fill_rgba);
 
-		set_line_gc_foreground (line);
-
 		foo_canvas_item_request_redraw (item);		
 	}
 }
@@ -866,7 +806,7 @@ foo_canvas_line_get_property (GObject              *object,
 		g_value_set_boxed (value, &color);
 		break;
 	}
-
+			
 	case PROP_FILL_COLOR_RGBA:
 		g_value_set_uint (value, line->fill_rgba);
 		break;
@@ -907,8 +847,8 @@ foo_canvas_line_get_property (GObject              *object,
 		g_value_set_boolean (value, line->smooth);
 		break;
 
-	case PROP_SPLINE_STEPS:
-		g_value_set_uint (value, line->spline_steps);
+	case PROP_AA:
+		g_value_set_boolean (value, line->aa);
 		break;
 
 	case PROP_ARROW_SHAPE_A:
@@ -942,10 +882,6 @@ foo_canvas_line_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, int f
 
 	reconfigure_arrows (line);
 
-	set_line_gc_foreground (line);
-	set_line_gc_width (line);
-	set_stipple (line, line->stipple, TRUE);
-	
 	get_bounds_canvas (line, &x1, &y1, &x2, &y2, i2w_dx, i2w_dy);
 	foo_canvas_update_bbox (item, x1, y1, x2, y2);
 }
@@ -959,13 +895,6 @@ foo_canvas_line_realize (FooCanvasItem *item)
 
 	if (parent_class->realize)
 		(* parent_class->realize) (item);
-
-	line->gc = gdk_gc_new (item->canvas->layout.bin_window);
-/* FIXME FIXME FIXME Need to recalc pixel values, set colours, etc. */
-
-#if 0
-	(* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0);
-#endif
 }
 
 static void
@@ -975,9 +904,6 @@ foo_canvas_line_unrealize (FooCanvasItem *item)
 
 	line = FOO_CANVAS_LINE (item);
 
-	g_object_unref (line->gc);
-	line->gc = NULL;
-
 	if (parent_class->unrealize)
 		(* parent_class->unrealize) (item);
 }
@@ -1016,102 +942,24 @@ item_to_canvas (FooCanvas *canvas, double *item_coords, GdkPoint *canvas_coords,
 	}
 }
 
-/**
- * Implements a cubic B-curve. 4 consecutive points are taken at a time to
- * build the curve segments. Any remaining points at the end that don't form
- * a curve are just joined as line segments.
- * 
- * The process modifies the line points of the canvas item. So after this, the
- * points are no longer what user originally supplied. The curve is computed
- * once before a draw and reused, until influencial properties are modified
- * (points, smooth, spline_steps properties of the canvas item). So, make sure
- * when these properties are modified, line->line_smoothed is reset to FALSE
- * so that next draw would recalculate it.
- * 
- * Algorithm: see http://en.wikipedia.org/wiki/Bezier_curve
- */
-static void
-foo_canvas_line_smooth (FooCanvasLine *line)
-{
-	gint curr_point = 0;
-	gint num_points = 0;
-	gdouble *line_points;
-
-	if (line->line_smoothed)
-		return;
-	
-	if (!line->smooth || line->num_points <= 2)
-	{
-		line->line_smoothed = TRUE;
-		return;
-	}
-
-	line_points = g_new (gdouble, 2 * ((line->num_points - 1) * line->spline_steps));
-	while (curr_point < (line->num_points - 3))
-	{
-		gint step;
-		gdouble p0_x, p0_y, p1_x, p1_y, p2_x, p2_y, p3_x, p3_y;
-		p0_x = line->coords[2 * curr_point];
-		p0_y = line->coords[2 * curr_point + 1];
-		p1_x = line->coords[2 * (curr_point + 1)];
-		p1_y = line->coords[2 * (curr_point + 1) + 1];
-		p2_x = line->coords[2 * (curr_point + 2)];
-		p2_y = line->coords[2 * (curr_point + 2) + 1];
-		p3_x = line->coords[2 * (curr_point + 3)];
-		p3_y = line->coords[2 * (curr_point + 3) + 1];
-		for (step = 0; step < line->spline_steps; step++)
-		{
-			gdouble q0_x, q0_y, q1_x, q1_y, q2_x, q2_y;
-			gdouble r0_x, r0_y, r1_x, r1_y;
-			
-			q0_x = p0_x + (p1_x - p0_x) * step / line->spline_steps;
-			q0_y = p0_y + (p1_y - p0_y) * step  / line->spline_steps;
-			q1_x = p1_x + (p2_x - p1_x) * step / line->spline_steps;
-			q1_y = p1_y + (p2_y - p1_y) * step / line->spline_steps;
-			q2_x = p2_x + (p3_x - p2_x) * step / line->spline_steps;
-			q2_y = p2_y + (p3_y - p2_y) * step / line->spline_steps;
-
-			r0_x = q0_x + (q1_x - q0_x) * step / line->spline_steps;
-			r0_y = q0_y + (q1_y - q0_y) * step  / line->spline_steps;
-			r1_x = q1_x + (q2_x - q1_x) * step / line->spline_steps;
-			r1_y = q1_y + (q2_y - q1_y) * step / line->spline_steps;
-			
-			line_points[2 * num_points] = r0_x + (r1_x - r0_x) * step / line->spline_steps;
-			line_points[2 * num_points + 1] = r0_y + (r1_y - r0_y) * step / line->spline_steps;
-			num_points++;
-		}
-		curr_point += 3;
-	}
-	for (; curr_point < line->num_points; curr_point++)
-	{
-			line_points[2 * num_points] = line->coords[2 * curr_point];
-			line_points[2 * num_points + 1] = line->coords[2 * curr_point + 1];
-			num_points++;
-	}
-	line->line_smoothed = TRUE;
-	g_free (line->coords);
-	line->coords = line_points;
-	line->num_points = num_points;
-}
-
 static void
 foo_canvas_line_draw (FooCanvasItem *item, GdkDrawable *drawable,
 			GdkEventExpose *event)
 {
+	gint i;
+	cairo_t *cr;
 	FooCanvasLine *line;
 	GdkPoint static_points[NUM_STATIC_POINTS];
 	GdkPoint *points;
 	int actual_num_points_drawn;
 	double i2w_dx, i2w_dy;
+	double width;
 	
 	line = FOO_CANVAS_LINE (item);
 
 	if (line->num_points == 0)
 		return;
 
-	/* Smooth the line, if not yet done */
-	foo_canvas_line_smooth (FOO_CANVAS_LINE (line));
-	
 	/* Build array of canvas pixel coordinates */
 
 	if (line->num_points <= NUM_STATIC_POINTS)
@@ -1126,10 +974,40 @@ foo_canvas_line_draw (FooCanvasItem *item, GdkDrawable *drawable,
 	item_to_canvas (item->canvas, line->coords, points, line->num_points,
 			&actual_num_points_drawn, i2w_dx, i2w_dy);
 
-	if (line->stipple)
-		foo_canvas_set_stipple_origin (item->canvas, line->gc);
-
-	gdk_draw_lines (drawable, line->gc, points, actual_num_points_drawn);
+	if (line->width_pixels)
+		width = line->width;
+	else
+		width = line->width * line->item.canvas->pixels_per_unit;
+
+	cr = gdk_cairo_create (drawable);
+	cairo_set_line_width (cr, width);
+	cairo_set_line_cap (cr, GDK_TO_CAIRO_LINE_CAP (line->cap));
+	cairo_set_line_join (cr, GDK_TO_CAIRO_LINE_JOIN (line->join));
+	/* FIXME: Set line dash */
+	cairo_set_source_rgba (cr,
+	                       ((double) ((line->fill_rgba & 0xff000000) >> 24)) / 255,
+						   ((double) ((line->fill_rgba & 0xff0000) >> 16)) / 255,
+						   ((double) ((line->fill_rgba & 0xff00) >> 8)) / 255,
+						   ((double) ((line->fill_rgba & 0xff))) / 255);
+	if (!line->aa)
+		cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+
+    cairo_move_to (cr, points[0].x, points[0].y);
+	i = 1;
+	if (line->smooth)
+	{
+		for (; (i+2) < actual_num_points_drawn; i += 3)
+		{
+			cairo_curve_to (cr,
+			                points[i].x, points[i].y,
+			                points[i+1].x, points[i+1].y,
+			                points[i+2].x, points[i+2].y);
+		}
+	}
+	for (; 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);
@@ -1141,14 +1019,23 @@ foo_canvas_line_draw (FooCanvasItem *item, GdkDrawable *drawable,
 	if (line->first_arrow) {
 		item_to_canvas (item->canvas, line->first_coords, points, NUM_ARROW_POINTS,
 				&actual_num_points_drawn, i2w_dx, i2w_dy);
-		gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn );
+		cairo_move_to (cr, points[0].x, points[0].y);
+		for (i = 1; i < actual_num_points_drawn - 1; i++)
+			cairo_line_to (cr, points[i].x, points[i].y);
+		cairo_close_path (cr);
+		cairo_fill (cr);
 	}
 
 	if (line->last_arrow) {
 		item_to_canvas (item->canvas, line->last_coords, points, NUM_ARROW_POINTS,
 				&actual_num_points_drawn, i2w_dx, i2w_dy);
-		gdk_draw_polygon (drawable, line->gc, TRUE, points, actual_num_points_drawn );
+		cairo_move_to (cr, points[0].x, points[0].y);
+		for (i = 1; i < actual_num_points_drawn - 1; i++)
+			cairo_line_to (cr, points[i].x, points[i].y);
+		cairo_close_path (cr);
+		cairo_fill (cr);
 	}
+	cairo_destroy (cr);
 }
 
 static double
diff --git a/libfoocanvas/foo-canvas-line.h b/libfoocanvas/foo-canvas-line.h
index f77c065..e928a75 100644
--- a/libfoocanvas/foo-canvas-line.h
+++ b/libfoocanvas/foo-canvas-line.h
@@ -107,8 +107,6 @@ struct _FooCanvasLine {
 	double *first_coords;	/* Array of points describing polygon for the first arrowhead */
 	double *last_coords;	/* Array of points describing polygon for the last arrowhead */
 
-	GdkGC *gc;		/* GC for drawing line */
-
 	GdkBitmap *stipple;	/* Stipple pattern */
 
 	double width;		/* Width of the line */
@@ -122,19 +120,14 @@ struct _FooCanvasLine {
 	GdkLineStyle line_style;/* Style for the line */
 
 	gulong fill_pixel;	/* Color for line */
-
 	guint32 fill_rgba;		/* RGBA color for outline */ /*AA*/
 
 	int num_points;		/* Number of points in the line */
-	guint fill_color;	/* Fill color, RGBA */
-
-	int 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)? */
-	gboolean line_smoothed : 1; /* If smooth == TRUE, has the line been smoothened */
+	guint aa: 1; /* Enable anti-alias for this item */
 };
 
 struct _FooCanvasLineClass {
diff --git a/libfoocanvas/foo-canvas-polygon.c b/libfoocanvas/foo-canvas-polygon.c
index 679d7bb..6833e20 100644
--- a/libfoocanvas/foo-canvas-polygon.c
+++ b/libfoocanvas/foo-canvas-polygon.c
@@ -66,7 +66,8 @@ enum {
 	PROP_FILL_STIPPLE,
 	PROP_OUTLINE_STIPPLE,
 	PROP_WIDTH_PIXELS,
-	PROP_WIDTH_UNITS
+	PROP_WIDTH_UNITS,
+	PROP_AA
 };
 
 
@@ -85,8 +86,6 @@ static void foo_canvas_polygon_get_property (GObject              *object,
 static void   foo_canvas_polygon_update      (FooCanvasItem *item,
 						double i2w_dx, double i2w_dy,
 						int flags);
-static void   foo_canvas_polygon_realize     (FooCanvasItem *item);
-static void   foo_canvas_polygon_unrealize   (FooCanvasItem *item);
 static void   foo_canvas_polygon_draw        (FooCanvasItem *item, GdkDrawable *drawable,
 						GdkEventExpose *expose);
 static double foo_canvas_polygon_point       (FooCanvasItem *item, double x, double y,
@@ -181,12 +180,16 @@ foo_canvas_polygon_class_init (FooCanvasPolygonClass *klass)
                  g_param_spec_double ("width-units", NULL, NULL,
 				      0.0, G_MAXDOUBLE, 0.0,
 				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_AA,
+                 g_param_spec_boolean ("aa", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
 
 	object_class->destroy = foo_canvas_polygon_destroy;
 
 	item_class->update = foo_canvas_polygon_update;
-	item_class->realize = foo_canvas_polygon_realize;
-	item_class->unrealize = foo_canvas_polygon_unrealize;
 	item_class->draw = foo_canvas_polygon_draw;
 	item_class->point = foo_canvas_polygon_point;
 	item_class->translate = foo_canvas_polygon_translate;
@@ -197,6 +200,7 @@ static void
 foo_canvas_polygon_init (FooCanvasPolygon *poly)
 {
 	poly->width = 0.0;
+	poly->aa = FALSE;
 }
 
 static void
@@ -332,57 +336,6 @@ set_points (FooCanvasPolygon *poly, FooCanvasPoints *points)
 	}
 }
 
-/* Convenience function to set a GC's foreground color to the specified pixel value */
-static void
-set_gc_foreground (GdkGC *gc, gulong pixel)
-{
-	GdkColor c;
-
-	if (!gc)
-		return;
-
-	c.pixel = pixel;
-	gdk_gc_set_foreground (gc, &c);
-}
-
-/* Sets the stipple pattern for the specified gc */
-static void
-set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure)
-{
-	if (*internal_stipple && !reconfigure)
-		g_object_unref (*internal_stipple);
-
-	*internal_stipple = stipple;
-	if (stipple && !reconfigure)
-		g_object_ref (stipple);
-
-	if (gc) {
-		if (stipple) {
-			gdk_gc_set_stipple (gc, stipple);
-			gdk_gc_set_fill (gc, GDK_STIPPLED);
-		} else
-			gdk_gc_set_fill (gc, GDK_SOLID);
-	}
-}
-
-/* Recalculate the outline width of the polygon and set it in its GC */
-static void
-set_outline_gc_width (FooCanvasPolygon *poly)
-{
-	int width;
-
-	if (!poly->outline_gc)
-		return;
-
-	if (poly->width_pixels)
-		width = (int) poly->width;
-	else
-		width = (int) (poly->width * poly->item.canvas->pixels_per_unit + 0.5);
-
-	gdk_gc_set_line_attributes (poly->outline_gc, width,
-				    GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_ROUND);
-}
-
 static void
 foo_canvas_polygon_set_property (GObject              *object,
 				   guint                 param_id,
@@ -470,7 +423,6 @@ foo_canvas_polygon_set_property (GObject              *object,
 			poly->fill_pixel = foo_canvas_get_color_pixel (item->canvas,
 									 poly->fill_color);
 
-		set_gc_foreground (poly->fill_gc, poly->fill_pixel);
 		foo_canvas_item_request_redraw (item);		
 		break;
 
@@ -524,24 +476,28 @@ foo_canvas_polygon_set_property (GObject              *object,
 			poly->outline_pixel = foo_canvas_get_color_pixel (item->canvas,
 									    poly->outline_color);
 
-		set_gc_foreground (poly->outline_gc, poly->outline_pixel);
 		foo_canvas_item_request_redraw (item);		
 		break;
 
 	case PROP_FILL_STIPPLE:
-		set_stipple (poly->fill_gc, &poly->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
+		if (poly->fill_stipple)
+			g_object_unref (poly->fill_stipple);
+		poly->fill_stipple = (GdkBitmap *) g_value_get_object (value);
+		g_object_ref (poly->fill_stipple);
 		foo_canvas_item_request_update (item);
 		break;
 
 	case PROP_OUTLINE_STIPPLE:
-		set_stipple (poly->outline_gc, &poly->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
+		if (poly->outline_stipple)
+			g_object_unref (poly->outline_stipple);
+		poly->outline_stipple = (GdkBitmap *) g_value_get_object (value);
+		g_object_ref (poly->outline_stipple);
 		foo_canvas_item_request_update (item);
 		break;
 
 	case PROP_WIDTH_PIXELS:
 		poly->width = g_value_get_uint (value);
 		poly->width_pixels = TRUE;
-		set_outline_gc_width (poly);
 #ifdef OLD_XFORM
 		recalc_bounds (poly);
 #else
@@ -552,13 +508,16 @@ foo_canvas_polygon_set_property (GObject              *object,
 	case PROP_WIDTH_UNITS:
 		poly->width = fabs (g_value_get_double (value));
 		poly->width_pixels = FALSE;
-		set_outline_gc_width (poly);
 #ifdef OLD_XFORM
 		recalc_bounds (poly);
 #else
 		foo_canvas_item_request_update (item);
 #endif
 		break;
+	case PROP_AA:
+		poly->aa = g_value_get_boolean (value);
+		foo_canvas_item_request_update (item);
+		break;
 
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -631,6 +590,10 @@ foo_canvas_polygon_get_property (GObject              *object,
 		g_value_set_object (value, (GObject *) poly->outline_stipple);
 		break;
 
+	case PROP_AA:
+		g_value_set_boolean (value, poly->aa);
+		break;
+
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -650,51 +613,10 @@ foo_canvas_polygon_update (FooCanvasItem *item,
 	if (parent_class->update)
 		(* parent_class->update) (item, i2w_dx, i2w_dy, flags);
 
-	set_outline_gc_width (poly);
-	set_gc_foreground (poly->fill_gc, poly->fill_pixel);
-	set_gc_foreground (poly->outline_gc, poly->outline_pixel);
-	set_stipple (poly->fill_gc, &poly->fill_stipple, poly->fill_stipple, TRUE);
-	set_stipple (poly->outline_gc, &poly->outline_stipple, poly->outline_stipple, TRUE);
-	
 	if (get_bounds_canvas (poly, &x1, &y1, &x2, &y2, i2w_dx, i2w_dy))
 		foo_canvas_update_bbox (item, x1, y1, x2, y2);
 }
 
-static void
-foo_canvas_polygon_realize (FooCanvasItem *item)
-{
-	FooCanvasPolygon *poly;
-
-	poly = FOO_CANVAS_POLYGON (item);
-
-	if (parent_class->realize)
-		(* parent_class->realize) (item);
-
-	poly->fill_gc = gdk_gc_new (item->canvas->layout.bin_window);
-	poly->outline_gc = gdk_gc_new (item->canvas->layout.bin_window);
-/* FIXME FIXME FIXME Need to recalc pixel values, set colours, etc. */
-
-#ifdef OLD_XFORM
-	(* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0);
-#endif
-}
-
-static void
-foo_canvas_polygon_unrealize (FooCanvasItem *item)
-{
-	FooCanvasPolygon *poly;
-
-	poly = FOO_CANVAS_POLYGON (item);
-
-	g_object_unref (poly->fill_gc);
-	poly->fill_gc = NULL;
-	g_object_unref (poly->outline_gc);
-	poly->outline_gc = NULL;
-
-	if (parent_class->unrealize)
-		(* parent_class->unrealize) (item);
-}
-
 /* Converts an array of world coordinates into an array of canvas pixel coordinates.  Takes in the
  * item->world deltas and the drawable deltas.
  */
@@ -717,11 +639,14 @@ static void
 foo_canvas_polygon_draw (FooCanvasItem *item, GdkDrawable *drawable,
 			   GdkEventExpose *expose)
 {
+	cairo_t *cr;
 	FooCanvasPolygon *poly;
 	GdkPoint static_points[NUM_STATIC_POINTS];
 	GdkPoint *points;
 	double i2w_dx, i2w_dy;
-
+	double width;
+	gint i;
+	
 	poly = FOO_CANVAS_POLYGON (item);
 
 	if (poly->num_points == 0)
@@ -742,18 +667,41 @@ foo_canvas_polygon_draw (FooCanvasItem *item, GdkDrawable *drawable,
 			poly->coords, points, poly->num_points,
 			i2w_dx, i2w_dy);
 
-	if (poly->fill_set) {
-		if (poly->fill_stipple)
-			foo_canvas_set_stipple_origin (item->canvas, poly->fill_gc);
+	if (poly->width_pixels)
+		width = poly->width;
+	else
+		width = poly->width * poly->item.canvas->pixels_per_unit;
 
-		gdk_draw_polygon (drawable, poly->fill_gc, TRUE, points, poly->num_points);
+	cr = gdk_cairo_create (drawable);
+	if (!poly->aa)
+		cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+	cairo_set_line_width (cr, width);
+
+	cairo_move_to (cr, points[0].x, points[0].y);
+	for(i = 1; i < poly->num_points - 1; i++)
+	{
+		cairo_line_to (cr, points[i].x, points[i].y);
+	}
+	cairo_close_path (cr);
+	
+	if (poly->fill_set) {
+		/* FIXME: Set stripple */
+		cairo_set_source_rgba (cr,
+		                       ((double) ((poly->fill_color & 0xff000000) >> 24)) / 255,
+		                       ((double) ((poly->fill_color & 0xff0000) >> 16)) / 255,
+		                       ((double) ((poly->fill_color & 0xff00) >> 8)) / 255,
+		                       ((double) ((poly->fill_color & 0xff))) / 255);
+		cairo_fill_preserve (cr);
 	}
 
 	if (poly->outline_set) {
-		if (poly->outline_stipple)
-			foo_canvas_set_stipple_origin (item->canvas, poly->outline_gc);
-
-		gdk_draw_polygon (drawable, poly->outline_gc, FALSE, points, poly->num_points);
+		/* FIXME: Set stripple */
+		cairo_set_source_rgba (cr,
+		                       ((double) ((poly->outline_color & 0xff000000) >> 24)) / 255,
+		                       ((double) ((poly->outline_color & 0xff0000) >> 16)) / 255,
+		                       ((double) ((poly->outline_color & 0xff00) >> 8)) / 255,
+		                       ((double) ((poly->outline_color & 0xff))) / 255);
+		cairo_stroke (cr);
 	}
 
 	/* Done */
diff --git a/libfoocanvas/foo-canvas-polygon.h b/libfoocanvas/foo-canvas-polygon.h
index d56fd45..354befc 100644
--- a/libfoocanvas/foo-canvas-polygon.h
+++ b/libfoocanvas/foo-canvas-polygon.h
@@ -88,9 +88,6 @@ struct _FooCanvasPolygon {
 	GdkBitmap *fill_stipple;	/* Stipple for fill */
 	GdkBitmap *outline_stipple;	/* Stipple for outline */
 
-	GdkGC *fill_gc;			/* GC for filling */
-	GdkGC *outline_gc;		/* GC for outline */
-
 	gulong fill_pixel;		/* Color for fill */
 	gulong outline_pixel;		/* Color for outline */
 	double width;			/* Width of polygon's outline */
@@ -99,12 +96,13 @@ struct _FooCanvasPolygon {
 	guint fill_color;		/* Fill color, RGBA */
 	guint outline_color;		/* Outline color, RGBA */
 
-        guint32 fill_rgba;		/* RGBA color for filling */ /*AA*/
+	guint32 fill_rgba;		/* RGBA color for filling */ /*AA*/
 	guint32 outline_rgba;		/* RGBA color for outline */ /*AA*/
 
 	guint fill_set : 1;		/* Is fill color set? */
 	guint outline_set : 1;		/* Is outline color set? */
 	guint width_pixels : 1;		/* Is outline width specified in pixels or units? */
+	guint aa: 1; /* Enable anti-alias for this item */
 };
 
 struct _FooCanvasPolygonClass {
diff --git a/libfoocanvas/foo-canvas-rect-ellipse.c b/libfoocanvas/foo-canvas-rect-ellipse.c
index 1c18949..c6a154a 100644
--- a/libfoocanvas/foo-canvas-rect-ellipse.c
+++ b/libfoocanvas/foo-canvas-rect-ellipse.c
@@ -61,7 +61,8 @@ enum {
 	PROP_FILL_STIPPLE,
 	PROP_OUTLINE_STIPPLE,
 	PROP_WIDTH_PIXELS,
-	PROP_WIDTH_UNITS
+	PROP_WIDTH_UNITS,
+	PROP_AA
 };
 
 
@@ -80,7 +81,6 @@ static void foo_canvas_re_get_property (GObject              *object,
 static void foo_canvas_re_update_shared (FooCanvasItem *item,
 					   double i2w_dx, double i2w_dy, int flags);
 static void foo_canvas_re_realize     (FooCanvasItem *item);
-static void foo_canvas_re_unrealize   (FooCanvasItem *item);
 static void foo_canvas_re_bounds      (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
 static void foo_canvas_re_translate   (FooCanvasItem *item, double dx, double dy);
 static void foo_canvas_rect_update      (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags);
@@ -225,11 +225,16 @@ foo_canvas_re_class_init (FooCanvasREClass *klass)
                  g_param_spec_double ("width-units", NULL, NULL,
 				      0.0, G_MAXDOUBLE, 0.0,
 				      G_PARAM_READWRITE));
+        g_object_class_install_property
+                (gobject_class,
+                 PROP_AA,
+                 g_param_spec_boolean ("aa", NULL, NULL,
+				       FALSE,
+				       G_PARAM_READWRITE));
 
 	object_class->destroy = foo_canvas_re_destroy;
 
 	item_class->realize = foo_canvas_re_realize;
-	item_class->unrealize = foo_canvas_re_unrealize;
 	item_class->translate = foo_canvas_re_translate;
 	item_class->bounds = foo_canvas_re_bounds;
 }
@@ -242,6 +247,7 @@ foo_canvas_re_init (FooCanvasRE *re)
 	re->x2 = 0.0;
 	re->y2 = 0.0;
 	re->width = 0.0;
+	re->aa = FALSE;
 }
 
 static void
@@ -268,6 +274,25 @@ foo_canvas_re_destroy (GtkObject *object)
 		(* GTK_OBJECT_CLASS (re_parent_class)->destroy) (object);
 }
 
+static double
+get_draw_width_pixels (FooCanvasRE *re)
+{
+	double width;
+	if (re->width_pixels)
+		width = re->width;
+	else
+		width = re->width * re->item.canvas->pixels_per_unit;
+	width += 2.0; /* AA puts 1 px around for fuzzing */
+	return width;
+}
+
+static double
+get_draw_width_units (FooCanvasRE *re)
+{
+	double width = get_draw_width_pixels (re);
+	return (width / re->item.canvas->pixels_per_unit);
+}
+
 static void get_bounds (FooCanvasRE *re, double *px1, double *py1, double *px2, double *py2)
 {
 	FooCanvasItem *item;
@@ -280,11 +305,7 @@ static void get_bounds (FooCanvasRE *re, double *px1, double *py1, double *px2,
 #endif
 	item = FOO_CANVAS_ITEM (re);
 
-	if (re->width_pixels)
-		hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0;
-	else
-		hwidth = re->width / 2.0;
-
+	hwidth = get_draw_width_units (re) / 2.0;
 	x1 = re->x1;
 	y1 = re->y1;
 	x2 = re->x2;
@@ -307,57 +328,6 @@ static void get_bounds (FooCanvasRE *re, double *px1, double *py1, double *px2,
 	*py2 += 2;
 }
 
-/* Convenience function to set a GC's foreground color to the specified pixel value */
-static void
-set_gc_foreground (GdkGC *gc, gulong pixel)
-{
-	GdkColor c;
-
-	if (!gc)
-		return;
-
-	c.pixel = pixel;
-	gdk_gc_set_foreground (gc, &c);
-}
-
-/* Sets the stipple pattern for the specified gc */
-static void
-set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure)
-{
-	if (*internal_stipple && !reconfigure)
-		g_object_unref (*internal_stipple);
-
-	*internal_stipple = stipple;
-	if (stipple && !reconfigure)
-		g_object_ref (stipple);
-
-	if (gc) {
-		if (stipple) {
-			gdk_gc_set_stipple (gc, stipple);
-			gdk_gc_set_fill (gc, GDK_STIPPLED);
-		} else
-			gdk_gc_set_fill (gc, GDK_SOLID);
-	}
-}
-
-/* Recalculate the outline width of the rectangle/ellipse and set it in its GC */
-static void
-set_outline_gc_width (FooCanvasRE *re)
-{
-	int width;
-
-	if (!re->outline_gc)
-		return;
-
-	if (re->width_pixels)
-		width = (int) re->width;
-	else
-		width = (int) (re->width * re->item.canvas->pixels_per_unit + 0.5);
-
-	gdk_gc_set_line_attributes (re->outline_gc, width,
-				    GDK_LINE_SOLID, GDK_CAP_PROJECTING, GDK_JOIN_MITER);
-}
-
 static void
 foo_canvas_re_set_fill (FooCanvasRE *re, gboolean fill_set)
 {
@@ -469,8 +439,6 @@ foo_canvas_re_set_property (GObject              *object,
 		else
 			re->fill_pixel = foo_canvas_get_color_pixel (item->canvas, re->fill_color);
 
-		set_gc_foreground (re->fill_gc, re->fill_pixel);
-
 		foo_canvas_item_request_redraw (item);		
 		break;
 
@@ -525,33 +493,37 @@ foo_canvas_re_set_property (GObject              *object,
 			re->outline_pixel = foo_canvas_get_color_pixel (item->canvas,
 									  re->outline_color);
 
-		set_gc_foreground (re->outline_gc, re->outline_pixel);
-
 		foo_canvas_item_request_redraw (item);		
 		break;
 
 	case PROP_FILL_STIPPLE:
-	        set_stipple (re->fill_gc, &re->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
-
+		if (re->fill_stipple)
+			g_object_unref (re->fill_stipple);
+		re->fill_stipple = (GdkBitmap *) g_value_get_object (value);
+		g_object_ref (re->fill_stipple);
 		break;
 
 	case PROP_OUTLINE_STIPPLE:
-	        set_stipple (re->outline_gc, &re->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE);
+		if (re->outline_stipple)
+			g_object_unref (re->outline_stipple);
+		re->outline_stipple = (GdkBitmap *) g_value_get_object (value);
+		g_object_ref (re->outline_stipple);
 		break;
 
 	case PROP_WIDTH_PIXELS:
 		re->width = g_value_get_uint (value);
 		re->width_pixels = TRUE;
-		set_outline_gc_width (re);
-
 		foo_canvas_item_request_update (item);
 		break;
 
 	case PROP_WIDTH_UNITS:
 		re->width = fabs (g_value_get_double (value));
 		re->width_pixels = FALSE;
-		set_outline_gc_width (re);
+		foo_canvas_item_request_update (item);
+		break;
 
+	case PROP_AA:
+		re->aa = g_value_get_boolean (value);
 		foo_canvas_item_request_update (item);
 		break;
 
@@ -629,6 +601,10 @@ foo_canvas_re_get_property (GObject              *object,
 		g_value_set_object (value,  (GObject *) re->outline_stipple);
 		break;
 
+	case PROP_AA:
+		g_value_set_boolean (value, re->aa);
+		break;
+
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -636,16 +612,6 @@ foo_canvas_re_get_property (GObject              *object,
 }
 
 static void
-set_colors_and_stipples (FooCanvasRE *re)
-{
-	set_gc_foreground (re->fill_gc, re->fill_pixel);
-	set_gc_foreground (re->outline_gc, re->outline_pixel);
-	set_stipple (re->fill_gc, &re->fill_stipple, re->fill_stipple, TRUE);
-	set_stipple (re->outline_gc, &re->outline_stipple, re->outline_stipple, TRUE);
-	set_outline_gc_width (re);
-}
-
-static void
 foo_canvas_re_update_shared (FooCanvasItem *item, double i2w_dx, double i2w_dy, int flags)
 {
 	FooCanvasRE *re;
@@ -658,8 +624,6 @@ foo_canvas_re_update_shared (FooCanvasItem *item, double i2w_dx, double i2w_dy,
 	if (re_parent_class->update)
 		(* re_parent_class->update) (item, i2w_dx, i2w_dy, flags);
 
-	set_colors_and_stipples (re);
-
 #ifdef OLD_XFORM
 	recalc_bounds (re);
 #endif
@@ -678,11 +642,8 @@ foo_canvas_re_realize (FooCanvasItem *item)
 	if (re_parent_class->realize)
 		(* re_parent_class->realize) (item);
 
-	re->fill_gc = gdk_gc_new (item->canvas->layout.bin_window);
 	re->fill_pixel = foo_canvas_get_color_pixel (item->canvas, re->fill_color);
-	re->outline_gc = gdk_gc_new (item->canvas->layout.bin_window);
 	re->outline_pixel = foo_canvas_get_color_pixel (item->canvas, re->outline_color);
-	set_colors_and_stipples (re);
 
 #ifdef OLD_XFORM
 	(* FOO_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0);
@@ -690,22 +651,6 @@ foo_canvas_re_realize (FooCanvasItem *item)
 }
 
 static void
-foo_canvas_re_unrealize (FooCanvasItem *item)
-{
-	FooCanvasRE *re;
-
-	re = FOO_CANVAS_RE (item);
-
-	g_object_unref (re->fill_gc);
-	re->fill_gc = NULL;
-	g_object_unref (re->outline_gc);
-	re->outline_gc = NULL;
-
-	if (re_parent_class->unrealize)
-		(* re_parent_class->unrealize) (item);
-}
-
-static void
 foo_canvas_re_translate (FooCanvasItem *item, double dx, double dy)
 {
 	FooCanvasRE *re;
@@ -721,7 +666,6 @@ foo_canvas_re_translate (FooCanvasItem *item, double dx, double dy)
 	re->y2 += dy;
 }
 
-
 static void
 foo_canvas_re_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
 {
@@ -733,10 +677,7 @@ foo_canvas_re_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, d
 #endif
 	re = FOO_CANVAS_RE (item);
 
-	if (re->width_pixels)
-		hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0;
-	else
-		hwidth = re->width / 2.0;
+	hwidth = get_draw_width_units (re) / 2.0;
 
 	*x1 = re->x1 - hwidth;
 	*y1 = re->y1 - hwidth;
@@ -833,140 +774,21 @@ foo_canvas_rect_finalize (GObject *object)
 static void
 foo_canvas_rect_realize  (FooCanvasItem *item)
 {
-#ifdef HAVE_RENDER
-	FooCanvasRectPrivate *priv;
-	int event_base, error_base;
-	Display *dpy;
-
-	priv = FOO_CANVAS_RECT (item)->priv;
-
-	dpy = gdk_x11_drawable_get_xdisplay (GTK_WIDGET (item->canvas)->window);
-	priv->use_render = XRenderQueryExtension (dpy, &event_base, &error_base);
-
-	if (priv->use_render) {
-		GdkVisual *gdk_visual;
-		Visual *visual;
-
-		gdk_visual = gtk_widget_get_visual (GTK_WIDGET (item->canvas));
-		visual = gdk_x11_visual_get_xvisual (gdk_visual);
-
-		priv->format = XRenderFindVisualFormat (dpy, visual);
-	}
-#endif
-	
 	if (FOO_CANVAS_ITEM_CLASS (rect_parent_class)->realize) {
 		(* FOO_CANVAS_ITEM_CLASS (rect_parent_class)->realize) (item);
 	}
 }
 
-
-static void
-render_rect_alpha (FooCanvasRect *rect,
-		   GdkDrawable *drawable,
-		   int x, int y,
-		   int width, int height,
-		   guint32 rgba)
-{
-	GdkPixbuf *pixbuf;
-	guchar *data;
-	int rowstride, i;
-	guchar r, g, b, a;
-	FooCanvasRectPrivate *priv;
-
-	if (width <= 0 || height <= 0 ) {
-		return;
-	}
-	
-	priv = rect->priv;
-
-	r = (rgba >> 24) & 0xff;
-	g = (rgba >> 16) & 0xff;
-	b = (rgba >> 8) & 0xff;
-	a = (rgba >> 0) & 0xff;
-
-#ifdef HAVE_RENDER
-	/* Every visual is not guaranteed to have a matching
-	 * XRenderPictFormat. So make sure that format is not null before
-	 * trying to render using Xrender calls.
-	 */
-	if (priv->use_render && (priv->format != NULL)) {
-		GdkDrawable *real_drawable;
-		int x_offset, y_offset;
-
-		Display *dpy;
-		Picture  pict;
-		XRenderPictureAttributes attributes;
-		XRenderColor color;
-
-		gdk_window_get_internal_paint_info (drawable, &real_drawable,
-						    &x_offset, &y_offset);
-
-		dpy = gdk_x11_drawable_get_xdisplay (real_drawable);
-
-		pict = XRenderCreatePicture (dpy,
-					     gdk_x11_drawable_get_xid (real_drawable),
-					     priv->format,
-					     0,
-					     &attributes);
-
-
-		/* Convert to premultiplied alpha: */
-		r = r * a / 255;
-		g = g * a / 255;
-		b = b * a / 255;
-		
-		color.red = (r << 8) + r;
-		color.green = (g << 8) + g;
-		color.blue = (b << 8) + b;
-		color.alpha = (a << 8) + a;
-		
-		XRenderFillRectangle (dpy,
-				      PictOpOver,
-				      pict,
-				      &color,
-				      x - x_offset, y - y_offset,
-				      width, height);
-		
-		XRenderFreePicture (dpy, pict);
-
-		return;
-	}
-#endif
-	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
-	data = gdk_pixbuf_get_pixels (pixbuf);
-	rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-	
-	r = (rgba >> 24) & 0xff;
-	g = (rgba >> 16) & 0xff;
-	b = (rgba >> 8) & 0xff;
-	a = (rgba >> 0) & 0xff;
-	
-	for (i = 0; i < width*4; ) {
-		data[i++] = r;
-		data[i++] = g;
-		data[i++] = b;
-		data[i++] = a;
-	}
-	
-	for (i = 1; i < height; i++) {
-		memcpy (data + i*rowstride, data, width*4);
-	}
-	
-	gdk_draw_pixbuf (drawable, NULL, pixbuf,
-			 0, 0, x, y, width, height,
-			 GDK_RGB_DITHER_NONE, 0, 0);
-	g_object_unref (pixbuf);
-}
-
-
 static void
 foo_canvas_rect_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
 {
+	cairo_t *cr;
 	FooCanvasRE *re;
 	double x1, y1, x2, y2;
 	int cx1, cy1, cx2, cy2;
 	double i2w_dx, i2w_dy;
-
+	double width;
+	
 	re = FOO_CANVAS_RE (item);
 
 	/* Get canvas pixel coordinates */
@@ -981,63 +803,39 @@ foo_canvas_rect_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose
 
 	foo_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1);
 	foo_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2);
+
+	if (re->width_pixels)
+		width = re->width;
+	else
+		width = re->width * re->item.canvas->pixels_per_unit;
+
+	cr = gdk_cairo_create (drawable);
+	if (!re->aa)
+		cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+	cairo_set_line_width (cr, width);
 	
 	if (re->fill_set) {
-		if ((re->fill_color & 0xff) != 255) {
-			GdkRectangle *rectangles;
-			gint i, n_rectangles;
-			GdkRectangle draw_rect;
-			GdkRectangle part;
-
-			draw_rect.x = cx1;
-			draw_rect.y = cy1;
-			draw_rect.width = cx2 - cx1 + 1;
-			draw_rect.height = cy2 - cy1 + 1;
-			
-			/* For alpha mode, only render the parts of the region
-			   that are actually exposed */
-			gdk_region_get_rectangles (expose->region,
-						   &rectangles,
-						   &n_rectangles);
-
-			for (i = 0; i < n_rectangles; i++) {
-				if (gdk_rectangle_intersect (&rectangles[i],
-							     &draw_rect,
-							     &part)) {
-					render_rect_alpha (FOO_CANVAS_RECT (item),
-							   drawable,
-							   part.x, part.y,
-							   part.width, part.height,
-							   re->fill_color);
-				}
-			}
-			
-			g_free (rectangles);
-		} else {
-			if (re->fill_stipple)
-				foo_canvas_set_stipple_origin (item->canvas, re->fill_gc);
-
-			gdk_draw_rectangle (drawable,
-					    re->fill_gc,
-					    TRUE,
-					    cx1, cy1,
-					    cx2 - cx1 + 1,
-					    cy2 - cy1 + 1);
-		}
+		/* FIXME: Use stipple */
+		cairo_set_source_rgba (cr,
+		                       ((double) ((re->fill_color & 0xff000000) >> 24)) / 255,
+		                       ((double) ((re->fill_color & 0xff0000) >> 16)) / 255,
+		                       ((double) ((re->fill_color & 0xff00) >> 8)) / 255,
+		                       ((double) ((re->fill_color & 0xff))) / 255);
+		cairo_rectangle (cr, cx1, cy1, cx2 - cx1 + 1, cy2 - cy1 + 1);
+		cairo_fill (cr);
 	}
 
 	if (re->outline_set) {
-		if (re->outline_stipple)
-			foo_canvas_set_stipple_origin (item->canvas, re->outline_gc);
-
-		gdk_draw_rectangle (drawable,
-				    re->outline_gc,
-				    FALSE,
-				    cx1,
-				    cy1,
-				    cx2 - cx1,
-				    cy2 - cy1);
+		/* FIXME: Use stipple */
+		cairo_set_source_rgba (cr,
+		                       ((double) ((re->outline_color & 0xff000000) >> 24)) / 255,
+		                       ((double) ((re->outline_color & 0xff0000) >> 16)) / 255,
+		                       ((double) ((re->outline_color & 0xff00) >> 8)) / 255,
+		                       ((double) ((re->outline_color & 0xff))) / 255);
+		cairo_rectangle (cr, cx1, cy1, cx2 - cx1, cy2 - cy1);
+		cairo_stroke (cr);
 	}
+	cairo_destroy (cr);
 }
 
 static double
@@ -1064,11 +862,7 @@ foo_canvas_rect_point (FooCanvasItem *item, double x, double y, int cx, int cy,
 	y2 = re->y2;
 
 	if (re->outline_set) {
-		if (re->width_pixels)
-			hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0;
-		else
-			hwidth = re->width / 2.0;
-
+		hwidth = get_draw_width_units (re) / 2.0;
 		x1 -= hwidth;
 		y1 -= hwidth;
 		x2 += hwidth;
@@ -1188,11 +982,8 @@ foo_canvas_rect_update (FooCanvasItem *item, double i2w_dx, double i2w_dy, gint
 
 	if (re->outline_set) {
 		/* Outline and bounding box */
-		if (re->width_pixels)
-			width_pixels = (int) re->width;
-		else
-			width_pixels = (int) floor (re->width * re->item.canvas->pixels_per_unit + 0.5);
-
+		width_pixels = get_draw_width_pixels (re);
+		
 		width_lt = width_pixels / 2;
 		width_rb = (width_pixels + 1) / 2;
 		
@@ -1274,10 +1065,12 @@ foo_canvas_ellipse_class_init (FooCanvasEllipseClass *klass)
 static void
 foo_canvas_ellipse_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose)
 {
+	cairo_t *cr;
 	FooCanvasRE *re;
 	int x1, y1, x2, y2;
 	double i2w_dx, i2w_dy;
-
+	double width;
+	
 	re = FOO_CANVAS_RE (item);
 
 	/* Get canvas pixel coordinates */
@@ -1294,36 +1087,51 @@ foo_canvas_ellipse_draw (FooCanvasItem *item, GdkDrawable *drawable, GdkEventExp
 			  re->x2 + i2w_dx,
 			  re->y2 + i2w_dy,
 			  &x2, &y2);
+	
+	if (re->width_pixels)
+		width = re->width;
+	else
+		width = re->width * re->item.canvas->pixels_per_unit;
 
+	cr = gdk_cairo_create (drawable);
+	if (!re->aa)
+		cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+	cairo_set_line_width (cr, width);
+	
 	if (re->fill_set) {
-		if (re->fill_stipple)
-			foo_canvas_set_stipple_origin (item->canvas, re->fill_gc);
-
-		gdk_draw_arc (drawable,
-			      re->fill_gc,
-			      TRUE,
-			      x1,
-			      y1,
-			      x2 - x1,
-			      y2 - y1,
-			      0 * 64,
-			      360 * 64);
+		/* FIXME: set stipple as source */
+		cairo_set_source_rgba (cr,
+		                       ((double) ((re->fill_color & 0xff000000) >> 24)) / 255,
+		                       ((double) ((re->fill_color & 0xff0000) >> 16)) / 255,
+		                       ((double) ((re->fill_color & 0xff00) >> 8)) / 255,
+		                       ((double) ((re->fill_color & 0xff))) / 255);
+		cairo_save (cr);
+		cairo_translate (cr, x1 + (x2 - x1)/2, y1 + (y2 - y1)/2);
+		cairo_scale (cr, (x2 - x1)/2, (y2 - y1)/2);
+		cairo_arc (cr, 0.0, 0.0, 1.0, 0 * 64, 360 * 64);
+		cairo_restore (cr);
+		cairo_fill_preserve (cr);
 	}
 
 	if (re->outline_set) {
-		if (re->outline_stipple)
-			foo_canvas_set_stipple_origin (item->canvas, re->outline_gc);
-
-		gdk_draw_arc (drawable,
-			      re->outline_gc,
-			      FALSE,
-			      x1,
-			      y1,
-			      x2 - x1,
-			      y2 - y1,
-			      0 * 64,
-			      360 * 64);
+		/* FIXME: set stipple as source */
+		
+		cairo_set_source_rgba (cr,
+		                       ((double) ((re->outline_color & 0xff000000) >> 24)) / 255,
+		                       ((double) ((re->outline_color & 0xff0000) >> 16)) / 255,
+		                       ((double) ((re->outline_color & 0xff00) >> 8)) / 255,
+		                       ((double) ((re->outline_color & 0xff))) / 255);
+		if (!re->fill_set)
+		{
+			cairo_save (cr);
+			cairo_translate (cr, x1 + (x2 - x1)/2, y1 + (y2 - y1)/2);
+			cairo_scale (cr, (x2 - x1)/2, (y2 - y1)/2);
+			cairo_arc (cr, 0.0, 0.0, 1.0, 0 * 64, 360 * 64);
+			cairo_restore (cr);
+		}
+		cairo_stroke (cr);
 	}
+	cairo_destroy (cr);
 }
 
 static double
@@ -1343,10 +1151,7 @@ foo_canvas_ellipse_point (FooCanvasItem *item, double x, double y, int cx, int c
 	*actual_item = item;
 
 	if (re->outline_set) {
-		if (re->width_pixels)
-			width = re->width / item->canvas->pixels_per_unit;
-		else
-			width = re->width;
+		width = get_draw_width_units (re);
 	} else
 		width = 0.0;
 
diff --git a/libfoocanvas/foo-canvas-rect-ellipse.h b/libfoocanvas/foo-canvas-rect-ellipse.h
index 5ee8a25..233481e 100644
--- a/libfoocanvas/foo-canvas-rect-ellipse.h
+++ b/libfoocanvas/foo-canvas-rect-ellipse.h
@@ -81,9 +81,6 @@ struct _FooCanvasRE {
 	GdkBitmap *fill_stipple;	/* Stipple for fill */
 	GdkBitmap *outline_stipple;	/* Stipple for outline */
 
-	GdkGC *fill_gc;			/* GC for filling */
-	GdkGC *outline_gc;		/* GC for outline */
-
 	gulong fill_pixel;		/* Fill color */
 	gulong outline_pixel;		/* Outline color */
 
@@ -98,6 +95,7 @@ struct _FooCanvasRE {
 	unsigned int fill_set : 1;	/* Is fill color set? */
 	unsigned int outline_set : 1;	/* Is outline color set? */
 	unsigned int width_pixels : 1;	/* Is outline width specified in pixels or units? */
+	unsigned int aa: 1; /* Enable anti-alias for this item */
 };
 
 struct _FooCanvasREClass {
diff --git a/libfoocanvas/foo-canvas-text.c b/libfoocanvas/foo-canvas-text.c
index ca876db..029e31c 100644
--- a/libfoocanvas/foo-canvas-text.c
+++ b/libfoocanvas/foo-canvas-text.c
@@ -1408,10 +1408,6 @@ foo_canvas_text_draw (FooCanvasItem *item, GdkDrawable *drawable,
 		gdk_gc_set_clip_rectangle (text->gc, &rect);
 	}
 
-	if (text->stipple)
-		foo_canvas_set_stipple_origin (item->canvas, text->gc);
-
-
 	gdk_draw_layout (drawable, text->gc, text->cx, text->cy, text->layout);
 
 	if (text->clip)
diff --git a/libfoocanvas/foo-canvas.c b/libfoocanvas/foo-canvas.c
index 0ac3534..f08ec21 100644
--- a/libfoocanvas/foo-canvas.c
+++ b/libfoocanvas/foo-canvas.c
@@ -2260,10 +2260,6 @@ foo_canvas_realize (GtkWidget *widget)
 				 | GDK_LEAVE_NOTIFY_MASK
 				 | GDK_FOCUS_CHANGE_MASK));
 
-	/* Create our own temporary pixmap gc and realize all the items */
-
-	canvas->pixmap_gc = gdk_gc_new (canvas->layout.bin_window);
-
 	(* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->realize) (canvas->root);
 }
 
@@ -2283,9 +2279,6 @@ foo_canvas_unrealize (GtkWidget *widget)
 
 	(* FOO_CANVAS_ITEM_GET_CLASS (canvas->root)->unrealize) (canvas->root);
 
-	g_object_unref (canvas->pixmap_gc);
-	canvas->pixmap_gc = NULL;
-
 	if (GTK_WIDGET_CLASS (canvas_parent_class)->unrealize)
 		(* GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) (widget);
 }
@@ -2908,14 +2901,15 @@ static void
 foo_canvas_draw_background (FooCanvas *canvas,
 			    int x, int y, int width, int height)
 {
+	cairo_t *cr;
+	
 	/* By default, we use the style background. */
-	gdk_gc_set_foreground (canvas->pixmap_gc,
-			       &GTK_WIDGET (canvas)->style->bg[GTK_STATE_NORMAL]);
-	gdk_draw_rectangle (canvas->layout.bin_window,
-			    canvas->pixmap_gc,
-			    TRUE,
-			    x, y,
-			    width, height);
+	cr = gdk_cairo_create (canvas->layout.bin_window);
+	cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+	gdk_cairo_set_source_color (cr, &GTK_WIDGET (canvas)->style->bg[GTK_STATE_NORMAL]);
+	cairo_rectangle (cr, x, y, width, height);
+	cairo_fill(cr);
+	cairo_destroy (cr);
 }
 
 static void
@@ -3548,26 +3542,6 @@ foo_canvas_get_color_pixel (FooCanvas *canvas, guint rgba)
 	return color.pixel;
 }
 
-
-/* FIXME: This function is not useful anymore */
-/**
- * foo_canvas_set_stipple_origin:
- * @canvas: A canvas.
- * @gc: GC on which to set the stipple origin.
- *
- * Sets the stipple origin of the specified GC as is appropriate for the canvas,
- * so that it will be aligned with other stipple patterns used by canvas items.
- * This is typically only needed by item implementations.
- **/
-void
-foo_canvas_set_stipple_origin (FooCanvas *canvas, GdkGC *gc)
-{
-	g_return_if_fail (FOO_IS_CANVAS (canvas));
-	g_return_if_fail (GDK_IS_GC (gc));
-
-	gdk_gc_set_ts_origin (gc, 0, 0);
-}
-
 static gboolean
 boolean_handled_accumulator (GSignalInvocationHint *ihint,
 			     GValue                *return_accu,
diff --git a/libfoocanvas/foo-canvas.h b/libfoocanvas/foo-canvas.h
index 401ba63..ee9208a 100644
--- a/libfoocanvas/foo-canvas.h
+++ b/libfoocanvas/foo-canvas.h
@@ -360,9 +360,6 @@ struct _FooCanvas {
 	/* If non-NULL, the currently focused item */
 	FooCanvasItem *focused_item;
 
-	/* GC for temporary draw pixmap */
-	GdkGC *pixmap_gc;
-
 	/* Event on which selection of current item is based */
 	GdkEvent pick_event;
 
@@ -517,13 +514,6 @@ int foo_canvas_get_color (FooCanvas *canvas, const char *spec, GdkColor *color);
 /* Allocates a color from the RGB value passed into this function. */
 gulong foo_canvas_get_color_pixel (FooCanvas *canvas,
 				   guint        rgba);
-     
-
-/* Sets the stipple origin of the specified gc so that it will be aligned with
- * all the stipples used in the specified canvas.  This is intended for use only
- * by canvas item implementations.
- */
-void foo_canvas_set_stipple_origin (FooCanvas *canvas, GdkGC *gc);
 
 G_END_DECLS
 
diff --git a/plugins/class-inheritance/class-callbacks.c b/plugins/class-inheritance/class-callbacks.c
index e9ca340..da9f6ee 100644
--- a/plugins/class-inheritance/class-callbacks.c
+++ b/plugins/class-inheritance/class-callbacks.c
@@ -169,14 +169,10 @@ create_class_item_tooltip (ClsNode *cls_node, const gchar *tooltip_text)
 		                     "points", points,
 		                     "fill_color_gdk",
 		                     &cls_node->plugin->style[STYLE_ITEM_BG],
-		                     NULL);
-	/* border */
-	canvas_item =
-		foo_canvas_item_new (FOO_CANVAS_GROUP (group),
-		                     foo_canvas_line_get_type (),
-		                     "points", points,
-		                     "fill_color_gdk",
-		                     &cls_node->plugin->style[STYLE_ITEM_FG],
+		                     "outline_color_gdk",
+		                     &cls_node->plugin->style[STYLE_FG],
+		                     "aa", TRUE,
+		                     "width_units", 1.0,
 		                     NULL);
 	/* shadow */
 	canvas_item =
diff --git a/plugins/class-inheritance/class-inherit.c b/plugins/class-inheritance/class-inherit.c
index 7e5ce15..e014fb8 100644
--- a/plugins/class-inheritance/class-inherit.c
+++ b/plugins/class-inheritance/class-inherit.c
@@ -93,11 +93,11 @@ create_canvas_arrow_item (FooCanvasGroup *canvas_group,
 	triangle->coords[7] = y1 + offset;
 
 	item = foo_canvas_item_new (canvas_group,
-	                              foo_canvas_polygon_get_type (),
-	                              "points", triangle,
-	                              "fill_color_gdk",
-	                              fill_color,
-	                              NULL);
+	                            foo_canvas_polygon_get_type (),
+	                            "points", triangle,
+	                            "fill_color_gdk", fill_color,
+	                            "aa", TRUE,
+	                            NULL);
 	foo_canvas_points_unref (triangle);
 	return item;
 }
@@ -122,6 +122,7 @@ create_canvas_line_item (FooCanvasGroup *canvas_group, GdkColor *fill_color,
 		                     "fill_color_gdk",
 		                     fill_color,
 		                     "width_units", 1.0,
+		                     "aa", TRUE,
 		                     NULL);
 	foo_canvas_points_unref (points);
 	return item;
@@ -709,6 +710,7 @@ cls_node_draw_expanded (ClsNode *cls_node)
 	                     "outline_color_gdk",
 	                     &cls_node->plugin->style[STYLE_FG],
 	                     "width_units", 1.0,
+	                     "aa", TRUE,
 	                     NULL);
 }
 
@@ -747,6 +749,7 @@ cls_node_draw_collapsed (ClsNode *cls_node)
 		                     "outline_color_gdk",
 		                     &cls_node->plugin->style[STYLE_FG],
 		                     "width_units", 1.0,
+		                     "aa", TRUE,
 		                     NULL);
 	g_signal_connect (GTK_OBJECT (item), "event",
 					  G_CALLBACK (on_collapsed_class_event),
@@ -846,6 +849,7 @@ cls_node_draw_edge (ClsNode *cls_node_to, ClsNodeEdge *cls_edge, ClsNode *cls_no
 			foo_canvas_item_new (foo_canvas_root
 			                     (FOO_CANVAS (cls_node_from->canvas)), 
 			                     foo_canvas_line_get_type(),
+			                     "aa", TRUE,
 			                     "smooth", TRUE,
 			                     "last_arrowhead", TRUE,
 			                     "arrow_shape_a", (gdouble) 8.0,
@@ -853,7 +857,7 @@ cls_node_draw_edge (ClsNode *cls_node_to, ClsNodeEdge *cls_edge, ClsNode *cls_no
 			                     "arrow_shape_c", (gdouble) 3.0,
 			                     "fill_color_gdk",
 			                     &cls_node_from->plugin->style[STYLE_FG],
-			                     "width_units", 2.0,
+			                     "width_units", 1.0,
 			                     "points", points,
 			                     NULL);
 		foo_canvas_item_lower_to_bottom (cls_edge->canvas_line);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]