[gtk+/native-layout] Fixed GtkLabel to wrap correctly and report width-for-height correctly when vertical.



commit dfd311497dda066e27b4b41ea920fa8e74cfc880
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date:   Tue Apr 20 18:54:50 2010 -0400

    Fixed GtkLabel to wrap correctly and report width-for-height correctly when vertical.

 gtk/gtklabel.c |  112 +++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 70 insertions(+), 42 deletions(-)
---
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 1408610..3a60938 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -3185,13 +3185,22 @@ gtk_label_ensure_layout (GtkLabel *label, gboolean guess_wrap_width)
 	  GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
 	  gint longest_paragraph;
 	  gint width, height;
+	  gint aux_width = 0;
 
- 	  if (aux_info && aux_info->width > 0)
-	    pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE);
+ 	  if ((angle == 90 || angle == 270) && aux_info && aux_info->height > 0)
+	    aux_width = aux_info->height;
+	  else if (aux_info && aux_info->width > 0)
+	    aux_width = aux_info->width;
+
+ 	  if (aux_width > 0)
+	    pango_layout_set_width (label->layout, aux_width * PANGO_SCALE);
 	  else if (guess_wrap_width == FALSE &&
 		   widget->allocation.width > 1)
  	    {
-	      width = widget->allocation.width - label->misc.xpad * 2;
+	      if (angle == 90 || angle == 270)
+		width = widget->allocation.height - label->misc.ypad * 2;
+	      else
+		width = widget->allocation.width  - label->misc.xpad * 2;
 
 	      pango_layout_set_wrap (label->layout, label->wrap_mode);
 	      pango_layout_set_width (label->layout, MAX (width, 1) * PANGO_SCALE);
@@ -3340,6 +3349,7 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
   GtkLabel      *label = GTK_LABEL (layout);
   PangoRectangle required_rect;
   PangoRectangle natural_rect;
+  gdouble        angle;
 
   /* "width-chars" Hard-coded minimum width: 
    *    - minimum size should be MAX (width-chars, strlen ("..."));
@@ -3357,6 +3367,9 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
     gtk_label_clear_layout (label);
   gtk_label_ensure_layout (label, TRUE);
 
+
+  angle = gtk_label_get_angle (label);
+
   /* Start off with the pixel extents of the rendered layout */
   pango_layout_get_extents (label->layout, NULL, &required_rect);
   required_rect.x = required_rect.y = 0;
@@ -3375,7 +3388,6 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
       PangoLayout       *layout  = pango_layout_copy (label->layout);
       PangoContext      *context = pango_layout_get_context (label->layout);
       const PangoMatrix *matrix  = pango_context_get_matrix (context);
-      gdouble           angle;
 
       pango_layout_set_width (layout, -1);
       pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
@@ -3390,9 +3402,7 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
        * (note, we could alternatively set the layout to not ellipsize when we know we have been
        * allocated our full natural size, or it may be that pango needs a fix here).
        */
-      angle = gtk_label_get_angle (label);
-      if (label->ellipsize && 
-	  angle != 0 && angle != 90 && angle != 180 && angle != 270 && angle != 360)
+      if (label->ellipsize && angle != 0 && angle != 90 && angle != 180 && angle != 270 && angle != 360)
 	{
 	  /* For some reason we only need this at about 110 degrees, and only
 	   * when gaining in height
@@ -3410,24 +3420,41 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout,
 
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
-      *minimum_size = required_rect.width + label->misc.xpad * 2;
-      *natural_size = natural_rect.width  + label->misc.xpad * 2;
-    }
-  else
-    {
-      if (!label->have_transform)
+      /* Note, we cant use get_size_for_allocation() when rotating ellipsize labels.
+       */
+      if (!(label->ellipsize && label->have_transform) && (angle == 90 || angle == 270))
 	{
-	  /* Doing a w4h request on a label here, return the required height for the minimum width. */
-	  get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL, 
-				   required_rect.width, minimum_size, natural_size);
+	  /* Doing a h4w request on a rotated label here, return the required width for the minimum height. */
+	  get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL, 
+				   required_rect.height, minimum_size, natural_size);
+
 	}
       else
 	{
-	  /* Rotated labels already setup the required height here */
+	  /* Normal desired width */
+	  *minimum_size = required_rect.width;
+	  *natural_size = natural_rect.width;
+	}
+      
+      *minimum_size += label->misc.xpad * 2;
+      *natural_size += label->misc.xpad * 2;
+    } 
+  else /* GTK_ORIENTATION_VERTICAL */
+    {
+      /* Note, we cant use get_size_for_allocation() when rotating ellipsize labels.
+       */
+      if (angle == 90 || angle == 270 || (label->ellipsize && label->have_transform))
+	{
+	  /* A vertically rotated label does w4h, so return the base desired height (text length) */
 	  *minimum_size = required_rect.height;
 	  *natural_size = natural_rect.height;
 	}
-
+      else
+	{
+	  /* Doing a w4h request on a label here, return the required height for the minimum width. */
+	  get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL, 
+				   required_rect.width, minimum_size, natural_size);
+	}
       *minimum_size += label->misc.ypad * 2;
       *natural_size += label->misc.ypad * 2;
     }
