Replace FcObjectStaticName by FcStrStaticName. Implement serialization of
'object' table (strings pointed to by FcPatternElt->object and used as keys) and loading of object table from cache file if more strings are present in cache file than in current version of fontconfig. Hash the object table in memory.
This commit is contained in:
parent
1b7be37790
commit
7f37423d8c
|
@ -773,7 +773,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
|
|||
break;
|
||||
case FcOpString:
|
||||
v.type = FcTypeString;
|
||||
v.u.s = FcObjectStaticName(e->u.sval);
|
||||
v.u.s = FcStrStaticName(e->u.sval);
|
||||
v = FcValueSave (v);
|
||||
break;
|
||||
case FcOpMatrix:
|
||||
|
@ -891,7 +891,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
|
|||
switch (e->op) {
|
||||
case FcOpPlus:
|
||||
v.type = FcTypeString;
|
||||
v.u.s = FcObjectStaticName (FcStrPlus (vl.u.s, vr.u.s));
|
||||
v.u.s = FcStrStaticName (FcStrPlus (vl.u.s, vr.u.s));
|
||||
|
||||
if (!v.u.s)
|
||||
v.type = FcTypeVoid;
|
||||
|
|
11
src/fcfs.c
11
src/fcfs.c
|
@ -87,7 +87,6 @@ void
|
|||
FcFontSetNewBank (void)
|
||||
{
|
||||
FcPatternNewBank();
|
||||
FcObjectNewBank();
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -104,7 +103,7 @@ FcFontSetNeededBytes (FcFontSet *s)
|
|||
}
|
||||
|
||||
if (cum > 0)
|
||||
return cum + sizeof(int);
|
||||
return cum + sizeof(int) + FcObjectNeededBytes();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -138,6 +137,7 @@ FcFontSetSerialize (int bank, FcFontSet * s)
|
|||
|
||||
s->fonts[i] = p;
|
||||
}
|
||||
FcObjectSerialize();
|
||||
|
||||
return FcTrue;
|
||||
}
|
||||
|
@ -166,10 +166,13 @@ FcFontSetUnserialize(FcCache metadata, FcFontSet * s, void * block_ptr)
|
|||
|
||||
if (nfont > 0)
|
||||
{
|
||||
FcPattern * p = FcPatternUnserialize (metadata, block_ptr);
|
||||
FcPattern * p = (FcPattern *)block_ptr;
|
||||
block_ptr = FcPatternUnserialize (metadata, block_ptr);
|
||||
for (i = 0; i < nfont; i++)
|
||||
s->fonts[n + i] = p+i;
|
||||
|
||||
block_ptr = FcObjectUnserialize (metadata, block_ptr);
|
||||
}
|
||||
|
||||
return FcTrue;
|
||||
return block_ptr != 0;
|
||||
}
|
||||
|
|
31
src/fcint.h
31
src/fcint.h
|
@ -808,9 +808,6 @@ FcListPatternMatchAny (const FcPattern *p,
|
|||
FcBool
|
||||
FcNameBool (const FcChar8 *v, FcBool *result);
|
||||
|
||||
void
|
||||
FcObjectNewBank(void);
|
||||
|
||||
void *
|
||||
FcObjectDistributeBytes (FcCache * metadata,
|
||||
void * block_ptr);
|
||||
|
@ -819,13 +816,22 @@ FcObjectPtr
|
|||
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 */
|
||||
|
||||
|
@ -858,13 +864,10 @@ FcBool
|
|||
FcPatternAppend (FcPattern *p, FcPattern *s);
|
||||
|
||||
const char *
|
||||
FcObjectStaticName (const char *name);
|
||||
FcStrStaticName (const char *name);
|
||||
|
||||
const char *
|
||||
FcObjectPtrU (FcObjectPtr p);
|
||||
|
||||
int
|
||||
FcObjectPtrCompare (FcObjectPtr a, FcObjectPtr b);
|
||||
FcChar32
|
||||
FcStringHash (const FcChar8 *s);
|
||||
|
||||
void
|
||||
FcPatternNewBank (void);
|
||||
|
@ -887,7 +890,7 @@ FcValueListPtrCreateDynamic(FcValueList * p);
|
|||
FcPattern *
|
||||
FcPatternSerialize (int bank, FcPattern * p);
|
||||
|
||||
FcPattern *
|
||||
void *
|
||||
FcPatternUnserialize (FcCache metadata, void *block_ptr);
|
||||
|
||||
/* fcrender.c */
|
||||
|
|
|
@ -67,7 +67,7 @@ FcObjectSetAdd (FcObjectSet *os, const char *object)
|
|||
low = 0;
|
||||
mid = 0;
|
||||
c = 1;
|
||||
object = FcObjectStaticName (object);
|
||||
object = FcStrStaticName (object);
|
||||
while (low <= high)
|
||||
{
|
||||
mid = (low + high) >> 1;
|
||||
|
|
181
src/fcname.c
181
src/fcname.c
|
@ -28,6 +28,7 @@
|
|||
#include <stdio.h>
|
||||
#include "fcint.h"
|
||||
|
||||
/* Please do not revoke any of these bindings. */
|
||||
static const FcObjectType _FcBaseObjectTypes[] = {
|
||||
{ FC_FAMILY, FcTypeString, },
|
||||
{ FC_FAMILYLANG, FcTypeString, },
|
||||
|
@ -106,8 +107,9 @@ FcNameRegisterObjectTypes (const FcObjectType *types, int ntypes)
|
|||
return FcTrue;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
|
||||
static FcBool
|
||||
FcNameUnregisterObjectTypesFree (const FcObjectType *types, int ntypes,
|
||||
FcBool do_free)
|
||||
{
|
||||
const FcObjectTypeList *l, **prev;
|
||||
|
||||
|
@ -118,14 +120,22 @@ FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
|
|||
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)
|
||||
{
|
||||
|
@ -145,26 +155,13 @@ FcNameGetObjectType (const char *object)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int objectptr_count = 1;
|
||||
static int objectptr_alloc = 0;
|
||||
static int * objectptr_indices = 0;
|
||||
|
||||
void
|
||||
FcObjectNewBank(void)
|
||||
static FcObjectPtr
|
||||
FcObjectToPtrLookup (const char * object)
|
||||
{
|
||||
objectptr_count = 1;
|
||||
objectptr_alloc = 0;
|
||||
objectptr_indices = 0;
|
||||
}
|
||||
|
||||
// XXX todo: introduce a hashtable for faster lookup
|
||||
FcObjectPtr
|
||||
FcObjectToPtr (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++)
|
||||
|
@ -174,37 +171,159 @@ FcObjectToPtr (const char * object)
|
|||
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
|
||||
|
@ -389,7 +508,7 @@ FcNameConvert (FcType type, FcChar8 *string, FcMatrix *m)
|
|||
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))
|
||||
|
|
19
src/fcpat.c
19
src/fcpat.c
|
@ -214,7 +214,7 @@ FcDoubleHash (double d)
|
|||
return (FcChar32) d;
|
||||
}
|
||||
|
||||
static FcChar32
|
||||
FcChar32
|
||||
FcStringHash (const FcChar8 *s)
|
||||
{
|
||||
FcChar8 c;
|
||||
|
@ -391,7 +391,7 @@ FcValueListEntCreate (FcValueListPtr h)
|
|||
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
|
||||
|
@ -984,7 +984,7 @@ FcPatternAddString (FcPattern *p, const char *object, const FcChar8 *s)
|
|||
FcValue v;
|
||||
|
||||
v.type = FcTypeString;
|
||||
v.u.s = FcObjectStaticName(s);
|
||||
v.u.s = FcStrStaticName(s);
|
||||
return FcPatternAdd (p, object, v, FcTrue);
|
||||
}
|
||||
|
||||
|
@ -1287,7 +1287,7 @@ struct objectBucket {
|
|||
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;
|
||||
|
@ -1311,7 +1311,7 @@ FcObjectStaticName (const char *name)
|
|||
}
|
||||
|
||||
static void
|
||||
FcObjectStaticNameFini (void)
|
||||
FcStrStaticNameFini (void)
|
||||
{
|
||||
int i, size;
|
||||
struct objectBucket *b, *next;
|
||||
|
@ -1336,6 +1336,7 @@ FcPatternFini (void)
|
|||
{
|
||||
FcPatternBaseThawAll ();
|
||||
FcValueListThawAll ();
|
||||
FcStrStaticNameFini ();
|
||||
FcObjectStaticNameFini ();
|
||||
}
|
||||
|
||||
|
@ -1409,8 +1410,6 @@ FcPatternNeededBytes (FcPattern * p)
|
|||
|
||||
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)
|
||||
|
@ -1526,7 +1525,7 @@ FcPatternSerialize (int bank, FcPattern *old)
|
|||
}
|
||||
|
||||
nep[i].values = nv_head;
|
||||
nep[i].object = FcObjectSerialize (e->object);
|
||||
nep[i].object = e->object;
|
||||
}
|
||||
|
||||
p->elts = old->elts;
|
||||
|
@ -1537,7 +1536,7 @@ FcPatternSerialize (int bank, FcPattern *old)
|
|||
return p;
|
||||
}
|
||||
|
||||
FcPattern *
|
||||
void *
|
||||
FcPatternUnserialize (FcCache metadata, void *block_ptr)
|
||||
{
|
||||
int bi = FcCacheBankToIndex(metadata.bank);
|
||||
|
@ -1558,7 +1557,7 @@ FcPatternUnserialize (FcCache metadata, void *block_ptr)
|
|||
block_ptr = FcStrUnserialize (metadata, block_ptr);
|
||||
block_ptr = FcValueListUnserialize (metadata, block_ptr);
|
||||
|
||||
return fcpatterns[bi];
|
||||
return block_ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in New Issue