Bug 57114 - regression on FcFontMatch with namelang

After 7587d1c99d applied, family,
style, and fullname is localized against current locale or lang
if any though, the string in other languages were dropped from
the pattern. this caused unexpected mismatch on the target="font"
rules.

This fix adds other strings at the end of the list.
This commit is contained in:
Akira TAGOH 2012-11-15 16:37:01 +09:00
parent bdaef0b80d
commit c20ac78b01
3 changed files with 210 additions and 21 deletions

View File

@ -923,15 +923,37 @@ FcObjectFini (void);
FcPrivate FcValue FcPrivate FcValue
FcValueCanonicalize (const FcValue *v); FcValueCanonicalize (const FcValue *v);
FcPrivate FcValueListPtr
FcValueListCreate (void);
FcPrivate void FcPrivate void
FcValueListDestroy (FcValueListPtr l); FcValueListDestroy (FcValueListPtr l);
FcPrivate FcValueListPtr
FcValueListPrepend (FcValueListPtr vallist,
FcValue value,
FcValueBinding binding);
FcPrivate FcValueListPtr
FcValueListAppend (FcValueListPtr vallist,
FcValue value,
FcValueBinding binding);
FcPrivate FcValueListPtr
FcValueListDuplicate(FcValueListPtr orig);
FcPrivate FcPatternElt * FcPrivate FcPatternElt *
FcPatternObjectFindElt (const FcPattern *p, FcObject object); FcPatternObjectFindElt (const FcPattern *p, FcObject object);
FcPrivate FcPatternElt * FcPrivate FcPatternElt *
FcPatternObjectInsertElt (FcPattern *p, FcObject object); FcPatternObjectInsertElt (FcPattern *p, FcObject object);
FcPrivate FcBool
FcPatternObjectListAdd (FcPattern *p,
FcObject object,
FcValueListPtr list,
FcBool append);
FcPrivate FcBool FcPrivate FcBool
FcPatternObjectAddWithBinding (FcPattern *p, FcPatternObjectAddWithBinding (FcPattern *p,
FcObject object, FcObject object,

View File

@ -432,7 +432,7 @@ FcFontRenderPrepare (FcConfig *config,
FcPattern *new; FcPattern *new;
int i; int i;
FcPatternElt *fe, *pe, *fel, *pel; FcPatternElt *fe, *pe, *fel, *pel;
FcValue v, vl; FcValue v;
FcResult result; FcResult result;
assert (pat != NULL); assert (pat != NULL);
@ -440,7 +440,7 @@ FcFontRenderPrepare (FcConfig *config,
new = FcPatternCreate (); new = FcPatternCreate ();
if (!new) if (!new)
return 0; return NULL;
for (i = 0; i < font->num; i++) for (i = 0; i < font->num; i++)
{ {
fe = &FcPatternElts(font)[i]; fe = &FcPatternElts(font)[i];
@ -478,47 +478,74 @@ FcFontRenderPrepare (FcConfig *config,
FcPatternEltValues(fe), &v, NULL, NULL, &result)) FcPatternEltValues(fe), &v, NULL, NULL, &result))
{ {
FcPatternDestroy (new); FcPatternDestroy (new);
return 0; return NULL;
} }
if (fel && pel) if (fel && pel)
{ {
int n = 1, j; int n = 1, j;
FcValueListPtr l1, l2, ln = NULL, ll = NULL;
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), &vl, NULL, &n, &result)) FcPatternEltValues (fel), NULL, NULL, &n, &result))
{ {
FcPatternDestroy (new); FcPatternDestroy (new);
return NULL; return NULL;
} }
else
{
FcValueListPtr l;
for (j = 0, l = FcPatternEltValues (fe); for (j = 0, l1 = FcPatternEltValues (fe), l2 = FcPatternEltValues (fel);
j < n && l != NULL; l1 != NULL || l2 != NULL;
j++, l = FcValueListNext (l)); j++, l1 = l1 ? FcValueListNext (l1) : NULL, l2 = l2 ? FcValueListNext (l2) : NULL)
if (l) {
v = FcValueCanonicalize (&l->value); if (j == n)
{
if (l1)
ln = FcValueListPrepend (ln,
FcValueCanonicalize (&l1->value),
FcValueBindingStrong);
if (l2)
ll = FcValueListPrepend (ll,
FcValueCanonicalize (&l2->value),
FcValueBindingStrong);
}
else else
v = FcValueCanonicalize (&FcPatternEltValues (fe)->value); {
if (l1)
ln = FcValueListAppend (ln,
FcValueCanonicalize (&l1->value),
FcValueBindingStrong);
if (l2)
ll = FcValueListAppend (ll,
FcValueCanonicalize (&l2->value),
FcValueBindingStrong);
}
} }
FcPatternObjectListAdd (new, fe->object, ln, FcFalse);
FcPatternObjectListAdd (new, fel->object, ll, FcFalse);
continue;
} }
else if (fel) else if (fel)
{ {
vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value); FcValueListPtr l1, l2;
copy_lang:
l1 = FcValueListDuplicate (FcPatternEltValues (fe));
l2 = FcValueListDuplicate (FcPatternEltValues (fel));
FcPatternObjectListAdd (new, fe->object, l1, FcFalse);
FcPatternObjectListAdd (new, fel->object, l2, FcFalse);
continue;
} }
} }
else else
{ {
v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
if (fel) if (fel)
vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value); goto copy_lang;
v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
} }
FcPatternObjectAdd (new, fe->object, v, FcFalse); FcPatternObjectAdd (new, fe->object, v, FcFalse);
if (fel)
FcPatternObjectAdd (new, fel->object, vl, FcFalse);
} }
for (i = 0; i < pat->num; i++) for (i = 0; i < pat->num; i++)
{ {

View File

@ -120,6 +120,20 @@ FcValueSave (FcValue v)
return v; return v;
} }
FcValueListPtr
FcValueListCreate (void)
{
FcValueListPtr ret;
ret = calloc (1, sizeof (FcValueList));
if (ret)
{
FcMemAlloc(FC_MEM_VALLIST, sizeof (FcValueList));
}
return ret;
}
void void
FcValueListDestroy (FcValueListPtr l) FcValueListDestroy (FcValueListPtr l)
{ {
@ -151,6 +165,81 @@ FcValueListDestroy (FcValueListPtr l)
} }
} }
FcValueListPtr
FcValueListPrepend (FcValueListPtr vallist,
FcValue value,
FcValueBinding binding)
{
FcValueListPtr new;
if (value.type == FcTypeVoid)
return vallist;
new = FcValueListCreate ();
if (!new)
return vallist;
new->value = FcValueSave (value);
new->binding = binding;
new->next = vallist;
return new;
}
FcValueListPtr
FcValueListAppend (FcValueListPtr vallist,
FcValue value,
FcValueBinding binding)
{
FcValueListPtr new, last;
if (value.type == FcTypeVoid)
return vallist;
new = FcValueListCreate ();
if (!new)
return vallist;
new->value = FcValueSave (value);
new->binding = binding;
new->next = NULL;
if (vallist)
{
for (last = vallist; FcValueListNext (last); last = FcValueListNext (last));
last->next = new;
}
else
vallist = new;
return vallist;
}
FcValueListPtr
FcValueListDuplicate(FcValueListPtr orig)
{
FcValueListPtr new = NULL, l, t = NULL;
FcValue v;
for (l = orig; l != NULL; l = FcValueListNext (l))
{
if (!new)
{
t = new = FcValueListCreate();
}
else
{
t->next = FcValueListCreate();
t = FcValueListNext (t);
}
v = FcValueCanonicalize (&l->value);
t->value = FcValueSave (v);
t->binding = l->binding;
t->next = NULL;
}
return new;
}
FcBool FcBool
FcValueEqual (FcValue va, FcValue vb) FcValueEqual (FcValue va, FcValue vb)
{ {
@ -460,6 +549,59 @@ FcPatternEqualSubset (const FcPattern *pai, const FcPattern *pbi, const FcObject
return FcTrue; return FcTrue;
} }
FcBool
FcPatternObjectListAdd (FcPattern *p,
FcObject object,
FcValueListPtr list,
FcBool append)
{
FcPatternElt *e;
FcValueListPtr l, *prev;
if (p->ref == FC_REF_CONSTANT)
goto bail0;
/*
* Make sure the stored type is valid for built-in objects
*/
for (l = list; l != NULL; l = FcValueListNext (l))
{
if (!FcObjectValidType (object, l->value.type))
{
if (FcDebug() & FC_DBG_OBJTYPES)
{
printf ("FcPattern object %s does not accept value ",
FcObjectName (object));
FcValuePrint (l->value);
}
goto bail0;
}
}
e = FcPatternObjectInsertElt (p, object);
if (!e)
goto bail0;
if (append)
{
for (prev = &e->values; *prev; prev = &(*prev)->next)
;
*prev = list;
}
else
{
for (prev = &list; *prev; prev = &(*prev)->next)
;
*prev = e->values;
e->values = list;
}
return FcTrue;
bail0:
return FcFalse;
}
FcBool FcBool
FcPatternObjectAddWithBinding (FcPattern *p, FcPatternObjectAddWithBinding (FcPattern *p,
FcObject object, FcObject object,
@ -473,12 +615,10 @@ FcPatternObjectAddWithBinding (FcPattern *p,
if (p->ref == FC_REF_CONSTANT) if (p->ref == FC_REF_CONSTANT)
goto bail0; goto bail0;
new = malloc (sizeof (FcValueList)); new = FcValueListCreate ();
if (!new) if (!new)
goto bail0; goto bail0;
memset(new, 0, sizeof (FcValueList));
FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
value = FcValueSave (value); value = FcValueSave (value);
if (value.type == FcTypeVoid) if (value.type == FcTypeVoid)
goto bail1; goto bail1;