[cairo-commit] goocanvas/src goocanvas.c, 1.6, 1.7 goocanvastable.c, 1.6, 1.7 goocanvastable.h, 1.4, 1.5 goocanvastext.c, 1.12, 1.13 goocanvaswidget.c, 1.4, 1.5

Damon Chaplin commit at pdx.freedesktop.org
Tue Feb 20 06:22:09 PST 2007


Committed by: damon

Update of /cvs/cairo/goocanvas/src
In directory kemper:/tmp/cvs-serv11348/src

Modified Files:
	goocanvas.c goocanvastable.c goocanvastable.h goocanvastext.c 
	goocanvaswidget.c 
Log Message:
2007-02-20  Damon Chaplin  <damon at gnome.org>

	* src/goocanvastext.c (goo_canvas_text_create_layout): 
	(goo_canvas_text_get_item_at): use the ink rect as well as the logical
	rect when calculating the bounds or doing hit-testing.

	* src/goocanvastable.c (goo_canvas_table_size_allocate_pass1): shrink
	homogeneous tables if appropriate.

	* src/goocanvaswidget.c (goo_canvas_widget_get_item_at): return the
	widget item if the point is within its bounds.

	* src/goocanvas.c (goo_canvas_render): if bounds are passed in set
	the clip path to the bounds.

	* demo/demo.c (write_pdf_clicked): added code to test clipped painting.



Index: goocanvas.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvas.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvas.c	13 Feb 2007 13:25:09 -0000	1.6
+++ goocanvas.c	20 Feb 2007 14:22:03 -0000	1.7
@@ -1826,9 +1826,22 @@
   cairo_set_line_width (cr, goo_canvas_get_default_line_width (canvas));
 
   if (bounds)
-    goo_canvas_item_paint (canvas->root_item, cr, bounds, scale);
+    {
+      /* Clip to the given bounds. */
+      cairo_new_path (cr);
+      cairo_move_to (cr, bounds->x1, bounds->y1);
+      cairo_line_to (cr, bounds->x2, bounds->y1);
+      cairo_line_to (cr, bounds->x2, bounds->y2);
+      cairo_line_to (cr, bounds->x1, bounds->y2);
+      cairo_close_path (cr);
+      cairo_clip (cr);
+
+      goo_canvas_item_paint (canvas->root_item, cr, bounds, scale);
+    }
   else
-    goo_canvas_item_paint (canvas->root_item, cr, &canvas->bounds, scale);
+    {
+      goo_canvas_item_paint (canvas->root_item, cr, &canvas->bounds, scale);
+    }
 }
 
 

Index: goocanvastable.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastable.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvastable.c	17 Feb 2007 13:48:37 -0000	1.6
+++ goocanvastable.c	20 Feb 2007 14:22:03 -0000	1.7
@@ -86,13 +86,16 @@
   GOO_CANVAS_TABLE_CHILD_SHRINK	= 1 << 2
 } GooCanvasTableChildFlags;
 
+
+/* This is used in the GooCanvasTableData children GArray to keep the child
+   properties for each of the children. */
 typedef struct _GooCanvasTableChild  GooCanvasTableChild;
 struct _GooCanvasTableChild
 {
-  gdouble position[2];
+  gdouble position[2];			/* Translation offset in table. */
   gdouble start_pad[2], end_pad[2];
   gdouble align[2];
-  guint16 start[2], size[2];
+  guint16 start[2], size[2];		/* Start row/col & num rows/cols. */
   guint8 flags[2];			/* GooCanvasTableChildFlags. */
 };
 
@@ -118,6 +121,8 @@
   gdouble requested_size[2];
 };
 
