[goocanvas] 2010-06-30 Damon Chaplin <damon gnome org>



commit cf809df7f75e46b870a5687faca2f268cf365097
Author: Damon Chaplin <damon gnome org>
Date:   Wed Jun 30 21:58:02 2010 +0100

    2010-06-30  Damon Chaplin  <damon gnome org>
    
    	    * docs: added empty internal subset "[]" to the DOCTYPEs to keep
    	    gtk-doc happy.
    
    	    * src/goocanvas.c (goo_canvas_expose_event): do a cairo_save()/restore()
    	    around painting the main items, so the static items don't get clipped.
    
    	    * src/goocanvasitemsimple.c (goo_canvas_item_simple_set_property):
    	    handle setting "clip-path" to NULL to reset it.
    
    	    * src/goocanvastable.c: try to handle RTL direction better.
    
    	    * src/goocanvasgroup.c (goo_canvas_group_paint): use the scale
    	    argument rather than the canvas scale.
    
    	    * src/goocanvas.c: added "before-initial-expose" flag which we use
    	    to ignore any redraw requests before the initial expose (since we
    	    know the entire canvas needs redrawing anyway). This speeds up the
    	    creation of lots of items, e.g. scalability-demo.
    
    	    * demo/Makefile.am (mv_demo_LDADD, demo_LDADD): added -lm to compile.
    
    	    * demo/mv-scalability-demo.c:
    	    * demo/scalability-demo.c: updated to compare with the new-api code.

 .gitignore                 |    1 +
 ChangeLog                  |   28 ++++++++-
 demo/Makefile.am           |    4 +-
 demo/demo-grabs.c          |    2 +-
 demo/mv-scalability-demo.c |  149 +++++++++++++++++++++++++++++---------------
 demo/scalability-demo.c    |  129 ++++++++++++++++++++++++++------------
 docs/architecture.xml      |    2 +-
 docs/coordinates.xml       |    2 +-
 docs/creating-items.xml    |    2 +-
 docs/model-view-canvas.xml |    2 +-
 docs/overview.xml          |    2 +-
 docs/simple-canvas.xml     |    2 +-
 docs/wysiwyg.xml           |    2 +-
 src/goocanvas.c            |   17 +++++-
 src/goocanvas.h            |    3 +
 src/goocanvasgroup.c       |    2 +-
 src/goocanvasitemsimple.c  |    8 ++-
 src/goocanvaspolyline.c    |    1 -
 src/goocanvastable.c       |   18 ++++-
 19 files changed, 265 insertions(+), 111 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 4f18981..b877ed1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,6 +61,7 @@ Makefile.in
 /docs/goocanvas.prerequisites
 /docs/goocanvas.signals
 /docs/*.stamp
+/docs/*.bak
 /docs/html
 /docs/xml
 /docs/tmpl/goo*.sgml
diff --git a/ChangeLog b/ChangeLog
index f30075d..63a42db 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2010-06-30  Damon Chaplin  <damon gnome org>
+
+	* docs: added empty internal subset "[]" to the DOCTYPEs to keep
+	gtk-doc happy.
+
+	* src/goocanvas.c (goo_canvas_expose_event): do a cairo_save()/restore()
+	around painting the main items, so the static items don't get clipped.
+
+	* src/goocanvasitemsimple.c (goo_canvas_item_simple_set_property):
+	handle setting "clip-path" to NULL to reset it.
+
+	* src/goocanvastable.c: try to handle RTL direction better.
+
+	* src/goocanvasgroup.c (goo_canvas_group_paint): use the scale
+	argument rather than the canvas scale.
+
+	* src/goocanvas.c: added "before-initial-expose" flag which we use
+	to ignore any redraw requests before the initial expose (since we
+	know the entire canvas needs redrawing anyway). This speeds up the
+	creation of lots of items, e.g. scalability-demo.
+
+	* demo/Makefile.am (mv_demo_LDADD, demo_LDADD): added -lm to compile.
+
+	* demo/mv-scalability-demo.c:
+	* demo/scalability-demo.c: updated to compare with the new-api code.
+
 2010-06-21  Damon Chaplin  <damon gnome org>
 
 	* Released GooCanvas 1.90.0
@@ -19,7 +45,7 @@
 	Replace use of gtk_fixed_set_has_window() with gtk_widget_set_has_window().
 	Replace use of GTK_WIDGET_CAN_FOCUS() with gtk_widget_get_can_focus().
 	Replace use of GTK_WIDGET_TOPLEVEL() with gtk_widget_is_toplevel().
-	
+
 	This seems to all work fine.
 
 2010-06-11  Murray Cumming  <murrayc murrayc com>
diff --git a/demo/Makefile.am b/demo/Makefile.am
index 4fe8d49..f1009f5 100644
--- a/demo/Makefile.am
+++ b/demo/Makefile.am
@@ -4,8 +4,8 @@ INCLUDES = \
 	-I$(top_srcdir)/src \
 	-I$(top_builddir)/src \
 	@PACKAGE_CFLAGS@
-	
-DEMO_LIBS = $(top_builddir)/src/libgoocanvas-2.0.la @PACKAGE_LIBS@ $(INTLLIBS)
+
+DEMO_LIBS = $(top_builddir)/src/libgoocanvas-2.0.la @PACKAGE_LIBS@ $(INTLLIBS) -lm
 
 #	-DG_DISABLE_DEPRECATED -DPANGO_DISABLE_DEPRECATED \
 #	-DGDK_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED \
diff --git a/demo/demo-grabs.c b/demo/demo-grabs.c
index e1d1c3f..9262de3 100644
--- a/demo/demo-grabs.c
+++ b/demo/demo-grabs.c
@@ -212,7 +212,7 @@ create_fixed (GtkTable *table, gint row, gchar *text, gchar *id)
   gtk_widget_show (label);
 
   fixed = gtk_fixed_new ();
-  gtk_widget_set_has_window (GTK_FIXED (fixed), TRUE);
+  gtk_widget_set_has_window (fixed, TRUE);
   gtk_widget_set_events (fixed,
 			 GDK_EXPOSURE_MASK
 			 | GDK_BUTTON_PRESS_MASK
diff --git a/demo/mv-scalability-demo.c b/demo/mv-scalability-demo.c
index 27ca565..e07f2d2 100644
--- a/demo/mv-scalability-demo.c
+++ b/demo/mv-scalability-demo.c
@@ -1,28 +1,33 @@
+#include <math.h>
 #include <stdlib.h>
 #include <goocanvas.h>
 
-#if 0
-#define N_GROUP_COLS 5
-#define N_GROUP_ROWS 5
-#else
+#if 1
 #define N_GROUP_COLS 25
-#define N_GROUP_ROWS 20
-#endif
+#define N_GROUP_ROWS 200
 #define N_COLS 10
 #define N_ROWS 10
 #define ITEM_WIDTH 400
-
+#define PADDING 10
 #if 1
 #define ROTATE
 #endif
+#else
+/* This tests a very wide canvas, nearly up to the 31-bit GDK window size
+   limit. */
+#define N_GROUP_COLS 100000
+#define N_GROUP_ROWS 1
+#define N_COLS 10
+#define N_ROWS 1
+#define ITEM_WIDTH 1000
+#define PADDING 100
+#endif
 
 #define N_TOTAL_ID_ITEMS (N_GROUP_COLS * N_GROUP_ROWS) * (N_COLS * N_ROWS)
 
 /* The maximum length of a string identifying an item (i.e. its coords). */
 #define MAX_ID_LEN 20
 
