[gtk/wip/otte/for-main] label: word-char wrapping should word-wrap for natural size




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]