aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src/fcmatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src/fcmatch.c')
-rw-r--r--fontconfig/src/fcmatch.c113
1 files changed, 97 insertions, 16 deletions
diff --git a/fontconfig/src/fcmatch.c b/fontconfig/src/fcmatch.c
index 655e62cf5..623538bd3 100644
--- a/fontconfig/src/fcmatch.c
+++ b/fontconfig/src/fcmatch.c
@@ -240,7 +240,8 @@ static const FcMatcher _FcMatchers [] = {
#define NUM_MATCH_VALUES 17
static const FcMatcher*
-FcObjectToMatcher (FcObject object)
+FcObjectToMatcher (FcObject object,
+ FcBool include_lang)
{
int i;
@@ -278,6 +279,16 @@ FcObjectToMatcher (FcObject object)
i = MATCH_OUTLINE; break;
case FC_DECORATIVE_OBJECT:
i = MATCH_DECORATIVE; break;
+ default:
+ if (include_lang)
+ {
+ switch (object) {
+ case FC_FAMILYLANG_OBJECT:
+ case FC_STYLELANG_OBJECT:
+ case FC_FULLNAMELANG_OBJECT:
+ i = MATCH_LANG; break;
+ }
+ }
}
if (i < 0)
@@ -287,22 +298,25 @@ FcObjectToMatcher (FcObject object)
}
static FcBool
-FcCompareValueList (FcObject object,
- FcValueListPtr v1orig, /* pattern */
- FcValueListPtr v2orig, /* target */
- FcValue *bestValue,
- double *value,
- FcResult *result)
+FcCompareValueList (FcObject object,
+ const FcMatcher *match,
+ FcValueListPtr v1orig, /* pattern */
+ FcValueListPtr v2orig, /* target */
+ FcValue *bestValue,
+ double *value,
+ int *n,
+ FcResult *result)
{
FcValueListPtr v1, v2;
double v, best, bestStrong, bestWeak;
- int j;
- const FcMatcher *match = FcObjectToMatcher(object);
+ int j, k, pos = 0;
if (!match)
{
if (bestValue)
*bestValue = FcValueCanonicalize(&v2orig->value);
+ if (n)
+ *n = 0;
return FcTrue;
}
@@ -312,7 +326,7 @@ FcCompareValueList (FcObject object,
j = 1;
for (v1 = v1orig; v1; v1 = FcValueListNext(v1))
{
- for (v2 = v2orig; v2; v2 = FcValueListNext(v2))
+ for (v2 = v2orig, k = 0; v2; v2 = FcValueListNext(v2), k++)
{
v = (match->compare) (&v1->value, &v2->value);
if (v < 0)
@@ -326,6 +340,7 @@ FcCompareValueList (FcObject object,
if (bestValue)
*bestValue = FcValueCanonicalize(&v2->value);
best = v;
+ pos = k;
}
if (v1->binding == FcValueBindingStrong)
{
@@ -360,6 +375,9 @@ FcCompareValueList (FcObject object,
value[strong] += bestStrong;
}
}
+ if (n)
+ *n = pos;
+
return FcTrue;
}
@@ -393,10 +411,11 @@ FcCompare (FcPattern *pat,
i1++;
else
{
- if (!FcCompareValueList (elt_i1->object,
+ const FcMatcher *match = FcObjectToMatcher (elt_i1->object, FcFalse);
+ if (!FcCompareValueList (elt_i1->object, match,
FcPatternEltValues(elt_i1),
FcPatternEltValues(elt_i2),
- 0, value, result))
+ NULL, value, NULL, result))
return FcFalse;
i1++;
i2++;
@@ -412,8 +431,8 @@ FcFontRenderPrepare (FcConfig *config,
{
FcPattern *new;
int i;
- FcPatternElt *fe, *pe;
- FcValue v;
+ FcPatternElt *fe, *pe, *fel, *pel;
+ FcValue v, vl;
FcResult result;
assert (pat != NULL);
@@ -425,19 +444,81 @@ FcFontRenderPrepare (FcConfig *config,
for (i = 0; i < font->num; i++)
{
fe = &FcPatternElts(font)[i];
+ if (fe->object == FC_FAMILYLANG_OBJECT ||
+ fe->object == FC_STYLELANG_OBJECT ||
+ fe->object == FC_FULLNAMELANG_OBJECT)
+ {
+ /* ignore those objects. we need to deal with them
+ * another way */
+ continue;
+ }
+ if (fe->object == FC_FAMILY_OBJECT ||
+ fe->object == FC_STYLE_OBJECT ||
+ fe->object == FC_FULLNAME_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_FULLNAME_OBJECT + 1) == FC_FULLNAMELANG_OBJECT);
+
+ fel = FcPatternObjectFindElt (font, fe->object + 1);
+ pel = FcPatternObjectFindElt (pat, fe->object + 1);
+ }
+ else
+ {
+ fel = NULL;
+ pel = NULL;
+ }
pe = FcPatternObjectFindElt (pat, fe->object);
if (pe)
{
- if (!FcCompareValueList (pe->object, FcPatternEltValues(pe),
- FcPatternEltValues(fe), &v, 0, &result))
+ const FcMatcher *match = FcObjectToMatcher (pe->object, FcFalse);
+
+ if (!FcCompareValueList (pe->object, match,
+ FcPatternEltValues(pe),
+ FcPatternEltValues(fe), &v, NULL, NULL, &result))
{
FcPatternDestroy (new);
return 0;
}
+ if (fel && pel)
+ {
+ int n = 1, j;
+
+ match = FcObjectToMatcher (pel->object, FcTrue);
+ if (!FcCompareValueList (pel->object, match,
+ FcPatternEltValues (pel),
+ FcPatternEltValues (fel), &vl, NULL, &n, &result))
+ {
+ FcPatternDestroy (new);
+ return NULL;
+ }
+ else
+ {
+ FcValueListPtr l;
+
+ for (j = 0, l = FcPatternEltValues (fe);
+ j < n && l != NULL;
+ j++, l = FcValueListNext (l));
+ if (l)
+ v = FcValueCanonicalize (&l->value);
+ else
+ v = FcValueCanonicalize (&FcPatternEltValues (fe)->value);
+ }
+ }
+ else if (fel)
+ {
+ vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value);
+ }
}
else
+ {
v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
+ if (fel)
+ vl = FcValueCanonicalize (&FcPatternEltValues (fel)->value);
+ }
FcPatternObjectAdd (new, fe->object, v, FcFalse);
+ if (fel)
+ FcPatternObjectAdd (new, fel->object, vl, FcFalse);
}
for (i = 0; i < pat->num; i++)
{