@@ -3469,7 +3496,7 @@ gtk_label_get_width_for_height (GtkExtendedLayout *layout,
   GtkLabel *label = GTK_LABEL (layout);
   gdouble angle = gtk_label_get_angle (label);
 
-  if (label->wrap && (90 == angle || 270 == angle))
+  if (label->wrap && (angle == 90 || angle == 270))
     {
       if (label->wrap)
 	gtk_label_clear_layout (label);
@@ -3497,7 +3524,7 @@ gtk_label_get_height_for_width (GtkExtendedLayout *layout,
   GtkLabel *label = GTK_LABEL (layout);
   gdouble angle = gtk_label_get_angle (label);
 
-  if (label->wrap && (0 == angle || 180 == angle))
+  if (label->wrap && (angle == 0 || angle == 180 || angle == 360))
     {
       if (label->wrap)
 	gtk_label_clear_layout (label);
@@ -3705,10 +3732,12 @@ get_layout_location (GtkLabel  *label,
   gint req_width, x, y;
   gint req_height;
   PangoRectangle logical;
+  gdouble angle;
 
-  misc = GTK_MISC (label);
+  misc   = GTK_MISC (label);
   widget = GTK_WIDGET (label);
-  priv = GTK_LABEL_GET_PRIVATE (label);
+  priv   = GTK_LABEL_GET_PRIVATE (label);
+  angle  = gtk_label_get_angle (label);
 
   if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
     xalign = misc->xalign;
@@ -3717,37 +3746,33 @@ get_layout_location (GtkLabel  *label,
 
   pango_layout_get_extents (label->layout, NULL, &logical);
 
-  if (label->have_transform)
-    {
-      PangoContext *context = gtk_widget_get_pango_context (widget);
-      const PangoMatrix *matrix = pango_context_get_matrix (context);
-      pango_matrix_transform_rectangle (matrix, &logical);
-    }
-
-  pango_extents_to_pixels (&logical, NULL);
-
+  /* Do the wrap width delimiting before the transform
+   */
   if (label->wrap || label->ellipsize || priv->width_chars > 0)
     {
       int width;
 
       width = pango_layout_get_width (label->layout);
 
-      req_width = logical.width;
-      req_height = logical.height;
-
       if (width != -1)
-	req_width = MIN(PANGO_PIXELS (width), req_width);
-      req_width += 2 * misc->xpad;
-      req_height += 2 * misc->ypad;
+	logical.width = MIN (width, logical.width);
     }
-  else
+
+  if (label->have_transform)
     {
-      req_width = logical.width;
-      req_height = logical.height;
-/*       req_width = widget->requisition.width; */
-/*       req_height = widget->requisition.height; */
+      PangoContext *context = gtk_widget_get_pango_context (widget);
+      const PangoMatrix *matrix = pango_context_get_matrix (context);
+      pango_matrix_transform_rectangle (matrix, &logical);
     }
 
+  pango_extents_to_pixels (&logical, NULL);
+
+  req_width  = logical.width;
+  req_height = logical.height;
+
+  req_width  += 2 * misc->xpad;
+  req_height += 2 * misc->ypad;
+
   x = floor (widget->allocation.x + (gint)misc->xpad +
 	      xalign * (widget->allocation.width - req_width));
 
@@ -3756,6 +3781,9 @@ get_layout_location (GtkLabel  *label,
   else
     x = MIN (x, widget->allocation.x + widget->allocation.width - misc->xpad);
 
+
+
+
   /* bgo#315462 - For single-line labels, *do* align the requisition with
    * respect to the allocation, even if we are under-allocated.  For multi-line
    * labels, always show the top of the text when they are under-allocated.  The



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