mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 10:50:10 +00:00
label: Redo get_preferred_width/height()
This is important for size groups mostly, but also has some small fixes. The label-sizing reftest as been updated accordingly.
This commit is contained in:
parent
f55fe7e20b
commit
aba0c5cc3b
126
gtk/gtklabel.c
126
gtk/gtklabel.c
@ -3439,23 +3439,6 @@ gtk_label_ensure_layout (GtkLabel *label)
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
get_single_line_height (GtkWidget *widget,
|
||||
PangoLayout *layout)
|
||||
{
|
||||
PangoContext *context;
|
||||
PangoFontMetrics *metrics;
|
||||
gint ascent, descent;
|
||||
|
||||
context = pango_layout_get_context (layout);
|
||||
metrics = get_font_metrics (context, widget);
|
||||
ascent = pango_font_metrics_get_ascent (metrics);
|
||||
descent = pango_font_metrics_get_descent (metrics);
|
||||
pango_font_metrics_unref (metrics);
|
||||
|
||||
return ascent + descent;
|
||||
}
|
||||
|
||||
static GtkSizeRequestMode
|
||||
gtk_label_get_request_mode (GtkWidget *widget)
|
||||
{
|
||||
@ -3512,11 +3495,12 @@ get_char_pixels (GtkWidget *label,
|
||||
|
||||
static void
|
||||
gtk_label_get_preferred_layout_size (GtkLabel *label,
|
||||
PangoRectangle *required,
|
||||
PangoRectangle *natural)
|
||||
PangoRectangle *widest,
|
||||
PangoRectangle *highest)
|
||||
{
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
PangoLayout *layout;
|
||||
gint char_pixels;
|
||||
|
||||
/* "width-chars" Hard-coded minimum width:
|
||||
* - minimum size should be MAX (width-chars, strlen ("..."));
|
||||
@ -3537,44 +3521,44 @@ gtk_label_get_preferred_layout_size (GtkLabel *label,
|
||||
/* Start off with the pixel extents of an as-wide-as-possible layout */
|
||||
layout = gtk_label_get_measuring_layout (label, NULL, -1);
|
||||
|
||||
pango_layout_get_extents (layout, NULL, natural);
|
||||
natural->x = natural->y = 0;
|
||||
|
||||
if (priv->wrap)
|
||||
natural->height = get_single_line_height (GTK_WIDGET (label), layout);
|
||||
if (priv->width_chars > -1 || priv->max_width_chars > -1)
|
||||
char_pixels = get_char_pixels (GTK_WIDGET (label), layout);
|
||||
else
|
||||
char_pixels = 0;
|
||||
|
||||
pango_layout_get_extents (layout, NULL, widest);
|
||||
widest->width = MAX (widest->width, char_pixels * priv->width_chars);
|
||||
widest->x = widest->y = 0;
|
||||
|
||||
if (priv->ellipsize || priv->wrap)
|
||||
{
|
||||
/* a layout with width 0 will be as small as humanly possible */
|
||||
layout = gtk_label_get_measuring_layout (label, layout, 0);
|
||||
layout = gtk_label_get_measuring_layout (label,
|
||||
layout,
|
||||
priv->width_chars > -1 ? char_pixels * priv->width_chars
|
||||
: 0);
|
||||
|
||||
pango_layout_get_extents (layout, NULL, required);
|
||||
pango_layout_get_extents (layout, NULL, highest);
|
||||
highest->width = MAX (highest->width, char_pixels * priv->width_chars);
|
||||
highest->x = highest->y = 0;
|
||||
|
||||
/* can happen when Pango decides to ellipsize text */
|
||||
if (required->width > natural->width)
|
||||
required->width = natural->width;
|
||||
|
||||
required->x = required->y = 0;
|
||||
required->height = natural->height;
|
||||
if (priv->max_width_chars > -1 && widest->width > char_pixels * priv->max_width_chars)
|
||||
{
|
||||
layout = gtk_label_get_measuring_layout (label,
|
||||
layout,
|
||||
MAX (highest->width, char_pixels * priv->max_width_chars));
|
||||
pango_layout_get_extents (layout, NULL, widest);
|
||||
widest->width = MAX (widest->width, char_pixels * priv->width_chars);
|
||||
widest->x = widest->y = 0;
|
||||
}
|
||||
g_assert (widest->width >= highest->width);
|
||||
}
|
||||
else
|
||||
{
|
||||
*required = *natural;
|
||||
*highest = *widest;
|
||||
}
|
||||
|
||||
if (priv->width_chars > -1 || priv->max_width_chars > -1)
|
||||
{
|
||||
gint char_pixels;
|
||||
|
||||
char_pixels = get_char_pixels (GTK_WIDGET (label), layout);
|
||||
|
||||
if (priv->width_chars > -1)
|
||||
required->width = MAX (required->width, char_pixels * priv->width_chars);
|
||||
|
||||
if (priv->max_width_chars > -1)
|
||||
natural->width = MIN (natural->width, priv->max_width_chars * char_pixels);
|
||||
natural->width = MAX (natural->width, required->width);
|
||||
}
|
||||
g_assert (widest->height <= highest->height);
|
||||
|
||||
g_object_unref (layout);
|
||||
}
|
||||
@ -3587,36 +3571,28 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = label->priv;
|
||||
PangoRectangle required_rect;
|
||||
PangoRectangle natural_rect;
|
||||
PangoRectangle widest_rect;
|
||||
PangoRectangle highest_rect;
|
||||
GtkBorder border;
|
||||
|
||||
gtk_label_get_preferred_layout_size (label, &required_rect, &natural_rect);
|
||||
gtk_label_get_preferred_layout_size (label, &widest_rect, &highest_rect);
|
||||
|
||||
/* Now that we have minimum and natural sizes in pango extents, apply a possible transform */
|
||||
if (priv->have_transform)
|
||||
{
|
||||
PangoLayout *copy;
|
||||
PangoContext *context;
|
||||
const PangoMatrix *matrix;
|
||||
|
||||
copy = pango_layout_copy (priv->layout);
|
||||
context = pango_layout_get_context (copy);
|
||||
context = pango_layout_get_context (priv->layout);
|
||||
matrix = pango_context_get_matrix (context);
|
||||
|
||||
pango_layout_set_width (copy, -1);
|
||||
pango_layout_set_ellipsize (copy, PANGO_ELLIPSIZE_NONE);
|
||||
pango_matrix_transform_rectangle (matrix, &widest_rect);
|
||||
pango_matrix_transform_rectangle (matrix, &highest_rect);
|
||||
|
||||
pango_layout_get_extents (copy, NULL, &natural_rect);
|
||||
g_object_unref (copy);
|
||||
|
||||
pango_matrix_transform_rectangle (matrix, &required_rect);
|
||||
pango_matrix_transform_rectangle (matrix, &natural_rect);
|
||||
|
||||
/* Bump the natural size in case of ellipsize to ensure pango has
|
||||
/* Bump the size in case of ellipsize to ensure pango has
|
||||
* enough space in the angles (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).
|
||||
* full size, or it may be that pango needs a fix here).
|
||||
*/
|
||||
if (priv->ellipsize && priv->angle != 0 && priv->angle != 90 &&
|
||||
priv->angle != 180 && priv->angle != 270 && priv->angle != 360)
|
||||
@ -3624,16 +3600,18 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
/* For some reason we only need this at about 110 degrees, and only
|
||||
* when gaining in height
|
||||
*/
|
||||
natural_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
natural_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
widest_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
widest_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
highest_rect.height += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
highest_rect.width += ROTATION_ELLIPSIZE_PADDING * 2 * PANGO_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
required_rect.width = PANGO_PIXELS_CEIL (required_rect.width);
|
||||
required_rect.height = PANGO_PIXELS_CEIL (required_rect.height);
|
||||
widest_rect.width = PANGO_PIXELS_CEIL (widest_rect.width);
|
||||
widest_rect.height = PANGO_PIXELS_CEIL (widest_rect.height);
|
||||
|
||||
natural_rect.width = PANGO_PIXELS_CEIL (natural_rect.width);
|
||||
natural_rect.height = PANGO_PIXELS_CEIL (natural_rect.height);
|
||||
highest_rect.width = PANGO_PIXELS_CEIL (highest_rect.width);
|
||||
highest_rect.height = PANGO_PIXELS_CEIL (highest_rect.height);
|
||||
|
||||
_gtk_misc_get_padding_and_border (GTK_MISC (label), &border);
|
||||
|
||||
@ -3650,15 +3628,15 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
*/
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_VERTICAL,
|
||||
required_rect.height,
|
||||
highest_rect.height,
|
||||
minimum_size, natural_size);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Normal desired width */
|
||||
*minimum_size = required_rect.width;
|
||||
*natural_size = natural_rect.width;
|
||||
*minimum_size = highest_rect.width;
|
||||
*natural_size = widest_rect.width;
|
||||
}
|
||||
|
||||
*minimum_size += border.left + border.right;
|
||||
@ -3677,7 +3655,7 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
*/
|
||||
get_size_for_allocation (label,
|
||||
GTK_ORIENTATION_HORIZONTAL,
|
||||
required_rect.width,
|
||||
widest_rect.width,
|
||||
minimum_size, natural_size);
|
||||
}
|
||||
else
|
||||
@ -3685,8 +3663,8 @@ gtk_label_get_preferred_size (GtkWidget *widget,
|
||||
/* A vertically rotated label does w4h, so return the base
|
||||
* desired height (text length)
|
||||
*/
|
||||
*minimum_size = required_rect.height;
|
||||
*natural_size = natural_rect.height;
|
||||
*minimum_size = widest_rect.height;
|
||||
*natural_size = highest_rect.height;
|
||||
}
|
||||
|
||||
*minimum_size += border.top + border.bottom;
|
||||
|
@ -5457,7 +5457,7 @@ ABCD</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
ABCD</property>
|
||||
<property name="max_width_chars">8</property>
|
||||
<attributes>
|
||||
@ -5476,7 +5476,7 @@ ABCD</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
ABCD</property>
|
||||
<property name="max_width_chars">8</property>
|
||||
<attributes>
|
||||
@ -6099,7 +6099,7 @@ ABCD</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
ABCD</property>
|
||||
<property name="width_chars">4</property>
|
||||
<property name="max_width_chars">8</property>
|
||||
@ -6119,7 +6119,7 @@ ABCD</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
<property name="label" translatable="yes">ABCDE
|
||||
ABCD</property>
|
||||
<property name="width_chars">4</property>
|
||||
<property name="max_width_chars">8</property>
|
||||
|
Loading…
Reference in New Issue
Block a user