[PATCH] Fix a number of GtkLabel extended layout issues
- From: Paolo Bonzini <bonzini gnu org>
- To: gtk-devel-list gnome org, mathias hasselmann gmx de
- Subject: [PATCH] Fix a number of GtkLabel extended layout issues
- Date: Thu, 04 Sep 2008 09:44:35 +0200
This is my first patch, so sorry if I get the submission process wrong.
This patch is meant for extended-layout branch, which hasn't been
merged in a year.
It fixes a number of issues with GtkLabel's extended layout support
which are uncovered by my next patch:
1) the height_for_width/width_for_height implementations worked by
computing the height in a separate PangoLayout object. However, they
did not record the desired wrapping width anywhere. This patch fixes it
by recording it in GtkLabelPrivate.
A side issue is that layout could be done before realizing. Then, upon
realizing, gtk_label_style_set is called and it invalidates the wrapping
with. This patch fixes it by not invalidating the wrapping width if it
was set by height_for_width/width_for_height.
2) For wrapping labels, gtk_label_extended_layout_get_natural_size was
destroying the wrapping width set by height_for_width/width_for_height.
This happened because it uses gtk_label_size_request which in turn
clears the layout in the case of a wrapping label.
This patch fixes it by preserving priv->wrap_width around
get_natural_size. I also modified a little the code to make it more
explicit that gtk_label_size_request computes a fresh layout for
wrapping labels.
However, I'm actually thinking of disabling completely
height_for_width/width_for_height for non-wrapping labels (right now
it's accepted for elliipsizing labels), as well as disabling
get_natural_size for wrapping labels. In the meanwhile, this patch
makes things work properly.
Ok? (I obviously require someone to commit it for me if accepted).
Paolo
2008-09-04 Paolo Bonzini <bonzini gnu org>
* gtk/gtklabel.c: Set priv->wrap_width in the extended-layout
height_for_width code. Preserve it in get_natural_size
because when label->wrap is set, gtk_label_size_request will
invalidate the layout and hence modify priv->wrap_width; for
the same reason, don't bother setting the layout's width to -1
if the label is wrapping. Add priv->wrap_at_container_size
so that changing the style (e.g. upon realization) does not
invalidate the layout.
---
ChangeLog.gtk-extended-layout | 11 +++++++++
gtk/gtklabel.c | 48 ++++++++++++++++++++++++++++++++++------
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 2082d6a..fac4b7f 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -60,7 +60,9 @@ typedef struct
gint width_chars;
gint max_width_chars;
gint baseline_offset;
- gboolean full_size;
+
+ guint full_size : 1;
+ guint wrap_at_container_size : 1;
}
GtkLabelPrivate;
@@ -826,6 +828,8 @@ gtk_label_init (GtkLabel *label)
priv->width_chars = -1;
priv->max_width_chars = -1;
priv->wrap_width = -1;
+ priv->wrap_at_container_size = FALSE;
+
label->label = NULL;
label->jtype = GTK_JUSTIFY_LEFT;
@@ -1987,6 +1991,7 @@ gtk_label_invalidate_wrap_width (GtkLabel *label)
priv = GTK_LABEL_GET_PRIVATE (label);
priv->wrap_width = -1;
+ priv->wrap_at_container_size = FALSE;
}
static gint
@@ -2366,6 +2371,7 @@ gtk_label_style_set (GtkWidget *widget,
GtkStyle *previous_style)
{
GtkLabel *label;
+ GtkLabelPrivate *priv;
g_return_if_fail (GTK_IS_LABEL (widget));
@@ -2373,7 +2379,10 @@ gtk_label_style_set (GtkWidget *widget,
/* We have to clear the layout, fonts etc. may have changed */
gtk_label_clear_layout (label);
- gtk_label_invalidate_wrap_width (label);
+
+ priv = GTK_LABEL_GET_PRIVATE (label);
+ if (!priv->wrap_at_container_size)
+ gtk_label_invalidate_wrap_width (label);
}
static void
@@ -4379,19 +4388,26 @@ static gint
gtk_label_extended_layout_get_size_for_allocation (GtkExtendedLayout *layout,
gint size)
{
- GtkLabel *label = GTK_LABEL (layout);
- gdouble angle = gtk_label_get_angle (label);
+ GtkLabel *label;
+ GtkLabelPrivate *priv;
+ gdouble angle;
PangoLayout *tmp;
- // this test is slightly more tolerant than the get_features test
+ label = GTK_LABEL (layout);
+ priv = GTK_LABEL_GET_PRIVATE (label);
+
+ /* This test is valid for both width_for_height, and height_for_width. */
+ angle = gtk_label_get_angle (label);
g_assert (0 == (((gint)angle) % 90));
gtk_label_ensure_layout (label);
tmp = pango_layout_copy (label->layout);
pango_layout_set_width (tmp, PANGO_SCALE * size);
+ priv->wrap_width = PANGO_SCALE * size;
+ priv->wrap_at_container_size = TRUE;
+
pango_layout_get_pixel_size (tmp, NULL, &size);
g_object_unref (tmp);
-
return size;
}
@@ -4400,24 +4416,40 @@ gtk_label_extended_layout_get_natural_size (GtkExtendedLayout *layout,
GtkRequisition *requisition)
{
GtkLabel *label;
+ GtkLabelPrivate *priv;
gboolean ellipsize;
+ gint wrap_width;
PangoLayout *tmp;
label = GTK_LABEL (layout);
+ priv = GTK_LABEL_GET_PRIVATE (label);
gtk_label_ensure_layout (label);
ellipsize = label->ellipsize;
label->ellipsize = PANGO_ELLIPSIZE_NONE;
+ wrap_width = priv->wrap_width;
tmp = label->layout;
- label->layout = pango_layout_copy (tmp);
- pango_layout_set_width (label->layout, -1);
+ /* See comment in gtk_label_size_request. */
+
+ if (label->wrap)
+ {
+ g_object_ref (label->layout);
+ gtk_label_clear_layout (label);
+ }
+ else
+ {
+ label->layout = pango_layout_copy (tmp);
+ pango_layout_set_width (label->layout, -1);
+ }
+
gtk_label_size_request (GTK_WIDGET (label), requisition);
g_object_unref (label->layout);
label->ellipsize = ellipsize;
label->layout = tmp;
+ priv->wrap_width = wrap_width;
}
static gint
--
1.5.5
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]