From 363fc46be82c936eb5e6303098d08a77745d1a3c Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 6 Feb 2022 07:05:12 -0500 Subject: 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 | 74 ++++++++++++++++++++++----------------------- tests/testattributes.c | 1 + 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,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 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, -- cgit v1.2.1