[cairo-commit] goocanvas/src goocanvasitem.c, 1.23, 1.24 goocanvasitem.h, 1.16, 1.17 goocanvastable.c, 1.10, 1.11 goocanvastext.c, 1.16, 1.17 goocanvastext.h, 1.6, 1.7

Damon Chaplin commit at pdx.freedesktop.org
Tue Mar 6 04:08:22 PST 2007


Committed by: damon

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

Modified Files:
	goocanvasitem.c goocanvasitem.h goocanvastable.c 
	goocanvastext.c goocanvastext.h 
Log Message:
2007-03-06  Damon Chaplin  <damon at gnome.org>

	* src/goocanvasitem.[hc]: added get_requested_height() method.

	* src/goocanvastable.c: Reworked a lot of code to support
	width-for-height layout. This gets the requested area of all children,
	calculates the column widths, then checks if any children want to
	change their requested height given their allocated width. Text items
	change their requested height based on their width, so this results in
	a better layout.

	* src/goocanvastext.h (struct _GooCanvasText): added layout_width to
	store the width used for the PangoLayout. This initially comes from
	the text's width property, but can be modified when the text item
	is layed out in a container like GooCanvasTable.

	* src/goocanvastext.c (goo_canvas_text_get_requested_height):
	calculates the requested height for the given width, or just returns
	-1 if the text item is rotated or has a clip path, in which case the
	original height is used.
	(goo_canvas_text_init, goo_canvas_text_create_layout) 
	(goo_canvas_text_update): use layout_width.

	* demo/demo-table.c (create_width_for_height_table): added tests for
	width-for-height layout.

	* demo/demo-clipping.c (setup_canvas): added text item to check
	clipping works OK with them.



Index: goocanvasitem.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- goocanvasitem.c	27 Feb 2007 01:42:07 -0000	1.23
+++ goocanvasitem.c	6 Mar 2007 12:08:15 -0000	1.24
@@ -1478,6 +1478,34 @@
 
 
 /**
+ * goo_canvas_item_get_requested_height:
+ * @item: a #GooCanvasItem.
+ * @cr: a cairo context.
+ * @width: the width that the item may be allocated.
+ * 
+ * Gets the requested height of the item, assuming it is allocated the given
+ * width. This is useful for text items whose requested height may change
+ * depending on the allocated width.
+ * 
+ * Returns: the requested height of the item, given the allocated width,
+ *  or %-1 if the item doesn't support this method or its height doesn't
+ *  change when allocated different widths.
+ **/
+gdouble
+goo_canvas_item_get_requested_height (GooCanvasItem       *item,
+				      cairo_t		  *cr,
+				      gdouble              width)
+{
+  GooCanvasItemIface *iface = GOO_CANVAS_ITEM_GET_IFACE (item);
+
+  if (iface->get_requested_height)
+    return iface->get_requested_height (item, cr, width);
+  else
+    return -1;
+}
+
+
+/**
  * goo_canvas_item_allocate_area:
  * @item: a #GooCanvasItem.
  * @cr: a cairo context.

Index: goocanvasitem.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvasitem.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- goocanvasitem.h	27 Feb 2007 01:42:07 -0000	1.16
+++ goocanvasitem.h	6 Mar 2007 12:08:15 -0000	1.17
@@ -107,6 +107,8 @@
  * @get_style: gets the item's style.
  * @set_style: sets the item's style.
  * @is_visible: returns %TRUE if the item is currently visible.
+ * @get_requested_height_for_width: returns the height requested for a
+ *  particular width, using the parent's coordinate space.
  * @get_model: gets the model that the canvas item is viewing.
  * @set_model: sets the model that the canvas item will view.
  * @enter_notify_event: signal emitted when the mouse enters the item.
@@ -222,6 +224,9 @@
   void			(* set_style)			(GooCanvasItem		*item,
 							 GooCanvasStyle		*style);
   gboolean		(* is_visible)			(GooCanvasItem		*item);
+  gdouble               (* get_requested_height)	(GooCanvasItem		*item,
+							 cairo_t		*cr,
+							 gdouble		 width);
 
   /* Virtual methods that model/view items must implement. */
   GooCanvasItemModel*	(* get_model)			(GooCanvasItem		*item);
@@ -402,6 +407,9 @@
 gboolean	   goo_canvas_item_get_requested_area (GooCanvasItem	*item,
 						       cairo_t          *cr,
 						       GooCanvasBounds  *requested_area);
+gdouble            goo_canvas_item_get_requested_height (GooCanvasItem  *item,
+							 cairo_t	*cr,
+							 gdouble         width);
 void		   goo_canvas_item_allocate_area      (GooCanvasItem	*item,
 						       cairo_t          *cr,
 						       GooCanvasBounds  *requested_area,

Index: goocanvastable.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastable.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- goocanvastable.c	27 Feb 2007 01:01:39 -0000	1.10
+++ goocanvastable.c	6 Mar 2007 12:08:15 -0000	1.11
@@ -1,8 +1,11 @@
 /*
- * GooCanvas. Copyright (C) 2005-6 Damon Chaplin.
+ * GooCanvas. Copyright (C) 2005-7 Damon Chaplin.
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 1997-2000 the GTK+ team.
  * Released under the GNU LGPL license. See COPYING for details.
  *
- * goocanvastable.c - table item.
+ * goocanvastable.c - table item. A lot of this code has been ported from
+ * the GtkTable widget.
  */
[...1058 lines suppressed...]
 	    continue;
 
 	  /* Check if any of the rows/columns the child is in can shrink. */
@@ -1814,7 +1990,7 @@
 	  if (clip)
 	    {
 	      cairo_save (cr);
-	      cairo_rectangle (cr, x, y, max_width, max_height);
+	      cairo_rectangle (cr, x, y, end_x - x, end_y - y);
 	      cairo_clip (cr);
 	    }
 	}
