]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
label-freetype: Ensure font metrics are up to date when querying dimensions
authorRay Strode <rstrode@redhat.com>
Thu, 28 Dec 2023 18:28:46 +0000 (13:28 -0500)
committerRay Strode <rstrode@redhat.com>
Thu, 28 Dec 2023 18:39:19 +0000 (13:39 -0500)
If code calls ply_label_get_width without ply_label_show or some other
call that forces the dimensions to be computed first, then the returned
width will be wrong.

This commit makes the freetype plugin look more like the pango plugin
where the size will computed on demand when querying the width, if
necessary.

src/plugins/controls/label-freetype/plugin.c

index 17cb134eeca55a319174d9d043326ec5a67a62aa..b0e88f9987570dacb494d726f2e19f8e570e04f8 100644 (file)
@@ -102,6 +102,7 @@ struct _ply_label_plugin_control
 
         uint32_t              is_hidden : 1;
         uint32_t              is_monospaced : 1;
+        uint32_t              needs_size_update : 1;
 };
 
 typedef enum
@@ -117,6 +118,9 @@ static void load_glyphs (ply_label_plugin_control_t *label,
                          ply_load_glyph_action_t     action,
                          ply_pixel_buffer_t         *pixel_buffer);
 
+static void size_control (ply_label_plugin_control_t *label,
+                          bool                        force);
+
 /* Query fontconfig, if available, for the default font. */
 static const char *
 query_fc_match ()
@@ -236,12 +240,14 @@ destroy_control (ply_label_plugin_control_t *label)
 static long
 get_width_of_control (ply_label_plugin_control_t *label)
 {
+        size_control (label, false);
         return label->area.width;
 }
 
 static long
 get_height_of_control (ply_label_plugin_control_t *label)
 {
+        size_control (label, false);
         return label->area.height;
 }
 
@@ -277,8 +283,17 @@ load_glyph (ply_label_plugin_control_t *label,
 }
 
 static void
-size_control (ply_label_plugin_control_t *label)
+size_control (ply_label_plugin_control_t *label,
+              bool                        force)
 {
+        if (!force && !label->needs_size_update)
+                return;
+
+        if (!force && label->is_hidden) {
+                label->needs_size_update = true;
+                return;
+        }
+
         if (label->rich_text == NULL && label->text == NULL) {
                 label->area.width = 0;
                 label->area.height = 0;
@@ -286,6 +301,7 @@ size_control (ply_label_plugin_control_t *label)
         }
 
         load_glyphs (label, PLY_LOAD_GLYPH_ACTION_MEASURE, NULL);
+        label->needs_size_update = false;
 }
 
 static void
@@ -295,7 +311,7 @@ trigger_redraw (ply_label_plugin_control_t *label,
         ply_rectangle_t dirty_area = label->area;
 
         if (adjust_size)
-                size_control (label);
+                size_control (label, true);
 
         if (label->is_hidden || label->display == NULL)
                 return;
@@ -425,7 +441,7 @@ update_scale_factor_from_pixel_buffer (ply_label_plugin_control_t *label,
 
         label->scale_factor = device_scale;
         set_font_for_control (label, label->font?: "Sans");
-        size_control (label);
+        size_control (label, true);
 }
 
 static void
@@ -689,6 +705,7 @@ set_alignment_for_control (ply_label_plugin_control_t *label,
 {
         if (label->alignment != alignment) {
                 label->alignment = alignment;
+                label->needs_size_update = true;
                 trigger_redraw (label, true);
         }
 }
@@ -699,6 +716,7 @@ set_width_for_control (ply_label_plugin_control_t *label,
 {
         if (label->width != width) {
                 label->width = width;
+                label->needs_size_update = true;
                 trigger_redraw (label, true);
         }
 }
@@ -726,6 +744,7 @@ set_text_for_control (ply_label_plugin_control_t *label,
         if (label->text != text) {
                 clear_text (label);
                 label->text = strdup (text);
+                label->needs_size_update = true;
                 trigger_redraw (label, true);
         }
 }
@@ -741,6 +760,7 @@ set_rich_text_for_control (ply_label_plugin_control_t *label,
         ply_rich_text_take_reference (rich_text);
         label->span = *span;
 
+        label->needs_size_update = true;
         trigger_redraw (label, true);
 }
 
@@ -758,6 +778,8 @@ set_font_for_control (ply_label_plugin_control_t *label,
         int dpi = 96;
         bool size_in_pixels = false;
 
+        label->needs_size_update = true;
+
         new_font = strdup (font);
         free (label->font);
         label->font = new_font;
@@ -809,7 +831,6 @@ set_font_for_control (ply_label_plugin_control_t *label,
                 FT_Set_Char_Size (label->face, size.as_integer, 0, dpi * label->scale_factor, 0);
 
         /* Ignore errors, to keep the current size. */
-
         trigger_redraw (label, true);
 }
 
@@ -843,7 +864,7 @@ show_control (ply_label_plugin_control_t *label,
 
         label->is_hidden = false;
 
-        size_control (label);
+        size_control (label, false);
 
         if (!label->is_hidden && label->display != NULL)
                 ply_pixel_display_draw_area (label->display,