]> git.wh0rd.org - fontconfig.git/blobdiff - src/fclist.c
Reinstate basename patch, but keep a hash table linking FcPatterns to their
[fontconfig.git] / src / fclist.c
index 6730f20324f92ac95e6bd76adfcb82bda8f3b71c..fa567a0491338eec3a2ee039a7bcf5097bebed42 100644 (file)
@@ -67,10 +67,11 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
     low = 0;
     mid = 0;
     c = 1;
+    object = (char *)FcStrStaticName ((FcChar8 *)object);
     while (low <= high)
     {
        mid = (low + high) >> 1;
-       c = strcmp (os->objects[mid], object);
+       c = os->objects[mid] - object;
        if (c == 0)
            return FcTrue;
        if (c < 0)
@@ -82,7 +83,7 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
        mid++;
     memmove (os->objects + mid + 1, os->objects + mid, 
             (os->nobject - mid) * sizeof (const char *));
-    os->objects[mid] = FcObjectStaticName (object);
+    os->objects[mid] = object;
     os->nobject++;
     return FcTrue;
 }
@@ -124,51 +125,59 @@ FcObjectSetBuild (const char *first, ...)
  * Font must have a containing value for every value in the pattern
  */
 static FcBool
-FcListValueListMatchAny (FcValueList *patOrig,     /* pattern */
-                        FcValueList *fntOrig)      /* font */
+FcListValueListMatchAny (FcValueListPtr patOrig,           /* pattern */
+                        FcValueListPtr fntOrig)            /* font */
 {
-    FcValueList            *pat, *fnt;
+    FcValueListPtr      pat, fnt;
 
-    for (pat = patOrig; pat; pat = pat->next)
+    for (pat = patOrig; FcValueListPtrU(pat); 
+        pat = FcValueListPtrU(pat)->next)
     {
-       for (fnt = fntOrig; fnt; fnt = fnt->next)
+       for (fnt = fntOrig; FcValueListPtrU(fnt); 
+            fnt = FcValueListPtrU(fnt)->next)
        {
            /*
             * make sure the font 'contains' the pattern.
             * (OpListing is OpContains except for strings
             *  where it requires an exact match)
             */
-           if (FcConfigCompareValue (fnt->value,
+           if (FcConfigCompareValue (&FcValueListPtrU(fnt)->value,
                                      FcOpListing, 
-                                     pat->value)) 
+                                     &FcValueListPtrU(pat)->value)) 
                break;
        }
-       if (!fnt)
+       if (!FcValueListPtrU(fnt))
            return FcFalse;
     }
     return FcTrue;
 }
 
 static FcBool
