Improve / cleanup namelang matching

Previously, if the patten didn't request, eg, style, then the style
and stylelang were fully copied from the font, even though the pattern
had a stylelang.  Eg:

$ fc-match 'Apple Color Emoji:stylelang=en'
Apple Color Emoji.ttf: "Apple Color Emoji" "標準體"

This change both fixes that and makes the code much more readable.  Now:

$ fc-match 'Apple Color Emoji:stylelang=en'
Apple Color Emoji.ttf: "Apple Color Emoji" "Regular"
This commit is contained in:
Behdad Esfahbod 2014-07-24 16:07:13 -04:00
parent 874a549164
commit 9839d0112c
1 changed files with 23 additions and 22 deletions

View File

@ -483,7 +483,7 @@ FcFontRenderPrepare (FcConfig *config,
{ {
FcPattern *new; FcPattern *new;
int i; int i;
FcPatternElt *fe, *pe, *fel, *pel; FcPatternElt *fe, *pe;
FcValue v; FcValue v;
FcResult result; FcResult result;
@ -508,36 +508,25 @@ FcFontRenderPrepare (FcConfig *config,
fe->object == FC_STYLE_OBJECT || fe->object == FC_STYLE_OBJECT ||
fe->object == FC_FULLNAME_OBJECT) fe->object == FC_FULLNAME_OBJECT)
{ {
FcPatternElt *fel, *pel;
FC_ASSERT_STATIC ((FC_FAMILY_OBJECT + 1) == FC_FAMILYLANG_OBJECT); FC_ASSERT_STATIC ((FC_FAMILY_OBJECT + 1) == FC_FAMILYLANG_OBJECT);
FC_ASSERT_STATIC ((FC_STYLE_OBJECT + 1) == FC_STYLELANG_OBJECT); FC_ASSERT_STATIC ((FC_STYLE_OBJECT + 1) == FC_STYLELANG_OBJECT);
FC_ASSERT_STATIC ((FC_FULLNAME_OBJECT + 1) == FC_FULLNAMELANG_OBJECT); FC_ASSERT_STATIC ((FC_FULLNAME_OBJECT + 1) == FC_FULLNAMELANG_OBJECT);
fel = FcPatternObjectFindElt (font, fe->object + 1); fel = FcPatternObjectFindElt (font, fe->object + 1);
pel = FcPatternObjectFindElt (pat, fe->object + 1); pel = FcPatternObjectFindElt (pat, fe->object + 1);
}
else
{
fel = NULL;
pel = NULL;
}
pe = FcPatternObjectFindElt (pat, fe->object);
if (pe)
{
const FcMatcher *match = FcObjectToMatcher (pe->object, FcFalse);
if (!FcCompareValueList (pe->object, match,
FcPatternEltValues(pe),
FcPatternEltValues(fe), &v, NULL, NULL, &result))
{
FcPatternDestroy (new);
return NULL;
}
if (fel && pel) if (fel && pel)
{ {
/* The font has name languages, and pattern asks for specific language(s).
* Match on language and and prefer that result.
* Note: Currently the code only give priority to first matching language.
*/
int n = 1, j; int n = 1, j;
FcValueListPtr l1, l2, ln = NULL, ll = NULL; FcValueListPtr l1, l2, ln = NULL, ll = NULL;
const FcMatcher *match = FcObjectToMatcher (pel->object, FcTrue);
match = FcObjectToMatcher (pel->object, FcTrue);
if (!FcCompareValueList (pel->object, match, if (!FcCompareValueList (pel->object, match,
FcPatternEltValues (pel), FcPatternEltValues (pel),
FcPatternEltValues (fel), NULL, NULL, &n, &result)) FcPatternEltValues (fel), NULL, NULL, &n, &result))
@ -580,9 +569,10 @@ FcFontRenderPrepare (FcConfig *config,
} }
else if (fel) else if (fel)
{ {
/* Pattern doesn't ask for specific language. Copy all for name and
* lang. */
FcValueListPtr l1, l2; FcValueListPtr l1, l2;
copy_lang:
l1 = FcValueListDuplicate (FcPatternEltValues (fe)); l1 = FcValueListDuplicate (FcPatternEltValues (fe));
l2 = FcValueListDuplicate (FcPatternEltValues (fel)); l2 = FcValueListDuplicate (FcPatternEltValues (fel));
FcPatternObjectListAdd (new, fe->object, l1, FcFalse); FcPatternObjectListAdd (new, fe->object, l1, FcFalse);
@ -590,12 +580,23 @@ FcFontRenderPrepare (FcConfig *config,
continue; continue;
} }
}
pe = FcPatternObjectFindElt (pat, fe->object);
if (pe)
{
const FcMatcher *match = FcObjectToMatcher (pe->object, FcFalse);
if (!FcCompareValueList (pe->object, match,
FcPatternEltValues(pe),
FcPatternEltValues(fe), &v, NULL, NULL, &result))
{
FcPatternDestroy (new);
return NULL;
}
FcPatternObjectAdd (new, fe->object, v, FcFalse); FcPatternObjectAdd (new, fe->object, v, FcFalse);
} }
else else
{ {
if (fel)
goto copy_lang;
FcPatternObjectListAdd (new, fe->object, FcPatternObjectListAdd (new, fe->object,
FcValueListDuplicate (FcPatternEltValues (fe)), FcValueListDuplicate (FcPatternEltValues (fe)),
FcTrue); FcTrue);