label performance patch
- From: Alex Larsson <alexl redhat com>
- To: <gtk-devel-list gnome org>
- Subject: label performance patch
- Date: Tue, 13 Nov 2001 23:46:08 -0500 (EST)
GtkLabel keeps reflowing wrapped labels all the time. Here is a fix:
Index: gtklabel.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtklabel.c,v
retrieving revision 1.107
diff -u -p -r1.107 gtklabel.c
--- gtklabel.c 2001/11/02 17:18:01 1.107
+++ gtklabel.c 2001/11/14 04:42:49
@@ -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;
@@ -1334,10 +1330,10 @@ gtk_label_ensure_layout (GtkLabel *label
* our text:
*
* 1. text changed.
- * 2. justification changed either from to to GTK_JUSTIFY_FILL.
+ * 2. justification changed either from or to GTK_JUSTIFY_FILL.
* 3. font changed.
*
- * These have been detected elsewhere, and label->words will be zero,
+ * These have been detected elsewhere, and label->layout will be NULL,
* if one of the above has occured.
*
* Additionally, though, if GTK_JUSTIFY_FILL, we need to re-fill if:
@@ -1346,8 +1342,8 @@ gtk_label_ensure_layout (GtkLabel *label
* 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.
+ * (un)Fortunately, PangoLayout does not currently support GTK_JUSTIFY_FILL,
+ * so this is not an issue.
*/
rwidth = label->misc.xpad * 2;
@@ -1383,107 +1379,74 @@ 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
+ if (label->wrap)
{
- pango_layout_set_width (label->layout, -1);
- pango_layout_get_extents (label->layout, NULL, &logical_rect);
-
- width = logical_rect.width;
- height = logical_rect.height;
+ GtkWidgetAuxInfo *aux_info;
+ gint longest_paragraph;
+ gint width, height;
- /* Try to guess a reasonable maximum width
- */
- longest_paragraph = width;
-
- width = MIN (width,
- PANGO_SCALE * gdk_string_width (gtk_style_get_font (GTK_WIDGET (label)->style),
- "This long string gives a good enough length for any line to have."));
- width = MIN (width,
- PANGO_SCALE * (gdk_screen_width () + 1) / 2);
-
- 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,
- * so we try short search for a narrower width that leaves us with the same height
- */
- if (longest_paragraph > 0)
+ 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);
+ else
{
- gint nlines, perfect_width;
+ pango_layout_set_width (label->layout, -1);
+ pango_layout_get_extents (label->layout, NULL, &logical_rect);
- nlines = pango_layout_get_line_count (label->layout);
- perfect_width = (longest_paragraph + nlines - 1) / nlines;
+ width = logical_rect.width;
+
+ /* Try to guess a reasonable maximum width */
+ longest_paragraph = width;
+
+ width = MIN (width,
+ PANGO_SCALE * gdk_string_width (gtk_style_get_font (GTK_WIDGET (label)->style),
+ "This long string gives a good enough length for any line to have."));
+ width = MIN (width,
+ PANGO_SCALE * (gdk_screen_width () + 1) / 2);
- if (perfect_width < width)
+ pango_layout_set_width (label->layout, width);
+ pango_layout_get_extents (label->layout, NULL, &logical_rect);
+ height = logical_rect.height;
+
+ /* Unfortunately, the above may leave us with a very unbalanced looking paragraph,
+ * so we try short search for a narrower width that leaves us with the same height
+ */
+ if (longest_paragraph > 0)
{
- pango_layout_set_width (label->layout, perfect_width);
- pango_layout_get_extents (label->layout, NULL, &logical_rect);
+ gint nlines, perfect_width;
- if (logical_rect.height <= height)
- {
- width = perfect_width;
- real_width = logical_rect.width;
- height = logical_rect.height;
- }
- else
+ nlines = pango_layout_get_line_count (label->layout);
+ perfect_width = (longest_paragraph + nlines - 1) / nlines;
+
+ if (perfect_width < width)
{
- gint mid_width = (perfect_width + width) / 2;
-
- if (mid_width > perfect_width)
+ pango_layout_set_width (label->layout, perfect_width);
+ pango_layout_get_extents (label->layout, NULL, &logical_rect);
+
+ if (logical_rect.height <= height)
+ width = perfect_width;
+ else
{
- pango_layout_set_width (label->layout, mid_width);
- pango_layout_get_extents (label->layout, NULL, &logical_rect);
-
- if (logical_rect.height <= height)
+ gint mid_width = (perfect_width + width) / 2;
+
+ if (mid_width > perfect_width)
{
- width = mid_width;
- real_width = logical_rect.width;
- height = logical_rect.height;
+ pango_layout_set_width (label->layout, mid_width);
+ pango_layout_get_extents (label->layout, NULL, &logical_rect);
+
+ if (logical_rect.height <= height)
+ width = mid_width;
}
}
}
}
+ pango_layout_set_width (label->layout, width);
}
- 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);
}
- 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 +1455,28 @@ 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);
+
+ gtk_label_ensure_layout (label);
- gtk_label_ensure_layout (label, &width, &height);
+ 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);
+
+ height += PANGO_PIXELS (logical_rect.height);
requisition->width = width;
requisition->height = height;
@@ -1658,7 +1636,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 +1704,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 +2073,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 +2598,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 +2732,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 +2772,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 +2816,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 +2870,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 +2901,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]