-FcListValueListEqual (FcValueList   *v1orig,
-                     FcValueList   *v2orig)
+FcListValueListEqual (FcValueListPtr v1orig,
+                     FcValueListPtr v2orig)
 {
-    FcValueList            *v1, *v2;
+    FcValueListPtr         v1, v2;
 
-    for (v1 = v1orig; v1; v1 = v1->next)
+    for (v1 = v1orig; FcValueListPtrU(v1); 
+        v1 = FcValueListPtrU(v1)->next)
     {
-       for (v2 = v2orig; v2; v2 = v2->next)
-           if (FcValueEqual (v1->value, v2->value))
+       for (v2 = v2orig; FcValueListPtrU(v2); 
+            v2 = FcValueListPtrU(v2)->next)
+           if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
+                             FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
                break;
-       if (!v2)
+       if (!FcValueListPtrU(v2))
            return FcFalse;
     }
-    for (v2 = v2orig; v2; v2 = v2->next)
+    for (v2 = v2orig; FcValueListPtrU(v2); 
+        v2 = FcValueListPtrU(v2)->next)
     {
-       for (v1 = v1orig; v1; v1 = v1->next)
-           if (FcValueEqual (v1->value, v2->value))
+       for (v1 = v1orig; FcValueListPtrU(v1); 
+            v1 = FcValueListPtrU(v1)->next)
+           if (FcValueEqual (FcValueCanonicalize(&FcValueListPtrU(v1)->value),
+                             FcValueCanonicalize(&FcValueListPtrU(v2)->value)))
                break;
-       if (!v1)
+       if (!FcValueListPtrU(v1))
            return FcFalse;
     }
     return FcTrue;
@@ -209,30 +218,17 @@ FcListPatternMatchAny (const FcPattern *p,
 
     for (i = 0; i < p->num; i++)
     {
-       e = FcPatternFindElt (font, p->elts[i].object);
+       e = FcPatternFindElt (font, 
+                             FcObjectPtrU((FcPatternEltU(p->elts)+i)->object));
        if (!e)
            return FcFalse;
-       if (!FcListValueListMatchAny (p->elts[i].values,    /* pat elts */
+       if (!FcListValueListMatchAny ((FcPatternEltU(p->elts)+i)->values,    /* pat elts */
                                      e->values))           /* font elts */
            return FcFalse;
     }
     return FcTrue;
 }
 
-static FcChar32
-FcListStringHash (const FcChar8        *s)
-{
-    FcChar32   h = 0;
-    FcChar8    c;
-
-    while ((c = *s++))
-    {
-       c = FcToLower (c);
-       h = ((h << 3) ^ (h >> 3)) ^ c;
-    }
-    return h;
-}
-
 static FcChar32
 FcListMatrixHash (const FcMatrix *m)
 {
@@ -245,8 +241,9 @@ FcListMatrixHash (const FcMatrix *m)
 }
 
 static FcChar32
-FcListValueHash (FcValue    v)
+FcListValueHash (FcValue    *value)
 {
+    FcValue v = FcValueCanonicalize(value);
     switch (v.type) {
     case FcTypeVoid:
        return 0;
@@ -255,7 +252,7 @@ FcListValueHash (FcValue    v)
     case FcTypeDouble:
        return (FcChar32) (int) v.u.d;
     case FcTypeString:
-       return FcListStringHash (v.u.s);
+       return FcStrHashIgnoreCase (v.u.s);
     case FcTypeBool:
        return (FcChar32) v.u.b;
     case FcTypeMatrix:
@@ -271,14 +268,14 @@ FcListValueHash (FcValue    v)
 }
 
 static FcChar32
-FcListValueListHash (FcValueList    *list)
+FcListValueListHash (FcValueListPtr list)
 {
     FcChar32   h = 0;
     
-    while (list)
+    while (FcValueListPtrU(list))
     {
-       h = h ^ FcListValueHash (list->value);
-       list = list->next;
+       h = h ^ FcListValueHash (&FcValueListPtrU(list)->value);
+       list = FcValueListPtrU(list)->next;
     }
     return h;
 }
@@ -340,6 +337,34 @@ FcListHashTableCleanup (FcListHashTable *table)
     table->entries = 0;
 }
 
+static int
+FcGetDefaultObjectLangIndex (FcPattern *font, const char *object)
+{
+    FcChar8       *lang = FcGetDefaultLang ();
+    FcPatternElt   *e = FcPatternFindElt (font, object);
+    FcValueListPtr  v;
+    FcValue         value;
+    int             idx = -1;
+    int             i;
+
+    if (e)
+    {
+       for (v = e->values, i = 0; FcValueListPtrU(v); v = FcValueListPtrU(v)->next, ++i)
+       {
+           value = FcValueCanonicalize (&FcValueListPtrU (v)->value);
+
+           if (value.type == FcTypeString)
+           {
+               FcLangResult res = FcLangCompare (value.u.s, lang);
+               if (res == FcLangEqual || (res == FcLangDifferentCountry && idx < 0))
+                   idx = i;
+           }
+       }
+    }
+
+    return (idx > 0) ? idx : 0;
+}
+
 static FcBool
 FcListAppend (FcListHashTable  *table,
              FcPattern         *font,
@@ -347,9 +372,14 @@ FcListAppend (FcListHashTable      *table,
 {
     int                    o;
     FcPatternElt    *e;
-    FcValueList            *v;
+    FcValueListPtr  v;
     FcChar32       hash;
     FcListBucket    **prev, *bucket;
+    int             familyidx = -1;
+    int             fullnameidx = -1;
+    int             styleidx = -1;
+    int             defidx = 0;
+    int             idx;
 
     hash = FcListPatternHash (font, os);
     for (prev = &table->buckets[hash % FC_LIST_HASH_SIZE];
@@ -371,14 +401,44 @@ FcListAppend (FcListHashTable     *table,
     
     for (o = 0; o < os->nobject; o++)
     {
+       if (!strcmp (os->objects[o], FC_FAMILY) || !strcmp (os->objects[o], FC_FAMILYLANG))
+       {
+           if (familyidx < 0)
+               familyidx = FcGetDefaultObjectLangIndex (font, FC_FAMILYLANG);
+           defidx = familyidx;
+       }
+       else if (!strcmp (os->objects[o], FC_FULLNAME) || !strcmp (os->objects[o], FC_FULLNAMELANG))
+       {
+           if (fullnameidx < 0)
+               fullnameidx = FcGetDefaultObjectLangIndex (font, FC_FULLNAMELANG);
+           defidx = fullnameidx;
+       }
+       else if (!strcmp (os->objects[o], FC_STYLE) || !strcmp (os->objects[o], FC_STYLELANG))
+       {
+           if (styleidx < 0)
+               styleidx = FcGetDefaultObjectLangIndex (font, FC_STYLELANG);
+           defidx = styleidx;
+       }
+       else
+           defidx = 0;
+
+        /* Also, copy over the full path info. */
+       if (!strcmp (os->objects[o], FC_FILE))
+       {
+           FcChar8 * s;
+           FcPatternGetString (font, FC_FILE, 0, &s);
+           FcPatternAddFullFname (bucket->pattern, FcPatternFindFullFname(font));
+       }
+
        e = FcPatternFindElt (font, os->objects[o]);
        if (e)
        {
-           for (v = e->values; v; v = v->next)
+           for (v = e->values, idx = 0; FcValueListPtrU(v); 
+                v = FcValueListPtrU(v)->next, ++idx)
            {
                if (!FcPatternAdd (bucket->pattern, 
                                   os->objects[o], 
-                                  v->value, FcTrue))
+                                  FcValueCanonicalize(&FcValueListPtrU(v)->value), defidx != idx))
                    goto bail2;
            }
        }