summaryrefslogtreecommitdiff
path: root/pango
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
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')
-rw-r--r--pango/fonts.c172
-rw-r--r--pango/pango-font.h13
-rw-r--r--pango/pangocairo-fcfont.c17
-rw-r--r--pango/pangofc-fontmap.c43
-rw-r--r--pango/pangofc-fontmap.h13
-rw-r--r--pango/pangofc-shape.c45
6 files changed, 288 insertions, 15 deletions
diff --git a/pango/fonts.c b/pango/fonts.c
index 49e035b8..d9a07c0b 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -52,8 +52,11 @@ struct _PangoFontDescription
PangoStretch stretch;
PangoGravity gravity;
+ char *variations;
+
guint16 mask;
guint static_family : 1;
+ guint static_variations : 1;
guint size_is_absolute : 1;
int size;
@@ -71,10 +74,12 @@ static const PangoFontDescription pfd_defaults = {
PANGO_WEIGHT_NORMAL, /* weight */
PANGO_STRETCH_NORMAL, /* stretch */
PANGO_GRAVITY_SOUTH, /* gravity */
+ NULL, /* variations */
0, /* mask */
0, /* static_family */
- FALSE, /* size_is_absolute */
+ 0, /* static_variations*/
+ 0, /* size_is_absolute */
0, /* size */
};
@@ -480,6 +485,98 @@ pango_font_description_get_gravity (const PangoFontDescription *desc)
}
/**
+ * pango_font_description_set_variations_static:
+ * @desc: a #PangoFontDescription
+ * @variations: a string representing the variations
+ *
+ * Like pango_font_description_set_variations(), except that no
+ * copy of @variations 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
+ * @variations is a static string such as a C string literal, or
+ * if @desc is only needed temporarily.
+ *
+ * Since: 1.42
+ **/
+void
+pango_font_description_set_variations_static (PangoFontDescription *desc,
+ const char *variations)
+{
+ g_return_if_fail (desc != NULL);
+
+ if (desc->variations == variations)
+ return;
+
+ if (desc->variations && !desc->static_variations)
+ g_free (desc->variations);
+
+ if (variations)
+ {
+ desc->variations = (char *)variations;
+ desc->static_variations = TRUE;
+ desc->mask |= PANGO_FONT_MASK_VARIATIONS;
+ }
+ else
+ {
+ desc->variations = pfd_defaults.variations;
+ desc->static_variations = pfd_defaults.static_variations;
+ desc->mask &= ~PANGO_FONT_MASK_VARIATIONS;
+ }
+}
+
+/**
+ * pango_font_description_set_variations:
+ * @desc: a #PangoFontDescription.
+ * @variations: a string representing the variations
+ *
+ * Sets the variations field of a font description. OpenType
+ * font variations allow to select a font instance by specifying
+ * values for a number of axes, such as width or weight.
+ *
+ * The format of the variations string is AXIS1=VALUE,AXIS2=VALUE...,
+ * with each AXIS a 4 character tag that identifies a font axis,
+ * and each VALUE a floating point number. Unknown axes are ignored,
+ * and values are clamped to their allowed range.
+ *
+ * Pango does not currently have a way to find supported axes of
+ * a font. Both harfbuzz or freetype have API for this.
+ *
+ * Since: 1.42
+ **/
+void
+pango_font_description_set_variations (PangoFontDescription *desc,
+ const char *variations)
+{
+ g_return_if_fail (desc != NULL);
+
+ pango_font_description_set_variations_static (desc, g_strdup (variations));
+ if (variations)
+ desc->static_variations = FALSE;
+}
+
+/**
+ * pango_font_description_get_variations:
+ * @desc: a #PangoFontDescription
+ *
+ * Gets the variations field of a font description. See
+ * pango_font_description_set_variations().
+ *
+ * Return value: (nullable): the varitions 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.42
+ **/
+const char *
+pango_font_description_get_variations (const PangoFontDescription *desc)
+{
+ g_return_val_if_fail (desc != NULL, NULL);
+
+ return desc->variations;
+}
+
+/**
* pango_font_description_get_set_fields:
* @desc: a #PangoFontDescription
*
@@ -541,6 +638,7 @@ pango_font_description_merge (PangoFontDescription *desc,
gboolean replace_existing)
{
gboolean family_merged;
+ gboolean variations_merged;
g_return_if_fail (desc != NULL);
@@ -548,6 +646,7 @@ pango_font_description_merge (PangoFontDescription *desc,
return;
family_merged = desc_to_merge->family_name && (replace_existing || !desc->family_name);
+ variations_merged = desc_to_merge->variations && (replace_existing || !desc->variations);
pango_font_description_merge_static (desc, desc_to_merge, replace_existing);
@@ -556,6 +655,12 @@ pango_font_description_merge (PangoFontDescription *desc,
desc->family_name = g_strdup (desc->family_name);
desc->static_family = FALSE;
}
+
+ if (variations_merged)
+ {
+ desc->variations = g_strdup (desc->variations);
+ desc->static_variations = FALSE;
+ }
}
/**
@@ -603,6 +708,8 @@ pango_font_description_merge_static (PangoFontDescription *desc,
}
if (new_mask & PANGO_FONT_MASK_GRAVITY)
desc->gravity = desc_to_merge->gravity;
+ if (new_mask & PANGO_FONT_MASK_VARIATIONS)
+ pango_font_description_set_variations_static (desc, desc_to_merge->variations);
desc->mask |= new_mask;
}
@@ -697,6 +804,9 @@ pango_font_description_copy (const PangoFontDescription *desc)
result->static_family = FALSE;
}
+ result->variations = g_strdup (result->variations);
+ result->static_variations = FALSE;
+
return result;
}
@@ -728,6 +838,10 @@ pango_font_description_copy_static (const PangoFontDescription *desc)
if (result->family_name)
result->static_family = TRUE;
+
+ if (result->variations)
+ result->static_variations = TRUE;
+
return result;
}
@@ -760,7 +874,8 @@ pango_font_description_equal (const PangoFontDescription *desc1,
desc1->size_is_absolute == desc2->size_is_absolute &&
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));
+ (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, desc2->family_name) == 0)) &&
+ (g_strcmp0 (desc1->variations, desc2->variations) == 0);
}
#define TOLOWER(c) \
@@ -800,6 +915,8 @@ pango_font_description_hash (const PangoFontDescription *desc)
if (desc->family_name)
hash = case_insensitive_hash (desc->family_name);
+ if (desc->variations)
+ hash ^= g_str_hash (desc->variations);
hash ^= desc->size;
hash ^= desc->size_is_absolute ? 0xc33ca55a : 0;
hash ^= desc->style << 16;
@@ -826,6 +943,9 @@ pango_font_description_free (PangoFontDescription *desc)
if (desc->family_name && !desc->static_family)
g_free (desc->family_name);
+ if (desc->variations && !desc->static_variations)
+ g_free (desc->variations);
+
g_slice_free (PangoFontDescription, desc);
}
@@ -1031,7 +1151,7 @@ find_field_any (const char *str, int len, PangoFontDescription *desc)
}
static const char *
-getword (const char *str, const char *last, size_t *wordlen)
+getword (const char *str, const char *last, size_t *wordlen, const char *stop)
{
const char *result;
@@ -1039,7 +1159,7 @@ getword (const char *str, const char *last, size_t *wordlen)
last--;
result = last;
- while (result > str && !g_ascii_isspace (*(result - 1)) && *(result - 1) != ',')
+ while (result > str && !g_ascii_isspace (*(result - 1)) && !strchr (stop, *(result - 1)))
result--;
*wordlen = last - result;
@@ -1073,6 +1193,23 @@ parse_size (const char *word,
return FALSE;
}
+static gboolean
+parse_variations (const char *word,
+ size_t wordlen,
+ char **variations)
+{
+ if (word[0] != '@')
+ {
+ *variations = NULL;
+ return FALSE;
+ }
+
+ /* XXX: actually validate here */
+ *variations = g_strndup (word + 1, wordlen - 1);
+
+ return TRUE;
+}
+
/**
* pango_font_description_from_string:
* @str: string representation of a font description.
@@ -1110,10 +1247,19 @@ pango_font_description_from_string (const char *str)
len = strlen (str);
last = str + len;
- p = getword (str, last, &wordlen);
+ p = getword (str, last, &wordlen, "");
+ /* Look for variations at the end of the string */
+ if (wordlen != 0)
+ {
+ if (parse_variations (p, wordlen, &desc->variations))
+ {
+ desc->mask |= PANGO_FONT_MASK_VARIATIONS;
+ last = p;
+ }
+ }
- /* Look for a size at the end of the string
- */
+ p = getword (str, last, &wordlen, ",");
+ /* Look for a size */
if (wordlen != 0)
{
gboolean size_is_absolute;
@@ -1127,7 +1273,7 @@ pango_font_description_from_string (const char *str)
/* Now parse style words
*/
- p = getword (str, last, &wordlen);
+ p = getword (str, last, &wordlen, ",");
while (wordlen != 0)
{
if (!find_field_any (p, wordlen, desc))
@@ -1135,7 +1281,7 @@ pango_font_description_from_string (const char *str)
else
{
last = p;
- p = getword (str, last, &wordlen);
+ p = getword (str, last, &wordlen, ",");
}
}
@@ -1234,7 +1380,7 @@ pango_font_description_to_string (const PangoFontDescription *desc)
* in a keyword like "Bold", or if the family name ends in
* a number and no keywords will be added.
*/
- p = getword (desc->family_name, desc->family_name + strlen(desc->family_name), &wordlen);
+ p = getword (desc->family_name, desc->family_name + strlen(desc->family_name), &wordlen, ",");
if (wordlen != 0 &&
(find_field_any (p, wordlen, NULL) ||
(parse_size (p, wordlen, NULL, NULL) &&
@@ -1275,6 +1421,12 @@ pango_font_description_to_string (const PangoFontDescription *desc)
g_string_append (result, "px");
}
+ if (desc->variations && desc->mask & PANGO_FONT_MASK_VARIATIONS)
+ {
+ g_string_append (result, " @");
+ g_string_append (result, desc->variations);
+ }
+
return g_string_free (result, FALSE);
}
diff --git a/pango/pango-font.h b/pango/pango-font.h
index a9702954..4af31a95 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -145,6 +145,7 @@ typedef enum {
* @PANGO_FONT_MASK_STRETCH: the font stretch is specified.
* @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)
*
* The bits in a #PangoFontMask correspond to fields in a
* #PangoFontDescription that have been set.
@@ -156,7 +157,8 @@ typedef enum {
PANGO_FONT_MASK_WEIGHT = 1 << 3,
PANGO_FONT_MASK_STRETCH = 1 << 4,
PANGO_FONT_MASK_SIZE = 1 << 5,
- PANGO_FONT_MASK_GRAVITY = 1 << 6
+ PANGO_FONT_MASK_GRAVITY = 1 << 6,
+ PANGO_FONT_MASK_VARIATIONS = 1 << 7,
} PangoFontMask;
/* CSS scale factors (1.2 factor between each size) */
@@ -277,6 +279,15 @@ void pango_font_description_set_gravity (PangoFontDescript
PANGO_AVAILABLE_IN_1_16
PangoGravity pango_font_description_get_gravity (const PangoFontDescription *desc) G_GNUC_PURE;
+PANGO_AVAILABLE_IN_1_42
+void pango_font_description_set_variations_static (PangoFontDescription *desc,
+ const char *settings);
+PANGO_AVAILABLE_IN_1_42
+void pango_font_description_set_variations (PangoFontDescription *desc,
+ const char *settings);
+PANGO_AVAILABLE_IN_1_42
+const char *pango_font_description_get_variations (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
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c
index 30ecde4d..ef4273e7 100644
--- a/pango/pangocairo-fcfont.c
+++ b/pango/pangocairo-fcfont.c
@@ -33,6 +33,9 @@
#include "pangofc-private.h"
#include "pango-impl-utils.h"
+#include <hb-ot.h>
+#include <freetype/ftmm.h>
+
#define PANGO_TYPE_CAIRO_FC_FONT (pango_cairo_fc_font_get_type ())
#define PANGO_CAIRO_FC_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFont))
#define PANGO_CAIRO_FC_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass))
@@ -222,6 +225,8 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
FcMatrix fc_matrix, *fc_matrix_val;
double size;
int i;
+ cairo_font_options_t *options;
+ const char *variations;
g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (cffontmap), NULL);
g_return_val_if_fail (pattern != NULL, NULL);
@@ -247,13 +252,23 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
cairo_matrix_scale (&font_matrix, size, size);
+ options = pango_fc_font_key_get_context_key (key);
+ variations = pango_fc_font_key_get_variations (key);
+ if (variations) {
+ options = cairo_font_options_copy (options);
+ cairo_font_options_set_variations (options, variations);
+ }
+
_pango_cairo_font_private_initialize (&cffont->cf_priv,
(PangoCairoFont *) cffont,
get_gravity (pattern),
- pango_fc_font_key_get_context_key (key),
+ options,
pango_fc_font_key_get_matrix (key),
&font_matrix);
+ if (variations)
+ cairo_font_options_destroy (options);
+
((PangoFcFont *)(cffont))->is_hinted = _pango_cairo_font_private_is_metrics_hinted (&cffont->cf_priv);
return (PangoFcFont *) cffont;
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;
}
diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h
index 4dab0839..63452a83 100644
--- a/pango/pangofc-fontmap.h
+++ b/pango/pangofc-fontmap.h
@@ -71,6 +71,8 @@ PANGO_AVAILABLE_IN_1_24
const PangoMatrix *pango_fc_font_key_get_matrix (const PangoFcFontKey *key);
PANGO_AVAILABLE_IN_1_24
gpointer pango_fc_font_key_get_context_key (const PangoFcFontKey *key);
+PANGO_AVAILABLE_IN_1_40
+const char *pango_fc_font_key_get_variations (const PangoFcFontKey *key);
#endif
@@ -311,6 +313,17 @@ PangoFontDescription *pango_fc_font_description_from_pattern (FcPattern *pattern
*/
#define PANGO_FC_FONT_FEATURES "fontfeatures"
+/**
+ * PANGO_FC_FONT_VARIATIONS:
+ *
+ * String representing a fontconfig property name that Pango reads from font
+ * patterns to populate list of OpenType font variations to be used for a font.
+ *
+ * The property will have a number of string elements, each of which is the
+ * OpenType axis setting of the form AXIS=VALUE.
+ */
+#define PANGO_FC_FONT_VARIATIONS "fontvariations"
+
G_END_DECLS
#endif /* __PANGO_FC_FONT_MAP_H__ */
diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c
index 57f70000..a59ca67c 100644
--- a/pango/pangofc-shape.c
+++ b/pango/pangofc-shape.c
@@ -278,6 +278,38 @@ pango_fc_get_hb_font_funcs (void)
return funcs;
}
+static void
+parse_variations (const char *variations,
+ hb_variation_t **hb_variations,
+ guint *n_variations)
+{
+ guint n;
+ hb_variation_t *var;
+ int i;
+ const char *p;
+
+ n = 1;
+ for (i = 0; variations[i]; i++)
+ {
+ if (variations[i] == ',')
+ n++;
+ }
+
+ var = g_new (hb_variation_t, n);
+
+ p = variations;
+ n = 0;
+ while (p && *p)
+ {
+ char *end = strchr (p, ',');
+ if (hb_variation_from_string (p, end ? end - p: -1, &var[n]))
+ n++;
+ p = end ? end + 1 : NULL;
+ }
+
+ *hb_variations = var;
+ *n_variations = n;
+}
void
_pango_fc_shape (PangoFont *font,
@@ -306,6 +338,7 @@ _pango_fc_shape (PangoFont *font,
unsigned int num_features = 0;
double x_scale_inv, y_scale_inv;
PangoGlyphInfo *infos;
+ const char *variations;
g_return_if_fail (font != NULL);
g_return_if_fail (analysis != NULL);
@@ -347,6 +380,18 @@ _pango_fc_shape (PangoFont *font,
fc_font->is_hinted ? ft_face->size->metrics.x_ppem : 0,
fc_font->is_hinted ? ft_face->size->metrics.y_ppem : 0);
+ variations = pango_fc_font_key_get_variations (key);
+ if (variations)
+ {
+ guint n_variations;
+ hb_variation_t *hb_variations;
+
+ parse_variations (variations, &hb_variations, &n_variations);
+ hb_font_set_variations (hb_font, hb_variations, n_variations);
+
+ g_free (hb_variations);
+ }
+
hb_buffer = acquire_buffer (&free_buffer);
hb_direction = PANGO_GRAVITY_IS_VERTICAL (analysis->gravity) ? HB_DIRECTION_TTB : HB_DIRECTION_LTR;