@@ -1997,6 +2173,7 @@
 
   iface->update                  = goo_canvas_table_update;
   iface->get_requested_area      = goo_canvas_table_get_requested_area;
+  iface->get_requested_height    = goo_canvas_table_get_requested_height;
   iface->allocate_area           = goo_canvas_table_allocate_area;
   iface->paint                   = goo_canvas_table_paint;
   iface->get_items_at	         = goo_canvas_table_get_items_at;

Index: goocanvastext.c
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastext.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- goocanvastext.c	27 Feb 2007 01:01:39 -0000	1.16
+++ goocanvastext.c	6 Mar 2007 12:08:15 -0000	1.17
@@ -127,6 +127,8 @@
   text->text_data = g_slice_new0 (GooCanvasTextData);
   text->text_data->width = -1.0;
   text->text_data->anchor = GTK_ANCHOR_NW;
+
+  text->layout_width = -1.0;
 }
 
 
@@ -356,8 +358,8 @@
   layout = pango_cairo_create_layout (cr);
   context = pango_layout_get_context (layout);
 
-  if (text_data->width > 0)
-    pango_layout_set_width (layout, (double) text_data->width * PANGO_SCALE);
+  if (text->layout_width > 0)
+    pango_layout_set_width (layout, (double) text->layout_width * PANGO_SCALE);
 
   if (text_data->use_markup)
     pango_layout_set_markup (layout, string, -1);
@@ -500,6 +502,11 @@
   GooCanvasText *text = (GooCanvasText*) simple;
   PangoLayout *layout;
 
+  /* Initialize the layout width to the text item's specified width property.
+     It may get changed later in get_requested_height() according to the
+     layout container and settings. */
+  text->layout_width = text->text_data->width;
+
   /* Compute the new bounds. */
   layout = goo_canvas_text_create_layout (text, cr, &simple->bounds,
 					  NULL, NULL);
@@ -619,6 +626,55 @@
 }
 
 
+static gdouble
+goo_canvas_text_get_requested_height (GooCanvasItem	*item,
+				      cairo_t		*cr,
+				      gdouble            width)
+{
+  GooCanvasItemSimple *simple = (GooCanvasItemSimple*) item;
+  GooCanvasItemSimpleData *simple_data = simple->simple_data;
+  GooCanvasText *text = (GooCanvasText*) item;
+  PangoLayout *layout;
+  gdouble height;
+
+  /* If we have a transformation besides a simple scale & translation, just
+     return -1 as we can't adjust the height in that case. */
+  if (simple_data->clip_path_commands
+      || (simple_data->transform && (simple_data->transform->xy != 0.0
+				     || simple_data->transform->yx != 0.0)))
+    return -1;
+
+  cairo_save (cr);
+  if (simple_data->transform)
+    cairo_transform (cr, simple_data->transform);
+
+  /* Convert the width from the parent's coordinate space. Note that we only
+     need to support a simple scale operation here. */
+  text->layout_width = width;
+  if (simple_data->transform)
+    text->layout_width /= simple_data->transform->xx;
+
+  /* Create layout with given width. */
+  layout = goo_canvas_text_create_layout (text, cr, &simple->bounds,
+					  NULL, NULL);
+  g_object_unref (layout);
+
+  /* Convert to the parent's coordinate space. As above,  we only need to
+     support a simple scale operation here. */
+  height = simple->bounds.y2 - simple->bounds.y1;
+  if (simple_data->transform)
+    height *= simple_data->transform->yy;
+
+  /* Convert the item's bounds to device space. */
+  goo_canvas_item_simple_user_bounds_to_device (simple, cr, &simple->bounds);
+
+  cairo_restore (cr);
+
+  /* Return the new requested height of the text. */
+  return height;
+}
+
+
 static void
 goo_canvas_text_set_model    (GooCanvasItem      *item,
 			      GooCanvasItemModel *model)
@@ -642,7 +698,8 @@
 static void
 canvas_item_interface_init (GooCanvasItemIface *iface)
 {
-  iface->set_model   = goo_canvas_text_set_model;
+  iface->get_requested_height = goo_canvas_text_get_requested_height;
+  iface->set_model            = goo_canvas_text_set_model;
 }
 
 

Index: goocanvastext.h
===================================================================
RCS file: /cvs/cairo/goocanvas/src/goocanvastext.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- goocanvastext.h	25 Feb 2007 18:25:52 -0000	1.6
+++ goocanvastext.h	6 Mar 2007 12:08:15 -0000	1.7
@@ -47,6 +47,7 @@
   GooCanvasItemSimple parent;
 
   GooCanvasTextData *text_data;
+  gdouble layout_width;
 };
 
 struct _GooCanvasTextClass



More information about the cairo-commit mailing list