summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-02-06 07:05:12 -0500
committerMatthias Clasen <mclasen@redhat.com>2022-02-13 14:28:05 -0600
commit363fc46be82c936eb5e6303098d08a77745d1a3c (patch)
tree94ef003866564e30b532b516d76532a0674541ff
parentee0197d50d923d435a87d9f621ea3f48c08d9684 (diff)
downloadpango-363fc46be82c936eb5e6303098d08a77745d1a3c.tar.gz
Add PangoAttrMerge flags
This generalizes the behavior of PangoAttrIterator wrt to merging attributes with overlapping ranges.
-rw-r--r--pango/pango-attr-iterator.c33
-rw-r--r--pango/pango-attr.c4
-rw-r--r--pango/pango-attr.h38
-rw-r--r--pango/pango-attributes.h74
-rw-r--r--tests/testattributes.c1
5 files changed, 91 insertions, 59 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 aa63960b..7278bb1e 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,6 +75,7 @@ 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,
@@ -81,6 +83,23 @@ typedef enum
} 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:
@@ -113,6 +140,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:
*
* Value for @start_index in `PangoAttribute` that indicates
@@ -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 edd49fed..3c102118 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
@@ -77,42 +77,42 @@ 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_BASELINE_SHIFT = PANGO_ATTR_TYPE (INT, ITEMIZATION),
- PANGO_ATTR_FONT_SCALE = 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_BASELINE_SHIFT = PANGO_ATTR_TYPE (INT, ITEMIZATION, ACCUMULATES),
+ PANGO_ATTR_FONT_SCALE = PANGO_ATTR_TYPE (INT, ITEMIZATION, ACCUMULATES),
} 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,