summaryrefslogtreecommitdiff
path: root/pango/fonts.c
diff options
context:
space:
mode:
Diffstat (limited to 'pango/fonts.c')
-rw-r--r--pango/fonts.c185
1 files changed, 176 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);
}