diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index a71791f4a5..9af80f43a9 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -1158,6 +1158,34 @@ get_height_for_width (GtkLabel *self, g_object_unref (layout); } +static int +my_pango_layout_get_width_for_height (PangoLayout *layout, + int for_height, + int min, + int max) +{ + int mid, text_width, text_height; + + min = PANGO_PIXELS_CEIL (min); + max = PANGO_PIXELS_CEIL (max); + + while (min < max) + { + mid = (min + max) / 2; + pango_layout_set_width (layout, mid * PANGO_SCALE); + pango_layout_get_size (layout, &text_width, &text_height); + text_width = PANGO_PIXELS_CEIL (text_width); + if (text_width > mid) + min = mid = text_width; + else if (text_height > for_height) + min = mid + 1; + else + max = mid; + } + + return min * PANGO_SCALE; +} + static void get_width_for_height (GtkLabel *self, int height, @@ -1183,13 +1211,15 @@ get_width_for_height (GtkLabel *self, } else { - int min, max, mid, text_width, text_height; + int min, max; /* Can't use a measuring layout here, because we need to force * ellipsizing mode */ gtk_label_ensure_layout (self); layout = pango_layout_copy (self->layout); pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE); + if (self->wrap_mode == PANGO_WRAP_WORD_CHAR) + pango_layout_set_wrap (layout, PANGO_WRAP_WORD); /* binary search for the smallest width where the height doesn't * eclipse the given height */ @@ -1198,23 +1228,7 @@ get_width_for_height (GtkLabel *self, pango_layout_set_width (layout, -1); pango_layout_get_size (layout, &max, NULL); - min = PANGO_PIXELS_CEIL (min); - max = PANGO_PIXELS_CEIL (max); - while (min < max) - { - mid = (min + max) / 2; - pango_layout_set_width (layout, mid * PANGO_SCALE); - pango_layout_get_size (layout, &text_width, &text_height); - text_width = PANGO_PIXELS_CEIL (text_width); - if (text_width > mid) - min = mid = text_width; - else if (text_height > height) - min = mid + 1; - else - max = mid; - } - - *natural_width = min * PANGO_SCALE; + *natural_width = my_pango_layout_get_width_for_height (layout, height, min, max); if (self->ellipsize != PANGO_ELLIPSIZE_NONE) { @@ -1223,6 +1237,11 @@ get_width_for_height (GtkLabel *self, pango_layout_get_size (layout, minimum_width, NULL); *minimum_width = MAX (*minimum_width, minimum_default); } + else if (self->wrap_mode == PANGO_WRAP_WORD_CHAR) + { + pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); + *minimum_width = my_pango_layout_get_width_for_height (layout, height, min, *natural_width); + } else { *minimum_width = *natural_width; diff --git a/testsuite/reftests/label-wrap-word-char-natural-size.ref.ui b/testsuite/reftests/label-wrap-word-char-natural-size.ref.ui new file mode 100644 index 0000000000..b8a08efc62 --- /dev/null +++ b/testsuite/reftests/label-wrap-word-char-natural-size.ref.ui @@ -0,0 +1,24 @@ + + + + 300 + 300 + + + center + center + + + two +lines + + + + + unwrapped + + + + + + diff --git a/testsuite/reftests/label-wrap-word-char-natural-size.ui b/testsuite/reftests/label-wrap-word-char-natural-size.ui new file mode 100644 index 0000000000..929e5a3089 --- /dev/null +++ b/testsuite/reftests/label-wrap-word-char-natural-size.ui @@ -0,0 +1,26 @@ + + + + 300 + 300 + + + center + center + + + two +lines + + + + + unwrapped + 1 + word-char + + + + + + diff --git a/testsuite/reftests/meson.build b/testsuite/reftests/meson.build index 587fa252ac..0b6d0fa84a 100644 --- a/testsuite/reftests/meson.build +++ b/testsuite/reftests/meson.build @@ -412,6 +412,8 @@ testdata = [ 'label-width-chars-dont-shrink.ui', 'label-wrap-width-chars.ref.ui', 'label-wrap-width-chars.ui', + 'label-wrap-word-char-natural-size.ref.ui', + 'label-wrap-word-char-natural-size.ui', 'label-wrapped-huge-max-width-chars.ref.ui', 'label-wrapped-huge-max-width-chars.ui', # this seems to make assumptions on text positioning