Set font-variations settings for standard axes in variable fonts

This is the last piece of the puzzle for variable-font support in
fontconfig.  This takes care of automatically setting the variation
settings when user requests a weight / width / size that has variation
in the matched font.
This commit is contained in:
Behdad Esfahbod 2017-12-19 15:04:25 -05:00
parent 288d334812
commit 650b051a25
2 changed files with 60 additions and 4 deletions

View File

@ -531,10 +531,22 @@ FcFontRenderPrepare (FcConfig *config,
FcPatternElt *fe, *pe;
FcValue v;
FcResult result;
FcBool variable = FcFalse;
FcStrBuf variations;
assert (pat != NULL);
assert (font != NULL);
FcPatternObjectGetBool (font, FC_VARIABLE_OBJECT, 0, &variable);
assert (variable != FcDontCare);
if (variable)
{
FcChar8 *vars = NULL;
FcStrBufInit (&variations, NULL, 0);
if (FcPatternObjectGetString (pat, FC_FONT_VARIATIONS_OBJECT, 0, &vars) == FcResultMatch)
FcStrBufString (&variations, vars);
}
new = FcPatternCreate ();
if (!new)
return NULL;
@ -639,6 +651,39 @@ FcFontRenderPrepare (FcConfig *config,
return NULL;
}
FcPatternObjectAdd (new, fe->object, v, FcFalse);
/* Set font-variations settings for standard axes in variable fonts. */
if (variable &&
FcPatternEltValues(fe)->value.type == FcTypeRange &&
(fe->object == FC_WEIGHT_OBJECT ||
fe->object == FC_WIDTH_OBJECT ||
fe->object == FC_SIZE_OBJECT))
{
double num;
FcChar8 temp[128];
const char *tag = " ";
assert (v.type == FcTypeDouble);
num = v.u.d;
if (variations.len)
FcStrBufChar (&variations, ',');
switch (fe->object)
{
case FC_WEIGHT_OBJECT:
tag = "wght";
num = FcWeightToOpenType (num);
break;
case FC_WIDTH_OBJECT:
tag = "wdth";
break;
case FC_SIZE_OBJECT:
tag = "opsz";
break;
}
sprintf ((char *) temp, "%4s=%g", tag, num);
FcStrBufString (&variations, temp);
}
}
else
{
@ -652,8 +697,6 @@ FcFontRenderPrepare (FcConfig *config,
if (!l)
goto bail0;
dir = FcStrDirname (FcValueString (&l->value));
if (!config)
config = FcConfigGetCurrent ();
if (config && FcHashTableFind (config->alias_table, dir, (void **) &alias))
{
FcChar8 *base = FcStrBasename (FcValueString (&l->value));
@ -696,6 +739,13 @@ FcFontRenderPrepare (FcConfig *config,
}
}
if (variable)
{
FcPatternObjectDel (new, FC_FONT_VARIATIONS_OBJECT);
FcPatternObjectAddString (new, FC_FONT_VARIATIONS_OBJECT, FcStrBufDoneStatic (&variations));
FcStrBufDestroy (&variations);
}
FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
return new;
}

View File

@ -1021,12 +1021,12 @@ FcPatternGetMatrix(const FcPattern *p, const char *object, int id, FcMatrix **m)
FcResult
FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
FcPatternObjectGetBool (const FcPattern *p, FcObject object, int id, FcBool *b)
{
FcValue v;
FcResult r;
r = FcPatternGet (p, object, id, &v);
r = FcPatternObjectGet (p, object, id, &v);
if (r != FcResultMatch)
return r;
if (v.type != FcTypeBool)
@ -1035,6 +1035,12 @@ FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
return FcResultMatch;
}
FcResult
FcPatternGetBool(const FcPattern *p, const char *object, int id, FcBool *b)
{
return FcPatternObjectGetBool (p, FcObjectFromName (object), id, b);
}
FcResult
FcPatternGetCharSet(const FcPattern *p, const char *object, int id, FcCharSet **c)
{