* 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;
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)
{
}
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;
}
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;
}
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);
static int FcValueListFrozenCount[FcTypeLangSet + 1];
static int FcValueListFrozenBytes[FcTypeLangSet + 1];
-static char FcValueListFrozenName[][8] = {
+static const char FcValueListFrozenName[][8] = {
"Void",
"Integer",
"Double",
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++)
{
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));
(FcPatternEltU(b->elts)+i)->object;
}
- if (FcPatternFindElt (b, FC_FILE))
- FcPatternTransferFullFname (ep, b);
-
ent->hash = hash;
ent->next = *bucket;
*bucket = ent;
FcPattern *
FcPatternFreeze (FcPattern *p)
{
- FcPattern *b, *n = 0;
+ FcPattern *b, *n = 0, *freeme = 0;
FcPatternElt *e;
int i;
e = malloc(b->num * sizeof (FcPatternElt));
if (!e)
+ {
+ FcPatternDestroy (b);
return 0;
+ }
b->elts = FcPatternEltPtrCreateDynamic(e);
FcMemAlloc (FC_MEM_PATELT, sizeof (FcPatternElt)*(b->num));
(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
*/
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
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;
{
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);
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;
}
FcTrue))
goto bail1;
}
- FcPatternTransferFullFname (new, orig);
return new;
int
FcPatternNeededBytesAlign (void)
{
- return __alignof__ (FcPattern) + __alignof__ (FcPatternElt) +
+ return fc_alignof (FcPattern) + fc_alignof (FcPatternElt) +
FcValueListNeededBytesAlign ();
}
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)
{
FcValueListNeededBytesAlign (void)
{
return FcCharSetNeededBytesAlign() + FcLangSetNeededBytesAlign() +
- FcStrNeededBytesAlign() + __alignof__ (FcValueList);
+ FcStrNeededBytesAlign() + fc_alignof (FcValueList);
}
static FcBool
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)))
* 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;
static int
FcStrNeededBytesAlign (void)
{
- return __alignof__ (char);
+ return fc_alignof (char);
}
static FcBool
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;
}
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)));
-}