[evolution/rendering-cleanup: 50/78] gnome-canvas: Convert canvas item transformation matrix to cairo



commit e505855951e870c549a38b93321db1b6f3c50010
Author: Benjamin Otte <otte redhat com>
Date:   Sun Oct 17 14:15:07 2010 +0200

    gnome-canvas: Convert canvas item transformation matrix to cairo
    
    Also update the GnomeCanvasItem.update vfunc to take a cairo_matrix_t
    and no longer pass the clip_path (what was it used for anyway?).

 calendar/gui/e-day-view-main-item.c        |    5 +-
 calendar/gui/e-day-view-time-item.c        |   11 +-
 calendar/gui/e-day-view-top-item.c         |    5 +-
 calendar/gui/e-meeting-time-sel-item.c     |    8 +-
 calendar/gui/e-week-view-event-item.c      |    5 +-
 calendar/gui/e-week-view-main-item.c       |    5 +-
 calendar/gui/e-week-view-titles-item.c     |    5 +-
 libgnomecanvas/gnome-canvas-pixbuf.c       |    8 +-
 libgnomecanvas/gnome-canvas-rect.c         |    6 +-
 libgnomecanvas/gnome-canvas-rich-text.c    |   10 +-
 libgnomecanvas/gnome-canvas-shape.c        |    6 +-
 libgnomecanvas/gnome-canvas-text.c         |    8 +-
 libgnomecanvas/gnome-canvas-widget.c       |   10 +-
 libgnomecanvas/gnome-canvas.c              |  410 +++++-----------------------
 libgnomecanvas/gnome-canvas.h              |   19 +-
 widgets/misc/e-calendar-item.c             |    8 +-
 widgets/misc/e-canvas-utils.c              |    7 +-
 widgets/misc/e-canvas.c                    |   34 +--
 widgets/table/e-table-field-chooser-item.c |   34 +--
 widgets/table/e-table-header-item.c        |   35 +--
 widgets/table/e-table-item.c               |   63 ++---
 widgets/text/e-reflow.c                    |    6 +-
 widgets/text/e-text.c                      |    4 +-
 23 files changed, 200 insertions(+), 512 deletions(-)
