FcBool
FcNameBool (const FcChar8 *v, FcBool *result);
-void
-FcObjectNewBank(void);
-
void *
FcObjectDistributeBytes (FcCache * metadata,
void * block_ptr);
FcObjectToPtr (const char * si);
int
-FcObjectNeededBytes (FcObjectPtr p);
+FcObjectNeededBytes (void);
+
+void *
+FcObjectUnserialize (FcCache metadata, void *block_ptr);
void
-FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr);
+FcObjectSerialize (void);
-FcObjectPtr
-FcObjectSerialize (FcObjectPtr s);
+const char *
+FcObjectPtrU (FcObjectPtr p);
+
+int
+FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
+
+void
+FcObjectStaticNameFini (void);
/* fcpat.c */
FcPatternAppend (FcPattern *p, FcPattern *s);
const char *
-FcObjectStaticName (const char *name);
-
-const char *
-FcObjectPtrU (FcObjectPtr p);
+FcStrStaticName (const char *name);
-int
-FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
+FcChar32
+FcStringHash (const FcChar8 *s);
void
FcPatternNewBank (void);
FcPattern *
FcPatternSerialize (int bank, FcPattern * p);
-FcPattern *
+void *
FcPatternUnserialize (FcCache metadata, void *block_ptr);
/* fcrender.c */
#include <stdio.h>
#include "fcint.h"
+/* Please do not revoke any of these bindings. */
static const FcObjectType _FcBaseObjectTypes[] = {
{ FC_FAMILY, FcTypeString, },
{ FC_FAMILYLANG, FcTypeString, },
return FcTrue;
}
-FcBool
-FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
+static FcBool
+FcNameUnregisterObjectTypesFree (const FcObjectType *types, int ntypes,
+ FcBool do_free)
{
const FcObjectTypeList *l, **prev;
if (l->types == types && l->ntypes == ntypes)
{
*prev = l->next;
- FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
- free ((void *) l);
+ if (do_free) {
+ FcMemFree (FC_MEM_OBJECTTYPE, sizeof (FcObjectTypeList));
+ free ((void *) l);
+ }
return FcTrue;
}
}
return FcFalse;
}
+FcBool
+FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
+{
+ return FcNameUnregisterObjectTypesFree (types, ntypes, FcTrue);
+}
+
const FcObjectType *
FcNameGetObjectType (const char *object)
{
return 0;
}
-static int objectptr_count = 1;
-static int objectptr_alloc = 0;
-static int * objectptr_indices = 0;
-
-void
-FcObjectNewBank(void)
-{
- objectptr_count = 1;
- objectptr_alloc = 0;
- objectptr_indices = 0;
-}
-
-// XXX todo: introduce a hashtable for faster lookup
-FcObjectPtr
-FcObjectToPtr (const char * object)
+static FcObjectPtr
+FcObjectToPtrLookup (const char * object)
{
- int i;
+ FcObjectPtr i;
const FcObjectTypeList *l;
const FcObjectType *t;
-
+
for (l = _FcObjectTypes; l; l = l->next)
{
for (i = 0; i < l->ntypes; i++)
return i;
}
}
- abort();
return 0;
}
+#define OBJECT_HASH_SIZE 31
+struct objectBucket {
+ struct objectBucket *next;
+ FcChar32 hash;
+ int id;
+};
+static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
+
+static const FcObjectType *biggest_known_types = _FcBaseObjectTypes;
+static FcBool allocated_biggest_known_types;
+static int biggest_known_ntypes = NUM_OBJECT_TYPES;
+static int biggest_known_count = 0;
+static char * biggest_ptr;
+
+FcObjectPtr
+FcObjectToPtr (const char * name)
+{
+ FcChar32 hash = FcStringHash ((const FcChar8 *) name);
+ struct objectBucket **p;
+ struct objectBucket *b;
+ int size;
+
+ for (p = &FcObjectBuckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next)
+)
+ if (b->hash == hash && !strcmp (name, (char *) (b + 1)))
+ return b->id;
+ size = sizeof (struct objectBucket) + strlen (name) + 1;
+ b = malloc (size);
+ FcMemAlloc (FC_MEM_STATICSTR, size);
+ if (!b)
+ return -1;
+ b->next = 0;
+ b->hash = hash;
+ b->id = FcObjectToPtrLookup (name);
+ strcpy ((char *) (b + 1), name);
+ *p = b;
+ return b->id;
+}
+
+void
+FcObjectStaticNameFini (void)
+{
+ int i, size;
+ struct objectBucket *b, *next;
+ char *name;
+
+ for (i = 0; i < OBJECT_HASH_SIZE; i++)
+ {
+ for (b = FcObjectBuckets[i]; b; b = next)
+ {
+ next = b->next;
+ name = (char *) (b + 1);
+ size = sizeof (struct objectBucket) + strlen (name) + 1;
+ FcMemFree (FC_MEM_STATICSTR, size);
+ free (b);
+ }
+ FcObjectBuckets[i] = 0;
+ }
+}
+
const char *
FcObjectPtrU (FcObjectPtr si)
{
- return _FcObjectTypes->types[si].object;
+ return biggest_known_types[si].object;
}
int
-FcObjectNeededBytes (FcObjectPtr si)
+FcObjectNeededBytes ()
{
- return 0;
+ int num = 0, i;
+ for (i = 0; i < biggest_known_ntypes; i++)
+ {
+ const char * t = biggest_known_types[i].object;
+ num = num + strlen(t) + 1;
+ }
+ biggest_known_count = num;
+ return num + sizeof(int);
}
void *
FcObjectDistributeBytes (FcCache * metadata, void * block_ptr)
{
+ *(int *)block_ptr = biggest_known_ntypes;
+ block_ptr = (int *) block_ptr + 1;
+ biggest_ptr = block_ptr;
+ block_ptr = (char *) block_ptr + biggest_known_count;
return block_ptr;
}
-FcObjectPtr
-FcObjectSerialize (FcObjectPtr si)
+void
+FcObjectSerialize ()
{
- return si;
+ int i;
+ for (i = 0; i < biggest_known_ntypes; i++)
+ {
+ const char * t = biggest_known_types[i].object;
+ strcpy (biggest_ptr, t);
+ biggest_ptr = biggest_ptr + strlen(t) + 1;
+ }
}
-void
-FcObjectUnserialize (FcCache metadata, FcConfig * config, void *block_ptr)
+void *
+FcObjectUnserialize (FcCache metadata, void *block_ptr)
{
+ int new_biggest;
+ new_biggest = *(int *)block_ptr;
+ block_ptr = (int *) block_ptr + 1;
+ if (biggest_known_ntypes < new_biggest)
+ {
+ int i;
+ char * bp = (char *)block_ptr;
+ FcObjectType * bn;
+ FcObjectTypeList * bnl;
+
+ bn = malloc (sizeof (const FcObjectType) * (new_biggest + 1));
+ if (!bn)
+ return 0;
+
+ bnl = malloc (sizeof (FcObjectTypeList));
+ if (!bnl)
+ {
+ free (bn);
+ return 0;
+ }
+
+ for (i = 0; i < new_biggest; i++)
+ {
+ const FcObjectType * t = FcNameGetObjectType(bp);
+ if (t)
+ bn[i].type = t->type;
+ else
+ bn[i].type = FcTypeVoid;
+ bn[i].object = bp;
+ bp = bp + strlen(bp) + 1;
+ }
+
+ FcNameUnregisterObjectTypesFree (biggest_known_types, biggest_known_ntypes, FcFalse);
+ if (allocated_biggest_known_types)
+ {
+ free ((FcObjectTypeList *)biggest_known_types);
+ }
+ else
+ allocated_biggest_known_types = FcTrue;
+
+ FcNameRegisterObjectTypes (bn, new_biggest);
+ biggest_known_ntypes = new_biggest;
+ biggest_known_types = (const FcObjectType *)bn;
+ }
+ block_ptr = (char *) block_ptr + biggest_known_count;
+ return block_ptr;
}
int
v.u.i = atoi ((char *) string);
break;
case FcTypeString:
- v.u.s = FcObjectStaticName(string);
+ v.u.s = FcStrStaticName(string);
break;
case FcTypeBool:
if (!FcNameBool (string, &v.u.b))
return (FcChar32) d;
}
-static FcChar32
+FcChar32
FcStringHash (const FcChar8 *s)
{
FcChar8 c;
if ((FcValueListPtrU(l)->value.type & ~FC_STORAGE_STATIC) == FcTypeString)
{
new->value.type = FcTypeString;
- new->value.u.s = FcObjectStaticName
+ new->value.u.s = FcStrStaticName
(fc_value_string(&FcValueListPtrU(l)->value));
}
else
FcValue v;
v.type = FcTypeString;
- v.u.s = FcObjectStaticName(s);
+ v.u.s = FcStrStaticName(s);
return FcPatternAdd (p, object, v, FcTrue);
}
static struct objectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
const char *
-FcObjectStaticName (const char *name)
+FcStrStaticName (const char *name)
{
FcChar32 hash = FcStringHash ((const FcChar8 *) name);
struct objectBucket **p;
}
static void
-FcObjectStaticNameFini (void)
+FcStrStaticNameFini (void)
{
int i, size;
struct objectBucket *b, *next;
{
FcPatternBaseThawAll ();
FcValueListThawAll ();
+ FcStrStaticNameFini ();
FcObjectStaticNameFini ();
}
for (i = 0; i < p->num; i++)
{
- cum += FcObjectNeededBytes
- ((FcPatternEltU(p->elts)+i)->object);
c = FcValueListNeededBytes (FcValueListPtrU
(((FcPatternEltU(p->elts)+i)->values)));
if (c < 0)
}
nep[i].values = nv_head;
- nep[i].object = FcObjectSerialize (e->object);
+ nep[i].object = e->object;
}
p->elts = old->elts;
return p;
}
-FcPattern *
+void *
FcPatternUnserialize (FcCache metadata, void *block_ptr)
{
int bi = FcCacheBankToIndex(metadata.bank);
block_ptr = FcStrUnserialize (metadata, block_ptr);
block_ptr = FcValueListUnserialize (metadata, block_ptr);
- return fcpatterns[bi];
+ return block_ptr;
}
static void