+/* This is only meant to be kept around while doing the layout.
+   It gets freed in goo_canvas_table_allocate_area(). */
 struct _GooCanvasTableLayoutData
 {
   GooCanvasTableDimensionLayoutData *dldata[2];
@@ -1408,25 +1413,29 @@
 
       total_size = layout_data->allocated_size[d] - table_data->border_width * 2;
 
+      natural_size = 0;
+      nexpand = 0;
+      nshrink = 0;
+
+      for (i = 0; i < dimension->size; i++)
+	{
+	  natural_size += dldata[i].requisition;
+	  if (dldata[i].expand)
+	    nexpand += 1;
+	  if (dldata[i].shrink)
+	    nshrink += 1;
+	}
+      for (i = 0; i + 1 < dimension->size; i++)
+	natural_size += dldata[i].spacing;
+      
       if (dimension->homogeneous)
 	{
 	  /* If the table is homogeneous in this dimension we check if any of
-	     the children expand. If they do we expand all rows/columns to
-	     fit the total_size. */
-	  /* FIXME: Should we try shrinking as well here? */
-	  if (table_data->children->len == 0)
-	    nexpand = 1;
-	  else
-	    {
-	      nexpand = 0;
-	      for (i = 0; i < dimension->size; i++)
-		if (dldata[i].expand)
-		  {
-		    nexpand += 1;
-		    break;
-		  }
-	    }
-	  if (nexpand)
+	     the children expand, or if there are no children, or if we were
+	     allocated less space than we requested and any children shrink.
+	     If so, we divide up all the allocated space. */
+	  if (nexpand || table_data->children->len == 0
+	      || (natural_size > total_size && nshrink))
 	    {
 	      size_to_allocate = total_size;
 	      for (i = 0; i + 1 < dimension->size; i++)
@@ -1440,21 +1449,6 @@
 	}
       else
 	{
-	  natural_size = 0;
-	  nexpand = 0;
-	  nshrink = 0;
-
-	  for (i = 0; i < dimension->size; i++)
-	    {
-	      natural_size += dldata[i].requisition;
-	      if (dldata[i].expand)
-		nexpand += 1;
-	      if (dldata[i].shrink)
-		nshrink += 1;
-	    }
-	  for (i = 0; i + 1 < dimension->size; i++)
-	    natural_size += dldata[i].spacing;
-      
 	  /* Check to see if we were allocated more width than we requested.
 	   */
 	  if ((natural_size < total_size) && (nexpand >= 1))

Index: goocanvastable.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastable.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- goocanvastable.h	9 Feb 2007 13:41:03 -0000	1.4
+++ goocanvastable.h	20 Feb 2007 14:22:03 -0000	1.5
@@ -44,6 +44,8 @@
   /* An array of GooCanvasTableChild. */
   GArray *children;
 
+  /* This is only meant to be kept around while doing the layout.
+     It gets freed in goo_canvas_table_allocate_area(). */
   GooCanvasTableLayoutData *layout_data;
 };
 

Index: goocanvastext.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastext.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- goocanvastext.c	17 Feb 2007 13:48:37 -0000	1.12
+++ goocanvastext.c	20 Feb 2007 14:22:03 -0000	1.13
@@ -342,9 +342,10 @@
   GValue *svalue;
   PangoLayout *layout;
   PangoContext *context;
-  PangoRectangle logical_rect;
+  PangoRectangle ink_rect, logical_rect;
   double logical_width, logical_height, align_width, origin_x, origin_y;
   gchar *string;
+  double x1_extension, x2_extension, y1_extension, y2_extension;
 
   string = text_data->text ? text_data->text : "";
 
@@ -370,12 +371,10 @@
   if (text_data->alignment != PANGO_ALIGN_LEFT)
     pango_layout_set_alignment (layout, text_data->alignment);
 
-  /* FIXME: Sometimes we should be using the ink_rect rather than the
-     logical rect, e.g. for the actual bounds of the item view. */
   if (bounds)
     {
       /* Get size of the text, so we can position it according to anchor. */
-      pango_layout_get_extents (layout, NULL, &logical_rect);
+      pango_layout_get_extents (layout, &ink_rect, &logical_rect);
 
       logical_width = (double) logical_rect.width / PANGO_SCALE;
       logical_height = (double) logical_rect.height / PANGO_SCALE;
@@ -430,7 +429,7 @@
       if (origin_y_return)
 	*origin_y_return = origin_y;
 
-      /* Now calculate the bounds. */
+      /* Now calculate the logical bounds. */
       bounds->x1 = origin_x;
       bounds->y1 = origin_y;
 
@@ -455,6 +454,27 @@
 
       bounds->x2 = origin_x + logical_width;
       bounds->y2 = origin_y + logical_height;
+
+      /* Now adjust it to take into account the ink bounds. Calculate how far
+	 the ink rect extends outside each edge of the logical rect and adjust
+	 the bounds as necessary. */
+      x1_extension = logical_rect.x - ink_rect.x;
+      if (x1_extension > 0)
+	bounds->x1 -= x1_extension / PANGO_SCALE;
+
+      x2_extension = (ink_rect.x + ink_rect.width)
+	- (logical_rect.x + logical_rect.width);
+      if (x2_extension > 0)
+	bounds->x2 += x2_extension / PANGO_SCALE;
+
+      y1_extension = logical_rect.y - ink_rect.y;
+      if (y1_extension > 0)
+	bounds->y1 -= y1_extension / PANGO_SCALE;
+
+      y2_extension = (ink_rect.y + ink_rect.height)
+	- (logical_rect.y + logical_rect.height);
+      if (y2_extension > 0)
+	bounds->y2 += y2_extension / PANGO_SCALE;
     }
 
   return layout;
@@ -503,8 +523,9 @@
   PangoLayout *layout;
   GooCanvasBounds bounds;
   PangoLayoutIter *iter;
-  PangoRectangle log_rect;
-  int px, py;
+  PangoRectangle ink_rect, log_rect;
+  int px, py, x1, y1, x2, y2;
+  int log_x2, ink_x2, log_y2, ink_y2;
   gdouble origin_x, origin_y;
 
   /* If there is no text just return. */
@@ -528,10 +549,24 @@
   iter = pango_layout_get_iter (layout);
   do
     {
-      pango_layout_iter_get_line_extents (iter, NULL, &log_rect);
+      pango_layout_iter_get_line_extents (iter, &ink_rect, &log_rect);
 
-      if (px >= log_rect.x && px < log_rect.x + log_rect.width 
-	  && py >= log_rect.y && py < log_rect.y + log_rect.height)
+      /* We use a union of the ink rect and the logical rect, as we want to
+	 let the user click on any part of the ink, even if it extends outside
+	 the character cell (i.e. the ink rect), or click on the space in the
+	 character cell (i.e. the logical rect). */
+      x1 = MIN (log_rect.x, ink_rect.x);
+      y1 = MIN (log_rect.y, ink_rect.y);
+
+      log_x2 = log_rect.x + log_rect.width;
+      ink_x2 = ink_rect.x + ink_rect.width;
+      x2 = MAX (log_x2, ink_x2);
+
+      log_y2 = log_rect.y + log_rect.height;
+      ink_y2 = ink_rect.y + ink_rect.height;
+      y2 = MAX (log_y2, ink_y2);
+
+      if (px >= x1 && px < x2 && py >= y1 && py < y2)
 	{
 	  found_item = (GooCanvasItem*) simple;
 	  break;

Index: goocanvaswidget.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvaswidget.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- goocanvaswidget.c	17 Feb 2007 13:48:37 -0000	1.4
+++ goocanvaswidget.c	20 Feb 2007 14:22:03 -0000	1.5
@@ -456,8 +456,10 @@
 			       cairo_t             *cr,
 			       gboolean             is_pointer_event)
 {
-  /* FIXME: Should we return the widget here? */
-  return NULL;
+  /* For now we just assume that the widget covers its entire bounds so we just
+     return it. In future if widget items support transforms we'll need to
+     modify this. */
+  return (GooCanvasItem*) simple;
 }
 
 



More information about the cairo-commit mailing list