---
diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c
index 33e45bb..0383d3b 100644
--- a/calendar/gui/e-day-view-main-item.c
+++ b/calendar/gui/e-day-view-main-item.c
@@ -980,15 +980,14 @@ day_view_main_item_dispose (GObject *object)
 
 static void
 day_view_main_item_update (GnomeCanvasItem *item,
-			   gdouble *affine,
-			   ArtSVP *clip_path,
+			   const cairo_matrix_t *i2c,
 			   gint flags)
 {
 	GnomeCanvasItemClass *canvas_item_class;
 
 	/* Chain up to parent's update() method. */
 	canvas_item_class = GNOME_CANVAS_ITEM_CLASS (parent_class);
-	canvas_item_class->update (item, affine, clip_path, flags);
+	canvas_item_class->update (item, i2c, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c
index e952515..e163e27 100644
--- a/calendar/gui/e-day-view-time-item.c
+++ b/calendar/gui/e-day-view-time-item.c
@@ -74,8 +74,8 @@ struct _EDayViewTimeItemPrivate {
 };
 
 static void e_day_view_time_item_update (GnomeCanvasItem *item,
-					 double *affine,
-					 ArtSVP *clip_path, gint flags);
+					 const cairo_matrix_t *i2c,
+					 gint flags);
 static void e_day_view_time_item_draw (GnomeCanvasItem *item,
 				       GdkDrawable *drawable,
 				       gint x, gint y,
@@ -257,12 +257,11 @@ e_day_view_time_item_get_type (void)
 
 static void
 e_day_view_time_item_update (GnomeCanvasItem *item,
-			    double *affine,
-			    ArtSVP *clip_path,
-			    gint flags)
+			     const cairo_matrix_t *i2c,
+			     gint flags)
 {
 	if (GNOME_CANVAS_ITEM_CLASS (parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, affine, clip_path, flags);
+		(* GNOME_CANVAS_ITEM_CLASS (parent_class)->update) (item, i2c, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c
index 41a2b66..126f983 100644
--- a/calendar/gui/e-day-view-top-item.c
+++ b/calendar/gui/e-day-view-top-item.c
@@ -576,15 +576,14 @@ day_view_top_item_dispose (GObject *object)
 
 static void
 day_view_top_item_update (GnomeCanvasItem *item,
-                          gdouble *affine,
-                          ArtSVP *clip_path,
+                          const cairo_matrix_t *i2c,
                           gint flags)
 {
 	GnomeCanvasItemClass *canvas_item_class;
 
 	/* Chain up to parent's update() method. */
 	canvas_item_class = GNOME_CANVAS_ITEM_CLASS (parent_class);
-	canvas_item_class->update (item, affine, clip_path, flags);
+	canvas_item_class->update (item, i2c, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
diff --git a/calendar/gui/e-meeting-time-sel-item.c b/calendar/gui/e-meeting-time-sel-item.c
index 2119127..a8b6e6b 100644
--- a/calendar/gui/e-meeting-time-sel-item.c
+++ b/calendar/gui/e-meeting-time-sel-item.c
@@ -48,8 +48,8 @@ static void e_meeting_time_selector_item_set_property (GObject *object,
 static void e_meeting_time_selector_item_realize (GnomeCanvasItem *item);
 static void e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item);
 static void e_meeting_time_selector_item_update (GnomeCanvasItem *item,
-						 double *affine,
-						 ArtSVP *clip_path, gint flags);
+						 const cairo_matrix_t *i2c,
+						 gint flags);
 static void e_meeting_time_selector_item_draw (GnomeCanvasItem *item,
 					       GdkDrawable *drawable,
 					       gint x, gint y,
@@ -221,10 +221,10 @@ e_meeting_time_selector_item_unrealize (GnomeCanvasItem *item)
 }
 
 static void
-e_meeting_time_selector_item_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, gint flags)
+e_meeting_time_selector_item_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags)
 {
 	if (GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->update)
-		(* GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->update) (item, affine, clip_path, flags);
+		(* GNOME_CANVAS_ITEM_CLASS (e_meeting_time_selector_item_parent_class)->update) (item, i2c, flags);
 
 	/* The grid covers the entire canvas area. */
 	item->x1 = 0;
diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c
index 8309dcd..c03f991 100644
--- a/calendar/gui/e-week-view-event-item.c
+++ b/calendar/gui/e-week-view-event-item.c
@@ -666,8 +666,7 @@ week_view_event_item_get_property (GObject *object,
 
 static void
 week_view_event_item_update (GnomeCanvasItem *item,
-                             gdouble *affine,
-                             ArtSVP *clip_path,
+                             const cairo_matrix_t *i2c,
                              gint flags)
 {
 	GnomeCanvasItemClass *canvas_item_class;
@@ -685,7 +684,7 @@ week_view_event_item_update (GnomeCanvasItem *item,
 
 	/* Chain up to parent's update() method. */
 	canvas_item_class = GNOME_CANVAS_ITEM_CLASS (parent_class);
-	canvas_item_class->update (item, affine, clip_path, flags);
+	canvas_item_class->update (item, i2c, flags);
 
 	item->x1 = 0;
 	item->y1 = 0;
diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c
index 5d09d45..3236504 100644
--- a/calendar/gui/e-week-view-main-item.c
+++ b/calendar/gui/e-week-view-main-item.c
@@ -354,15 +354,14 @@ week_view_main_item_dispose (GObject *object)
 
 static void
 week_view_main_item_update (GnomeCanvasItem *item,
-                            gdouble *affine,
-                            ArtSVP *clip_path,
+                            const cairo_matrix_t *i2c,
                             gint flags)
 {
 	GnomeCanvasItemClass *canvas_item_class;
 
 	/* Chain up to parent's update() method. */
 	canvas_item_class = GNOME_CANVAS_ITEM_CLASS (parent_class);
-	canvas_item_class->update (item, affine, clip_path, flags);
+	canvas_item_class->update (item, i2c, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
diff --git a/calendar/gui/e-week-view-titles-item.c b/calendar/gui/e-week-view-titles-item.c
index 2e058d1..91fe233 100644
--- a/calendar/gui/e-week-view-titles-item.c
+++ b/calendar/gui/e-week-view-titles-item.c
@@ -97,15 +97,14 @@ week_view_titles_item_dispose (GObject *object)
 
 static void
 week_view_titles_item_update (GnomeCanvasItem *item,
-                              gdouble *affine,
-                              ArtSVP *clip_path,
+                              const cairo_matrix_t *i2c,
                               gint flags)
 {
 	GnomeCanvasItemClass *canvas_item_class;
 
 	/* Chain up to parent's update() method. */
 	canvas_item_class = GNOME_CANVAS_ITEM_CLASS (parent_class);
-	canvas_item_class->update (item, affine, clip_path, flags);
+	canvas_item_class->update (item, i2c, flags);
 
 	/* The item covers the entire canvas area. */
 	item->x1 = 0;
diff --git a/libgnomecanvas/gnome-canvas-pixbuf.c b/libgnomecanvas/gnome-canvas-pixbuf.c
index 1fc7760..017ee26 100644
--- a/libgnomecanvas/gnome-canvas-pixbuf.c
+++ b/libgnomecanvas/gnome-canvas-pixbuf.c
@@ -49,8 +49,7 @@ static void gnome_canvas_pixbuf_get_property (GObject *object,
 					      GValue *value,
 					      GParamSpec *pspec);
 
-static void gnome_canvas_pixbuf_update (GnomeCanvasItem *item, gdouble *affine,
-					ArtSVP *clip_path, gint flags);
+static void gnome_canvas_pixbuf_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags);
 static void gnome_canvas_pixbuf_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 				      gint x, gint y, gint width, gint height);
 static GnomeCanvasItem *gnome_canvas_pixbuf_point (GnomeCanvasItem *item,
@@ -242,8 +241,7 @@ recompute_bounding_box (GnomeCanvasPixbuf *gcp)
 /* Update handler for the pixbuf canvas item */
 static void
 gnome_canvas_pixbuf_update (GnomeCanvasItem *item,
-                            gdouble *affine,
-                            ArtSVP *clip_path,
+                            const cairo_matrix_t *i2c,
                             gint flags)
 {
 	GnomeCanvasPixbuf *gcp;
@@ -253,7 +251,7 @@ gnome_canvas_pixbuf_update (GnomeCanvasItem *item,
 	priv = gcp->priv;
 
 	if (GNOME_CANVAS_ITEM_CLASS (gnome_canvas_pixbuf_parent_class)->update)
-		GNOME_CANVAS_ITEM_CLASS (gnome_canvas_pixbuf_parent_class)->update (item, affine, clip_path, flags);
+		GNOME_CANVAS_ITEM_CLASS (gnome_canvas_pixbuf_parent_class)->update (item, i2c, flags);
 
 	/* ordinary update logic */
         gnome_canvas_request_redraw (
diff --git a/libgnomecanvas/gnome-canvas-rect.c b/libgnomecanvas/gnome-canvas-rect.c
index 013ce08..e41abb9 100644
--- a/libgnomecanvas/gnome-canvas-rect.c
+++ b/libgnomecanvas/gnome-canvas-rect.c
@@ -59,7 +59,7 @@ static void gnome_canvas_rect_get_property (GObject              *object,
                                             GValue               *value,
                                             GParamSpec           *pspec);
 
-static void gnome_canvas_rect_update       (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags);
+static void gnome_canvas_rect_update       (GnomeCanvasItem *item, const cairo_matrix_t *matrix, gint flags);
 
 G_DEFINE_TYPE(GnomeCanvasRect, gnome_canvas_rect, GNOME_TYPE_CANVAS_SHAPE)
 
@@ -197,7 +197,7 @@ gnome_canvas_rect_get_property (GObject              *object,
 }
 
 static void
-gnome_canvas_rect_update (GnomeCanvasItem *item, gdouble affine[6], ArtSVP *clip_path, gint flags)
+gnome_canvas_rect_update (GnomeCanvasItem *item, const cairo_matrix_t *matrix, gint flags)
 {
         GnomeCanvasRect *rect = GNOME_CANVAS_RECT (item);
 
@@ -220,5 +220,5 @@ gnome_canvas_rect_update (GnomeCanvasItem *item, gdouble affine[6], ArtSVP *clip
 	}
 
 	if (GNOME_CANVAS_ITEM_CLASS (gnome_canvas_rect_parent_class)->update)
-		GNOME_CANVAS_ITEM_CLASS (gnome_canvas_rect_parent_class)->update (item, affine, clip_path, flags);
+		GNOME_CANVAS_ITEM_CLASS (gnome_canvas_rect_parent_class)->update (item, matrix, flags);
 }
diff --git a/libgnomecanvas/gnome-canvas-rich-text.c b/libgnomecanvas/gnome-canvas-rich-text.c
index 9d241f4..26c72f1 100644
--- a/libgnomecanvas/gnome-canvas-rich-text.c
+++ b/libgnomecanvas/gnome-canvas-rich-text.c
@@ -118,8 +118,8 @@ static void gnome_canvas_rich_text_set_property (GObject *object, guint property
 						const GValue *value, GParamSpec *pspec);
 static void gnome_canvas_rich_text_get_property (GObject *object, guint property_id,
 						GValue *value, GParamSpec *pspec);
-static void gnome_canvas_rich_text_update (GnomeCanvasItem *item, gdouble *affine,
-					  ArtSVP *clip_path, gint flags);
+static void gnome_canvas_rich_text_update (GnomeCanvasItem *item,
+					   const cairo_matrix_t *matrix, gint flags);
 static void gnome_canvas_rich_text_realize (GnomeCanvasItem *item);
 static void gnome_canvas_rich_text_unrealize (GnomeCanvasItem *item);
 static GnomeCanvasItem * gnome_canvas_rich_text_point (GnomeCanvasItem *item,
@@ -2062,15 +2062,15 @@ gnome_canvas_rich_text_get_bounds (GnomeCanvasItem *item,
 }
 
 static void
-gnome_canvas_rich_text_update (GnomeCanvasItem *item, gdouble *affine,
-			      ArtSVP *clip_path, gint flags)
+gnome_canvas_rich_text_update (GnomeCanvasItem *item, const cairo_matrix_t *matrix,
+			       gint flags)
 {
 	GnomeCanvasRichText *text = GNOME_CANVAS_RICH_TEXT (item);
 	gdouble x1, y1, x2, y2;
 	GtkTextIter start;
 
 	(* GNOME_CANVAS_ITEM_CLASS (parent_class)->update)(
-		item, affine, clip_path, flags);
+		item, matrix, flags);
 
 	get_bounds (text, &x1, &y1, &x2, &y2);
 
diff --git a/libgnomecanvas/gnome-canvas-shape.c b/libgnomecanvas/gnome-canvas-shape.c
index d1ad26c..346230a 100644
--- a/libgnomecanvas/gnome-canvas-shape.c
+++ b/libgnomecanvas/gnome-canvas-shape.c
@@ -55,7 +55,7 @@ static void gnome_canvas_shape_get_property (GObject               *object,
 					     GValue                *value,
                                              GParamSpec            *pspec);
 
-static void   gnome_canvas_shape_update      (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags);
+static void   gnome_canvas_shape_update      (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags);
 static void   gnome_canvas_shape_draw        (GnomeCanvasItem *item, GdkDrawable *drawable,
                                               gint x, gint y, gint width, gint height);
 static GnomeCanvasItem *gnome_canvas_shape_point (GnomeCanvasItem *item, gdouble x, gdouble y,
@@ -512,7 +512,7 @@ gnome_canvas_shape_bounds (GnomeCanvasItem *item, gdouble *x1, gdouble *y1, gdou
 }
 
 static void
-gnome_canvas_shape_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags)
+gnome_canvas_shape_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags)
 {
 	GnomeCanvasShape * shape;
 	GnomeCanvasShapePriv * priv;
@@ -525,7 +525,7 @@ gnome_canvas_shape_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_
 
 	/* Common part */
 	if (GNOME_CANVAS_ITEM_CLASS (gnome_canvas_shape_parent_class)->update)
-		GNOME_CANVAS_ITEM_CLASS (gnome_canvas_shape_parent_class)->update (item, affine, clip_path, flags);
+		GNOME_CANVAS_ITEM_CLASS (gnome_canvas_shape_parent_class)->update (item, i2c, flags);
 
         gnome_canvas_shape_bounds (item, &x1, &x2, &y1, &y2);
         gnome_canvas_item_i2w_matrix (item, &matrix);
diff --git a/libgnomecanvas/gnome-canvas-text.c b/libgnomecanvas/gnome-canvas-text.c
index 0d4d915..09c721a 100644
--- a/libgnomecanvas/gnome-canvas-text.c
+++ b/libgnomecanvas/gnome-canvas-text.c
@@ -112,8 +112,7 @@ static void gnome_canvas_text_get_property (GObject            *object,
 					    GValue             *value,
 					    GParamSpec         *pspec);
 
-static void gnome_canvas_text_update (GnomeCanvasItem *item, gdouble *affine,
-				      ArtSVP *clip_path, gint flags);
+static void gnome_canvas_text_update (GnomeCanvasItem *item, const cairo_matrix_t *matrix, gint flags);
 static void gnome_canvas_text_realize (GnomeCanvasItem *item);
 static void gnome_canvas_text_unrealize (GnomeCanvasItem *item);
 static void gnome_canvas_text_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
@@ -1329,8 +1328,7 @@ gnome_canvas_text_set_markup (GnomeCanvasText *textitem,
 /* Update handler for the text item */
 static void
 gnome_canvas_text_update (GnomeCanvasItem *item,
-                          gdouble *affine,
-                          ArtSVP *clip_path,
+                          const cairo_matrix_t *matrix,
                           gint flags)
 {
 	GnomeCanvasText *text;
@@ -1339,7 +1337,7 @@ gnome_canvas_text_update (GnomeCanvasItem *item,
 	text = GNOME_CANVAS_TEXT (item);
 
 	if (parent_class->update)
-		(* parent_class->update) (item, affine, clip_path, flags);
+		(* parent_class->update) (item, matrix, flags);
 
 	set_text_gc_foreground (text);
 	get_bounds (text, &x1, &y1, &x2, &y2);
diff --git a/libgnomecanvas/gnome-canvas-widget.c b/libgnomecanvas/gnome-canvas-widget.c
index b57b59e..bff49e5 100644
--- a/libgnomecanvas/gnome-canvas-widget.c
+++ b/libgnomecanvas/gnome-canvas-widget.c
@@ -60,8 +60,7 @@ static void gnome_canvas_widget_set_property (GObject            *object,
 					      GParamSpec         *pspec);
 
 static void	gnome_canvas_widget_update	(GnomeCanvasItem *item,
-						 gdouble *affine,
-						 ArtSVP *clip_path,
+						 const cairo_matrix_t *matrix,
 						 gint flags);
 static GnomeCanvasItem *gnome_canvas_widget_point (GnomeCanvasItem *item,
 						 gdouble x,
@@ -389,7 +388,7 @@ gnome_canvas_widget_set_property (GObject            *object,
 	}
 
 	if (update)
-		(* GNOME_CANVAS_ITEM_GET_CLASS (item)->update) (item, NULL, NULL, 0);
+		(* GNOME_CANVAS_ITEM_GET_CLASS (item)->update) (item, NULL, 0);
 
 	if (calc_bounds)
 		recalc_bounds (witem);
@@ -445,8 +444,7 @@ gnome_canvas_widget_get_property (GObject            *object,
 
 static void
 gnome_canvas_widget_update (GnomeCanvasItem *item,
-                            gdouble *affine,
-                            ArtSVP *clip_path,
+                            const cairo_matrix_t *matrix,
                             gint flags)
 {
 	GnomeCanvasWidget *witem;
@@ -454,7 +452,7 @@ gnome_canvas_widget_update (GnomeCanvasItem *item,
 	witem = GNOME_CANVAS_WIDGET (item);
 
 	if (parent_class->update)
-		(* parent_class->update) (item, affine, clip_path, flags);
+		(* parent_class->update) (item, matrix, flags);
 
 	if (witem->widget) {
 		if (witem->size_pixels) {
diff --git a/libgnomecanvas/gnome-canvas.c b/libgnomecanvas/gnome-canvas.c
index 71d18c2..4e29ea6 100644
--- a/libgnomecanvas/gnome-canvas.c
+++ b/libgnomecanvas/gnome-canvas.c
@@ -87,6 +87,7 @@
 #include "gailcanvas.h"
 #include "gnome-canvas.h"
 #include "gnome-canvas-i18n.h"
+#include "gnome-canvas-util.h"
 #include <libart_lgpl/art_rect.h>
 #include <libart_lgpl/art_rect_uta.h>
 #include <libart_lgpl/art_uta_rect.h>
@@ -177,6 +178,8 @@ static void
 gnome_canvas_item_init (GnomeCanvasItem *item)
 {
 	item->flags |= GNOME_CANVAS_ITEM_VISIBLE;
+
+        cairo_matrix_init_identity (&item->matrix);
 }
 
 /**
@@ -359,9 +362,6 @@ gnome_canvas_item_dispose (GObject *object)
 	if (item->parent)
 		group_remove (GNOME_CANVAS_GROUP (item->parent), item);
 
-	g_free (item->xform);
-	item->xform = NULL;
-
 	if (GNOME_CANVAS_ITEM_GET_CLASS (item)->destroy)
 		GNOME_CANVAS_ITEM_GET_CLASS (item)->destroy (item);
 
@@ -404,8 +404,7 @@ gnome_canvas_item_unmap (GnomeCanvasItem *item)
 /* Update handler for canvas items */
 static void
 gnome_canvas_item_update (GnomeCanvasItem *item,
-                          gdouble *affine,
-                          ArtSVP *clip_path,
+                          const cairo_matrix_t *matrix,
                           gint flags)
 {
 	item->flags &= ~GNOME_CANVAS_ITEM_NEED_UPDATE;
@@ -414,20 +413,6 @@ 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
-
 /*
  * This routine invokes the update method of the item
  * Please notice, that we take parent to canvas pixel matrix as argument
@@ -443,16 +428,11 @@ gnome_canvas_matrix_from_affine (cairo_matrix_t *matrix,
 
 static void
 gnome_canvas_item_invoke_update (GnomeCanvasItem *item,
-                                 gdouble *p2cpx,
-                                 ArtSVP *clip_path,
+                                 const cairo_matrix_t *p2c,
                                  gint flags)
 {
 	gint child_flags;
-	gdouble i2cpx[6];
-
-#ifdef HACKISH_AFFINE
-	gdouble i2w[6], w2c[6], i2c[6];
-#endif
+	cairo_matrix_t i2c;
 
 	child_flags = flags;
 	if (!(item->flags & GNOME_CANVAS_ITEM_VISIBLE))
@@ -460,28 +440,7 @@ gnome_canvas_item_invoke_update (GnomeCanvasItem *item,
 
 	/* Calculate actual item transformation matrix */
 
-	if (item->xform) {
-		if (item->flags & GNOME_CANVAS_ITEM_AFFINE_FULL) {
-			/* Item has full affine */
-			art_affine_multiply (i2cpx, item->xform, p2cpx);
-		} else {
-			/* Item has only translation */
-			memcpy (i2cpx, p2cpx, 4 * sizeof (gdouble));
-			i2cpx[4] = item->xform[0] * p2cpx[0] + item->xform[1] * p2cpx[2] + p2cpx[4];
-			i2cpx[5] = item->xform[0] * p2cpx[1] + item->xform[1] * p2cpx[3] + p2cpx[5];
-		}
-	} else {
-		/* Item has no matrix (i.e. identity) */
-		memcpy (i2cpx, p2cpx, 6 * sizeof (gdouble));
-	}
-
-#ifdef HACKISH_AFFINE
-	gnome_canvas_item_i2w_affine (item, i2w);
-	gnome_canvas_w2c_affine (item->canvas, w2c);
-	art_affine_multiply (i2c, i2w, w2c);
-	/* invariant (doesn't hold now): child_affine == i2c */
-	child_affine = i2c;
-#endif
+        cairo_matrix_multiply (&i2c, &item->matrix, p2c);
 
 	/* apply object flags to child flags */
 
@@ -501,7 +460,7 @@ gnome_canvas_item_invoke_update (GnomeCanvasItem *item,
 
 	if (child_flags & GCI_UPDATE_MASK) {
 		if (GNOME_CANVAS_ITEM_GET_CLASS (item)->update)
-			GNOME_CANVAS_ITEM_GET_CLASS (item)->update (item, i2cpx, clip_path, child_flags);
+			GNOME_CANVAS_ITEM_GET_CLASS (item)->update (item, &i2c, child_flags);
 	}
 }
 
@@ -519,39 +478,14 @@ gnome_canvas_item_invoke_point (GnomeCanvasItem *item,
                                 gint cx,
                                 gint cy)
 {
-	/* Calculate x & y in item local coordinates */
-
-	if (item->xform) {
-		if (item->flags & GNOME_CANVAS_ITEM_AFFINE_FULL) {
-			gdouble p2i[6], t;
-			/* Item has full affine */
-			art_affine_invert (p2i, item->xform);
-			t = x * p2i[0] + y * p2i[2] + p2i[4];
-			y = x * p2i[1] + y * p2i[3] + p2i[5];
-			x = t;
-		} else {
-			/* Item has only translation */
-			x -= item->xform[0];
-			y -= item->xform[1];
-		}
-	}
+        cairo_matrix_t inverse;
 
-#ifdef HACKISH_AFFINE
-	gdouble i2w[6], w2c[6], i2c[6], c2i[6];
-	ArtPoint c, i;
-#endif
+	/* Calculate x & y in item local coordinates */
+        inverse = item->matrix;
+        if (cairo_matrix_invert (&inverse) != CAIRO_STATUS_SUCCESS)
+                return NULL;
 
-#ifdef HACKISH_AFFINE
-	gnome_canvas_item_i2w_affine (item, i2w);
-	gnome_canvas_w2c_affine (item->canvas, w2c);
-	art_affine_multiply (i2c, i2w, w2c);
-	art_affine_invert (c2i, i2c);
-	c.x = cx;
-	c.y = cy;
-	art_affine_point (&i, &c, c2i);
-	x = i.x;
-	y = i.y;
-#endif
+        cairo_matrix_transform_point (&inverse, &x, &y);
 
 	if (GNOME_CANVAS_ITEM_GET_CLASS (item)->point)
 		return GNOME_CANVAS_ITEM_GET_CLASS (item)->point (item, x, y, cx, cy);
@@ -601,82 +535,44 @@ gnome_canvas_item_set_valist (GnomeCanvasItem *item,
 }
 
 /**
- * gnome_canvas_item_affine_relative:
+ * gnome_canvas_item_transform:
  * @item: A canvas item.
- * @affine: An affine transformation matrix.
+ * @matrix: An affine transformation matrix.
  *
  * Combines the specified affine transformation matrix with the item's current
- * transformation. NULL affine is not allowed.
+ * transformation.
  **/
-#define GCIAR_EPSILON 1e-6
 void
-gnome_canvas_item_affine_relative (GnomeCanvasItem *item, const gdouble affine[6])
+gnome_canvas_item_transform (GnomeCanvasItem *item, const cairo_matrix_t *matrix)
 {
-	gdouble i2p[6];
+	cairo_matrix_t i2p;
 
-	g_return_if_fail (item != NULL);
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
-	g_return_if_fail (affine != NULL);
+	g_return_if_fail (matrix != NULL);
 
 	/* Calculate actual item transformation matrix */
+	cairo_matrix_multiply (&i2p, matrix, &item->matrix);
 
-	if (item->xform) {
-		if (item->flags & GNOME_CANVAS_ITEM_AFFINE_FULL) {
-			/* Item has full affine */
-			art_affine_multiply (i2p, affine, item->xform);
-		} else {
-			/* Item has only translation */
-			memcpy (i2p, affine, 6 * sizeof (gdouble));
-			i2p[4] += item->xform[0];
-			i2p[5] += item->xform[1];
-		}
-	} else {
-		/* Item has no matrix (i.e. identity) */
-		memcpy (i2p, affine, 6 * sizeof (gdouble));
-	}
-
-	gnome_canvas_item_affine_absolute (item, i2p);
+	gnome_canvas_item_set_matrix (item, &i2p);
 }
 
 /**
- * gnome_canvas_item_affine_absolute:
+ * gnome_canvas_item_set_matrix:
  * @item: A canvas item.
- * @affine: An affine transformation matrix.
+ * @matrix: An affine transformation matrix or %NULL for the identity matrix.
  *
  * Makes the item's affine transformation matrix be equal to the specified
- * matrix. NULL affine is treated as identity.
+ * matrix. NULL is treated as identity.
  **/
 void
-gnome_canvas_item_affine_absolute (GnomeCanvasItem *item, const gdouble i2p[6])
+gnome_canvas_item_set_matrix (GnomeCanvasItem *item, const cairo_matrix_t *matrix)
 {
-	g_return_if_fail (item != NULL);
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
 
-	if (i2p &&
-	    (fabs (i2p[0] - 1.0) < GCI_EPSILON) &&
-	    (fabs (i2p[1] - 0.0) < GCI_EPSILON) &&
-	    (fabs (i2p[2] - 0.0) < GCI_EPSILON) &&
-	    (fabs (i2p[3] - 1.0) < GCI_EPSILON) &&
-	    (fabs (i2p[4] - 0.0) < GCI_EPSILON) &&
-	    (fabs (i2p[5] - 0.0) < GCI_EPSILON)) {
-		/* We are identity */
-		i2p = NULL;
-	}
-
-	if (i2p) {
-		if (item->xform && !(item->flags & GNOME_CANVAS_ITEM_AFFINE_FULL)) {
-			/* We do not want to deal with translation-only affines */
-			g_free (item->xform);
-			item->xform = NULL;
-		}
-		if (!item->xform) item->xform = g_new (gdouble, 6);
-		memcpy (item->xform, i2p, 6 * sizeof (gdouble));
-		item->flags |= GNOME_CANVAS_ITEM_AFFINE_FULL;
+	if (matrix) {
+                item->matrix = *matrix;
 	} else {
-		if (item->xform) {
-			g_free (item->xform);
-			item->xform = NULL;
-		}
+                cairo_matrix_init_identity (&item->matrix);
 	}
 
 	if (!(item->flags & GNOME_CANVAS_ITEM_NEED_AFFINE)) {
@@ -702,14 +598,13 @@ gnome_canvas_item_affine_absolute (GnomeCanvasItem *item, const gdouble i2p[6])
 void
 gnome_canvas_item_move (GnomeCanvasItem *item, gdouble dx, gdouble dy)
 {
-	gdouble translate[6];
+	cairo_matrix_t translate;
 
-	g_return_if_fail (item != NULL);
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
 
-	art_affine_translate (translate, dx, dy);
+	cairo_matrix_init_translate (&translate, dx, dy);
 
-	gnome_canvas_item_affine_relative (item, translate);
+	gnome_canvas_item_transform (item, &translate);
 }
 
 /* Convenience function to reorder items in a group's child list.  This puts the
@@ -1014,36 +909,6 @@ gnome_canvas_item_ungrab (GnomeCanvasItem *item, guint32 etime)
 	gdk_pointer_ungrab (etime);
 }
 
-/**
- * gnome_canvas_item_i2w_affine:
- * @item: A canvas item
- * @affine: An affine transformation matrix (return value).
- *
- * Gets the affine transform that converts from the item's coordinate system to
- * world coordinates.
- **/
-void
-gnome_canvas_item_i2w_affine (GnomeCanvasItem *item, gdouble affine[6])
-{
-	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
-	g_return_if_fail (affine != NULL);
-
-	art_affine_identity (affine);
-
-	while (item) {
-		if (item->xform != NULL) {
-			if (item->flags & GNOME_CANVAS_ITEM_AFFINE_FULL) {
-				art_affine_multiply (affine, affine, item->xform);
-			} else {
-				affine[4] += item->xform[0];
-				affine[5] += item->xform[1];
-			}
-		}
-
-		item = item->parent;
-	}
-}
-
 void
 gnome_canvas_item_i2w_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix)
 {
@@ -1053,11 +918,7 @@ gnome_canvas_item_i2w_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix)
 	cairo_matrix_init_identity (matrix);
 
 	while (item) {
-		if (item->xform != NULL) {
-                        cairo_matrix_t tmp;
-                        gnome_canvas_matrix_from_affine (&tmp, item->xform);
-                        cairo_matrix_multiply (matrix, matrix, &tmp);
-		}
+                cairo_matrix_multiply (matrix, matrix, &item->matrix);
 
 		item = item->parent;
 	}
@@ -1072,12 +933,7 @@ gnome_canvas_item_w2i_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix)
 	cairo_matrix_init_identity (matrix);
 
 	while (item) {
-		if (item->xform != NULL) {
-                        cairo_matrix_t tmp;
-                        gnome_canvas_matrix_from_affine (&tmp, item->xform);
-                        cairo_matrix_multiply (matrix, &tmp, matrix);
-		}
-
+                cairo_matrix_multiply (matrix, &item->matrix, matrix);
 		item = item->parent;
 	}
 }
@@ -1094,20 +950,14 @@ gnome_canvas_item_w2i_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix)
 void
 gnome_canvas_item_w2i (GnomeCanvasItem *item, gdouble *x, gdouble *y)
 {
-	gdouble affine[6], inv[6];
-	ArtPoint w, i;
+        cairo_matrix_t matrix;
 
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
 	g_return_if_fail (x != NULL);
 	g_return_if_fail (y != NULL);
 
-	gnome_canvas_item_i2w_affine (item, affine);
-	art_affine_invert (inv, affine);
-	w.x = *x;
-	w.y = *y;
-	art_affine_point (&i, &w, inv);
-	*x = i.x;
-	*y = i.y;
+	gnome_canvas_item_w2i_matrix (item, &matrix);
+        cairo_matrix_transform_point (&matrix, x, y);
 }
 
 /**
@@ -1122,37 +972,14 @@ gnome_canvas_item_w2i (GnomeCanvasItem *item, gdouble *x, gdouble *y)
 void
 gnome_canvas_item_i2w (GnomeCanvasItem *item, gdouble *x, gdouble *y)
 {
-	gdouble affine[6];
-	ArtPoint w, i;
+        cairo_matrix_t matrix;
 
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
 	g_return_if_fail (x != NULL);
 	g_return_if_fail (y != NULL);
 
-	gnome_canvas_item_i2w_affine (item, affine);
-	i.x = *x;
-	i.y = *y;
-	art_affine_point (&w, &i, affine);
-	*x = w.x;
-	*y = w.y;
-}
-
-/**
- * gnome_canvas_item_i2c_affine:
- * @item: A canvas item.
- * @affine: An affine transformation matrix (return value).
- *
- * Gets the affine transform that converts from item-relative coordinates to
- * canvas pixel coordinates.
- **/
-void
-gnome_canvas_item_i2c_affine (GnomeCanvasItem *item, gdouble affine[6])
-{
-	gdouble i2w[6], w2c[6];
-
-	gnome_canvas_item_i2w_affine (item, i2w);
-	gnome_canvas_w2c_affine (item->canvas, w2c);
-	art_affine_multiply (affine, i2w, w2c);
+	gnome_canvas_item_i2w_matrix (item, &matrix);
+        cairo_matrix_transform_point (&matrix, x, y);
 }
 
 /**
@@ -1297,10 +1124,6 @@ gnome_canvas_item_get_bounds (GnomeCanvasItem *item,
                               gdouble *y2)
 {
 	gdouble tx1, ty1, tx2, ty2;
-	ArtPoint p1, p2, p3, p4;
-	ArtPoint q1, q2, q3, q4;
-	gdouble min_x1, min_y1, min_x2, min_y2;
-	gdouble max_x1, max_y1, max_x2, max_y2;
 
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
 
@@ -1312,60 +1135,7 @@ gnome_canvas_item_get_bounds (GnomeCanvasItem *item,
 		(* GNOME_CANVAS_ITEM_GET_CLASS (item)->bounds) (item, &tx1, &ty1, &tx2, &ty2);
 
 	/* Make the bounds relative to the item's parent coordinate system */
-
-	if (item->xform && (item->flags & GNOME_CANVAS_ITEM_AFFINE_FULL)) {
-		p1.x = p2.x = tx1;
-		p1.y = p4.y = ty1;
-		p3.x = p4.x = tx2;
-		p2.y = p3.y = ty2;
-
-		art_affine_point (&q1, &p1, item->xform);
-		art_affine_point (&q2, &p2, item->xform);
-		art_affine_point (&q3, &p3, item->xform);
-		art_affine_point (&q4, &p4, item->xform);
-
-		if (q1.x < q2.x) {
-			min_x1 = q1.x;
-			max_x1 = q2.x;
-		} else {
-			min_x1 = q2.x;
-			max_x1 = q1.x;
-		}
-
-		if (q1.y < q2.y) {
-			min_y1 = q1.y;
-			max_y1 = q2.y;
-		} else {
-			min_y1 = q2.y;
-			max_y1 = q1.y;
-		}
-
-		if (q3.x < q4.x) {
-			min_x2 = q3.x;
-			max_x2 = q4.x;
-		} else {
-			min_x2 = q4.x;
-			max_x2 = q3.x;
-		}
-
-		if (q3.y < q4.y) {
-			min_y2 = q3.y;
-			max_y2 = q4.y;
-		} else {
-			min_y2 = q4.y;
-			max_y2 = q3.y;
-		}
-
-		tx1 = MIN (min_x1, min_x2);
-		ty1 = MIN (min_y1, min_y2);
-		tx2 = MAX (max_x1, max_x2);
-		ty2 = MAX (max_y1, max_y2);
-	} else if (item->xform) {
-		tx1 += item->xform[0];
-		ty1 += item->xform[1];
-		tx2 += item->xform[0];
-		ty2 += item->xform[1];
-	}
+        gnome_canvas_matrix_transform_rect (&item->matrix, &tx1, &ty1, &tx2, &ty2);
 
 	/* Return the values */
 
@@ -1427,8 +1197,9 @@ static void gnome_canvas_group_get_property (GObject               *object,
 
 static void gnome_canvas_group_destroy     (GnomeCanvasItem *object);
 
-static void   gnome_canvas_group_update      (GnomeCanvasItem *item, gdouble *affine,
-					      ArtSVP *clip_path, gint flags);
+static void   gnome_canvas_group_update      (GnomeCanvasItem *item,
+                                              const cairo_matrix_t *matrix,
+					      gint flags);
 static void   gnome_canvas_group_realize     (GnomeCanvasItem *item);
 static void   gnome_canvas_group_unrealize   (GnomeCanvasItem *item);
 static void   gnome_canvas_group_map         (GnomeCanvasItem *item);
@@ -1526,27 +1297,6 @@ gnome_canvas_group_class_init (GnomeCanvasGroupClass *class)
 static void
 gnome_canvas_group_init (GnomeCanvasGroup *group)
 {
-#if 0
-	group->xpos = 0.0;
-	group->ypos = 0.0;
-#endif
-}
-
-/* Translate handler for canvas groups */
-static gdouble *
-gnome_canvas_ensure_translate (GnomeCanvasItem *item)
-{
-	if (item->xform == NULL) {
-		item->flags &= ~GNOME_CANVAS_ITEM_AFFINE_FULL;
-		item->xform = g_new (double, 2);
-		item->xform[0] = 0.0;
-		item->xform[1] = 0.0;
-		return item->xform;
-	} else if (item->flags & GNOME_CANVAS_ITEM_AFFINE_FULL) {
-		return item->xform + 4;
-	} else {
-		return item->xform;
-	}
 }
 
 /* Set_property handler for canvas groups */
@@ -1555,7 +1305,6 @@ gnome_canvas_group_set_property (GObject *gobject, guint param_id,
 				 const GValue *value, GParamSpec *pspec)
 {
 	GnomeCanvasItem *item;
-	gdouble *xlat;
 
 	g_return_if_fail (GNOME_IS_CANVAS_GROUP (gobject));
 
@@ -1563,13 +1312,11 @@ gnome_canvas_group_set_property (GObject *gobject, guint param_id,
 
 	switch (param_id) {
 	case GROUP_PROP_X:
-		xlat = gnome_canvas_ensure_translate (item);
-		xlat[0] = g_value_get_double (value);
+		item->matrix.x0 = g_value_get_double (value);
 		break;
 
 	case GROUP_PROP_Y:
-		xlat = gnome_canvas_ensure_translate (item);
-		xlat[1] = g_value_get_double (value);
+		item->matrix.y0 = g_value_get_double (value);
 		break;
 
 	default:
@@ -1591,21 +1338,11 @@ gnome_canvas_group_get_property (GObject *gobject, guint param_id,
 
 	switch (param_id) {
 	case GROUP_PROP_X:
-		if (item->xform == NULL)
-			g_value_set_double (value, 0);
-		else if (GNOME_CANVAS_ITEM (gobject)->flags & GNOME_CANVAS_ITEM_AFFINE_FULL)
-			g_value_set_double (value, item->xform[4]);
-		else
-			g_value_set_double (value, item->xform[0]);
+		g_value_set_double (value, item->matrix.x0);
 		break;
 
 	case GROUP_PROP_Y:
-		if (item->xform == NULL)
-			g_value_set_double (value, 0);
-		else if (GNOME_CANVAS_ITEM (gobject)->flags & GNOME_CANVAS_ITEM_AFFINE_FULL)
-			g_value_set_double (value, item->xform[5]);
-		else
-			g_value_set_double (value, item->xform[1]);
+		g_value_set_double (value, item->matrix.y0);
 		break;
 
 	default:
@@ -1636,39 +1373,41 @@ gnome_canvas_group_destroy (GnomeCanvasItem *object)
 /* Update handler for canvas groups */
 static void
 gnome_canvas_group_update (GnomeCanvasItem *item,
-                           gdouble *affine,
-                           ArtSVP *clip_path,
+                           const cairo_matrix_t *i2c,
                            gint flags)
 {
 	GnomeCanvasGroup *group;
 	GList *list;
 	GnomeCanvasItem *i;
-	ArtDRect bbox, child_bbox;
+        double x1, y1, x2, y2;
 
 	group = GNOME_CANVAS_GROUP (item);
 
-	(* group_parent_class->update) (item, affine, clip_path, flags);
+	(* group_parent_class->update) (item, i2c, flags);
 
-	bbox.x0 = 0;
-	bbox.y0 = 0;
-	bbox.x1 = 0;
-	bbox.y1 = 0;
+	x1 = G_MAXDOUBLE;
+	y1 = G_MAXDOUBLE;
+	x2 = -G_MAXDOUBLE;
+	y2 = -G_MAXDOUBLE;
 
 	for (list = group->item_list; list; list = list->next) {
 		i = list->data;
 
-		gnome_canvas_item_invoke_update (i, affine, clip_path, flags);
+		gnome_canvas_item_invoke_update (i, i2c, flags);
 
-		child_bbox.x0 = i->x1;
-		child_bbox.y0 = i->y1;
-		child_bbox.x1 = i->x2;
-		child_bbox.y1 = i->y2;
-		art_drect_union (&bbox, &bbox, &child_bbox);
+                x1 = MIN (x1, i->x1);
+                x2 = MAX (x2, i->x2);
+                y1 = MIN (y1, i->y1);
+                y2 = MAX (y2, i->y2);
 	}
-	item->x1 = bbox.x0;
-	item->y1 = bbox.y0;
-	item->x2 = bbox.x1;
-	item->y2 = bbox.y1;
+        if (x1 >= x2 || y1 >= y2) {
+                item->x1 = item->x2 = item->y1 = item->y2 = 0;
+        } else {
+                item->x1 = x1;
+                item->y1 = y1;
+                item->x2 = x2;
+                item->y2 = y2;
+        }
 }
 
 /* Realize handler for canvas groups */
@@ -3182,17 +2921,12 @@ do_update (GnomeCanvas *canvas)
 
 update_again:
 	if (canvas->need_update) {
-		gdouble w2cpx[6];
+                cairo_matrix_t w2c;
 
-		/* We start updating root with w2cpx affine */
-		w2cpx[0] = canvas->pixels_per_unit;
-		w2cpx[1] = 0.0;
-		w2cpx[2] = 0.0;
-		w2cpx[3] = canvas->pixels_per_unit;
-		w2cpx[4] = -canvas->scroll_x1 * canvas->pixels_per_unit;
-		w2cpx[5] = -canvas->scroll_y1 * canvas->pixels_per_unit;
+		/* We start updating root with w2c matrix */
+                gnome_canvas_w2c_matrix (canvas, &w2c);
 
-		gnome_canvas_item_invoke_update (canvas->root, w2cpx, NULL, 0);
+		gnome_canvas_item_invoke_update (canvas->root, &w2c, 0);
 
 		canvas->need_update = FALSE;
 	}
diff --git a/libgnomecanvas/gnome-canvas.h b/libgnomecanvas/gnome-canvas.h
index 5f35f33..f0040ac 100644
--- a/libgnomecanvas/gnome-canvas.h
+++ b/libgnomecanvas/gnome-canvas.h
@@ -94,8 +94,7 @@ typedef enum {
 	GNOME_CANVAS_ITEM_NEED_UPDATE	= 1 << 4,
 	GNOME_CANVAS_ITEM_NEED_AFFINE	= 1 << 5,
 	GNOME_CANVAS_ITEM_NEED_CLIP	= 1 << 6,
-	GNOME_CANVAS_ITEM_NEED_VIS	= 1 << 7,
-	GNOME_CANVAS_ITEM_AFFINE_FULL	= 1 << 8
+	GNOME_CANVAS_ITEM_NEED_VIS	= 1 << 7
 } GnomeCanvasItemFlags;
 
 /* Update flags for items */
@@ -123,12 +122,8 @@ struct _GnomeCanvasItem {
 	/* Parent canvas group for this item (a GnomeCanvasGroup) */
 	GnomeCanvasItem *parent;
 
-	/* If NULL, assumed to be the identity tranform.  If flags does not have
-	 * AFFINE_FULL, then a two-element array containing a translation.  If
-	 * flags contains AFFINE_FULL, a six-element array containing an affine
-	 * transformation.
-	 */
-	gdouble *xform;
+	/* The transformation for this item */
+	cairo_matrix_t matrix;
 
 	/* Bounding box for this item (in canvas coordinates) */
 	gdouble x1, y1, x2, y2;
@@ -147,7 +142,7 @@ struct _GnomeCanvasItemClass {
 	 * affine, if used, is a pointer to a 6-element array of doubles.  The
 	 * update method also recomputes the bounding box of the item.
 	 */
-	void (* update) (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags);
+	void (* update) (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags);
 
 	/* Realize an item -- create GCs, etc. */
 	void (* realize) (GnomeCanvasItem *item);
@@ -219,10 +214,10 @@ void gnome_canvas_item_set_valist (GnomeCanvasItem *item,
 void gnome_canvas_item_move (GnomeCanvasItem *item, gdouble dx, gdouble dy);
 
 /* Apply a relative affine transformation to the item. */
-void gnome_canvas_item_affine_relative (GnomeCanvasItem *item, const gdouble affine[6]);
+void gnome_canvas_item_transform (GnomeCanvasItem *item, const cairo_matrix_t *matrix);
 
 /* Apply an absolute affine transformation to the item. */
-void gnome_canvas_item_affine_absolute (GnomeCanvasItem *item, const gdouble affine[6]);
+void gnome_canvas_item_set_matrix (GnomeCanvasItem *item, const cairo_matrix_t *matrix);
 
 /* Raise an item in the z-order of its parent group by the specified number of
  * positions.
@@ -272,14 +267,12 @@ void gnome_canvas_item_i2w (GnomeCanvasItem *item, gdouble *x, gdouble *y);
 /* Gets the affine transform that converts from item-relative coordinates to
  * world coordinates.
  */
-void gnome_canvas_item_i2w_affine (GnomeCanvasItem *item, gdouble affine[6]);
 void gnome_canvas_item_i2w_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix);
 void gnome_canvas_item_w2i_matrix (GnomeCanvasItem *item, cairo_matrix_t *matrix);
 
 /* Gets the affine transform that converts from item-relative coordinates to
  * 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
diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c
index 5ca1143..40d2c2d 100644
--- a/widgets/misc/e-calendar-item.c
+++ b/widgets/misc/e-calendar-item.c
@@ -62,8 +62,7 @@ static void e_calendar_item_realize	(GnomeCanvasItem *item);
 static void e_calendar_item_unrealize	(GnomeCanvasItem *item);
 static void e_calendar_item_unmap	(GnomeCanvasItem *item);
 static void e_calendar_item_update	(GnomeCanvasItem *item,
-					 gdouble		 *affine,
-					 ArtSVP		 *clip_path,
+					 const cairo_matrix_t *i2c,
 					 gint		  flags);
 static void e_calendar_item_draw	(GnomeCanvasItem *item,
 					 GdkDrawable	 *drawable,
@@ -891,8 +890,7 @@ e_calendar_item_unmap		(GnomeCanvasItem *item)
 
 static void
 e_calendar_item_update		(GnomeCanvasItem *item,
-				 gdouble		 *affine,
-				 ArtSVP		 *clip_path,
+				 const cairo_matrix_t *i2c,
 				 gint		  flags)
 {
 	GnomeCanvasItemClass *item_class;
@@ -906,7 +904,7 @@ e_calendar_item_update		(GnomeCanvasItem *item,
 
 	item_class = GNOME_CANVAS_ITEM_CLASS (e_calendar_item_parent_class);
 	if (item_class->update != NULL)
-		item_class->update (item, affine, clip_path, flags);
+		item_class->update (item, i2c, flags);
 
 	calitem = E_CALENDAR_ITEM (item);
 	style = gtk_widget_get_style (GTK_WIDGET (item->canvas));
diff --git a/widgets/misc/e-canvas-utils.c b/widgets/misc/e-canvas-utils.c
index 29dc21d..8189dc1 100644
--- a/widgets/misc/e-canvas-utils.c
+++ b/widgets/misc/e-canvas-utils.c
@@ -26,14 +26,13 @@
 void
 e_canvas_item_move_absolute (GnomeCanvasItem *item, gdouble dx, gdouble dy)
 {
-	gdouble translate[6];
+	cairo_matrix_t translate;
 
-	g_return_if_fail (item != NULL);
 	g_return_if_fail (GNOME_IS_CANVAS_ITEM (item));
 
-	art_affine_translate (translate, dx, dy);
+	cairo_matrix_init_translate (&translate, dx, dy);
 
-	gnome_canvas_item_affine_absolute (item, translate);
+	gnome_canvas_item_set_matrix (item, &translate);
 }
 
 static double
diff --git a/widgets/misc/e-canvas.c b/widgets/misc/e-canvas.c
index 0b24b84..21a7796 100644
--- a/widgets/misc/e-canvas.c
+++ b/widgets/misc/e-canvas.c
@@ -165,8 +165,6 @@ canvas_emit_event (GnomeCanvas *canvas,
  * should be in the parent's item-relative coordinate system.  This routine
  * applies the inverse of the item's transform, maintaining the affine
  * invariant. */
-#define HACKISH_AFFINE
-
 static GnomeCanvasItem *
 gnome_canvas_item_invoke_point (GnomeCanvasItem *item,
                                 gdouble x,
@@ -174,25 +172,19 @@ gnome_canvas_item_invoke_point (GnomeCanvasItem *item,
                                 gint cx,
                                 gint cy)
 {
-#ifdef HACKISH_AFFINE
-	gdouble i2w[6], w2c[6], i2c[6], c2i[6];
-	ArtPoint c, i;
-#endif
+        cairo_matrix_t inverse;
 
-#ifdef HACKISH_AFFINE
-	gnome_canvas_item_i2w_affine (item, i2w);
-	gnome_canvas_w2c_affine (item->canvas, w2c);
-	art_affine_multiply (i2c, i2w, w2c);
-	art_affine_invert (c2i, i2c);
-	c.x = cx;
-	c.y = cy;
-	art_affine_point (&i, &c, c2i);
-	x = i.x;
-	y = i.y;
-#endif
+	/* Calculate x & y in item local coordinates */
+        inverse = item->matrix;
+        if (cairo_matrix_invert (&inverse) != CAIRO_STATUS_SUCCESS)
+                return NULL;
+
+        cairo_matrix_transform_point (&inverse, &x, &y);
+
+	if (GNOME_CANVAS_ITEM_GET_CLASS (item)->point)
+		return GNOME_CANVAS_ITEM_GET_CLASS (item)->point (item, x, y, cx, cy);
 
-	return (* GNOME_CANVAS_ITEM_CLASS (G_OBJECT_GET_CLASS (item))->point) (
-		item, x, y, cx, cy);
+	return NULL;
 }
 
 /* Re-picks the current item in the canvas, based on the event's coordinates.
diff --git a/widgets/table/e-table-field-chooser-item.c b/widgets/table/e-table-field-chooser-item.c
index 3c28434..fb8f2ba 100644
--- a/widgets/table/e-table-field-chooser-item.c
+++ b/widgets/table/e-table-field-chooser-item.c
@@ -176,38 +176,34 @@ etfci_reflow (GnomeCanvasItem *item, gint flags)
 
 static void
 etfci_update (GnomeCanvasItem *item,
-              gdouble *affine,
-              ArtSVP *clip_path,
+              const cairo_matrix_t *i2c,
               gint flags)
 {
 	ETableFieldChooserItem *etfci = E_TABLE_FIELD_CHOOSER_ITEM (item);
-	gdouble   i2c[6];
-	ArtPoint c1, c2, i1, i2;
+	double x1, y1, x2, y2;
 
 	if (GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update)
 		GNOME_CANVAS_ITEM_CLASS (etfci_parent_class)->update (
-			item, affine, clip_path, flags);
+			item, i2c, flags);
 
-	i1.x = i1.y = 0;
-	i2.x = etfci->width;
-	i2.y = etfci->height;
+	x1 = y1 = 0;
+	x2 = etfci->width;
+	y2 = etfci->height;
 
-	gnome_canvas_item_i2c_affine (item, i2c);
-	art_affine_point (&c1, &i1, i2c);
-	art_affine_point (&c2, &i2, i2c);
+        gnome_canvas_matrix_transform_rect (i2c, &x1, &y1, &x2, &y2);
 
-	if (item->x1 != c1.x ||
-	     item->y1 != c1.y ||
-	     item->x2 != c2.x ||
-	     item->y2 != c2.y)
+	if (item->x1 != x1 ||
+	    item->y1 != y1 ||
+	    item->x2 != x2 ||
+	    item->y2 != y2)
 		{
 			gnome_canvas_request_redraw (
 				item->canvas, item->x1,
 				item->y1, item->x2, item->y2);
-			item->x1 = c1.x;
-			item->y1 = c1.y;
-			item->x2 = c2.x;
-			item->y2 = c2.y;
+			item->x1 = x1;
+			item->y1 = y1;
+			item->x2 = x2;
+			item->y2 = y2;
 /* FIXME: Group Child bounds !? */
 #if 0
 			gnome_canvas_group_child_bounds (
diff --git a/widgets/table/e-table-header-item.c b/widgets/table/e-table-header-item.c
index cf4cc94..e1c6c57 100644
--- a/widgets/table/e-table-header-item.c
+++ b/widgets/table/e-table-header-item.c
@@ -184,18 +184,15 @@ e_table_header_item_get_height (ETableHeaderItem *ethi)
 
 static void
 ethi_update (GnomeCanvasItem *item,
-             gdouble *affine,
-             ArtSVP *clip_path,
+             const cairo_matrix_t *i2c,
              gint flags)
 {
 	ETableHeaderItem *ethi = E_TABLE_HEADER_ITEM (item);
-
-	gdouble   i2c[6];
-	ArtPoint c1, c2, i1, i2;
+        double x1, y1, x2, y2;
 
 	if (GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update)
 		GNOME_CANVAS_ITEM_CLASS (ethi_parent_class)->update (
-			item, affine, clip_path, flags);
+			item, i2c, flags);
 
 	if (ethi->sort_info)
 		ethi->group_indent_width =
@@ -208,27 +205,25 @@ ethi_update (GnomeCanvasItem *item,
 		e_table_header_total_width (ethi->eth) +
 		ethi->group_indent_width;
 
-	i1.x = i1.y = 0;
-	i2.x = ethi->width;
-	i2.y = ethi->height;
+	x1 = y1 = 0;
+	x2 = ethi->width;
+	y2 = ethi->height;
 
-	gnome_canvas_item_i2c_affine (item, i2c);
-	art_affine_point (&c1, &i1, i2c);
-	art_affine_point (&c2, &i2, i2c);
+        gnome_canvas_matrix_transform_rect (i2c, &x1, &y1, &x2, &y2);
 
-	if (item->x1 != c1.x ||
-	    item->y1 != c1.y ||
-	    item->x2 != c2.x ||
-	    item->y2 != c2.y)
+	if (item->x1 != x1 ||
+	    item->y1 != y1 ||
+	    item->x2 != x2 ||
+	    item->y2 != y2)
 		{
 			gnome_canvas_request_redraw (
 				item->canvas,
 				item->x1, item->y1,
 				item->x2, item->y2);
-			item->x1 = c1.x;
-			item->y1 = c1.y;
-			item->x2 = c2.x;
-			item->y2 = c2.y;
+			item->x1 = x1;
+			item->y1 = y1;
+			item->x2 = x2;
+			item->y2 = y2;
 /* FIXME: Group Child bounds !? (FOO BAA) */
 #if 0
 			gnome_canvas_group_child_bounds (GNOME_CANVAS_GROUP (item->parent), item);
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index b6dc6ad..d2f5c4f 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -435,25 +435,18 @@ eti_detach_cell_views (ETableItem *eti)
 static void
 eti_bounds (GnomeCanvasItem *item, gdouble *x1, gdouble *y1, gdouble *x2, gdouble *y2)
 {
-	gdouble   i2c[6];
-	ArtPoint c1, c2, i1, i2;
+	cairo_matrix_t i2c;
 	ETableItem *eti = E_TABLE_ITEM (item);
 
 	/* Wrong BBox's are the source of redraw nightmares */
 
-	gnome_canvas_item_i2c_affine (GNOME_CANVAS_ITEM (eti), i2c);
-
-	i1.x = 0;
-	i1.y = 0;
-	i2.x = eti->width;
-	i2.y = eti->height;
-	art_affine_point (&c1, &i1, i2c);
-	art_affine_point (&c2, &i2, i2c);
+	*x1 = 0;
+	*y1 = 0;
+	*x2 = eti->width;
+	*y2 = eti->height;
 
-	*x1 = c1.x;
-	*y1 = c1.y;
-	*x2 = c2.x + 1;
-	*y2 = c2.y + 1;
+	gnome_canvas_item_i2c_matrix (GNOME_CANVAS_ITEM (eti), &i2c);
+        gnome_canvas_matrix_transform_rect (&i2c, x1, y1, x2, y2);
 }
 
 static void
@@ -488,25 +481,25 @@ eti_reflow (GnomeCanvasItem *item, gint flags)
  * GnomeCanvasItem::update method
  */
 static void
-eti_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags)
+eti_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags)
 {
-	ArtPoint o1, o2;
 	ETableItem *eti = E_TABLE_ITEM (item);
+        double x1, x2, y1, y2;
 
 	if (GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)
-		(*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, affine, clip_path, flags);
+		(*GNOME_CANVAS_ITEM_CLASS (eti_parent_class)->update)(item, i2c, flags);
 
-	o1.x = item->x1;
-	o1.y = item->y1;
-	o2.x = item->x2;
-	o2.y = item->y2;
+	x1 = item->x1;
+	y1 = item->y1;
+	x2 = item->x2;
+	y2 = item->y2;
 
 	eti_bounds (item, &item->x1, &item->y1, &item->x2, &item->y2);
-	if (item->x1 != o1.x ||
-	    item->y1 != o1.y ||
-	    item->x2 != o2.x ||
-	    item->y2 != o2.y) {
-		gnome_canvas_request_redraw (item->canvas, o1.x, o1.y, o2.x, o2.y);
+	if (item->x1 != x1 ||
+	    item->y1 != y1 ||
+	    item->x2 != x1 ||
+	    item->y2 != y1) {
+		gnome_canvas_request_redraw (item->canvas, x2, y2, x2, y2);
 		eti->needs_redraw = 1;
 	}
 
@@ -799,18 +792,18 @@ static void
 eti_item_region_redraw (ETableItem *eti, gint x0, gint y0, gint x1, gint y1)
 {
 	GnomeCanvasItem *item = GNOME_CANVAS_ITEM (eti);
-	ArtDRect rect;
-	gdouble i2c[6];
+	double dx1, dy1, dx2, dy2;
+	cairo_matrix_t i2c;
 
-	rect.x0 = x0;
-	rect.y0 = y0;
-	rect.x1 = x1;
-	rect.y1 = y1;
+	dx1 = x0;
+	dy1 = y0;
+	dx2 = x1;
+	dy2 = y1;
 
-	gnome_canvas_item_i2c_affine (item, i2c);
-	art_drect_affine_transform (&rect, &rect, i2c);
+	gnome_canvas_item_i2c_matrix (item, &i2c);
+	gnome_canvas_matrix_transform_rect (&i2c, &dx1, &dy1, &dx2, &dy2);
 
-	gnome_canvas_request_redraw (item->canvas, rect.x0, rect.y0, rect.x1, rect.y1);
+	gnome_canvas_request_redraw (item->canvas, floor (dx1), floor (dy1), ceil (dx2), ceil (dy2));
 }
 
 /*
diff --git a/widgets/text/e-reflow.c b/widgets/text/e-reflow.c
index df45984..9ccbd86 100644
--- a/widgets/text/e-reflow.c
+++ b/widgets/text/e-reflow.c
@@ -42,7 +42,7 @@ static void e_reflow_realize (GnomeCanvasItem *item);
 static void e_reflow_unrealize (GnomeCanvasItem *item);
 static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 				    gint x, gint y, gint width, gint height);
-static void e_reflow_update (GnomeCanvasItem *item, gdouble affine[6], ArtSVP *clip_path, gint flags);
+static void e_reflow_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags);
 static GnomeCanvasItem *e_reflow_point (GnomeCanvasItem *item, gdouble x, gdouble y, gint cx, gint cy);
 static void e_reflow_reflow (GnomeCanvasItem *item, gint flags);
 static void set_empty (EReflow *reflow);
@@ -1252,7 +1252,7 @@ static void e_reflow_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
 }
 
 static void
-e_reflow_update (GnomeCanvasItem *item, gdouble affine[6], ArtSVP *clip_path, gint flags)
+e_reflow_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags)
 {
 	EReflow *reflow;
 	gdouble x0, x1, y0, y1;
@@ -1260,7 +1260,7 @@ e_reflow_update (GnomeCanvasItem *item, gdouble affine[6], ArtSVP *clip_path, gi
 	reflow = E_REFLOW (item);
 
 	if (GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->update)
-		GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->update (item, affine, clip_path, flags);
+		GNOME_CANVAS_ITEM_CLASS (e_reflow_parent_class)->update (item, i2c, flags);
 
 	x0 = item->x1;
 	y0 = item->y1;
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index d0b18f2..9736558 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -1185,7 +1185,7 @@ e_text_reflow (GnomeCanvasItem *item, gint flags)
 
 /* Update handler for the text item */
 static void
-e_text_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint flags)
+e_text_update (GnomeCanvasItem *item, const cairo_matrix_t *i2c, gint flags)
 {
 	EText *text;
 	gdouble x1, y1, x2, y2;
@@ -1194,7 +1194,7 @@ e_text_update (GnomeCanvasItem *item, gdouble *affine, ArtSVP *clip_path, gint f
 
 	if (GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->update)
 		GNOME_CANVAS_ITEM_CLASS (e_text_parent_class)->update (
-			item, affine, clip_path, flags);
+			item, i2c, flags);
 
 	if ( text->needs_recalc_bounds
 	     || (flags & GNOME_CANVAS_UPDATE_AFFINE)) {



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