[pango: 1/2] Add API to compare PangoAttrLists



commit f1ad230857df4a9d34f2230ecff41fe03ec89800
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Wed Feb 12 11:45:57 2020 +0100

    Add API to compare PangoAttrLists
    
    Add a new `pango_attr_list_equal` API that allows comparing the
    attributes included in two PangoAttrLists and returns TRUE if the lists
    contain the same attributes and apply to the same ranges.
    
    The function avoids any copying of attributes or lists and applies a
    minor optimization of skipping the equality check for attributes that
    were already found in both lists. Other possible optimizations that
    could be added if necessary would be storing the length of the
    attributes list in the PangoAttrList class to avoid the `g_slist_length`
    calls or reusing the `other_iter` pointer in case all attributes from 0
    to n were already found.

 docs/pango-sections.txt  |  1 +
 pango/pango-attributes.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++
 pango/pango-attributes.h |  4 +++
 3 files changed, 81 insertions(+)
---
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index e87b8750..4648816b 100644
--- a/docs/pango-sections.txt
+++ b/docs/pango-sections.txt
@@ -440,6 +440,7 @@ pango_attr_list_filter
 pango_attr_list_update
 PangoAttrFilterFunc
 pango_attr_list_get_attributes
+pango_attr_list_equal
 pango_attr_list_get_iterator
 PangoAttrIterator
 pango_attr_iterator_copy
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 2d2dd2a2..03a45de4 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -1916,6 +1916,82 @@ pango_attr_list_get_attributes (PangoAttrList *list)
   return g_slist_copy_deep (list->attributes, (GCopyFunc)pango_attribute_copy, NULL);
 }
 
+/**
+ * pango_attr_list_equal:
+ * @list: a #PangoAttrList
+ * @other_list: the other #PangoAttrList
+ *
+ * Checks whether @list and @other_list contain the same attributes and
+ * whether those attributes apply to the same ranges. Beware that this
+ * will return wrong values if any list contains duplicates.
+ *
+ * Return value: %TRUE if the lists are equal, %FALSE if they aren't.
+ *
+ * Since: 1.46
+ */
+gboolean
+pango_attr_list_equal (PangoAttrList *list,
+                       PangoAttrList *other_list)
+{
+  GSList *attrs, *other_attrs;
+  GSList *iter = NULL;
+  guint attrs_length = 0;
+  guint64 skip_bitmask = 0;
+
+  if (list == other_list)
+    return TRUE;
+
+  if (list == NULL || other_list == NULL)
+    return FALSE;
+
+  attrs = list->attributes;
+  other_attrs = other_list->attributes;
+
+  for (iter = attrs; iter != NULL; iter = iter->next)
+    {
+      PangoAttribute *attr = iter->data;
+      GSList *other_iter = NULL;
+      gboolean attr_equal = FALSE;
+      guint other_attr_index = 0;
+
+      attrs_length++;
+
+      for (other_iter = other_attrs;
+           other_iter != NULL;
+           other_iter = other_iter->next)
+        {
+          PangoAttribute *other_attr = other_iter->data;
+          guint64 other_attr_bitmask =
+            other_attr_index < 64 ? 1 << other_attr_index : 0;
+
+          if ((skip_bitmask & other_attr_bitmask) != 0)
+            {
+              other_attr_index++;
+              continue;
+            }
+
+          if (attr->start_index == other_attr->start_index &&
+              attr->end_index == other_attr->end_index &&
+              pango_attribute_equal (attr, other_attr))
+            {
+              skip_bitmask |= other_attr_bitmask;
+              attr_equal = TRUE;
+              break;
+            }
+
+          other_attr_index++;
+        }
+
+      if (!attr_equal)
+        return FALSE;
+    }
+
+  if (attrs_length != g_slist_length (other_attrs))
+    return FALSE;
+
+  return TRUE;
+}
+
 G_DEFINE_BOXED_TYPE (PangoAttrIterator,
                      pango_attr_iterator,
                      pango_attr_iterator_copy,
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index 09d1a69a..6f6622ab 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -633,6 +633,10 @@ PangoAttrList *pango_attr_list_filter (PangoAttrList       *list,
 PANGO_AVAILABLE_IN_1_44
 GSList        *pango_attr_list_get_attributes    (PangoAttrList *list);
 
+PANGO_AVAILABLE_IN_1_46
+gboolean       pango_attr_list_equal             (PangoAttrList *list,
+                                                  PangoAttrList *other_list);
+
 PANGO_AVAILABLE_IN_1_44
 GType              pango_attr_iterator_get_type  (void) G_GNUC_CONST;
 


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