Re: label performance patch



On 14 Nov 2001, Owen Taylor wrote:

> Alex Larsson <alexl redhat com> writes:
> 
> > GtkLabel keeps reflowing wrapped labels all the time. Here is a fix:
> 
> Actually, this comment drifted a bit from the the code ... if I
> recall correctly GTK_JUSTIFY_FILL was overloaded to mean 
> autowrap originally, and we only later separated out wrap.
> GTK_JUSTIFY_FILL, if implemented would only affect drawing,
> what this is actually referring to is a case that still
> happens:
> 
>  If word wrap is on, and gtk_widget_set_usize() has been called to
>  explicitely set the width of the widget, then the requested height
>  will depend on the width, which is a function of:
> 
>   - The width set on the width
>   - the padding of the widget
> 
> I think the way we should handle this is do something in 
> gtk_label_size_request() like:
> 
>  if (label->wrap && _gtk_widget_get_aux_info (widget, FALSE))
>    gtk_label_clear_layout (label);

Ok. Here is a new patch, this time without whitespace changes:

Index: gtklabel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklabel.c,v
retrieving revision 1.108
diff -u -p -w -r1.108 gtklabel.c
--- gtklabel.c	2001/11/08 18:56:23	1.108
+++ gtklabel.c	2001/11/14 17:17:35
@@ -136,9 +136,7 @@ static void gtk_label_hierarchy_changed 
 static void gtk_label_create_window       (GtkLabel *label);
 static void gtk_label_destroy_window      (GtkLabel *label);
 static void gtk_label_clear_layout        (GtkLabel *label);
-static void gtk_label_ensure_layout       (GtkLabel *label,
-                                           gint     *widthp,
-                                           gint     *heightp);
+static void gtk_label_ensure_layout       (GtkLabel *label);
 static void gtk_label_select_region_index (GtkLabel *label,
                                            gint      anchor_index,
                                            gint      end_index);
@@ -1319,9 +1317,7 @@ gtk_label_clear_layout (GtkLabel *label)
 }
 
 static void
