]> git.wh0rd.org - fontconfig.git/blobdiff - src/fcpat.c
Make path names in cache files absolute (NB, cache format change) Stop
[fontconfig.git] / src / fcpat.c
index a626ab6b120256bbb094eecaf9381640126f8a86..c78e670a6b2200ffc17872d680be7d4d0c151732 100644 (file)
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include "fcint.h"
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
-#include "fcint.h"
 
 static FcPattern ** _fcPatterns = 0;
 static int fcpattern_bank_count = 0, fcpattern_ptr, fcpattern_count;
@@ -39,16 +39,6 @@ FcPatternEltPtrCreateDynamic (FcPatternElt * e);
 static FcBool
 FcStrHashed (const FcChar8 *name);
 
-static const char *
-FcPatternFindFullFname (const FcPattern *p);
-
-/* If you are trying to duplicate an FcPattern which will be used for
- * rendering, be aware that (internally) you also have to use
- * FcPatternTransferFullFname to transfer the associated filename.  If
- * you are copying the font (externally) using FcPatternGetString,
- * then everything's fine; this caveat only applies if you're copying
- * the bits individually.  */
-
 FcPattern *
 FcPatternCreate (void)
 {
@@ -241,32 +231,31 @@ FcStringHash (const FcChar8 *s)
 }
 
 static FcChar32
-FcValueHash (const FcValue *v0)
+FcValueHash (const FcValue *v)
 {
-    FcValue v = FcValueCanonicalize(v0);
-    switch (v.type) {
+    switch (fc_storage_type(v)) {
     case FcTypeVoid:
        return 0;
     case FcTypeInteger:
-       return (FcChar32) v.u.i;
+       return (FcChar32) v->u.i;
     case FcTypeDouble:
-       return FcDoubleHash (v.u.d);
+       return FcDoubleHash (v->u.d);
     case FcTypeString:
-       return FcStringHash (v.u.s);
+       return FcStringHash (fc_value_string(v));
     case FcTypeBool:
-       return (FcChar32) v.u.b;
+       return (FcChar32) v->u.b;
     case FcTypeMatrix:
-       return (FcDoubleHash (v.u.m->xx) ^ 
-               FcDoubleHash (v.u.m->xy) ^ 
-               FcDoubleHash (v.u.m->yx) ^ 
-               FcDoubleHash (v.u.m->yy));
+       return (FcDoubleHash (v->u.m->xx) ^ 
+               FcDoubleHash (v->u.m->xy) ^ 
+               FcDoubleHash (v->u.m->yx) ^ 
+               FcDoubleHash (v->u.m->yy));
     case FcTypeCharSet:
-       return (FcChar32) v.u.c->num;
+       return (FcChar32) fc_value_charset(v)->num;
     case FcTypeFTFace:
-       return FcStringHash ((const FcChar8 *) ((FT_Face) v.u.f)->family_name) ^
-              FcStringHash ((const FcChar8 *) ((FT_Face) v.u.f)->style_name);
+       return FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->family_name) ^
+              FcStringHash ((const FcChar8 *) ((FT_Face) v->u.f)->style_name);
     case FcTypeLangSet:
-       return FcLangSetHash (v.u.l);
+       return FcLangSetHash (fc_value_langset(v));
     }
     return FcFalse;
 }
@@ -294,12 +283,12 @@ static FcChar32
 FcValueListHash (FcValueListPtr l)
 {
     FcChar32   hash = 0;
+    FcValueList *l_ptrU;
     
-    while (FcValueListPtrU(l))
+    for (l_ptrU = FcValueListPtrU(l); l_ptrU; 
+        l_ptrU = FcValueListPtrU(l_ptrU->next))
     {
-       hash = ((hash << 1) | (hash >> 31)) ^ 
-           FcValueHash (&FcValueListPtrU(l)->value);
-       l = FcValueListPtrU(l)->next;
+       hash = ((hash << 1) | (hash >> 31)) ^ FcValueHash (&l_ptrU->value);
     }
     return hash;
 }
@@ -312,12 +301,6 @@ FcPatternDestroy (FcPattern *p)
     if (p->ref == FC_REF_CONSTANT || --p->ref > 0)
        return;
 