-#define PADDING 10
-
 #if 1
 #define SET_STYLE
 #endif
@@ -31,6 +36,10 @@
 #define USE_TEXT
 #endif
 
+#if 1
+#define SET_IDS
+#endif
+
 #if 0
 #define USE_PIXMAP 
 #endif
@@ -43,6 +52,12 @@ double total_width, total_height;
 double left_offset, top_offset;
 char ids[N_TOTAL_ID_ITEMS][MAX_ID_LEN];
 
+GdkPixbuf *pixbuf = NULL;
+cairo_pattern_t *pattern = NULL;
+double item_width, item_height;
+double cell_width, cell_height;
+double group_width, group_height;
+
 static clock_t start;
 
 static gboolean
@@ -71,20 +86,46 @@ on_motion_notify (GooCanvasItem *item,
 
 
 static void
+init_ids (void)
+{
+  int group_i, group_j, i, j;
+  int id_item_num = 0;;
+	
+  for (group_i = 0; group_i < N_GROUP_COLS; group_i++)
+    {
+      for (group_j = 0; group_j < N_GROUP_ROWS; group_j++)
+	{
+	  double group_x = left_offset + (group_i * group_width);
+	  double group_y = top_offset + (group_j * group_height);
+
+	  for (i = 0; i < N_COLS; i++)
+	    {
+	      for (j = 0; j < N_ROWS; j++)
+		{
+		  double item_x = (i * cell_width) + PADDING;
+		  double item_y = (j * cell_height) + PADDING;
+
+		  sprintf (ids[id_item_num++], "%.10g, %.10g",
+			   group_x + item_x, group_y + item_y);
+		}
+	    }
+	}
+    }
+}
+
+
+static void
 setup_canvas (GtkWidget *canvas)
 {
   GooCanvasItemModel *root, *group, *model;
   GooCanvasItem *item;
-  GdkPixbuf *pixbuf = NULL;
-  cairo_pattern_t *pattern = NULL;
   int group_i, group_j, i, j;
-  double item_width, item_height;
-  double cell_width, cell_height;
-  double group_width, group_height;
   int total_items = 0, id_item_num = 0;;
   GdkColor color = { 0, 0, 0, 0, };
   GooCanvasStyle *style, *style2;
   GValue tmpval = { 0 };
+  cairo_matrix_t item_matrix;
+  GQuark id_quark = g_quark_from_static_string ("id");
 
   root = goo_canvas_group_model_new (NULL,
 				     "font", "Sans 8",
@@ -96,30 +137,6 @@ setup_canvas (GtkWidget *canvas)
   g_signal_connect (item, "motion_notify_event",
 		    G_CALLBACK (on_motion_notify), NULL);
 
-#ifdef USE_PIXMAP
-  pixbuf = gdk_pixbuf_new_from_file("toroid.png", NULL);
-  item_width = gdk_pixbuf_get_width (pixbuf);
-  item_height = gdk_pixbuf_get_height (pixbuf);
-  pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
-#else
-  pixbuf = NULL;
-  item_width = ITEM_WIDTH;
-  item_height = 19;
-#endif
-	
-  cell_width = item_width + PADDING * 2;
-  cell_height = item_height + PADDING * 2;
-
-  group_width = N_COLS * cell_width;
-  group_height = N_ROWS * cell_height;
-
-  total_width = N_GROUP_COLS * group_width;
-  total_height = N_GROUP_ROWS * group_height;
-
-  /* We use -ve offsets to test if -ve coords are handled correctly. */
-  left_offset = -total_width / 2;
-  top_offset = -total_height / 2;
-
   style = goo_canvas_style_new ();
   gdk_color_parse ("mediumseagreen", &color);
   pattern = cairo_pattern_create_rgb (color.red / 65535.0,
@@ -158,14 +175,11 @@ setup_canvas (GtkWidget *canvas)
 		  double item_x = (i * cell_width) + PADDING;
 		  double item_y = (j * cell_height) + PADDING;
 #ifdef ROTATE
-		  double rotation = i % 10 * 2;
+		  double rotation = (i % 10 * 2) * M_PI / 180;
 		  double rotation_x = item_x + item_width / 2;
 		  double rotation_y = item_y + item_height / 2;
 #endif
 
-		  sprintf (ids[id_item_num], "%g, %g",
-			   group_x + item_x, group_y + item_y);
-
 #ifdef USE_PIXMAP
 		  model = goo_canvas_image_model_new (group, NULL,
 						      item_x, item_y,
@@ -181,14 +195,18 @@ setup_canvas (GtkWidget *canvas)
 		  goo_canvas_item_model_set_style (model, (j % 2) ? style : style2);
 #endif
 #ifdef ROTATE
-		  goo_canvas_item_model_rotate (model, rotation, rotation_x, rotation_y);
+		  cairo_matrix_init_identity (&item_matrix);
+		  cairo_matrix_translate (&item_matrix, rotation_x, rotation_y);
+		  cairo_matrix_rotate (&item_matrix, rotation);
+		  cairo_matrix_translate (&item_matrix, -rotation_x, -rotation_y);
+		  goo_canvas_item_model_set_transform (model, &item_matrix);
 #endif
 #endif
-
+#ifdef SET_IDS
 		  item = goo_canvas_get_item (GOO_CANVAS (canvas), model);
-		  g_object_set_data (G_OBJECT (item), "id",
-				     ids[id_item_num]);
-
+		  g_object_set_qdata (G_OBJECT (item), id_quark,
+				      ids[id_item_num]);
+#endif
 #if 0
 		  g_signal_connect (item, "motion_notify_event",
 				    G_CALLBACK (on_motion_notify), NULL);
@@ -198,8 +216,12 @@ setup_canvas (GtkWidget *canvas)
 		  model = goo_canvas_text_model_new (group, ids[id_item_num],
 						     item_x + item_width / 2,
 						     item_y + item_height / 2,
-						     -1, GTK_ANCHOR_CENTER,
+						     item_width, GTK_ANCHOR_CENTER,
+						     "height", item_height,
+						     /*"alignment", PANGO_ALIGN_CENTER,*/
 						     NULL);
+		  /* FIXME: This is slightly naughty, but much faster. */
+		  GOO_CANVAS_TEXT_MODEL (model)->text_data.alignment = PANGO_ALIGN_CENTER;
 #else
 		  model = goo_canvas_rect_model_new (group,
 						     item_x + 20,
@@ -210,8 +232,7 @@ setup_canvas (GtkWidget *canvas)
 #endif
 
 #ifdef ROTATE
-		  goo_canvas_item_model_rotate (model, rotation, rotation_x,
-						rotation_y);
+		  goo_canvas_item_model_set_transform (model, &item_matrix);
 #endif
 		  id_item_num++;
 		  total_items += 2;
@@ -264,6 +285,34 @@ create_canvas (void)
 {
   GtkWidget *canvas;
 
+#ifdef USE_PIXMAP
+  pixbuf = gdk_pixbuf_new_from_file("toroid.png", NULL);
+  item_width = gdk_pixbuf_get_width (pixbuf);
+  item_height = gdk_pixbuf_get_height (pixbuf);
+  pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
+#else
+  pixbuf = NULL;
+  item_width = ITEM_WIDTH;
+  item_height = 19;
+#endif
+	
+  cell_width = item_width + PADDING * 2;
+  cell_height = item_height + PADDING * 2;
+
+  group_width = N_COLS * cell_width;
+  group_height = N_ROWS * cell_height;
+
+  total_width = N_GROUP_COLS * group_width;
+  total_height = N_GROUP_ROWS * group_height;
+
+  /* We use -ve offsets to test if -ve coords are handled correctly. */
+  left_offset = -total_width / 2;
+  top_offset = -total_height / 2;
+
+#ifdef SET_IDS
+  init_ids ();
+#endif
+
   /* Create the canvas. */
   canvas = goo_canvas_new ();
   gtk_widget_set_size_request (canvas, 600, 450);
diff --git a/demo/scalability-demo.c b/demo/scalability-demo.c
index 1be0463..6d9dd55 100644
--- a/demo/scalability-demo.c
+++ b/demo/scalability-demo.c
@@ -1,9 +1,10 @@
+#include <math.h>
 #include <stdlib.h>
 #include <goocanvas.h>
 
 #if 1
 #define N_GROUP_COLS 25
-#define N_GROUP_ROWS 20
+#define N_GROUP_ROWS 200
 #define N_COLS 10
 #define N_ROWS 10
 #define ITEM_WIDTH 400
@@ -35,6 +36,10 @@
 #define USE_TEXT
 #endif
 
+#if 1
+#define SET_IDS
+#endif
+
 #if 0
 #define USE_PIXMAP 
 #endif
@@ -47,6 +52,12 @@ double total_width, total_height;
 double left_offset, top_offset;
 char ids[N_TOTAL_ID_ITEMS][MAX_ID_LEN];
 
+GdkPixbuf *pixbuf = NULL;
+cairo_pattern_t *pattern = NULL;
+double item_width, item_height;
+double cell_width, cell_height;
+double group_width, group_height;
+
 static clock_t start;
 
 static gboolean
@@ -75,19 +86,45 @@ on_motion_notify (GooCanvasItem *item,
 
 
 static void
+init_ids (void)
+{
+  int group_i, group_j, i, j;
+  int id_item_num = 0;;
+	
+  for (group_i = 0; group_i < N_GROUP_COLS; group_i++)
+    {
+      for (group_j = 0; group_j < N_GROUP_ROWS; group_j++)
+	{
+	  double group_x = left_offset + (group_i * group_width);
+	  double group_y = top_offset + (group_j * group_height);
+
+	  for (i = 0; i < N_COLS; i++)
+	    {
+	      for (j = 0; j < N_ROWS; j++)
+		{
+		  double item_x = (i * cell_width) + PADDING;
+		  double item_y = (j * cell_height) + PADDING;
+
+		  sprintf (ids[id_item_num++], "%.10g, %.10g",
+			   group_x + item_x, group_y + item_y);
+		}
+	    }
+	}
+    }
+}
+
+
+static void
 setup_canvas (GtkWidget *canvas)
 {
   GooCanvasItem *root, *group, *item;
-  GdkPixbuf *pixbuf = NULL;
-  cairo_pattern_t *pattern = NULL;
   int group_i, group_j, i, j;
-  double item_width, item_height;
-  double cell_width, cell_height;
-  double group_width, group_height;
   int total_items = 0, id_item_num = 0;;
   GdkColor color = { 0, 0, 0, 0, };
   GooCanvasStyle *style, *style2;
   GValue tmpval = { 0 };
+  cairo_matrix_t item_matrix;
+  GQuark id_quark = g_quark_from_static_string ("id");
 
   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
 
@@ -98,30 +135,6 @@ setup_canvas (GtkWidget *canvas)
 		"font", "Sans 8",
 		NULL);
 
-#ifdef USE_PIXMAP
-  pixbuf = gdk_pixbuf_new_from_file("toroid.png", NULL);
-  item_width = gdk_pixbuf_get_width (pixbuf);
-  item_height = gdk_pixbuf_get_height (pixbuf);
-  pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
-#else
-  pixbuf = NULL;
-  item_width = ITEM_WIDTH;
-  item_height = 19;
-#endif
-	
-  cell_width = item_width + PADDING * 2;
-  cell_height = item_height + PADDING * 2;
-
-  group_width = N_COLS * cell_width;
-  group_height = N_ROWS * cell_height;
-
-  total_width = N_GROUP_COLS * group_width;
-  total_height = N_GROUP_ROWS * group_height;
-
-  /* We use -ve offsets to test if -ve coords are handled correctly. */
-  left_offset = -total_width / 2;
-  top_offset = -total_height / 2;
-
   style = goo_canvas_style_new ();
   gdk_color_parse ("mediumseagreen", &color);
   pattern = cairo_pattern_create_rgb (color.red / 65535.0,
@@ -160,14 +173,11 @@ setup_canvas (GtkWidget *canvas)
 		  double item_x = (i * cell_width) + PADDING;
 		  double item_y = (j * cell_height) + PADDING;
 #ifdef ROTATE
-		  double rotation = i % 10 * 2;
+		  double rotation = (i % 10 * 2) * M_PI / 180;
 		  double rotation_x = item_x + item_width / 2;
 		  double rotation_y = item_y + item_height / 2;
 #endif
 
-		  sprintf (ids[id_item_num], "%.10g, %.10g",
-			   group_x + item_x, group_y + item_y);
-
 #ifdef USE_PIXMAP
 		  item = goo_canvas_image_new (group, NULL, item_x, item_y,
 					       "pattern", pattern,
@@ -182,12 +192,17 @@ setup_canvas (GtkWidget *canvas)
 		  goo_canvas_item_set_style (item, (j % 2) ? style : style2);
 #endif
 #ifdef ROTATE
-		  goo_canvas_item_rotate (item, rotation, rotation_x, rotation_y);
+		  cairo_matrix_init_identity (&item_matrix);
+		  cairo_matrix_translate (&item_matrix, rotation_x, rotation_y);
+		  cairo_matrix_rotate (&item_matrix, rotation);
+		  cairo_matrix_translate (&item_matrix, -rotation_x, -rotation_y);
+		  goo_canvas_item_set_transform (item, &item_matrix);
 #endif
 #endif
-		  g_object_set_data (G_OBJECT (item), "id",
-				     ids[id_item_num]);
-
+#ifdef SET_IDS
+		  g_object_set_qdata (G_OBJECT (item), id_quark,
+				      ids[id_item_num]);
+#endif
 #if 0
 		  g_signal_connect (item, "motion_notify_event",
 				    G_CALLBACK (on_motion_notify), NULL);
@@ -197,8 +212,13 @@ setup_canvas (GtkWidget *canvas)
 		  item = goo_canvas_text_new (group, ids[id_item_num],
 					      item_x + item_width / 2,
 					      item_y + item_height / 2,
-					      -1, GTK_ANCHOR_CENTER,
+					      item_width, GTK_ANCHOR_CENTER,
+					      "height", item_height,
+					      /*"alignment", PANGO_ALIGN_CENTER,*/
 					      NULL);
+		  /* FIXME: This is slightly naughty, but much faster. */
+		  GOO_CANVAS_TEXT (item)->text_data->alignment = PANGO_ALIGN_CENTER;
+
 #else
 		  item = goo_canvas_rect_new (group, item_x + 20, item_y + 4,
 					      item_width - 40, item_height - 8,
@@ -206,8 +226,7 @@ setup_canvas (GtkWidget *canvas)
 #endif
 
 #ifdef ROTATE
-		  goo_canvas_item_rotate (item, rotation, rotation_x,
-					  rotation_y);
+		  goo_canvas_item_set_transform (item, &item_matrix);
 #endif
 		  id_item_num++;
 		  total_items += 2;
@@ -259,6 +278,34 @@ create_canvas (void)
 {
   GtkWidget *canvas;
 
+#ifdef USE_PIXMAP
+  pixbuf = gdk_pixbuf_new_from_file("toroid.png", NULL);
+  item_width = gdk_pixbuf_get_width (pixbuf);
+  item_height = gdk_pixbuf_get_height (pixbuf);
+  pattern = goo_canvas_cairo_pattern_from_pixbuf (pixbuf);
+#else
+  pixbuf = NULL;
+  item_width = ITEM_WIDTH;
+  item_height = 19;
+#endif
+	
+  cell_width = item_width + PADDING * 2;
+  cell_height = item_height + PADDING * 2;
+
+  group_width = N_COLS * cell_width;
+  group_height = N_ROWS * cell_height;
+
+  total_width = N_GROUP_COLS * group_width;
+  total_height = N_GROUP_ROWS * group_height;
+
+  /* We use -ve offsets to test if -ve coords are handled correctly. */
+  left_offset = -total_width / 2;
+  top_offset = -total_height / 2;
+
+#ifdef SET_IDS
+  init_ids ();
+#endif
+
   /* Create the canvas. */
   canvas = goo_canvas_new ();
   gtk_widget_set_size_request (canvas, 600, 450);
diff --git a/docs/architecture.xml b/docs/architecture.xml
index 75ce44e..2de573a 100644
--- a/docs/architecture.xml
+++ b/docs/architecture.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; []>
 <refentry id="goocanvas-architecture">
   <refmeta>
     <refentrytitle>Underlying Architecture</refentrytitle>
diff --git a/docs/coordinates.xml b/docs/coordinates.xml
index 4a7e5a6..7a9c509 100644
--- a/docs/coordinates.xml
+++ b/docs/coordinates.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; []>
 <refentry id="goocanvas-coordinates">
   <refmeta>
     <refentrytitle>Coordinate Spaces and Limits</refentrytitle>
diff --git a/docs/creating-items.xml b/docs/creating-items.xml
index 2eb7921..a199557 100644
--- a/docs/creating-items.xml
+++ b/docs/creating-items.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; []>
 <refentry id="goocanvas-creating-items">
   <refmeta>
     <refentrytitle>Creating New Items</refentrytitle>
diff --git a/docs/model-view-canvas.xml b/docs/model-view-canvas.xml
index e87637e..18b7617 100644
--- a/docs/model-view-canvas.xml
+++ b/docs/model-view-canvas.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; []>
 <refentry id="goocanvas-model-view-canvas">
   <refmeta>
     <refentrytitle>Model/View Canvas Example</refentrytitle>
diff --git a/docs/overview.xml b/docs/overview.xml
index 08846f8..6dd35ef 100644
--- a/docs/overview.xml
+++ b/docs/overview.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; []>
 <refentry id="goocanvas-overview">
   <refmeta>
     <refentrytitle>Overview</refentrytitle>
diff --git a/docs/simple-canvas.xml b/docs/simple-canvas.xml
index f737056..6551901 100644
--- a/docs/simple-canvas.xml
+++ b/docs/simple-canvas.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; []>
 <refentry id="goocanvas-simple-canvas">
   <refmeta>
     <refentrytitle>Simple Canvas Example</refentrytitle>
diff --git a/docs/wysiwyg.xml b/docs/wysiwyg.xml
index 249ede6..92bf57e 100644
--- a/docs/wysiwyg.xml
+++ b/docs/wysiwyg.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
-               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
+               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd"; []>
 <refentry id="goocanvas-wysiwyg">
   <refmeta>
     <refentrytitle>WYSIWYG Printing</refentrytitle>
diff --git a/src/goocanvas.c b/src/goocanvas.c
index cfa51a5..cc24dd9 100644
--- a/src/goocanvas.c
+++ b/src/goocanvas.c
@@ -489,6 +489,7 @@ goo_canvas_init (GooCanvas *canvas)
   canvas->anchor = GTK_ANCHOR_NORTH_WEST;
   canvas->clear_background = TRUE;
   canvas->redraw_when_scrolled = FALSE;
+  canvas->before_initial_expose = TRUE;
 
   /* Set the default bounds to a reasonable size. */
   canvas->bounds.x1 = 0.0;
@@ -2609,6 +2610,11 @@ goo_canvas_request_item_redraw (GooCanvas             *canvas,
 				const GooCanvasBounds *bounds,
 				gboolean               is_static)
 {
+  /* If the canvas hasn't been painted yet, we can just return as it all needs
+     a redraw. This can save a lot of time if there are lots of items. */
+  if (canvas->before_initial_expose)
+    return;
+
   if (is_static)
     request_static_redraw (canvas, bounds);
   else
@@ -2650,7 +2656,10 @@ goo_canvas_expose_event (GtkWidget      *widget,
   double x1, y1, x2, y2;
 
   if (!canvas->root_item)
-    return FALSE;
+    {
+      canvas->before_initial_expose = FALSE;
+      return FALSE;
+    }
 
   if (event->window != canvas->canvas_window)
     return FALSE;
@@ -2666,6 +2675,8 @@ goo_canvas_expose_event (GtkWidget      *widget,
 
   cr = goo_canvas_create_cairo_context (canvas);
 
+  cairo_save (cr);
+
   if (canvas->need_update)
     goo_canvas_update_internal (canvas, cr);
 
@@ -2717,12 +2728,16 @@ goo_canvas_expose_event (GtkWidget      *widget,
 
   goo_canvas_item_paint (canvas->root_item, cr, &bounds, canvas->scale);
 
+  cairo_restore (cr);
+
   paint_static_items (canvas, event, cr);
 
   cairo_destroy (cr);
 
   GTK_WIDGET_CLASS (goo_canvas_parent_class)->expose_event (widget, event);
 
+  canvas->before_initial_expose = FALSE;
+
   return FALSE;
 }
 
diff --git a/src/goocanvas.h b/src/goocanvas.h
index 780b585..3b2bcd0 100644
--- a/src/goocanvas.h
+++ b/src/goocanvas.h
@@ -88,6 +88,9 @@ struct _GooCanvas
      useful when there are sticky items to reduce flicker, but is slower. */
   guint redraw_when_scrolled : 1;
 
+  /* If the canvas hasn't received the initial expose event yet. */
+  guint before_initial_expose : 1;
+
   /* This is the padding around the automatic bounds. */
   gdouble bounds_padding;
 
diff --git a/src/goocanvasgroup.c b/src/goocanvasgroup.c
index 0f709ac..a41423a 100644
--- a/src/goocanvasgroup.c
+++ b/src/goocanvasgroup.c
@@ -749,7 +749,7 @@ goo_canvas_group_paint (GooCanvasItem         *item,
   /* Check if the item should be visible. */
   if (simple_data->visibility <= GOO_CANVAS_ITEM_INVISIBLE
       || (simple_data->visibility == GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD
-	  && simple->canvas->scale < simple_data->visibility_threshold))
+	  && scale < simple_data->visibility_threshold))
     return;
 
   /* Paint all the items in the group. */
diff --git a/src/goocanvasitemsimple.c b/src/goocanvasitemsimple.c
index 46544ed..7bdc267 100644
--- a/src/goocanvasitemsimple.c
+++ b/src/goocanvasitemsimple.c
@@ -603,7 +603,7 @@ goo_canvas_item_simple_set_common_property (GObject                 *object,
   gboolean recompute_bounds = FALSE;
   cairo_matrix_t *transform;
   GValue tmpval = { 0 };
-  const char *font_name;
+  const char *font_name, *path_data;
   PangoFontDescription *font_desc = NULL;
 
   /* See if we need to create our own style. */
@@ -734,7 +734,11 @@ goo_canvas_item_simple_set_common_property (GObject                 *object,
     case PROP_CLIP_PATH:
       if (simple_data->clip_path_commands)
 	g_array_free (simple_data->clip_path_commands, TRUE);
-      simple_data->clip_path_commands = goo_canvas_parse_path_data (g_value_get_string (value));
+      path_data = g_value_get_string (value);
+      if (path_data)
+	simple_data->clip_path_commands = goo_canvas_parse_path_data (path_data);
+      else
+	simple_data->clip_path_commands = NULL;
       recompute_bounds = TRUE;
       break;
     case PROP_CLIP_FILL_RULE:
diff --git a/src/goocanvaspolyline.c b/src/goocanvaspolyline.c
index d6c98fd..b34908e 100644
--- a/src/goocanvaspolyline.c
+++ b/src/goocanvaspolyline.c
@@ -995,7 +995,6 @@ goo_canvas_polyline_update  (GooCanvasItemSimple *simple,
 			     cairo_t             *cr)
 {
   GooCanvasPolyline *polyline = (GooCanvasPolyline*) simple;
-  GooCanvasPolylineData *polyline_data = polyline->polyline_data;
 
   goo_canvas_polyline_reconfigure_arrows (polyline);
 
diff --git a/src/goocanvastable.c b/src/goocanvastable.c
index 05e5718..911869e 100644
--- a/src/goocanvastable.c
+++ b/src/goocanvastable.c
@@ -1823,7 +1823,7 @@ goo_canvas_table_size_allocate_pass3 (GooCanvasTable *table,
 	}
 
       if (direction == GTK_TEXT_DIR_RTL)
-	x = layout_data->allocated_size[HORZ] - width;
+	x = layout_data->allocated_size[HORZ] - width - x;
 
       requested_area.x1 = layout_data->children[i].requested_position[HORZ];
       requested_area.y1 = layout_data->children[i].requested_position[VERT];
@@ -2229,11 +2229,12 @@ goo_canvas_table_paint (GooCanvasItem         *item,
   GooCanvasItem *child;
   gboolean check_clip = FALSE, clip;
   gint start_column, end_column, start_row, end_row, i, j;
-  gdouble x, y, end_x, end_y;
+  gdouble x, y, end_x, end_y, clip_width, clip_height;
   gdouble frame_width, frame_height;
   gdouble line_start, line_end;
   gdouble spacing, half_spacing_before, half_spacing_after;
-  gboolean old_grid_line_visibility, cur_grid_line_visibility;
+  gboolean old_grid_line_visibility = FALSE, cur_grid_line_visibility;
+  GtkTextDirection direction = GTK_TEXT_DIR_NONE;
 
   /* Skip the item if the bounds don't intersect the expose rectangle. */
   if (simple->bounds.x1 > bounds->x2 || simple->bounds.x2 < bounds->x1
@@ -2246,6 +2247,9 @@ goo_canvas_table_paint (GooCanvasItem         *item,
 	  && simple->canvas->scale < simple_data->visibility_threshold))
     return;
 
+  if (simple->canvas)
+    direction = gtk_widget_get_direction (GTK_WIDGET (simple->canvas));
+
   /* Paint all the items in the group. */
   cairo_save (cr);
   if (simple_data->transform)
@@ -2487,8 +2491,14 @@ goo_canvas_table_paint (GooCanvasItem         *item,
 	  /* Only clip the child if it may have been shrunk. */
 	  if (clip)
 	    {
+	      clip_width = end_x - x;
+	      clip_height = end_y - y;
+
+	      if (direction == GTK_TEXT_DIR_RTL)
+		x = layout_data->allocated_size[HORZ] - clip_width - x;
+
 	      cairo_save (cr);
-	      cairo_rectangle (cr, x, y, end_x - x, end_y - y);
+	      cairo_rectangle (cr, x, y, clip_width, clip_height);
 	      cairo_clip (cr);
 	    }
 	}



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