Merge branch 'label-sizing' into 'master'

Make label-sizing reftest pass

See merge request 
This commit is contained in:
Benjamin Otte 2021-10-19 00:19:52 +00:00
commit bf5350e13c
7 changed files with 147 additions and 56 deletions

View File

@ -1017,31 +1017,6 @@ gtk_label_get_measuring_layout (GtkLabel *self,
return copy;
}
static void
get_height_for_width (GtkLabel *self,
int width,
int *minimum_height,
int *natural_height,
int *minimum_baseline,
int *natural_baseline)
{
PangoLayout *layout;
int text_height, baseline;
layout = gtk_label_get_measuring_layout (self, NULL, width * PANGO_SCALE);
pango_layout_get_pixel_size (layout, NULL, &text_height);
*minimum_height = text_height;
*natural_height = text_height;
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
*minimum_baseline = baseline;
*natural_baseline = baseline;
g_object_unref (layout);
}
static int
get_char_pixels (GtkWidget *self,
PangoLayout *layout)
@ -1059,6 +1034,44 @@ get_char_pixels (GtkWidget *self,
return MAX (char_width, digit_width);
}
static void
get_height_for_width (GtkLabel *self,
int width,
int *minimum_height,
int *natural_height,
int *minimum_baseline,
int *natural_baseline)
{
PangoLayout *layout;
int text_height, baseline;
width *= PANGO_SCALE;
if (self->max_width_chars > -1)
{
int char_pixels, width_chars;
layout = gtk_label_get_measuring_layout (self, NULL, -1);
char_pixels = get_char_pixels (GTK_WIDGET (self), layout);
if (self->width_chars > self->max_width_chars)
width_chars = self->width_chars;
else
width_chars = self->max_width_chars;
width = MIN (char_pixels * width_chars, width);
}
layout = gtk_label_get_measuring_layout (self, NULL, width);
pango_layout_get_pixel_size (layout, NULL, &text_height);
*minimum_height = text_height;
*natural_height = text_height;
baseline = pango_layout_get_baseline (layout) / PANGO_SCALE;
*minimum_baseline = baseline;
*natural_baseline = baseline;
g_object_unref (layout);
}
static void
gtk_label_get_preferred_layout_size (GtkLabel *self,
PangoRectangle *smallest,

View File

@ -3841,29 +3841,42 @@ gtk_widget_adjust_size_allocation (GtkWidget *widget,
if (priv->halign == GTK_ALIGN_FILL && priv->valign == GTK_ALIGN_FILL)
return;
/* Note that adjust_for_align removes any margins from the
* allocated sizes and possibly limits them to the natural sizes */
if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH)
{
/* Go ahead and request the height for allocated width, note that the internals
* of get_height_for_width will internally limit the for_size to natural size
* when aligning implicitly.
*/
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
&min_width, &natural_width, NULL, NULL);
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL,
allocation->width + priv->margin.left + priv->margin.right,
&min_height, &natural_height, NULL, NULL);
}
else
{
/* Go ahead and request the width for allocated height, note that the internals
* of get_width_for_height will internally limit the for_size to natural size
* when aligning implicitly.
*/
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL, -1,
&min_height, &natural_height, NULL, NULL);
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL,
allocation->height + priv->margin.top + priv->margin.bottom,
&min_width, &natural_width, NULL, NULL);
adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
natural_width - priv->margin.left - priv->margin.right,
&allocation->x,
&allocation->width);
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL,
allocation->width,
&min_height, &natural_height, NULL, NULL);
adjust_for_align (priv->valign,
natural_height - priv->margin.top - priv->margin.bottom,
&allocation->y,
&allocation->height);
}
else
{
gtk_widget_measure (widget, GTK_ORIENTATION_VERTICAL,
allocation->width + priv->margin.left + priv->margin.right,
&min_height, &natural_height, NULL, NULL);
adjust_for_align (priv->valign,
natural_height - priv->margin.top - priv->margin.bottom,
&allocation->y,
&allocation->height);
gtk_widget_measure (widget, GTK_ORIENTATION_HORIZONTAL,
allocation->height,
&min_width, &natural_width, NULL, NULL);
adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
natural_width - priv->margin.left - priv->margin.right,
&allocation->x,
&allocation->width);
}
#ifdef G_ENABLE_CONSISTENCY_CHECKS
@ -3877,16 +3890,6 @@ gtk_widget_adjust_size_allocation (GtkWidget *widget,
allocation->width, allocation->height,
min_width, min_height);
#endif
/* Now that we have the right natural height and width, go ahead and remove any margins from the
* allocated sizes and possibly limit them to the natural sizes */
adjust_for_align (effective_align (priv->halign, _gtk_widget_get_direction (widget)),
natural_width - priv->margin.left - priv->margin.right,
&allocation->x,
&allocation->width);
adjust_for_align (priv->valign,
natural_height - priv->margin.top - priv->margin.bottom,
&allocation->y,
&allocation->height);
}
/**

View File

@ -292,6 +292,36 @@ save_image (GdkTexture *texture,
g_free (filename);
}
static void
save_node (GskRenderNode *node,
const char *test_name,
const char *extension)
{
GError *error = NULL;
char *filename;
gboolean ret;
GBytes *bytes;
filename = get_output_file (test_name, extension, &error);
if (filename == NULL)
{
g_test_message ("Not storing test result node: %s", error->message);
g_error_free (error);
return;
}
g_test_message ("Storing test result node at %s", filename);
bytes = gsk_render_node_serialize (node);
ret = g_file_set_contents (filename,
g_bytes_get_data (bytes, NULL),
g_bytes_get_size (bytes),
NULL);
g_assert_true (ret);
g_bytes_unref (bytes);
g_free (filename);
}
static void
test_ui_file (GFile *file)
{
@ -335,6 +365,8 @@ test_ui_file (GFile *file)
save_image (reference_image, ui_file, ".ref.png");
if (diff_image)
{
save_node (g_object_get_data (G_OBJECT (ui_image), "source-render-node"), ui_file, ".out.node");
save_node (g_object_get_data (G_OBJECT (reference_image), "source-render-node"), ui_file, ".ref.node");
save_image (diff_image, ui_file, ".diff.png");
g_object_unref (diff_image);
g_test_fail ();

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" >
<property name="decorated">0</property>
<property name="width-request">200</property>
<child>
<object class="GtkLabel" >
<property name="halign">start</property>
<property name="valign">end</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">ABCDE
ABCD</property>
<property name="max_width_chars">4</property>
<attributes>
<attribute name="font-desc" value="Monospace"></attribute>
</attributes>
</object>
</child>
</object>
</interface>

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkWindow" >
<property name="decorated">0</property>
<property name="width-request">200</property>
<child>
<object class="GtkLabel" >
<property name="halign">start</property>
<property name="valign">end</property>
<property name="label" translatable="yes">ABCDE ABCD</property>
<property name="xalign">0.0</property>
<property name="wrap">1</property>
<property name="max-width-chars">4</property>
<attributes>
<attribute name="font-desc" value="Monospace"></attribute>
</attributes>
</object>
</child>
</object>
</interface>

View File

@ -314,6 +314,8 @@ testdata = [
'label-fonts.css',
'label-fonts.ref.ui',
'label-fonts.ui',
'label-max-width-chars-and-halign-and-infinite-width.ui',
'label-max-width-chars-and-halign-and-infinite-width.ref.ui',
'label-shadows.css',
'label-shadows.ref.ui',
'label-shadows.ui',
@ -478,8 +480,6 @@ testdata = [
# These need to be fixed but the issue hasn't been tracked down.
xfails = [
'sizegroups-evolution-identity-page.ui',
# these depend on details of text layout
'label-sizing.ui',
# the NGL renderer can't deal with non-integer sizes
'border-half-pixel.ui'
]

View File

@ -248,7 +248,10 @@ draw_paintable (GdkPaintable *paintable,
gdk_paintable_get_intrinsic_width (paintable),
gdk_paintable_get_intrinsic_height (paintable)
));
gsk_render_node_unref (node);
g_object_set_data_full (G_OBJECT (texture),
"source-render-node",
node,
(GDestroyNotify) gsk_render_node_unref);
g_signal_handlers_disconnect_by_func (paintable, draw_paintable, out_texture);