-    if (FcPatternFindFullFname (p))
-    {
-       FcStrFree ((FcChar8 *)FcPatternFindFullFname (p));
-       FcPatternAddFullFname (p, 0);
-    }
-
     for (i = 0; i < p->num; i++)
        FcValueListDestroy ((FcPatternEltU(p->elts)+i)->values);
 
@@ -351,7 +334,7 @@ typedef union _FcValueListAlign {
 
 static int         FcValueListFrozenCount[FcTypeLangSet + 1];
 static int         FcValueListFrozenBytes[FcTypeLangSet + 1];
-static char        FcValueListFrozenName[][8] = {
+static const char   FcValueListFrozenName[][8] = {
     "Void", 
     "Integer", 
     "Double", 
@@ -394,17 +377,20 @@ FcValueListEntCreate (FcValueListPtr h)
     size = sizeof (FcValueListAlign) + n * sizeof (FcValueList);
     FcValueListFrozenCount[FcValueListPtrU(h)->value.type]++;
     FcValueListFrozenBytes[FcValueListPtrU(h)->value.type] += size;
-    // this leaks for some reason
+    /* this leaks for some reason */
     ea = malloc (sizeof (FcValueListAlign));
     if (!ea)
        return 0;
     new = malloc (n * sizeof (FcValueList));
     if (!new)
+    {
+        free (ea);
         return 0;
+    }
     memset(new, 0, n * sizeof (FcValueList));
     FcMemAlloc (FC_MEM_VALLIST, size);
     e = &ea->ent;
-    e->list = (FcValueListPtr) FcValueListPtrCreateDynamic(new);
+    e->list = FcValueListPtrCreateDynamic(new);
     for (l = h; FcValueListPtrU(l); 
         l = FcValueListPtrU(l)->next, new++)
     {
@@ -576,11 +562,14 @@ FcPatternBaseFreeze (FcPattern *b)
 
     ep = FcPatternCreate();
     if (!ep)
-        return 0;
+        goto bail;
     ent->pattern = ep;
     epp = malloc(b->num * sizeof (FcPatternElt));
     if (!epp)
+    {
+        FcPatternDestroy (ep);
         goto bail;
+    }
     ep->elts = FcPatternEltPtrCreateDynamic(epp);
 
     FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num));
@@ -597,9 +586,6 @@ FcPatternBaseFreeze (FcPattern *b)
            (FcPatternEltU(b->elts)+i)->object;
     }
 
-    if (FcPatternFindElt (b, FC_FILE))
-       FcPatternTransferFullFname (ep, b);
-
     ent->hash = hash;
     ent->next = *bucket;
     *bucket = ent;
@@ -634,7 +620,7 @@ FcPatternBaseThawAll (void)
 FcPattern *
 FcPatternFreeze (FcPattern *p)
 {
-    FcPattern  *b, *n = 0;
+    FcPattern  *b, *n = 0, *freeme = 0;
     FcPatternElt *e;
     int                i;
     
@@ -651,7 +637,10 @@ FcPatternFreeze (FcPattern *p)
 
     e = malloc(b->num * sizeof (FcPatternElt));
     if (!e)
+    {
+        FcPatternDestroy (b);
         return 0;
+    }
     b->elts = FcPatternEltPtrCreateDynamic(e);
     FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num));
 
@@ -665,12 +654,12 @@ FcPatternFreeze (FcPattern *p)
        (FcPatternEltU(b->elts)+i)->values = 
            FcValueListFreeze((FcPatternEltU(p->elts)+i)->values);
        if (!FcValueListPtrU((FcPatternEltU(p->elts)+i)->values))
+        {
+           freeme = b;
            goto bail;
+        }
     }
 
-    if (FcPatternFindElt (p, FC_FILE))
-       FcPatternTransferFullFname (b, p);
-
     /*
      * Freeze base
      */
@@ -687,6 +676,8 @@ FcPatternFreeze (FcPattern *p)
     b->elts = FcPatternEltPtrCreateDynamic(0);
     FcMemFree (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num));
     b->num = -1;
+    if (freeme)
+       FcPatternDestroy (freeme);
 #ifdef DEBUG
     assert (FcPatternEqual (n, p));
 #endif
