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



commit 51f06dcd3b04b2a2339c7febece2c81ae23fd744
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 54bc566f31..736807ae22 100644
--- a/clutter/clutter/clutter-text.c
+++ b/clutter/clutter/clutter-text.c
@@ -5978,6 +5978,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
@@ -6001,10 +6050,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]