Re: label performance patch
- From: Alex Larsson <alexl redhat com>
- To: Owen Taylor <otaylor redhat com>
- Cc: <gtk-devel-list gnome org>
- Subject: Re: label performance patch
- Date: Wed, 14 Nov 2001 12:19:44 -0500 (EST)
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]