[pango/pango2: 123/135] Add PangoAttrMerge flags




commit 22bba1347f646969fc1ecf588f2fcde33fcd3cff
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Feb 6 07:05:12 2022 -0500

    Add PangoAttrMerge flags
    
    This generalizes the behavior of PangoAttrIterator
    wrt to merging attributes with overlapping ranges.

 pango/pango-attr-iterator.c | 33 ++++++++-----------
 pango/pango-attr.c          |  4 ++-
 pango/pango-attr.h          | 38 +++++++++++++++++++++-
 pango/pango-attributes.h    | 78 ++++++++++++++++++++++-----------------------
 tests/testattributes.c      |  1 +
 5 files changed, 93 insertions(+), 61 deletions(-)
---
diff --git a/pango/pango-attr-iterator.c b/pango/pango-attr-iterator.c
index e940d5a1..02765425 100644
--- a/pango/pango-attr-iterator.c
+++ b/pango/pango-attr-iterator.c
@@ -419,14 +419,7 @@ pango_attr_iterator_get_font (PangoAttrIterator     *iterator,
             {
               gboolean found = FALSE;
 
-              /* Hack: special-case FONT_FEATURES, BASELINE_SHIFT and FONT_SCALE.
-               * We don't want these to accumulate, not override each other,
-               * so we never merge them.
-               * This needs to be handled more systematically.
-               */
-              if (attr->type != PANGO_ATTR_FONT_FEATURES &&
-                  attr->type != PANGO_ATTR_BASELINE_SHIFT &&
-                  attr->type != PANGO_ATTR_FONT_SCALE)
+              if (PANGO_ATTR_MERGE (attr) == PANGO_ATTR_MERGE_OVERRIDES)
                 {
                   GSList *tmp_list = *extra_attrs;
                   while (tmp_list)
@@ -493,18 +486,18 @@ pango_attr_iterator_get_attrs (PangoAttrIterator *iterator)
       GSList *tmp_list2;
       gboolean found = FALSE;
 
-      if (attr->type != PANGO_ATTR_FONT_DESC &&
-          attr->type != PANGO_ATTR_BASELINE_SHIFT &&
-          attr->type != PANGO_ATTR_FONT_SCALE)
-        for (tmp_list2 = attrs; tmp_list2; tmp_list2 = tmp_list2->next)
-          {
-            PangoAttribute *old_attr = tmp_list2->data;
-            if (attr->type == old_attr->type)
-              {
-                found = TRUE;
-                break;
-              }
-          }
+      if (PANGO_ATTR_MERGE (attr) == PANGO_ATTR_MERGE_OVERRIDES)
+        {
+          for (tmp_list2 = attrs; tmp_list2; tmp_list2 = tmp_list2->next)
+            {
+              PangoAttribute *old_attr = tmp_list2->data;
+              if (attr->type == old_attr->type)
+                {
+                  found = TRUE;
+                  break;
+                }
+            }
+        }
 
       if (!found)
         attrs = g_slist_prepend (attrs, pango_attribute_copy (attr));
diff --git a/pango/pango-attr.c b/pango/pango-attr.c
index 048cabb6..0b2e6200 100644
--- a/pango/pango-attr.c
+++ b/pango/pango-attr.c
@@ -62,6 +62,7 @@ get_attr_type_nick (PangoAttrType type)
  * @name: (nullable): an identifier for the type
  * @value_type: the `PangoAttrValueType` for the attribute
  * @affects: `PangoAttrAffects` flags for the attribute
+ * @merge: `PangoAttrMerge` flags for the attribute
  * @copy: (nullable): function to copy the data of an attribute
  *   of this type
  * @destroy: (nullable): function to free the data of an attribute
@@ -91,6 +92,7 @@ guint
 pango_attr_type_register (const char                 *name,
                           PangoAttrValueType          value_type,
                           PangoAttrAffects            affects,
+                          PangoAttrMerge              merge,
                           PangoAttrDataCopyFunc       copy,
                           GDestroyNotify              destroy,
                           GEqualFunc                  equal,
@@ -101,7 +103,7 @@ pango_attr_type_register (const char                 *name,
 
   G_LOCK (attr_type);
 
-  class.type = value_type | (affects << 8) | (current_id << 16);
+  class.type = value_type | (affects << 8) | (merge << 12) | (current_id << 16);
   current_id++;
 
   class.copy = copy;
diff --git a/pango/pango-attr.h b/pango/pango-attr.h
index 8b38dffe..331a183a 100644
--- a/pango/pango-attr.h
+++ b/pango/pango-attr.h
@@ -61,6 +61,7 @@ typedef enum
 
 /**
  * PangoAttrAffects:
+ * @PANGO_ATTR_AFFECTS_NONE: the attribute does not affect rendering
  * @PANGO_ATTR_AFFECTS_ITEMIZATION: the attribute affecs itemization
  * @PANGO_ATTR_AFFECTS_BREAKING: the attribute affects `PangoLogAttr` determination
  * @PANGO_ATTR_AFFECTS_SHAPING: the attribute affects shaping
@@ -74,12 +75,30 @@ typedef enum
  */
 typedef enum
 {
+  PANGO_ATTR_AFFECTS_NONE        = 0,
   PANGO_ATTR_AFFECTS_ITEMIZATION = 1 << 0,
   PANGO_ATTR_AFFECTS_BREAKING    = 1 << 1,
   PANGO_ATTR_AFFECTS_SHAPING     = 1 << 2,
   PANGO_ATTR_AFFECTS_RENDERING   = 1 << 3
 } PangoAttrAffects;
 
+/**
+ * PangoAttrMerge:
+ * @PANGO_ATTR_MERGE_OVERRIDES: only the attribute with the narrowest range is used
+ * @PANGO_ATTR_MERGE_ACCUMULATES: all attributes with overlapping range are kept
+ *
+ * Options to indicate how overlapping attribute values should be
+ * reconciled to determine the effective attribute value.
+ *
+ * These options influence the @extra_attrs returned by
+ * [method@Pango.AttrIterator.get_font].
+ */
+typedef enum
+{
+  PANGO_ATTR_MERGE_OVERRIDES,
+  PANGO_ATTR_MERGE_ACCUMULATES
+} PangoAttrMerge;
+
 /**
  * PANGO_ATTR_TYPE_VALUE_TYPE:
  * @type: an attribute type
@@ -94,7 +113,15 @@ typedef enum
  *
  * Extracts the `PangoAttrAffects` flags from an attribute type.
  */
-#define PANGO_ATTR_TYPE_AFFECTS(type) ((PangoAttrAffects)(((type) >> 8) & 0xff))
+#define PANGO_ATTR_TYPE_AFFECTS(type) ((PangoAttrAffects)(((type) >> 8) & 0xf))
+
+/**
+ * PANGO_ATTR_TYPE_MERGE:
+ * @type: an attribute type
+ *
+ * Extracts the `PangoAttrMerge` flags from an attribute type.
+ */
+#define PANGO_ATTR_TYPE_MERGE(type) ((PangoAttrMerge)(((type) >> 12) & 0xf))
 
 /**
  * PANGO_ATTR_VALUE_TYPE:
@@ -112,6 +139,14 @@ typedef enum
  */
 #define PANGO_ATTR_AFFECTS(attr) PANGO_ATTR_TYPE_AFFECTS ((attr)->type)
 
+/**
+ * PANGO_ATTR_MERGE:
+ * @attr: a `PangoAttribute`
+ *
+ * Obtains the `PangoAttrMerge` flags of a `PangoAttribute`.
+ */
+#define PANGO_ATTR_MERGE(attr) PANGO_ATTR_TYPE_MERGE ((attr)->type)
+
 /**
  * PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING:
  *
@@ -202,6 +237,7 @@ PANGO_AVAILABLE_IN_ALL
 guint                   pango_attr_type_register                (const char                 *name,
                                                                  PangoAttrValueType          value_type,
                                                                  PangoAttrAffects            affects,
+                                                                 PangoAttrMerge              merge,
                                                                  PangoAttrDataCopyFunc       copy,
                                                                  GDestroyNotify              destroy,
                                                                  GEqualFunc                  equal,
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index f115d613..908cc194 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -28,7 +28,7 @@
 G_BEGIN_DECLS
 
 
-#define PANGO_ATTR_TYPE(value, affects) (PANGO_ATTR_VALUE_##value | (PANGO_ATTR_AFFECTS_##affects << 8) | 
(__COUNTER__ << 16))
+#define PANGO_ATTR_TYPE(value, affects, merge) (PANGO_ATTR_VALUE_##value | (PANGO_ATTR_AFFECTS_##affects << 
8) | (PANGO_ATTR_MERGE_##merge << 12) | (__COUNTER__ << 16))
 /**
  * PangoAttrType:
  * @PANGO_ATTR_INVALID: does not happen
@@ -80,44 +80,44 @@ G_BEGIN_DECLS
 typedef enum
 {
   PANGO_ATTR_INVALID,
-  PANGO_ATTR_LANGUAGE             = PANGO_ATTR_TYPE (LANGUAGE, ITEMIZATION),
-  PANGO_ATTR_FAMILY               = PANGO_ATTR_TYPE (STRING, ITEMIZATION),
-  PANGO_ATTR_STYLE                = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_WEIGHT               = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_VARIANT              = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_STRETCH              = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_SIZE                 = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_FONT_DESC            = PANGO_ATTR_TYPE (FONT_DESC, ITEMIZATION),
-  PANGO_ATTR_FOREGROUND           = PANGO_ATTR_TYPE (COLOR, RENDERING),
-  PANGO_ATTR_BACKGROUND           = PANGO_ATTR_TYPE (COLOR, RENDERING),
-  PANGO_ATTR_UNDERLINE            = PANGO_ATTR_TYPE (INT, RENDERING),
-  PANGO_ATTR_STRIKETHROUGH        = PANGO_ATTR_TYPE (BOOLEAN, RENDERING),
-  PANGO_ATTR_RISE                 = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_SCALE                = PANGO_ATTR_TYPE (FLOAT, ITEMIZATION),
-  PANGO_ATTR_FALLBACK             = PANGO_ATTR_TYPE (BOOLEAN, ITEMIZATION),
-  PANGO_ATTR_LETTER_SPACING       = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_UNDERLINE_COLOR      = PANGO_ATTR_TYPE (COLOR, RENDERING),
-  PANGO_ATTR_STRIKETHROUGH_COLOR  = PANGO_ATTR_TYPE (COLOR, RENDERING),
-  PANGO_ATTR_ABSOLUTE_SIZE        = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_GRAVITY              = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_GRAVITY_HINT         = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_FONT_FEATURES        = PANGO_ATTR_TYPE (STRING, SHAPING),
-  PANGO_ATTR_FOREGROUND_ALPHA     = PANGO_ATTR_TYPE (INT, RENDERING),
-  PANGO_ATTR_BACKGROUND_ALPHA     = PANGO_ATTR_TYPE (INT, RENDERING),
-  PANGO_ATTR_ALLOW_BREAKS         = PANGO_ATTR_TYPE (BOOLEAN, BREAKING),
-  PANGO_ATTR_SHOW                 = PANGO_ATTR_TYPE (INT, SHAPING),
-  PANGO_ATTR_INSERT_HYPHENS       = PANGO_ATTR_TYPE (BOOLEAN, SHAPING),
-  PANGO_ATTR_OVERLINE             = PANGO_ATTR_TYPE (INT, RENDERING),
-  PANGO_ATTR_OVERLINE_COLOR       = PANGO_ATTR_TYPE (COLOR, RENDERING),
-  PANGO_ATTR_LINE_HEIGHT          = PANGO_ATTR_TYPE (FLOAT, ITEMIZATION),
-  PANGO_ATTR_ABSOLUTE_LINE_HEIGHT = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_TEXT_TRANSFORM       = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_WORD                 = PANGO_ATTR_TYPE (BOOLEAN, BREAKING),
-  PANGO_ATTR_SENTENCE             = PANGO_ATTR_TYPE (BOOLEAN, BREAKING),
-  PANGO_ATTR_PARAGRAPH            = PANGO_ATTR_TYPE (BOOLEAN, BREAKING),
-  PANGO_ATTR_BASELINE_SHIFT       = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_FONT_SCALE           = PANGO_ATTR_TYPE (INT, ITEMIZATION),
-  PANGO_ATTR_LINE_SPACING         = PANGO_ATTR_TYPE (INT, ITEMIZATION),
+  PANGO_ATTR_LANGUAGE             = PANGO_ATTR_TYPE (LANGUAGE, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_FAMILY               = PANGO_ATTR_TYPE (STRING, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_STYLE                = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_WEIGHT               = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_VARIANT              = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_STRETCH              = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_SIZE                 = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_FONT_DESC            = PANGO_ATTR_TYPE (FONT_DESC, ITEMIZATION, ACCUMULATES),
+  PANGO_ATTR_FOREGROUND           = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES),
+  PANGO_ATTR_BACKGROUND           = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES),
+  PANGO_ATTR_UNDERLINE            = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
+  PANGO_ATTR_STRIKETHROUGH        = PANGO_ATTR_TYPE (BOOLEAN, RENDERING, OVERRIDES),
+  PANGO_ATTR_RISE                 = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_SCALE                = PANGO_ATTR_TYPE (FLOAT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_FALLBACK             = PANGO_ATTR_TYPE (BOOLEAN, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_LETTER_SPACING       = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_UNDERLINE_COLOR      = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES),
+  PANGO_ATTR_STRIKETHROUGH_COLOR  = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES),
+  PANGO_ATTR_ABSOLUTE_SIZE        = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_GRAVITY              = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_GRAVITY_HINT         = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_FONT_FEATURES        = PANGO_ATTR_TYPE (STRING, SHAPING, ACCUMULATES),
+  PANGO_ATTR_FOREGROUND_ALPHA     = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
+  PANGO_ATTR_BACKGROUND_ALPHA     = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
+  PANGO_ATTR_ALLOW_BREAKS         = PANGO_ATTR_TYPE (BOOLEAN, BREAKING, OVERRIDES),
+  PANGO_ATTR_SHOW                 = PANGO_ATTR_TYPE (INT, SHAPING, OVERRIDES),
+  PANGO_ATTR_INSERT_HYPHENS       = PANGO_ATTR_TYPE (BOOLEAN, SHAPING, OVERRIDES),
+  PANGO_ATTR_OVERLINE             = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
+  PANGO_ATTR_OVERLINE_COLOR       = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES),
+  PANGO_ATTR_LINE_HEIGHT          = PANGO_ATTR_TYPE (FLOAT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_ABSOLUTE_LINE_HEIGHT = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_TEXT_TRANSFORM       = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
+  PANGO_ATTR_WORD                 = PANGO_ATTR_TYPE (BOOLEAN, BREAKING, OVERRIDES),
+  PANGO_ATTR_SENTENCE             = PANGO_ATTR_TYPE (BOOLEAN, BREAKING, OVERRIDES),
+  PANGO_ATTR_PARAGRAPH            = PANGO_ATTR_TYPE (BOOLEAN, BREAKING, OVERRIDES),
+  PANGO_ATTR_BASELINE_SHIFT       = PANGO_ATTR_TYPE (INT, ITEMIZATION, ACCUMULATES),
+  PANGO_ATTR_FONT_SCALE           = PANGO_ATTR_TYPE (INT, ITEMIZATION, ACCUMULATES),
+  PANGO_ATTR_LINE_SPACING         = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
 } PangoAttrType;
 
 #undef PANGO_ATTR_TYPE
diff --git a/tests/testattributes.c b/tests/testattributes.c
index 4e095b76..9fc172c6 100644
--- a/tests/testattributes.c
+++ b/tests/testattributes.c
@@ -134,6 +134,7 @@ test_attributes_register (void)
   type = pango_attr_type_register ("my-attribute",
                                    PANGO_ATTR_VALUE_POINTER,
                                    PANGO_ATTR_AFFECTS_RENDERING,
+                                   PANGO_ATTR_MERGE_OVERRIDES,
                                    copy_my_attribute_data,
                                    destroy_my_attribute_data,
                                    my_attribute_data_equal,


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