[gtk/wip/otte/for-main] label: word-char wrapping should word-wrap for natural size
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/for-main] label: word-char wrapping should word-wrap for natural size
- Date: Mon, 13 Dec 2021 13:50:59 +0000 (UTC)
commit 5face79cd06fb0afe20505ed2521db9e6c52e894
Author: Benjamin Otte <otte redhat com>
Date: Mon Dec 13 14:49:39 2021 +0100
label: word-char wrapping should word-wrap for natural size
Testcase added
Fixes #4535
gtk/gtklabel.c | 55 +++++++++++++++-------
.../label-wrap-word-char-natural-size.ref.ui | 24 ++++++++++
.../reftests/label-wrap-word-char-natural-size.ui | 26 ++++++++++
testsuite/reftests/meson.build | 2 +
4 files changed, 89 insertions(+), 18 deletions(-)
---
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index b3744ae838..46af96c7b0 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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkWindow">
+ <property name="default-width">300</property>
+ <property name="default-height">300</property>
+ <child>
+ <object class="GtkBox">
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label">two
+lines</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label">unwrapped</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkWindow">
+ <property name="default-width">300</property>
+ <property name="default-height">300</property>
+ <child>
+ <object class="GtkBox">
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="label">two
+lines</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="label">unwrapped</property>
+ <property name="wrap">1</property>
+ <property name="wrap-mode">word-char</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]