@@ -874,7 +865,14 @@ FcPatternAddWithBinding  (FcPattern            *p,
     new = FcValueListPtrCreateDynamic(newp);
     FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
     /* dup string */
-    value = FcValueSave (value);
+    if (value.type == FcTypeString)
+    {
+       value.u.s = FcStrStaticName (value.u.s);
+       if (!value.u.s)
+           value.type = FcTypeVoid;
+    }
+    else
+       value = FcValueSave (value);
     if (value.type == FcTypeVoid)
        goto bail1;
 
@@ -1029,6 +1027,13 @@ FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
 {
     FcValue    v;
 
+    if (!s)
+    {
+       v.type = FcTypeVoid;
+       v.u.s = 0;
+       return FcPatternAdd (p, object, v, FcTrue);
+    }
+
     v.type = FcTypeString;
     v.u.s = FcStrStaticName(s);
     return FcPatternAdd (p, object, v, FcTrue);
@@ -1162,41 +1167,6 @@ FcPatternGetString (const FcPattern *p, const char *object, int id, FcChar8 ** s
     if (v.type != FcTypeString)
         return FcResultTypeMismatch;
 
-    if (FcObjectToPtr(object) == FcObjectToPtr(FC_FILE))
-    {
-       const char *fn, *fpath;
-       FcChar8 *fname;
-       int size;
-
-       fn = FcPatternFindFullFname(p);
-       if (fn)
-       {
-           *s = (FcChar8 *) fn;
-           return FcResultMatch;
-       }
-
-       if (!p->bank)
-       {
-           *s = (FcChar8 *) v.u.s;
-           return FcResultMatch;
-       }
-
-       fpath = FcCacheFindBankDir (p->bank);
-       size = strlen((char*)fpath) + 1 + strlen ((char *)v.u.s) + 1;
-       fname = malloc (size);
-       if (!fname)
-           return FcResultOutOfMemory;
-
-       FcMemAlloc (FC_MEM_STRING, size);
-       strcpy ((char *)fname, (char *)fpath);
-       strcat ((char *)fname, "/");
-       strcat ((char *)fname, (char *)v.u.s);
-       
-       FcPatternAddFullFname (p, (const char *)fname);
-       *s = (FcChar8 *)fname;
-       return FcResultMatch;
-    }
-
     *s = (FcChar8 *) v.u.s;
     return FcResultMatch;
 }
@@ -1301,7 +1271,6 @@ FcPatternDuplicate (const FcPattern *orig)
                               FcTrue))
                goto bail1;
     }
-    FcPatternTransferFullFname (new, orig);
 
     return new;
 
@@ -1514,7 +1483,7 @@ FcPatternNeededBytes (FcPattern * p)
 int
 FcPatternNeededBytesAlign (void)
 {
-    return __alignof__ (FcPattern) + __alignof__ (FcPatternElt) + 
+    return fc_alignof (FcPattern) + fc_alignof (FcPatternElt) + 
        FcValueListNeededBytesAlign ();
 }
 
@@ -1681,7 +1650,8 @@ FcValueListNeededBytes (FcValueList *p)
         vl; 
         vl = FcValueListPtrU(vl->next))
     {
-       FcValue v = FcValueCanonicalize(&vl->value); // unserialize just in case
+        /* unserialize just in case */
+        FcValue v = FcValueCanonicalize(&vl->value); 
 
        switch (v.type)
        {
@@ -1707,7 +1677,7 @@ static int
 FcValueListNeededBytesAlign (void)
 {
     return FcCharSetNeededBytesAlign() + FcLangSetNeededBytesAlign() + 
-       FcStrNeededBytesAlign() + __alignof__ (FcValueList);
+       FcStrNeededBytesAlign() + fc_alignof (FcValueList);
 }
 
 static FcBool
@@ -1881,6 +1851,7 @@ FcStrNeededBytes (const FcChar8 * s)
     struct objectBucket **p;
     struct objectBucket *b;
     int                 size;
+    FcChar8 *const null = 0;
 
     for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
         if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1)))
@@ -1898,7 +1869,8 @@ FcStrNeededBytes (const FcChar8 * s)
      * incorrect to replace the with a memset, because the C
      * specification doesn't guarantee that the null pointer is
      * the same as the zero bit pattern. */
