diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-01-03 22:10:29 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-01-28 09:03:03 -0500 |
commit | 23cf33a37efb324e633845353e584730e6ef385c (patch) | |
tree | c2020db1666eec6ac21481417aca92ebeecd3c43 /pango | |
parent | 41d718553a1358661e58ca7915b59f958e780600 (diff) | |
download | pango-23cf33a37efb324e633845353e584730e6ef385c.tar.gz |
Add a faceid field to font descriptions
The faceid will be used in future commits
to improve font -> description -> font roundtrip
accuracy.
Update affected tests.
Minimal test included.
Diffstat (limited to 'pango')
-rw-r--r-- | pango/fonts.c | 185 | ||||
-rw-r--r-- | pango/pango-font.h | 11 |
2 files changed, 187 insertions, 9 deletions
diff --git a/pango/fonts.c b/pango/fonts.c index 0f566a79..89607683 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -41,14 +41,16 @@ struct _PangoFontDescription PangoStretch stretch; PangoGravity gravity; + int size; + char *variations; + char *faceid; guint16 mask; guint static_family : 1; guint static_variations : 1; + guint static_faceid: 1; guint size_is_absolute : 1; - - int size; }; G_DEFINE_BOXED_TYPE (PangoFontDescription, pango_font_description, @@ -63,14 +65,16 @@ static const PangoFontDescription pfd_defaults = { PANGO_WEIGHT_NORMAL, /* weight */ PANGO_STRETCH_NORMAL, /* stretch */ PANGO_GRAVITY_SOUTH, /* gravity */ + + 0, /* size */ NULL, /* variations */ + NULL, /* faceid */ 0, /* mask */ 0, /* static_family */ - 0, /* static_variations*/ + 0, /* static_variations */ + 0, /* static_faceid */ 0, /* size_is_absolute */ - - 0, /* size */ }; /** @@ -601,6 +605,101 @@ pango_font_description_get_variations (const PangoFontDescription *desc) } /** + * pango_font_description_set_faceid_static: + * @desc: a `PangoFontDescription` + * @faceid: the faceid string + * + * Sets the faceid field of a font description. + * + * This is like [method@Pango.FontDescription.set_faceid], except + * that no copy of @faceid is made. The caller must make sure that + * the string passed in stays around until @desc has been freed + * or the name is set again. This function can be used if + * @faceid is a static string such as a C string literal, + * or if @desc is only needed temporarily. + * + * Since: 1.52 + */ +void +pango_font_description_set_faceid_static (PangoFontDescription *desc, + const char *faceid) +{ + g_return_if_fail (desc != NULL); + + if (desc->faceid == faceid) + return; + + if (desc->faceid && !desc->static_faceid) + g_free (desc->faceid); + + if (faceid) + { + desc->faceid = (char *)faceid; + desc->static_faceid = TRUE; + desc->mask |= PANGO_FONT_MASK_FACEID; + } + else + { + desc->faceid = pfd_defaults.faceid; + desc->static_faceid = pfd_defaults.static_faceid; + desc->mask &= ~PANGO_FONT_MASK_FACEID; + } +} + +/** + * pango_font_description_set_faceid: + * @desc: a `PangoFontDescription`. + * @faceid: (nullable): the faceid string + * + * Sets the faceid field of a font description. + * + * The faceid is mainly for internal use by Pango, to ensure + * that font -> description -> font roundtrips end up with + * the same font they started with, if possible. + * + * Font descriptions originating from [method@Pango.FontFace.describe] + * should ideally include a faceid. Pango takes the faceid + * into account when looking for the best matching face while + * loading a fontset or font. + * + * The format of this string is not guaranteed. + * + * Since: 1.52 + */ +void +pango_font_description_set_faceid (PangoFontDescription *desc, + const char *faceid) +{ + g_return_if_fail (desc != NULL); + + pango_font_description_set_faceid_static (desc, g_strdup (faceid)); + if (faceid) + desc->static_faceid = FALSE; +} + +/** + * pango_font_description_get_faceid: + * @desc: a `PangoFontDescription` + * + * Gets the faceid field of a font description. + * + * See [method@Pango.FontDescription.set_faceid]. + * + * Return value: (nullable): the faceid field for the font + * description, or %NULL if not previously set. This has the same + * life-time as the font description itself and should not be freed. + * + * Since: 1.52 + */ +const char * +pango_font_description_get_faceid (const PangoFontDescription *desc) +{ + g_return_val_if_fail (desc != NULL, NULL); + + return desc->faceid; +} + +/** * pango_font_description_get_set_fields: * @desc: a `PangoFontDescription` * @@ -667,6 +766,7 @@ pango_font_description_merge (PangoFontDescription *desc, { gboolean family_merged; gboolean variations_merged; + gboolean faceid_merged; g_return_if_fail (desc != NULL); @@ -675,6 +775,7 @@ pango_font_description_merge (PangoFontDescription *desc, family_merged = desc_to_merge->family_name && (replace_existing || !desc->family_name); variations_merged = desc_to_merge->variations && (replace_existing || !desc->variations); + faceid_merged = desc_to_merge->faceid && (replace_existing || !desc->faceid); pango_font_description_merge_static (desc, desc_to_merge, replace_existing); @@ -689,6 +790,12 @@ pango_font_description_merge (PangoFontDescription *desc, desc->variations = g_strdup (desc->variations); desc->static_variations = FALSE; } + + if (faceid_merged) + { + desc->faceid = g_strdup (desc->faceid); + desc->static_faceid = FALSE; + } } /** @@ -741,6 +848,8 @@ pango_font_description_merge_static (PangoFontDescription *desc, desc->gravity = desc_to_merge->gravity; if (new_mask & PANGO_FONT_MASK_VARIATIONS) pango_font_description_set_variations_static (desc, desc_to_merge->variations); + if (new_mask & PANGO_FONT_MASK_FACEID) + pango_font_description_set_faceid_static (desc, desc_to_merge->faceid); desc->mask |= new_mask; } @@ -844,6 +953,9 @@ pango_font_description_copy (const PangoFontDescription *desc) result->variations = g_strdup (result->variations); result->static_variations = FALSE; + result->faceid = g_strdup (result->faceid); + result->static_faceid = FALSE; + return result; } @@ -877,10 +989,12 @@ pango_font_description_copy_static (const PangoFontDescription *desc) if (result->family_name) result->static_family = TRUE; - if (result->variations) result->static_variations = TRUE; + if (result->faceid) + result->static_faceid = TRUE; + return result; } @@ -915,7 +1029,8 @@ pango_font_description_equal (const PangoFontDescription *desc1, desc1->gravity == desc2->gravity && (desc1->family_name == desc2->family_name || (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, desc2->family_name) == 0)) && - (g_strcmp0 (desc1->variations, desc2->variations) == 0); + (g_strcmp0 (desc1->variations, desc2->variations) == 0) && + (g_strcmp0 (desc1->faceid, desc2->faceid) == 0); } #define TOLOWER(c) \ @@ -958,6 +1073,8 @@ pango_font_description_hash (const PangoFontDescription *desc) hash = case_insensitive_hash (desc->family_name); if (desc->variations) hash ^= g_str_hash (desc->variations); + if (desc->faceid) + hash ^= g_str_hash (desc->faceid); hash ^= desc->size; hash ^= desc->size_is_absolute ? 0xc33ca55a : 0; hash ^= desc->style << 16; @@ -987,6 +1104,9 @@ pango_font_description_free (PangoFontDescription *desc) if (desc->variations && !desc->static_variations) g_free (desc->variations); + if (desc->faceid && !desc->static_faceid) + g_free (desc->faceid); + g_slice_free (PangoFontDescription, desc); } @@ -1256,6 +1376,40 @@ parse_variations (const char *word, return TRUE; } +static void +faceid_from_variations (PangoFontDescription *desc) +{ + const char *p, *q; + + p = desc->variations; + + if (g_str_has_prefix (p, "faceid=")) + { + p += strlen ("faceid="); + q = strchr (p, ','); + if (q) + { + desc->faceid = g_strndup (p, q - p); + p = q + 1; + } + else + { + desc->faceid = g_strdup (p); + p = NULL; + } + desc->mask |= PANGO_FONT_MASK_FACEID; + } + + if (p != desc->variations) + { + char *variations = g_strdup (p); + g_free (desc->variations); + desc->variations = variations; + if (variations == NULL || *variations == '\0') + desc->mask &= ~PANGO_FONT_MASK_VARIATIONS; + } +} + /** * pango_font_description_from_string: * @str: string representation of a font description. @@ -1333,6 +1487,8 @@ pango_font_description_from_string (const char *str) { desc->mask |= PANGO_FONT_MASK_VARIATIONS; last = p; + + faceid_from_variations (desc); } } @@ -1421,7 +1577,7 @@ append_field (GString *str, const char *what, const FieldMap *map, int n_element return; } - if (G_LIKELY (str->len > 0 || str->str[str->len -1] != ' ')) + if (G_LIKELY (str->len > 0 && str->str[str->len - 1] != ' ')) g_string_append_c (str, ' '); g_string_append_printf (str, "%s=%d", what, val); } @@ -1443,6 +1599,7 @@ char * pango_font_description_to_string (const PangoFontDescription *desc) { GString *result; + gboolean in_variations = FALSE; g_return_val_if_fail (desc != NULL, NULL); @@ -1500,10 +1657,20 @@ pango_font_description_to_string (const PangoFontDescription *desc) g_string_append (result, "px"); } + if (desc->mask & PANGO_FONT_MASK_FACEID) + { + in_variations = TRUE; + g_string_append (result, " @"); + g_string_append_printf (result, "faceid=%s", desc->faceid); + } + if ((desc->variations && desc->mask & PANGO_FONT_MASK_VARIATIONS) && desc->variations[0] != '\0') { - g_string_append (result, " @"); + if (!in_variations) + g_string_append (result, " @"); + else + g_string_append (result, ","); g_string_append (result, desc->variations); } diff --git a/pango/pango-font.h b/pango/pango-font.h index 1ba02b06..f4824c80 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -179,6 +179,7 @@ typedef enum { * @PANGO_FONT_MASK_SIZE: the font size is specified. * @PANGO_FONT_MASK_GRAVITY: the font gravity is specified (Since: 1.16.) * @PANGO_FONT_MASK_VARIATIONS: OpenType font variations are specified (Since: 1.42) + * @PANGO_FONT_MASK_FACEID: the face ID is specified (Since: 1.52) * * The bits in a `PangoFontMask` correspond to the set fields in a * `PangoFontDescription`. @@ -192,6 +193,7 @@ typedef enum { PANGO_FONT_MASK_SIZE = 1 << 5, PANGO_FONT_MASK_GRAVITY = 1 << 6, PANGO_FONT_MASK_VARIATIONS = 1 << 7, + PANGO_FONT_MASK_FACEID = 1 << 8, } PangoFontMask; /* CSS scale factors (1.2 factor between each size) */ @@ -316,6 +318,15 @@ void pango_font_description_set_variations (PangoFontDescript PANGO_AVAILABLE_IN_1_42 const char *pango_font_description_get_variations (const PangoFontDescription *desc) G_GNUC_PURE; +PANGO_AVAILABLE_IN_1_52 +void pango_font_description_set_faceid (PangoFontDescription *desc, + const char *faceid); +PANGO_AVAILABLE_IN_ALL +void pango_font_description_set_faceid_static (PangoFontDescription *desc, + const char *faceid); +PANGO_AVAILABLE_IN_1_52 +const char * pango_font_description_get_faceid (const PangoFontDescription *desc) G_GNUC_PURE; + PANGO_AVAILABLE_IN_ALL PangoFontMask pango_font_description_get_set_fields (const PangoFontDescription *desc) G_GNUC_PURE; PANGO_AVAILABLE_IN_ALL |