diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index e94615473d..661902a275 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -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, diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 78a282829b..6360fa16c7 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -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); } /** diff --git a/testsuite/reftests/gtk-reftest.c b/testsuite/reftests/gtk-reftest.c index f247ac4ef1..2bf3fcc5f8 100644 --- a/testsuite/reftests/gtk-reftest.c +++ b/testsuite/reftests/gtk-reftest.c @@ -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 (); diff --git a/testsuite/reftests/label-max-width-chars-and-halign-and-infinite-width.ref.ui b/testsuite/reftests/label-max-width-chars-and-halign-and-infinite-width.ref.ui new file mode 100644 index 0000000000..68c5d0a112 --- /dev/null +++ b/testsuite/reftests/label-max-width-chars-and-halign-and-infinite-width.ref.ui @@ -0,0 +1,20 @@ + + + + 0 + 200 + + + start + end + 0 + ABCDE +ABCD + 4 + + + + + + + diff --git a/testsuite/reftests/label-max-width-chars-and-halign-and-infinite-width.ui b/testsuite/reftests/label-max-width-chars-and-halign-and-infinite-width.ui new file mode 100644 index 0000000000..10dd7d2d5a --- /dev/null +++ b/testsuite/reftests/label-max-width-chars-and-halign-and-infinite-width.ui @@ -0,0 +1,20 @@ + + + + 0 + 200 + + + start + end + ABCDE ABCD + 0.0 + 1 + 4 + + + + + + + diff --git a/testsuite/reftests/meson.build b/testsuite/reftests/meson.build index d4322f5c63..4a84e1de72 100644 --- a/testsuite/reftests/meson.build +++ b/testsuite/reftests/meson.build @@ -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' ] diff --git a/testsuite/reftests/reftest-snapshot.c b/testsuite/reftests/reftest-snapshot.c index 1787c73ab8..167311630e 100644 --- a/testsuite/reftests/reftest-snapshot.c +++ b/testsuite/reftests/reftest-snapshot.c @@ -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);