-    *(char **)((char *) (b + 1) + strlen((char *)s) + 1) = 0;
+    /* Misaligned pointers are not guaranteed to work, either! */
+    memcpy (((char *) (b + 1) + strlen((char *)s) + 1), &null, sizeof (null));
     *p = b;
 
     fcstr_count += strlen((char *)s) + 1;
@@ -1908,7 +1880,7 @@ FcStrNeededBytes (const FcChar8 * s)
 static int
 FcStrNeededBytesAlign (void)
 {
-    return __alignof__ (char);
+    return fc_alignof (char);
 }
 
 static FcBool
@@ -1961,13 +1933,15 @@ FcStrSerialize (int bank, const FcChar8 * s)
     for (p = &FcStrBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
         if (b->hash == hash && !strcmp ((char *)s, (char *) (b + 1)))
        {
-           FcChar8 * t = *(FcChar8 **)(((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1);
+           FcChar8 * t;
+           memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *));
            if (!t)
            {
                strcpy((char *)(static_strs[bi] + fcstr_ptr), (char *)s);
-               *(FcChar8 **)((FcChar8 *) (b + 1) + strlen((char *)s) + 1) = (static_strs[bi] + fcstr_ptr);
+               t = static_strs[bi] + fcstr_ptr;
+               memcpy ((FcChar8 *) (b + 1) + strlen((char *)s) + 1, &t, sizeof (FcChar8 *));
                fcstr_ptr += strlen((char *)s) + 1;
-               t = *(FcChar8 **)(((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1);
+               memcpy (&t, ((FcChar8 *)(b + 1)) + strlen ((char *)s) + 1, sizeof (FcChar8 *));
            }
            return t;
        }
@@ -1989,71 +1963,3 @@ FcStrUnserialize (FcCache * metadata, void *block_ptr)
 
     return block_ptr;
 }
-
-/* we don't store these in the FcPattern itself because
- * we don't want to serialize the directory names */
-
-/* I suppose this should be cleaned, too... */
-typedef struct _FcPatternDirMapping {
-    const FcPattern    *p;
-    const char *fname;
-} FcPatternDirMapping;
-
-#define PATTERNDIR_HASH_SIZE    31
-static struct patternDirBucket {
-    struct patternDirBucket    *next;
-    FcPatternDirMapping                m;
-} FcPatternDirBuckets[PATTERNDIR_HASH_SIZE];
-
-void
-FcPatternAddFullFname (const FcPattern *p, const char *fname)
-{
-    struct patternDirBucket    *pb;
-
-    /* N.B. FcPatternHash fails, since it's contents-based, not
-     * address-based, and we're in the process of mutating the FcPattern. */
-    for (pb = &FcPatternDirBuckets
-             [((int)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE];
-         pb->m.p != p && pb->next; 
-         pb = pb->next)
-        ;
-
-    if (pb->m.p == p)
-    {
-        pb->m.fname = fname;
-        return;
-    }
-
-    pb->next = malloc (sizeof (struct patternDirBucket));
-    if (!pb->next)
-        return;
-    FcMemAlloc (FC_MEM_CACHE, sizeof (struct patternDirBucket));
-
-    pb->next->next = 0;
-    pb->next->m.p = p;
-    pb->next->m.fname = fname;
-}
-
-static const char *
-FcPatternFindFullFname (const FcPattern *p)
-{
-    struct patternDirBucket    *pb;
-
-    for (pb = &FcPatternDirBuckets
-             [((int)p / sizeof (FcPattern *)) % PATTERNDIR_HASH_SIZE]; 
-         pb; pb = pb->next)
-       if (pb->m.p == p)
-           return pb->m.fname;
-
-    return 0;
-}
-
-void
-FcPatternTransferFullFname (const FcPattern *new, const FcPattern *orig)
-{
-    FcChar8 * s;
-    FcPatternGetString (orig, FC_FILE, 0, &s);
-    FcPatternAddFullFname (new, 
-                          (char *)FcStrCopy 
-                          ((FcChar8 *)FcPatternFindFullFname(orig)));
-}