-gtk_label_ensure_layout (GtkLabel *label,
-                         gint     *widthp,
-                         gint     *heightp)
+gtk_label_ensure_layout (GtkLabel *label)
 {
   GtkWidget *widget;
   PangoRectangle logical_rect;
@@ -1329,27 +1325,6 @@ gtk_label_ensure_layout (GtkLabel *label
 
   widget = GTK_WIDGET (label);
 
-  /*
-   * There are a number of conditions which will necessitate re-filling
-   * our text:
-   *
-   *     1. text changed.
-   *     2. justification changed either from to to GTK_JUSTIFY_FILL.
-   *     3. font changed.
-   *
-   * These have been detected elsewhere, and label->words will be zero,
-   * if one of the above has occured.
-   *
-   * Additionally, though, if GTK_JUSTIFY_FILL, we need to re-fill if:
-   *
-   *     4. gtk_widget_set_usize has changed the requested width.
-   *     5. gtk_misc_set_padding has changed xpad.
-   *     6.  maybe others?...
-   *
-   * Too much of a pain to detect all these case, so always re-fill.  I
-   * don't think it's really that slow.
-   */
-
   rwidth = label->misc.xpad * 2;
   rheight = label->misc.ypad * 2;
 
@@ -1383,34 +1358,24 @@ gtk_label_ensure_layout (GtkLabel *label
 	}
 
       pango_layout_set_alignment (label->layout, align);
-    }
 
   if (label->wrap)
     {
       GtkWidgetAuxInfo *aux_info;
       gint longest_paragraph;
       gint width, height;
-      gint real_width;
 
       aux_info = _gtk_widget_get_aux_info (widget, FALSE);
       if (aux_info && aux_info->width > 0)
-	{
 	  pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE);
-	  pango_layout_get_extents (label->layout, NULL, &logical_rect);
-
-	  rwidth += aux_info->width;
-	  rheight += PANGO_PIXELS (logical_rect.height);
-	}
       else
 	{
 	  pango_layout_set_width (label->layout, -1);
 	  pango_layout_get_extents (label->layout, NULL, &logical_rect);
       
 	  width = logical_rect.width;
-	  height = logical_rect.height;
 	  
-	  /* Try to guess a reasonable maximum width
-	   */
+	      /* Try to guess a reasonable maximum width */
 	  longest_paragraph = width;
 
 	  width = MIN (width,
@@ -1421,7 +1386,6 @@ gtk_label_ensure_layout (GtkLabel *label
 
 	  pango_layout_set_width (label->layout, width);
 	  pango_layout_get_extents (label->layout, NULL, &logical_rect);
-	  real_width = logical_rect.width;
 	  height = logical_rect.height;
 	  
 	  /* Unfortunately, the above may leave us with a very unbalanced looking paragraph,
@@ -1440,11 +1404,7 @@ gtk_label_ensure_layout (GtkLabel *label
 		  pango_layout_get_extents (label->layout, NULL, &logical_rect);
 		  
 		  if (logical_rect.height <= height)
-		    {
 		      width = perfect_width;
-		      real_width = logical_rect.width;
-		      height = logical_rect.height;
-		    }
 		  else
 		    {
 		      gint mid_width = (perfect_width + width) / 2;
@@ -1455,35 +1415,17 @@ gtk_label_ensure_layout (GtkLabel *label
 			  pango_layout_get_extents (label->layout, NULL, &logical_rect);
 
 			  if (logical_rect.height <= height)
-			    {
 			      width = mid_width;
-			      real_width = logical_rect.width;
-			      height = logical_rect.height;
 			    }
 			}
 		    }
 		}
-	    }
 	  pango_layout_set_width (label->layout, width);
-
-	  rwidth += PANGO_PIXELS (real_width);
-	  rheight += PANGO_PIXELS (height);
 	}
     }
   else				/* !label->wrap */
-    {
       pango_layout_set_width (label->layout, -1);
-      pango_layout_get_extents (label->layout, NULL, &logical_rect);
-
-      rwidth += PANGO_PIXELS (logical_rect.width);
-      rheight += PANGO_PIXELS (logical_rect.height);
     }
-
-  if (widthp)
-    *widthp = rwidth;
-
-  if (heightp)
-    *heightp = rheight;
 }
 
 static void
@@ -1492,13 +1434,53 @@ gtk_label_size_request (GtkWidget      *
 {
   GtkLabel *label;
   gint width, height;
+  PangoRectangle logical_rect;
+  GtkWidgetAuxInfo *aux_info;
   
   g_return_if_fail (GTK_IS_LABEL (widget));
   g_return_if_fail (requisition != NULL);
   
   label = GTK_LABEL (widget);
+
+  /*
+   * There are a number of conditions which will necessitate re-filling
+   * our text, potentially changing the size request.
+   *
+   *     1. text changed.
+   *     2. wrapping has been turned on or off
+   *     3. font changed.
+   *
+   * These have been detected elsewhere, and label->layout will be NULL,
+   * if one of the above has occured.
+   *
+   * Additionally, though, if word wrap is on, and gtk_widget_set_usize()
+   * has been called to explicitely set the width of the widget, then the
+   * requested height will depend on the width, which is a function of:
+   *
+   *   - The width set on the widget
+   *   - the padding of the widget (xpad, set by gtk_misc_set_padding)
+   *
+   * We don't actually detect this, instead we just clear the layout
+   * whenever we're wrapping and have a usize.
+   */
+
+  if (label->wrap && _gtk_widget_get_aux_info (widget, FALSE))
+    gtk_label_clear_layout (label);
+
+  gtk_label_ensure_layout (label);
+
+  width = label->misc.xpad * 2;
+  height = label->misc.ypad * 2;
+
+  pango_layout_get_extents (label->layout, NULL, &logical_rect);
+  
+  aux_info = _gtk_widget_get_aux_info (widget, FALSE);
+  if (label->wrap && aux_info && aux_info->width > 0)
+    width += aux_info->width;
+  else 
+    width += PANGO_PIXELS (logical_rect.width);
 
-  gtk_label_ensure_layout (label, &width, &height);
+  height += PANGO_PIXELS (logical_rect.height);
 
   requisition->width = width;
   requisition->height = height;
@@ -1658,7 +1640,7 @@ gtk_label_draw_cursor (GtkLabel  *label,
 
       widget_direction = gtk_widget_get_direction (widget);
 
-      gtk_label_ensure_layout (label, NULL, NULL);
+      gtk_label_ensure_layout (label);
       
       pango_layout_get_cursor_pos (label->layout, label->select_info->selection_end,
 				   &strong_pos, &weak_pos);
@@ -1726,7 +1708,7 @@ gtk_label_expose (GtkWidget      *widget
   
   label = GTK_LABEL (widget);
 
-  gtk_label_ensure_layout (label, NULL, NULL);
+  gtk_label_ensure_layout (label);
   
   if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_MAPPED (widget) &&
       label->text && (*label->text != '\0'))
@@ -2095,7 +2077,7 @@ get_layout_index (GtkLabel *label,
 
   *index = 0;
   
-  gtk_label_ensure_layout (label, NULL, NULL);
+  gtk_label_ensure_layout (label);
   
   window_to_layout_coords (label, &x, &y);
 
@@ -2620,7 +2602,7 @@ gtk_label_get_layout (GtkLabel *label)
 {
   g_return_val_if_fail (GTK_IS_LABEL (label), NULL);
 
-  gtk_label_ensure_layout (label, NULL, NULL);
+  gtk_label_ensure_layout (label);
 
   return label->layout;
 }
@@ -2754,7 +2736,7 @@ get_better_cursor (GtkLabel *label,
 		"gtk-split-cursor", &split_cursor,
 		NULL);
 
-  gtk_label_ensure_layout (label, NULL, NULL);
+  gtk_label_ensure_layout (label);
   
   pango_layout_get_cursor_pos (label->layout, index,
 			       &strong_pos, &weak_pos);
@@ -2794,7 +2776,7 @@ gtk_label_move_logically (GtkLabel *labe
       gint n_attrs;
       gint length;
 
-      gtk_label_ensure_layout (label, NULL, NULL);
+      gtk_label_ensure_layout (label);
       
       length = g_utf8_strlen (label->label, -1);
 
@@ -2838,7 +2820,7 @@ gtk_label_move_visually (GtkLabel *label
       gboolean split_cursor;
       gboolean strong;
 
-      gtk_label_ensure_layout (label, NULL, NULL);
+      gtk_label_ensure_layout (label);
 
       g_object_get (gtk_widget_get_settings (GTK_WIDGET (label)),
 		    "gtk-split-cursor", &split_cursor,
@@ -2892,7 +2874,7 @@ gtk_label_move_forward_word (GtkLabel *l
       PangoLogAttr *log_attrs;
       gint n_attrs;
 
-      gtk_label_ensure_layout (label, NULL, NULL);
+      gtk_label_ensure_layout (label);
       
       pango_layout_get_log_attrs (label->layout, &log_attrs, &n_attrs);
       
@@ -2923,7 +2905,7 @@ gtk_label_move_backward_word (GtkLabel *
       PangoLogAttr *log_attrs;
       gint n_attrs;
 
-      gtk_label_ensure_layout (label, NULL, NULL);
+      gtk_label_ensure_layout (label);
       
       pango_layout_get_log_attrs (label->layout, &log_attrs, &n_attrs);
       




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