summaryrefslogtreecommitdiff
path: root/pango/pangofc-fontmap.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2017-09-05 07:37:31 -0400
committerBehdad Esfahbod <behdad@behdad.org>2018-01-03 12:41:46 +0000
commitefa66e7b634050ef395418b544b012a4a5183973 (patch)
tree4823301a56e843fb864b7e25b8aef5f530e51f2d /pango/pangofc-fontmap.c
parent95c2aaaa9a1f0167e832a3d31700ae51e519fff4 (diff)
downloadpango-efa66e7b634050ef395418b544b012a4a5183973.tar.gz
Add initial support for OpenType font variations
This commit lets PangoFontDescription carry font variation information as a string. Only pangocairo has been updated to make use of this information. We pass it to harfbuzz for shaping, and we pass it to cairo when creating scaled fonts.
Diffstat (limited to 'pango/pangofc-fontmap.c')
-rw-r--r--pango/pangofc-fontmap.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 70e9ee7e..c5e95c44 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -357,6 +357,7 @@ struct _PangoFcFontsetKey {
int pixelsize;
double resolution;
gpointer context_key;
+ char *variations;
};
struct _PangoFcFontKey {
@@ -364,6 +365,7 @@ struct _PangoFcFontKey {
FcPattern *pattern;
PangoMatrix matrix;
gpointer context_key;
+ char *variations;
};
static void
@@ -381,8 +383,9 @@ pango_fc_fontset_key_init (PangoFcFontsetKey *key,
key->pixelsize = get_scaled_size (fcfontmap, context, desc);
key->resolution = pango_fc_font_map_get_resolution (fcfontmap, context);
key->language = language;
+ key->variations = g_strdup (pango_font_description_get_variations (desc));
key->desc = pango_font_description_copy_static (desc);
- pango_font_description_unset_fields (key->desc, PANGO_FONT_MASK_SIZE);
+ pango_font_description_unset_fields (key->desc, PANGO_FONT_MASK_SIZE | PANGO_FONT_MASK_VARIATIONS);
if (context && PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get)
key->context_key = (gpointer)PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
@@ -397,6 +400,8 @@ pango_fc_fontset_key_equal (const PangoFcFontsetKey *key_a,
if (key_a->language == key_b->language &&
key_a->pixelsize == key_b->pixelsize &&
key_a->resolution == key_b->resolution &&
+ ((key_a->variations == NULL && key_b->variations == NULL) ||
+ (key_a->variations && key_b->variations && (strcmp (key_a->variations, key_b->variations) == 0))) &&
pango_font_description_equal (key_a->desc, key_b->desc) &&
0 == memcmp (&key_a->matrix, &key_b->matrix, 4 * sizeof (double)))
{
@@ -422,6 +427,9 @@ pango_fc_fontset_key_hash (const PangoFcFontsetKey *key)
hash ^= key->pixelsize;
+ if (key->variations)
+ hash ^= g_str_hash (key->variations);
+
if (key->context_key)
hash ^= PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap,
key->context_key);
@@ -435,6 +443,7 @@ static void
pango_fc_fontset_key_free (PangoFcFontsetKey *key)
{
pango_font_description_free (key->desc);
+ g_free (key->variations);
if (key->context_key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
@@ -454,6 +463,8 @@ pango_fc_fontset_key_copy (const PangoFcFontsetKey *old)
key->matrix = old->matrix;
key->pixelsize = old->pixelsize;
key->resolution = old->resolution;
+ key->variations = g_strdup (old->variations);
+
if (old->context_key)
key->context_key = PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_copy (key->fontmap,
old->context_key);
@@ -569,6 +580,8 @@ pango_fc_font_key_equal (const PangoFcFontKey *key_a,
const PangoFcFontKey *key_b)
{
if (key_a->pattern == key_b->pattern &&
+ ((key_a->variations == NULL && key_b->variations == NULL) ||
+ (key_a->variations && key_b->variations && (strcmp (key_a->variations, key_b->variations) == 0))) &&
0 == memcmp (&key_a->matrix, &key_b->matrix, 4 * sizeof (double)))
{
if (key_a->context_key && key_b->context_key)
@@ -590,6 +603,9 @@ pango_fc_font_key_hash (const PangoFcFontKey *key)
/* We do a bytewise hash on the doubles */
hash = hash_bytes_fnv ((unsigned char *)(&key->matrix), sizeof (double) * 4, hash);
+ if (key->variations)
+ hash ^= g_str_hash (key->variations);
+
if (key->context_key)
hash ^= PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap,
key->context_key);
@@ -607,6 +623,8 @@ pango_fc_font_key_free (PangoFcFontKey *key)
PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
key->context_key);
+ g_free (key->variations);
+
g_slice_free (PangoFcFontKey, key);
}
@@ -619,6 +637,7 @@ pango_fc_font_key_copy (const PangoFcFontKey *old)
FcPatternReference (old->pattern);
key->pattern = old->pattern;
key->matrix = old->matrix;
+ key->variations = g_strdup (old->variations);
if (old->context_key)
key->context_key = PANGO_FC_FONT_MAP_GET_CLASS (key->fontmap)->context_key_copy (key->fontmap,
old->context_key);
@@ -637,6 +656,7 @@ pango_fc_font_key_init (PangoFcFontKey *key,
key->fontmap = fcfontmap;
key->pattern = pattern;
key->matrix = *pango_fc_fontset_key_get_matrix (fontset_key);
+ key->variations = g_strdup (fontset_key->variations);
key->context_key = pango_fc_fontset_key_get_context_key (fontset_key);
}
@@ -690,6 +710,11 @@ pango_fc_font_key_get_context_key (const PangoFcFontKey *key)
return key->context_key;
}
+const char *
+pango_fc_font_key_get_variations (const PangoFcFontKey *key)
+{
+ return key->variations;
+}
/*
* PangoFcPatterns
@@ -1445,7 +1470,8 @@ static FcPattern *
pango_fc_make_pattern (const PangoFontDescription *description,
PangoLanguage *language,
int pixel_size,
- double dpi)
+ double dpi,
+ const char *variations)
{
FcPattern *pattern;
const char *prgname;
@@ -1490,6 +1516,7 @@ pango_fc_make_pattern (const PangoFontDescription *description,
FC_DPI, FcTypeDouble, dpi,
FC_SIZE, FcTypeDouble, pixel_size * (72. / 1024. / dpi),
FC_PIXEL_SIZE, FcTypeDouble, pixel_size / 1024.,
+ PANGO_FC_FONT_VARIATIONS, FcTypeString, variations ? variations : "",
NULL);
if (pango_font_description_get_family (description))
@@ -1655,7 +1682,8 @@ pango_fc_fontset_key_make_pattern (PangoFcFontsetKey *key)
return pango_fc_make_pattern (key->desc,
key->language,
key->pixelsize,
- key->resolution);
+ key->resolution,
+ key->variations);
}
static PangoFcPatterns *
@@ -1739,12 +1767,14 @@ pango_fc_fontset_cache (PangoFcFontset *fontset,
{
/* Add to cache initially
*/
+#if 1
if (cache->length == FONTSET_CACHE_SIZE)
{
PangoFcFontset *tmp_fontset = g_queue_pop_tail (cache);
tmp_fontset->cache_link = NULL;
g_hash_table_remove (priv->fontset_hash, tmp_fontset->key);
}
+#endif
fontset->cache_link = g_list_prepend (NULL, fontset);
}
@@ -1783,6 +1813,7 @@ pango_fc_font_map_load_fontset (PangoFontMap *fontmap,
pango_fc_fontset_cache (fontset, fcfontmap);
pango_font_description_free (key.desc);
+ g_free (key.variations);
return g_object_ref (fontset);
}
@@ -2287,6 +2318,12 @@ pango_fc_font_description_from_pattern (FcPattern *pattern, gboolean include_siz
pango_font_description_set_gravity (desc, gravity);
}
+ if (include_size && FcPatternGetString (pattern, PANGO_FC_FONT_VARIATIONS, 0, (FcChar8 **)&s) == FcResultMatch)
+ {
+ if (s && *s)
+ pango_font_description_set_variations (desc, (char *)s);
+ }
+
return desc;
}