]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcmatch.c
Eliminate .so PLT entries for local symbols. (thanks to Arjan van de Ven)
[fontconfig.git] / src / fcmatch.c
index 74829a70b8dc84be6fde4bf7389c8202bd268291..f0410528e4c0edc42b8710a6dd5801ac243cc2d9 100644 (file)
@@ -22,9 +22,9 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include "fcint.h"
 #include <string.h>
 #include <ctype.h>
-#include "fcint.h"
 #include <stdio.h>
 
 static double
@@ -173,8 +173,7 @@ FcCompareSize (FcValue *value1, FcValue *value2)
 }
 
 typedef struct _FcMatcher {
-    const char     *object;
-    FcObjectPtr            objectPtr;
+    FcObject       object;
     double         (*compare) (FcValue *value1, FcValue *value2);
     int                    strong, weak;
 } FcMatcher;
@@ -185,90 +184,118 @@ typedef struct _FcMatcher {
  * later values
  */
 static FcMatcher _FcMatchers [] = {
-    { FC_FOUNDRY,      0, FcCompareString,     0, 0 },
+    { FC_FOUNDRY_OBJECT,       FcCompareString,        0, 0 },
 #define MATCH_FOUNDRY      0
 #define MATCH_FOUNDRY_INDEX 0
     
-    { FC_CHARSET,      0, FcCompareCharSet,    1, 1 },
+    { FC_CHARSET_OBJECT,       FcCompareCharSet,       1, 1 },
 #define MATCH_CHARSET      1
 #define MATCH_CHARSET_INDEX 1
     
-    { FC_FAMILY,       0, FcCompareFamily,     2, 4 },
+    { FC_FAMILY_OBJECT,        FcCompareFamily,        2, 4 },
 #define MATCH_FAMILY       2
 #define MATCH_FAMILY_STRONG_INDEX   2
 #define MATCH_FAMILY_WEAK_INDEX            4
     
-    { FC_LANG,         0, FcCompareLang,       3, 3 },
+    { FC_LANG_OBJECT,          FcCompareLang,  3, 3 },
 #define MATCH_LANG         3
 #define MATCH_LANG_INDEX    3
     
-    { FC_SPACING,      0, FcCompareNumber,     5, 5 },
+    { FC_SPACING_OBJECT,       FcCompareNumber,        5, 5 },
 #define MATCH_SPACING      4
 #define MATCH_SPACING_INDEX 5
     
-    { FC_PIXEL_SIZE,   0, FcCompareSize,       6, 6 },
+    { FC_PIXEL_SIZE_OBJECT,    FcCompareSize,  6, 6 },
 #define MATCH_PIXEL_SIZE    5
 #define MATCH_PIXEL_SIZE_INDEX 6
     
-    { FC_STYLE,                0, FcCompareString,     7, 7 },
+    { FC_STYLE_OBJECT,         FcCompareString,        7, 7 },
 #define MATCH_STYLE        6
 #define MATCH_STYLE_INDEX   7
     
-    { FC_SLANT,                0, FcCompareNumber,     8, 8 },
+    { FC_SLANT_OBJECT,         FcCompareNumber,        8, 8 },
 #define MATCH_SLANT        7
 #define MATCH_SLANT_INDEX   8
     
-    { FC_WEIGHT,       0, FcCompareNumber,     9, 9 },
+    { FC_WEIGHT_OBJECT,                FcCompareNumber,        9, 9 },
 #define MATCH_WEIGHT       8
 #define MATCH_WEIGHT_INDEX  9
     
-    { FC_WIDTH,                0, FcCompareNumber,     10, 10 },
+    { FC_WIDTH_OBJECT,         FcCompareNumber,        10, 10 },
 #define MATCH_WIDTH        9
 #define MATCH_WIDTH_INDEX   10
     
-    { FC_ANTIALIAS,    0, FcCompareBool,       11, 11 },
-#define MATCH_ANTIALIAS            10
-#define MATCH_ANTIALIAS_INDEX      11
+    { FC_DECORATIVE_OBJECT,    FcCompareBool,          11, 11 },
+#define MATCH_DECORATIVE       11
+#define MATCH_DECORATIVE_INDEX 12
+
+    { FC_ANTIALIAS_OBJECT,     FcCompareBool,          12, 12 },
+    
+#define MATCH_ANTIALIAS                    11
+#define MATCH_ANTIALIAS_INDEX      12
     
-    { FC_RASTERIZER,   0, FcCompareString,     12, 12 },
-#define MATCH_RASTERIZER    11
-#define MATCH_RASTERIZER_INDEX    12
+    { FC_RASTERIZER_OBJECT,    FcCompareString,        13, 13 },
+#define MATCH_RASTERIZER           12
+#define MATCH_RASTERIZER_INDEX     12
 
-    { FC_OUTLINE,      0, FcCompareBool,       13, 13 },
-#define MATCH_OUTLINE      12
-#define MATCH_OUTLINE_INDEX        13
+    { FC_OUTLINE_OBJECT,       FcCompareBool,          14, 14 },
+#define MATCH_OUTLINE              13
+#define MATCH_OUTLINE_INDEX        14
 
-    { FC_FONTVERSION,  0, FcCompareNumber,     14, 14 },
-#define MATCH_FONTVERSION   13
-#define MATCH_FONTVERSION_INDEX   14
+    { FC_FONTVERSION_OBJECT,   FcCompareNumber,        15, 15 },
+#define MATCH_FONTVERSION          14
+#define MATCH_FONTVERSION_INDEX            15
 };
 
-#define NUM_MATCH_VALUES    15
+#define NUM_MATCH_VALUES    16
 
-static FcBool matchObjectPtrsInit = FcFalse;
-
-static void
-FcMatchObjectPtrsInit (void)
+static FcMatcher*
+FcObjectToMatcher (FcObject object)
 {
-    _FcMatchers[MATCH_FOUNDRY].objectPtr = FcObjectToPtr(FC_FOUNDRY);
-    _FcMatchers[MATCH_CHARSET].objectPtr = FcObjectToPtr(FC_CHARSET);
-    _FcMatchers[MATCH_FAMILY].objectPtr = FcObjectToPtr(FC_FAMILY);
-    _FcMatchers[MATCH_LANG].objectPtr = FcObjectToPtr(FC_LANG);
-    _FcMatchers[MATCH_SPACING].objectPtr = FcObjectToPtr(FC_SPACING);
-    _FcMatchers[MATCH_PIXEL_SIZE].objectPtr = FcObjectToPtr(FC_PIXEL_SIZE);
-    _FcMatchers[MATCH_STYLE].objectPtr = FcObjectToPtr(FC_STYLE);
-    _FcMatchers[MATCH_SLANT].objectPtr = FcObjectToPtr(FC_SLANT);
-    _FcMatchers[MATCH_WEIGHT].objectPtr = FcObjectToPtr(FC_WEIGHT);
-    _FcMatchers[MATCH_WIDTH].objectPtr = FcObjectToPtr(FC_WIDTH);
-    _FcMatchers[MATCH_ANTIALIAS].objectPtr = FcObjectToPtr(FC_ANTIALIAS);
-    _FcMatchers[MATCH_RASTERIZER].objectPtr = FcObjectToPtr(FC_RASTERIZER);
-    _FcMatchers[MATCH_OUTLINE].objectPtr = FcObjectToPtr(FC_OUTLINE);
-    _FcMatchers[MATCH_FONTVERSION].objectPtr = FcObjectToPtr(FC_FONTVERSION);
-    matchObjectPtrsInit = FcTrue;
+    int        i;
+
+    i = -1;
+    switch (object) {
+    case FC_FOUNDRY_OBJECT:
+       i = MATCH_FOUNDRY; break;
+    case FC_FONTVERSION_OBJECT:
+       i = MATCH_FONTVERSION; break;
+    case FC_FAMILY_OBJECT:
+       i = MATCH_FAMILY; break;
+    case FC_CHARSET_OBJECT:
+       i = MATCH_CHARSET; break;
+    case FC_ANTIALIAS_OBJECT:
+       i = MATCH_ANTIALIAS; break;
+    case FC_LANG_OBJECT:
+       i = MATCH_LANG; break;
+    case FC_SPACING_OBJECT:
+        i = MATCH_SPACING; break;
+    case FC_STYLE_OBJECT:
+        i = MATCH_STYLE; break;
+    case FC_SLANT_OBJECT:
+        i = MATCH_SLANT; break;
+    case FC_PIXEL_SIZE_OBJECT:
+       i = MATCH_PIXEL_SIZE; break;
+    case FC_WIDTH_OBJECT:
+        i = MATCH_WIDTH; break;
+    case FC_WEIGHT_OBJECT:
+        i = MATCH_WEIGHT; break;
+    case FC_RASTERIZER_OBJECT:
+       i = MATCH_RASTERIZER; break;
+    case FC_OUTLINE_OBJECT:
+       i = MATCH_OUTLINE; break;
+    case FC_DECORATIVE_OBJECT:
+       i = MATCH_DECORATIVE; break;
+    }
+
+    if (i < 0)
+       return NULL;
+
+    return _FcMatchers+i;
 }
 
 static FcBool
-FcCompareValueList (FcObjectPtr o,
+FcCompareValueList (FcObject    object,
                    FcValueListPtr v1orig,      /* pattern */
                    FcValueListPtr v2orig,      /* target */
                    FcValue     *bestValue,
@@ -276,88 +303,26 @@ FcCompareValueList (FcObjectPtr o,
                    FcResult    *result)
 {
     FcValueListPtr  v1, v2;
-    FcValueList     *v1_ptrU, *v2_ptrU;
     double         v, best, bestStrong, bestWeak;
-    int                    i;
     int                    j;
-    const char     *object = FcObjectPtrU(o);
+    FcMatcher       *match = FcObjectToMatcher(object);
 
-    /*
-     * Locate the possible matching entry by examining the
-     * first few characters in object
-     */
-    i = -1;
-    switch (object[0]) {
-    case 'f':
-       switch (object[1]) {
-       case 'o':
-           switch (object[2]) {
-           case 'u':
-               i = MATCH_FOUNDRY; break;
-           case 'n':
-               i = MATCH_FONTVERSION; break;
-           }
-           break;
-       case 'a':
-           i = MATCH_FAMILY; break;
-       }
-       break;
-    case 'c':
-       i = MATCH_CHARSET; break;
-    case 'a':
-       i = MATCH_ANTIALIAS; break;
-    case 'l':
-       i = MATCH_LANG; break;
-    case 's':
-       switch (object[1]) {
-       case 'p':
-           i = MATCH_SPACING; break;
-       case 't':
-           i = MATCH_STYLE; break;
-       case 'l':
-           i = MATCH_SLANT; break;
-       }
-       break;
-    case 'p':
-       i = MATCH_PIXEL_SIZE; break;
-    case 'w':
-       switch (object[1]) {
-       case 'i':
-           i = MATCH_WIDTH; break;
-       case 'e':
-           i = MATCH_WEIGHT; break;
-       }
-       break;
-    case 'r':
-       i = MATCH_RASTERIZER; break;
-    case 'o':
-       i = MATCH_OUTLINE; break;
-    }
-
-    if (!matchObjectPtrsInit)
-        FcMatchObjectPtrsInit();
-    if (_FcMatchers[i].objectPtr != o) i = -1;
-
-    if (i == -1 || 
-       FcStrCmpIgnoreCase ((FcChar8 *) _FcMatchers[i].object,
-                           (FcChar8 *) object) != 0)
+    if (!match)
     {
        if (bestValue)
-           *bestValue = FcValueCanonicalize(&FcValueListPtrU(v2orig)->value);
+           *bestValue = FcValueCanonicalize(&v2orig->value);
        return FcTrue;
     }
+
     best = 1e99;
     bestStrong = 1e99;
     bestWeak = 1e99;
     j = 0;
-    for (v1 = v1orig, v1_ptrU = FcValueListPtrU(v1); v1_ptrU;
-        v1 = v1_ptrU->next, v1_ptrU = FcValueListPtrU(v1))
+    for (v1 = v1orig; v1; v1 = FcValueListNext(v1))
     {
-       for (v2 = v2orig, v2_ptrU = FcValueListPtrU(v2); v2_ptrU;
-            v2 = v2_ptrU->next, v2_ptrU = FcValueListPtrU(v2))
+       for (v2 = v2orig; v2; v2 = FcValueListNext(v2))
        {
-           v = (*_FcMatchers[i].compare) (&v1_ptrU->value,
-                                          &v2_ptrU->value);
+           v = (match->compare) (&v1->value, &v2->value);
            if (v < 0)
            {
                *result = FcResultTypeMismatch;
@@ -367,10 +332,10 @@ FcCompareValueList (FcObjectPtr o,
            if (v < best)
            {
                if (bestValue)
-                   *bestValue = FcValueCanonicalize(&v2_ptrU->value);
+                   *bestValue = FcValueCanonicalize(&v2->value);
                best = v;
            }
-           if (v1_ptrU->binding == FcValueBindingStrong)
+           if (v1->binding == FcValueBindingStrong)
            {
                if (v < bestStrong)
                    bestStrong = v;
@@ -385,7 +350,7 @@ FcCompareValueList (FcObjectPtr o,
     }
     if (FcDebug () & FC_DBG_MATCHV)
     {
-       printf (" %s: %g ", object, best);
+       printf (" %s: %g ", FcObjectName (object), best);
        FcValueListPrint (v1orig);
        printf (", ");
        FcValueListPrint (v2orig);
@@ -393,8 +358,8 @@ FcCompareValueList (FcObjectPtr o,
     }
     if (value)
     {
-       int weak    = _FcMatchers[i].weak;
-       int strong  = _FcMatchers[i].strong;
+       int weak    = match->weak;
+       int strong  = match->strong;
        if (weak == strong)
            value[strong] += best;
        else
@@ -426,10 +391,10 @@ FcCompare (FcPattern      *pat,
     i2 = 0;
     while (i1 < pat->num && i2 < fnt->num)
     {
-       FcPatternElt *elt_i1 = FcPatternEltU(pat->elts)+i1;
-       FcPatternElt *elt_i2 = FcPatternEltU(fnt->elts)+i2;
+       FcPatternElt *elt_i1 = &FcPatternElts(pat)[i1];
+       FcPatternElt *elt_i2 = &FcPatternElts(fnt)[i2];
 
-       i = FcObjectPtrCompare(elt_i1->object, elt_i2->object);
+       i = FcObjectCompare(elt_i1->object, elt_i2->object);
        if (i > 0)
            i2++;
        else if (i < 0)
@@ -437,7 +402,8 @@ FcCompare (FcPattern        *pat,
        else
        {
            if (!FcCompareValueList (elt_i1->object,
-                                    elt_i1->values, elt_i2->values,
+                                    FcPatternEltValues(elt_i1),
+                                    FcPatternEltValues(elt_i2),
                                     0, value, result))
                return FcFalse;
            i1++;
@@ -463,33 +429,32 @@ FcFontRenderPrepare (FcConfig         *config,
        return 0;
     for (i = 0; i < font->num; i++)
     {
-       fe = FcPatternEltU(font->elts)+i;
-       pe = FcPatternFindElt (pat, FcObjectPtrU(fe->object));
+       fe = &FcPatternElts(font)[i];
+       pe = FcPatternObjectFindElt (pat, fe->object);
        if (pe)
        {
-           if (!FcCompareValueList (pe->object, pe->values
-                                    fe->values, &v, 0, &result))
+           if (!FcCompareValueList (pe->object, FcPatternEltValues(pe)
+                                    FcPatternEltValues(fe), &v, 0, &result))
            {
                FcPatternDestroy (new);
                return 0;
            }
        }
        else
-           v = FcValueCanonicalize(&FcValueListPtrU(fe->values)->value);
-       FcPatternAdd (new, FcObjectPtrU(fe->object), v, FcFalse);
+           v = FcValueCanonicalize(&FcPatternEltValues (fe)->value);
+       FcPatternObjectAdd (new, fe->object, v, FcFalse);
     }
     for (i = 0; i < pat->num; i++)
     {
-       pe = FcPatternEltU(pat->elts)+i;
-       fe = FcPatternFindElt (font, FcObjectPtrU(pe->object));
+       pe = &FcPatternElts(pat)[i];
+       fe = FcPatternObjectFindElt (font, pe->object);
        if (!fe)
-           FcPatternAdd (new, FcObjectPtrU(pe->object), 
-                          FcValueCanonicalize(&FcValueListPtrU(pe->values)->value), FcTrue);
+       {
+           v = FcValueCanonicalize(&FcPatternEltValues(pe)->value);
+           FcPatternObjectAdd (new, pe->object, v, FcTrue);
+       }
     }
 
-    if (FcPatternFindElt (font, FC_FILE))
-       FcPatternTransferFullFname (new, font);
-
     FcConfigSubstituteWithPat (config, new, pat, FcMatchFont);
     return new;
 }
@@ -520,10 +485,7 @@ FcFontSetMatch (FcConfig    *config,
     {
        config = FcConfigGetCurrent ();
        if (!config)
-       {
-           *result = FcResultOutOfMemory;
            return 0;
-       }
     }
     for (set = 0; set < nsets; set++)
     {
@@ -621,7 +583,7 @@ FcSortCompare (const void *aa, const void *ab)
 }
 
 static FcBool
-FcSortWalk (FcSortNode **n, int nnode, FcFontSet *fs, FcCharSet **cs, FcBool trim)
+FcSortWalk (FcSortNode **n, int nnode, FcFontSet *fs, FcCharSet **cs, FcBool trim, FcBool build_cs)
 {
     FcCharSet  *ncs;
     FcSortNode *node;
@@ -638,18 +600,22 @@ FcSortWalk (FcSortNode **n, int nnode, FcFontSet *fs, FcCharSet **cs, FcBool tri
             */
            if (!trim || !*cs || !FcCharSetIsSubset (ncs, *cs))
            {
-               if (*cs)
-               {
-                   ncs = FcCharSetUnion (ncs, *cs);
-                   if (!ncs)
-                       return FcFalse;
-                   FcCharSetDestroy (*cs);
-               }
-               else
-                   ncs = FcCharSetCopy (ncs);
-               *cs = ncs;
+                if (trim || build_cs)
+                {
+                    if (*cs)
+                    {
+                        ncs = FcCharSetUnion (ncs, *cs);
+                        if (!ncs)
+                            return FcFalse;
+                        FcCharSetDestroy (*cs);
+                    }
+                    else
+                        ncs = FcCharSetCopy (ncs);
+                    *cs = ncs;
+                }
+
                FcPatternReference (node->pattern);
-               if (FcDebug () & FC_DBG_MATCH)
+               if (FcDebug () & FC_DBG_MATCHV)
                {
                    printf ("Add ");
                    FcPatternPrint (node->pattern);
@@ -771,7 +737,7 @@ FcFontSetSort (FcConfig         *config,
         * If this node matches any language, go check
         * which ones and satisfy those entries
         */
-       if (nodeps[f]->score[MATCH_LANG_INDEX] < nPatternLang)
+       if (nodeps[f]->score[MATCH_LANG_INDEX] < 200)
        {
            for (i = 0; i < nPatternLang; i++)
            {
@@ -816,16 +782,24 @@ FcFontSetSort (FcConfig       *config,
 
     cs = 0;
 
-    if (!FcSortWalk (nodeps, nnodes, ret, &cs, trim))
+    if (!FcSortWalk (nodeps, nnodes, ret, &cs, trim, (csp!=0)))
        goto bail2;
 
     if (csp)
        *csp = cs;
     else
-       FcCharSetDestroy (cs);
+    {
+        if (cs)
+            FcCharSetDestroy (cs);
+    }
 
     free (nodes);
 
+    if (FcDebug() & FC_DBG_MATCH)
+    {
+       printf ("First font ");
+       FcPatternPrint (ret->fonts[0]);
+    }
     return ret;
 
 bail2:
@@ -861,3 +835,6 @@ FcFontSort (FcConfig        *config,
        sets[nsets++] = config->fonts[FcSetApplication];
     return FcFontSetSort (config, sets, nsets, p, trim, csp, result);
 }
+#define __fcmatch__
+#include "fcaliastail.h"
+#undef __fcmatch__