]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcmatch.c
Move FC_BANK_DYNAMIC, FC_BANK_FIRST to internal header.
[fontconfig.git] / src / fcmatch.c
index 9afe495169b6ffa4b354dd4cefedeecd9a014852..b0d4bf8dd31cfa0fd21902e52d35b404d6f00fd7 100644 (file)
 #include <stdio.h>
 
 static double
-FcCompareNumber (char *object, FcValue value1, FcValue value2)
+FcCompareNumber (const char *object, FcValue *value1, FcValue *value2)
 {
     double  v1, v2, v;
     
-    switch (value1.type) {
+    switch (value1->type) {
     case FcTypeInteger:
-       v1 = (double) value1.u.i;
+       v1 = (double) value1->u.i;
        break;
     case FcTypeDouble:
-       v1 = value1.u.d;
+       v1 = value1->u.d;
        break;
     default:
        return -1.0;
     }
-    switch (value2.type) {
+    switch (value2->type) {
     case FcTypeInteger:
-       v2 = (double) value2.u.i;
+       v2 = (double) value2->u.i;
        break;
     case FcTypeDouble:
-       v2 = value2.u.d;
+       v2 = value2->u.d;
        break;
     default:
        return -1.0;
@@ -55,29 +55,34 @@ FcCompareNumber (char *object, FcValue value1, FcValue value2)
     v = v2 - v1;
     if (v < 0)
        v = -v;
-    return (double) v;
+    return v;
 }
 
 static double
-FcCompareString (char *object, FcValue value1, FcValue value2)
+FcCompareString (const char *object, FcValue *v1, FcValue *v2)
 {
-    if (value2.type != FcTypeString || value1.type != FcTypeString)
-       return -1.0;
-    return (double) FcStrCmpIgnoreCase (value1.u.s, value2.u.s) != 0;
+    return (double) FcStrCmpIgnoreCase (fc_value_string(v1), fc_value_string(v2)) != 0;
 }
 
 static double
-FcCompareFamily (char *object, FcValue value1, FcValue value2)
+FcCompareFamily (const char *object, FcValue *v1, FcValue *v2)
 {
-    if (value2.type != FcTypeString || value1.type != FcTypeString)
-       return -1.0;
-    return (double) FcStrCmpIgnoreBlanksAndCase (value1.u.s, value2.u.s) != 0;
+    /* rely on the guarantee in FcPatternAddWithBinding that
+     * families are always FcTypeString. */
+    const FcChar8* v1_string = fc_value_string(v1);
+    const FcChar8* v2_string = fc_value_string(v2);
+
+    if (FcToLower(*v1_string) != FcToLower(*v2_string))
+       return 1.0;
+
+    return (double) FcStrCmpIgnoreBlanksAndCase (v1_string, v2_string) != 0;
 }
 
 static double
-FcCompareLang (char *object, FcValue value1, FcValue value2)
+FcCompareLang (const char *object, FcValue *v1, FcValue *v2)
 {
     FcLangResult    result;
+    FcValue value1 = FcValueCanonicalize(v1), value2 = FcValueCanonicalize(v2);
     
     switch (value1.type) {
     case FcTypeLangSet:
@@ -86,7 +91,8 @@ FcCompareLang (char *object, FcValue value1, FcValue value2)
            result = FcLangSetCompare (value1.u.l, value2.u.l);
            break;
        case FcTypeString:
-           result = FcLangSetHasLang (value1.u.l, value2.u.s);
+           result = FcLangSetHasLang (value1.u.l, 
+                                      value2.u.s);
            break;
        default:
            return -1.0;
@@ -98,7 +104,8 @@ FcCompareLang (char *object, FcValue value1, FcValue value2)
            result = FcLangSetHasLang (value2.u.l, value1.u.s);
            break;
        case FcTypeString:
-           result = FcLangCompare (value1.u.s, value2.u.s);
+           result = FcLangCompare (value1.u.s, 
+                                   value2.u.s);
            break;
        default:
            return -1.0;
@@ -119,42 +126,40 @@ FcCompareLang (char *object, FcValue value1, FcValue value2)
 }
 
 static double
-FcCompareBool (char *object, FcValue value1, FcValue value2)
+FcCompareBool (const char *object, FcValue *v1, FcValue *v2)
 {
-    if (value2.type != FcTypeBool || value1.type != FcTypeBool)
+    if (fc_storage_type(v2) != FcTypeBool || fc_storage_type(v1) != FcTypeBool)
        return -1.0;
-    return (double) value2.u.b != value1.u.b;
+    return (double) v2->u.b != v1->u.b;
 }
 
 static double
-FcCompareCharSet (char *object, FcValue value1, FcValue value2)
+FcCompareCharSet (const char *object, FcValue *v1, FcValue *v2)
 {
-    if (value2.type != FcTypeCharSet || value1.type != FcTypeCharSet)
-       return -1.0;
-    return (double) FcCharSetSubtractCount (value1.u.c, value2.u.c);
+    return (double) FcCharSetSubtractCount (fc_value_charset(v1), fc_value_charset(v2));
 }
 
 static double
-FcCompareSize (char *object, FcValue value1, FcValue value2)
+FcCompareSize (const char *object, FcValue *value1, FcValue *value2)
 {
     double  v1, v2, v;
 
-    switch (value1.type) {
+    switch (value1->type) {
     case FcTypeInteger:
-       v1 = value1.u.i;
+       v1 = value1->u.i;
        break;
     case FcTypeDouble:
-       v1 = value1.u.d;
+       v1 = value1->u.d;
        break;
     default:
        return -1;
     }
-    switch (value2.type) {
+    switch (value2->type) {
     case FcTypeInteger:
-       v2 = value2.u.i;
+       v2 = value2->u.i;
        break;
     case FcTypeDouble:
-       v2 = value2.u.d;
+       v2 = value2->u.d;
        break;
     default:
        return -1;
@@ -168,8 +173,8 @@ FcCompareSize (char *object, FcValue value1, FcValue value2)
 }
 
 typedef struct _FcMatcher {
-    char           *object;
-    double         (*compare) (char *object, FcValue value1, FcValue value2);
+    const char     *object;
+    double         (*compare) (const char *object, FcValue *value1, FcValue *value2);
     int                    strong, weak;
 } FcMatcher;
 
@@ -241,13 +246,14 @@ static FcMatcher _FcMatchers [] = {
 
 static FcBool
 FcCompareValueList (const char  *object,
-                   FcValueList *v1orig,        /* pattern */
-                   FcValueList *v2orig,        /* target */
+                   FcValueListPtr v1orig,      /* pattern */
+                   FcValueListPtr v2orig,      /* target */
                    FcValue     *bestValue,
                    double      *value,
                    FcResult    *result)
 {
-    FcValueList    *v1, *v2;
+    FcValueListPtr  v1, v2;
+    FcValueList     *v1_ptrU, *v2_ptrU;
     double         v, best, bestStrong, bestWeak;
     int                    i;
     int                    j;
@@ -308,7 +314,7 @@ FcCompareValueList (const char  *object,
                            (FcChar8 *) object) != 0)
     {
        if (bestValue)
-           *bestValue = v2orig->value;
+           *bestValue = FcValueCanonicalize(&FcValueListPtrU(v2orig)->value);
        return FcTrue;
     }
 #if 0
@@ -329,13 +335,15 @@ FcCompareValueList (const char  *object,
     bestStrong = 1e99;
     bestWeak = 1e99;
     j = 0;
-    for (v1 = v1orig; v1; v1 = v1->next)
+    for (v1 = v1orig, v1_ptrU = FcValueListPtrU(v1); v1_ptrU;
+        v1 = FcValueListPtrU(v1)->next, v1_ptrU = FcValueListPtrU(v1))
     {
-       for (v2 = v2orig; v2; v2 = v2->next)
+       for (v2 = v2orig, v2_ptrU = FcValueListPtrU(v2); FcValueListPtrU(v2); 
+            v2 = FcValueListPtrU(v2)->next)
        {
            v = (*_FcMatchers[i].compare) (_FcMatchers[i].object,
-                                           v1->value,
-                                           v2->value);
+                                          &v1_ptrU->value,
+                                          &v2_ptrU->value);
            if (v < 0)
            {
                *result = FcResultTypeMismatch;
@@ -347,10 +355,10 @@ FcCompareValueList (const char  *object,
            if (v < best)
            {
                if (bestValue)
-                   *bestValue = v2->value;
+                   *bestValue = FcValueCanonicalize(&v2_ptrU->value);
                best = v;
            }
-           if (v1->binding == FcValueBindingStrong)
+           if (v1_ptrU->binding == FcValueBindingStrong)
            {
                if (v < bestStrong)
                    bestStrong = v;
@@ -406,16 +414,17 @@ FcCompare (FcPattern      *pat,
     i2 = 0;
     while (i1 < pat->num && i2 < fnt->num)
     {
-       i = strcmp (pat->elts[i1].object, fnt->elts[i2].object);
+       i = FcObjectPtrCompare((FcPatternEltU(pat->elts)+i1)->object,
+                              (FcPatternEltU(fnt->elts)+i2)->object);
        if (i > 0)
            i2++;
        else if (i < 0)
            i1++;
        else
        {
-           if (!FcCompareValueList (pat->elts[i1].object,
-                                    pat->elts[i1].values,
-                                    fnt->elts[i2].values,
+           if (!FcCompareValueList (FcObjectPtrU((FcPatternEltU(pat->elts)+i1)->object),
+                                    (FcPatternEltU(pat->elts)+i1)->values,
+                                    (FcPatternEltU(fnt->elts)+i2)->values,
                                     0,
                                     value,
                                     result))
@@ -456,11 +465,11 @@ FcFontRenderPrepare (FcConfig         *config,
        return 0;
     for (i = 0; i < font->num; i++)
     {
-       fe = &font->elts[i];
-       pe = FcPatternFindElt (pat, fe->object);
+       fe = FcPatternEltU(font->elts)+i;
+       pe = FcPatternFindElt (pat, FcObjectPtrU(fe->object));
        if (pe)
        {
-           if (!FcCompareValueList (pe->object, pe->values, 
+           if (!FcCompareValueList (FcObjectPtrU(pe->object), pe->values, 
                                     fe->values, &v, 0, &result))
            {
                FcPatternDestroy (new);
@@ -468,16 +477,21 @@ FcFontRenderPrepare (FcConfig         *config,
            }
        }
        else
-           v = fe->values->value;
-       FcPatternAdd (new, fe->object, v, FcFalse);
+           v = FcValueCanonicalize(&FcValueListPtrU(fe->values)->value);
+       FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse);
     }
     for (i = 0; i < pat->num; i++)
     {
-       pe = &pat->elts[i];
-       fe = FcPatternFindElt (font, pe->object);
+       pe = FcPatternEltU(pat->elts)+i;
+       fe = FcPatternFindElt (font, FcObjectPtrU(pe->object));
        if (!fe)
-           FcPatternAdd (new, pe->object, pe->values->value, FcTrue);
+           FcPatternAdd (new, FcObjectPtrU(pe->object), 
+                          FcValueCanonicalize(&FcValueListPtrU(pe->values)->value), FcTrue);
     }
+
+    if (FcPatternFindElt (font, FC_FILE))
+       FcPatternTransferFullFname (new, font);
+
     FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
     return new;
 }
@@ -769,8 +783,8 @@ FcFontSetSort (FcConfig         *config,
                    FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch &&
                    FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch)
                {
-                   double  compare = FcCompareLang (FC_LANG, patternLang, 
-                                                    nodeLang);
+                   double  compare = FcCompareLang (FC_LANG, &patternLang, 
+                                                    &nodeLang);
                    if (compare >= 0 && compare < 2)
                    {
                        if (FcDebug () & FC_DBG_MATCHV)