[mutter/gnome-3-36] clutter/text: Check if attributes are equal before applying



commit 84512cb1f36633d32418720e3608d01c6122ee26
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Fri Dec 20 19:15:21 2019 +0800

    clutter/text: Check if attributes are equal before applying
    
    Pango doesn't make it easy but the lists are generally extremely
    short and it's worth the effort. Because when they are equal we
    can avoid the `clutter_actor_queue_relayout` in
    `clutter_text_set_attributes`. This particularly avoids stuttering
    when moving the mouse over the gnome-shell calendar (which repeatedly
    sets `font-feature-settings: "tnum"` on `calendar-day-base` themed
    widgets).
    
    Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1411
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/983

 clutter/clutter/clutter-text.c | 54 ++++++++++++++++++++++++++++++++++++++----
 1 file changed, 50 insertions(+), 4 deletions(-)
---
diff --git a/clutter/clutter/clutter-text.c b/clutter/clutter/clutter-text.c
index e1947c437d..caa689c94e 100644
--- a/clutter/clutter/clutter-text.c
+++ b/clutter/clutter/clutter-text.c
@@ -5956,6 +5956,55 @@ clutter_text_get_line_wrap_mode (ClutterText *self)
   return self->priv->wrap_mode;
 }
 
+static gboolean
+attr_list_equal (PangoAttrList *old_attrs, PangoAttrList *new_attrs)
+{
+  PangoAttrIterator *i, *j;
+  gboolean equal = TRUE;
+
+  if (old_attrs == new_attrs)
+    return TRUE;
+
+  if (old_attrs == NULL || new_attrs == NULL)
+    return FALSE;
+
+  i = pango_attr_list_get_iterator (old_attrs);
+  j = pango_attr_list_get_iterator (new_attrs);
+
+  do
+    {
+      GSList *old_attributes, *new_attributes, *a, *b;
+
+      old_attributes = pango_attr_iterator_get_attrs (i);
+      new_attributes = pango_attr_iterator_get_attrs (j);
+
+      for (a = old_attributes, b = new_attributes;
+           a != NULL && b != NULL && equal;
+           a = a->next, b = b->next)
+        {
+          if (!pango_attribute_equal (a->data, b->data))
+            equal = FALSE;
+        }
+
+      if (a != NULL || b != NULL)
+        equal = FALSE;
+
+      g_slist_free_full (old_attributes,
+                         (GDestroyNotify) pango_attribute_destroy);
+      g_slist_free_full (new_attributes,
+                         (GDestroyNotify) pango_attribute_destroy);
+    }
+  while (equal && pango_attr_iterator_next (i) && pango_attr_iterator_next (j));
+
+  if (pango_attr_iterator_next (i) || pango_attr_iterator_next (j))
+    equal = FALSE;
+
+  pango_attr_iterator_destroy (i);
+  pango_attr_iterator_destroy (j);
+
+  return equal;
+}
+
 /**
  * clutter_text_set_attributes:
  * @self: a #ClutterText
@@ -5979,10 +6028,7 @@ clutter_text_set_attributes (ClutterText   *self,
 
   priv = self->priv;
 
-  /* While we should probably test for equality, Pango doesn't
-   * provide us an easy method to check for AttrList equality.
-   */
-  if (priv->attrs == attrs)
+  if (attr_list_equal (priv->attrs, attrs))
     return;
 
   if (attrs)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]