summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-02-06 06:35:57 -0500
committerMatthias Clasen <mclasen@redhat.com>2022-02-13 14:28:05 -0600
commitee0197d50d923d435a87d9f621ea3f48c08d9684 (patch)
treeffe3423d965ea6d26a134baa3d3e7509ac4f8a38
parent03d2aff5518b72652fab592ef3d72852ce3ae3ef (diff)
downloadpango-ee0197d50d923d435a87d9f621ea3f48c08d9684.tar.gz
Add PangoAttrAffects
Declare what part of the pipeline an attribute affects as part of the type. This lets us handle attribute filtering for that purpose in a generalized fashion.
-rw-r--r--pango/pango-attr.c82
-rw-r--r--pango/pango-attr.h50
-rw-r--r--pango/pango-attributes.h74
-rw-r--r--pango/pango-layout.c45
-rw-r--r--tests/testattributes.c12
5 files changed, 128 insertions, 135 deletions
diff --git a/pango/pango-attr.c b/pango/pango-attr.c
index 0314bdcf..048cabb6 100644
--- a/pango/pango-attr.c
+++ b/pango/pango-attr.c
@@ -59,13 +59,15 @@ get_attr_type_nick (PangoAttrType type)
/**
* pango_attr_type_register:
- * @copy: function to copy the data of an attribute
+ * @name: (nullable): an identifier for the type
+ * @value_type: the `PangoAttrValueType` for the attribute
+ * @affects: `PangoAttrAffects` flags for the attribute
+ * @copy: (nullable): function to copy the data of an attribute
* of this type
- * @destroy: function to free the data of an attribute
+ * @destroy: (nullable): function to free the data of an attribute
* of this type
- * @equal: function to compare the data of two attributes
+ * @equal: (nullable): function to compare the data of two attributes
* of this type
- * @name: (nullable): an identifier for the type
* @serialize: (nullable): function to serialize the data
* of an attribute of this type
*
@@ -74,7 +76,11 @@ get_attr_type_nick (PangoAttrType type)
* The attribute type name can be accessed later
* by using [func@Pango.AttrType.get_name].
*
- * If @name and to @serialize are provided, they will be used
+ * The callbacks are only needed if @type is `PANGO_ATTR_VALUE_POINTER`,
+ * Pango knows how to handle other value types and will only use the
+ * callbacks for generic pointer values.
+ *
+ * If @name and @serialize are provided, they will be used
* to serialize attributes of this type.
*
* To create attributes with the new type, use [func@Pango.attr_custom_new].
@@ -82,10 +88,12 @@ get_attr_type_nick (PangoAttrType type)
* Return value: the attribute type ID
*/
guint
-pango_attr_type_register (PangoAttrDataCopyFunc copy,
+pango_attr_type_register (const char *name,
+ PangoAttrValueType value_type,
+ PangoAttrAffects affects,
+ PangoAttrDataCopyFunc copy,
GDestroyNotify destroy,
GEqualFunc equal,
- const char *name,
PangoAttrDataSerializeFunc serialize)
{
static guint current_id = MIN_CUSTOM; /* MT-safe */
@@ -93,7 +101,7 @@ pango_attr_type_register (PangoAttrDataCopyFunc copy,
G_LOCK (attr_type);
- class.type = PANGO_ATTR_VALUE_POINTER | (current_id << 8);
+ class.type = value_type | (affects << 8) | (current_id << 16);
current_id++;
class.copy = copy;
@@ -139,7 +147,7 @@ pango_attr_type_get_name (guint type)
{
const char *result = NULL;
- if ((type >> 8) < MIN_CUSTOM)
+ if ((type >> 16) < MIN_CUSTOM)
return get_attr_type_nick (type);
G_LOCK (attr_type);
@@ -208,9 +216,8 @@ pango_attribute_copy (const PangoAttribute *attr)
G_UNLOCK (attr_type);
- g_assert (copy != NULL);
-
- result->pointer_value = copy (attr->pointer_value);
+ if (copy)
+ result->pointer_value = copy (attr->pointer_value);
}
break;
@@ -266,9 +273,8 @@ pango_attribute_destroy (PangoAttribute *attr)
G_UNLOCK (attr_type);
- g_assert (destroy != NULL);
-
- destroy (attr->pointer_value);
+ if (destroy)
+ destroy (attr->pointer_value);
}
break;
@@ -355,7 +361,10 @@ pango_attribute_equal (const PangoAttribute *attr1,
g_assert (equal != NULL);
- return equal (attr1->pointer_value, attr2->pointer_value);
+ if (equal)
+ return equal (attr1->pointer_value, attr2->pointer_value);
+
+ return attr1->pointer_value == attr2->pointer_value;
}
default:
@@ -364,52 +373,33 @@ pango_attribute_equal (const PangoAttribute *attr1,
}
/**
- * pango_attr_custom_new:
+ * pango_attribute_new:
* @type: the attribute type
- * @user_data: data for the attribute
*
* Creates a new attribute for the given type.
*
* The type must have been registered with [func@Pango.register_attr_type]
- * before. @user_data will be copied with the copy function that
- * was given when the type was registered.
+ * before or be one of the `PangoAttrType` values.
+ *
+ * Pango will initialize @start_index and @end_index to an
+ * all-inclusive range of `[0,G_MAXUINT]`.
+ *
+ * The caller is responsible for filling the proper value field
+ * with the desired value.
*
* Return value: (transfer full): the newly allocated
* `PangoAttribute`, which should be freed with
* [method@Pango.Attribute.destroy]
*/
PangoAttribute *
-pango_attr_custom_new (guint type,
- gpointer user_data)
+pango_attribute_new (guint type)
{
PangoAttribute *attr;
- PangoAttrDataCopyFunc copy = NULL;
-
- g_return_val_if_fail (PANGO_ATTR_TYPE_VALUE_TYPE (type) == PANGO_ATTR_VALUE_POINTER, NULL);
-
- G_LOCK (attr_type);
-
- g_assert (attr_type != NULL);
-
- for (int i = 0; i < attr_type->len; i++)
- {
- PangoAttrClass *class = &g_array_index (attr_type, PangoAttrClass, i);
- if (class->type == type)
- {
- copy = class->copy;
- break;
- }
- }
-
- g_assert (copy != NULL);
-
- G_UNLOCK (attr_type);
- attr = g_slice_new (PangoAttribute);
+ attr = g_slice_new0 (PangoAttribute);
attr->type = type;
attr->start_index = PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING;
attr->end_index = PANGO_ATTR_INDEX_TO_TEXT_END;
- attr->pointer_value = copy (user_data);
return attr;
}
@@ -441,7 +431,7 @@ pango_attr_value_serialize (PangoAttribute *attr)
if (serialize)
return serialize (attr->pointer_value);
- return NULL;
+ return g_strdup_printf ("%p", attr->pointer_value);
}
/* }}} */
diff --git a/pango/pango-attr.h b/pango/pango-attr.h
index 7258d3ff..aa63960b 100644
--- a/pango/pango-attr.h
+++ b/pango/pango-attr.h
@@ -60,6 +60,27 @@ typedef enum
} PangoAttrValueType;
/**
+ * PangoAttrAffects:
+ * @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
+ * @PANGO_ATTR_AFFECTS_RENDERING: the attribute affects rendering
+ *
+ * Flags to indicate what part of Pangos processing pipeline is
+ * affected by an attribute.
+ *
+ * Marking an attribute with `PANGO_ATTR_AFFECTS_ITEMIZATION` ensures
+ * that the attribute values are constant across items.
+ */
+typedef enum
+{
+ 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;
+
+/**
* PANGO_ATTR_TYPE_VALUE_TYPE:
* @type: an attribute type
*
@@ -68,6 +89,14 @@ typedef enum
#define PANGO_ATTR_TYPE_VALUE_TYPE(type) ((PangoAttrValueType)((type) & 0xff))
/**
+ * PANGO_ATTR_TYPE_AFFECTS:
+ * @type: an attribute type
+ *
+ * Extracts the `PangoAttrAffects` flags from an attribute type.
+ */
+#define PANGO_ATTR_TYPE_AFFECTS(type) ((PangoAttrAffects)(((type) >> 8) & 0xff))
+
+/**
* PANGO_ATTR_VALUE_TYPE:
* @attr: a `PangoAttribute`
*
@@ -76,6 +105,14 @@ typedef enum
#define PANGO_ATTR_VALUE_TYPE(attr) PANGO_ATTR_TYPE_VALUE_TYPE ((attr)->type)
/**
+ * PANGO_ATTR_AFFECTS:
+ * @attr: a `PangoAttribute`
+ *
+ * Obtains the `PangoAttrAffects` flags of a `PangoAttribute`.
+ */
+#define PANGO_ATTR_AFFECTS(attr) PANGO_ATTR_TYPE_AFFECTS ((attr)->type)
+
+/**
* PANGO_ATTR_INDEX_FROM_TEXT_BEGINNING:
*
* Value for @start_index in `PangoAttribute` that indicates
@@ -97,7 +134,7 @@ typedef enum
/**
* PangoAttribute:
- * @klass: the class structure holding information about the type of the attribute
+ * @type: the type of the attribute
* @start_index: the start index of the range (in bytes).
* @end_index: end index of the range (in bytes). The character at this index
* is not included in the range.
@@ -116,7 +153,7 @@ typedef enum
* The common portion of the attribute holds the range to which
* the value in the type-specific part of the attribute applies.
* By default, an attribute will have an all-inclusive range of
- * [0,%G_MAXUINT].
+ * `[0,G_MAXUINT]`.
*
* Which of the values is used depends on the value type of the
* attribute, which can be obtained with `PANGO_ATTR_VALUE_TYPE()`.
@@ -162,10 +199,12 @@ PANGO_AVAILABLE_IN_ALL
GType pango_attribute_get_type (void) G_GNUC_CONST;
PANGO_AVAILABLE_IN_ALL
-guint pango_attr_type_register (PangoAttrDataCopyFunc copy,
+guint pango_attr_type_register (const char *name,
+ PangoAttrValueType value_type,
+ PangoAttrAffects affects,
+ PangoAttrDataCopyFunc copy,
GDestroyNotify destroy,
GEqualFunc equal,
- const char *name,
PangoAttrDataSerializeFunc serialize);
PANGO_AVAILABLE_IN_1_22
@@ -179,8 +218,7 @@ gboolean pango_attribute_equal (const PangoAttr
const PangoAttribute *attr2) G_GNUC_PURE;
PANGO_AVAILABLE_IN_1_52
-PangoAttribute * pango_attr_custom_new (guint type,
- gpointer user_data);
+PangoAttribute * pango_attribute_new (guint type);
PANGO_AVAILABLE_IN_1_52
gboolean pango_attribute_get_string (PangoAttribute *attribute,
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index 0dc9146d..edd49fed 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -28,7 +28,7 @@
G_BEGIN_DECLS
-#define PANGO_ATTR_TYPE(value) (PANGO_ATTR_VALUE_##value | (__COUNTER__ << 8))
+#define PANGO_ATTR_TYPE(value, affects) (PANGO_ATTR_VALUE_##value | (PANGO_ATTR_AFFECTS_##affects << 8) | (__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),
- PANGO_ATTR_FAMILY = PANGO_ATTR_TYPE (STRING),
- PANGO_ATTR_STYLE = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_WEIGHT = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_VARIANT = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_STRETCH = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_SIZE = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_FONT_DESC = PANGO_ATTR_TYPE (FONT_DESC),
- PANGO_ATTR_FOREGROUND = PANGO_ATTR_TYPE (COLOR),
- PANGO_ATTR_BACKGROUND = PANGO_ATTR_TYPE (COLOR),
- PANGO_ATTR_UNDERLINE = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_STRIKETHROUGH = PANGO_ATTR_TYPE (BOOLEAN),
- PANGO_ATTR_RISE = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_SCALE = PANGO_ATTR_TYPE (FLOAT),
- PANGO_ATTR_FALLBACK = PANGO_ATTR_TYPE (BOOLEAN),
- PANGO_ATTR_LETTER_SPACING = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_UNDERLINE_COLOR = PANGO_ATTR_TYPE (COLOR),
- PANGO_ATTR_STRIKETHROUGH_COLOR = PANGO_ATTR_TYPE (COLOR),
- PANGO_ATTR_ABSOLUTE_SIZE = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_GRAVITY = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_GRAVITY_HINT = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_FONT_FEATURES = PANGO_ATTR_TYPE (STRING),
- PANGO_ATTR_FOREGROUND_ALPHA = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_BACKGROUND_ALPHA = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_ALLOW_BREAKS = PANGO_ATTR_TYPE (BOOLEAN),
- PANGO_ATTR_SHOW = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_INSERT_HYPHENS = PANGO_ATTR_TYPE (BOOLEAN),
- PANGO_ATTR_OVERLINE = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_OVERLINE_COLOR = PANGO_ATTR_TYPE (COLOR),
- PANGO_ATTR_LINE_HEIGHT = PANGO_ATTR_TYPE (FLOAT),
- PANGO_ATTR_ABSOLUTE_LINE_HEIGHT = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_TEXT_TRANSFORM = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_WORD = PANGO_ATTR_TYPE (BOOLEAN),
- PANGO_ATTR_SENTENCE = PANGO_ATTR_TYPE (BOOLEAN),
- PANGO_ATTR_BASELINE_SHIFT = PANGO_ATTR_TYPE (INT),
- PANGO_ATTR_FONT_SCALE = PANGO_ATTR_TYPE (INT),
+ 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),
} PangoAttrType;
#undef PANGO_ATTR_TYPE
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index d0cc812c..2a92dbda 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -4648,54 +4648,15 @@ static gboolean
affects_itemization (PangoAttribute *attr,
gpointer data)
{
- switch ((int)attr->type)
- {
- /* These affect font selection */
- case PANGO_ATTR_LANGUAGE:
- case PANGO_ATTR_FAMILY:
- case PANGO_ATTR_STYLE:
- case PANGO_ATTR_WEIGHT:
- case PANGO_ATTR_VARIANT:
- case PANGO_ATTR_STRETCH:
- case PANGO_ATTR_SIZE:
- case PANGO_ATTR_FONT_DESC:
- case PANGO_ATTR_SCALE:
- case PANGO_ATTR_FALLBACK:
- case PANGO_ATTR_ABSOLUTE_SIZE:
- case PANGO_ATTR_GRAVITY:
- case PANGO_ATTR_GRAVITY_HINT:
- case PANGO_ATTR_FONT_SCALE:
- /* These need to be constant across runs */
- case PANGO_ATTR_LETTER_SPACING:
- case PANGO_ATTR_RISE:
- case PANGO_ATTR_BASELINE_SHIFT:
- case PANGO_ATTR_LINE_HEIGHT:
- case PANGO_ATTR_ABSOLUTE_LINE_HEIGHT:
- case PANGO_ATTR_TEXT_TRANSFORM:
- return TRUE;
- default:
- return FALSE;
- }
+ return (PANGO_ATTR_AFFECTS (attr) & PANGO_ATTR_AFFECTS_ITEMIZATION) != 0;
}
static gboolean
affects_break_or_shape (PangoAttribute *attr,
gpointer data)
{
- switch ((int)attr->type)
- {
- /* Affects breaks */
- case PANGO_ATTR_ALLOW_BREAKS:
- case PANGO_ATTR_WORD:
- case PANGO_ATTR_SENTENCE:
- /* Affects shaping */
- case PANGO_ATTR_INSERT_HYPHENS:
- case PANGO_ATTR_FONT_FEATURES:
- case PANGO_ATTR_SHOW:
- return TRUE;
- default:
- return FALSE;
- }
+ return (PANGO_ATTR_AFFECTS (attr) & (PANGO_ATTR_AFFECTS_BREAKING |
+ PANGO_ATTR_AFFECTS_SHAPING)) != 0;
}
static void
diff --git a/tests/testattributes.c b/tests/testattributes.c
index be98cdd0..4e095b76 100644
--- a/tests/testattributes.c
+++ b/tests/testattributes.c
@@ -131,21 +131,25 @@ test_attributes_register (void)
PangoAttrList *list;
char *str;
- type = pango_attr_type_register (copy_my_attribute_data,
+ type = pango_attr_type_register ("my-attribute",
+ PANGO_ATTR_VALUE_POINTER,
+ PANGO_ATTR_AFFECTS_RENDERING,
+ copy_my_attribute_data,
destroy_my_attribute_data,
my_attribute_data_equal,
- "my-attribute",
my_attribute_data_serialize);
g_assert_cmpstr (pango_attr_type_get_name (type), ==, "my-attribute");
- attr = pango_attr_custom_new (type, (gpointer)0x42);
+ attr = pango_attribute_new (type);
+ attr->pointer_value = (gpointer)0x42;
ret = pango_attribute_get_custom (attr, &value);
g_assert_true (ret);
g_assert_true (value == (gpointer)0x42);
- attr2 = pango_attr_custom_new (type, (gpointer)0x43);
+ attr2 = pango_attribute_new (type);
+ attr2->pointer_value = (gpointer)0x43;
ret = pango_attribute_equal (attr, attr2);
g_assert_false (ret);