Use a static perfect hash table for object-name lookup

The hash table is generated by gperf.  For runtime element types, we use
a append-only linked list.

A bit clumsy, but I think I got it right.
This commit is contained in:
Behdad Esfahbod 2012-09-20 14:42:31 -04:00
parent 7c0f79c5fe
commit d58c31e6dc
7 changed files with 291 additions and 330 deletions

View File

@ -21,6 +21,8 @@
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE. # PERFORMANCE OF THIS SOFTWARE.
EXTRA_DIST =
if OS_WIN32 if OS_WIN32
export_symbols = -export-symbols fontconfig.def export_symbols = -export-symbols fontconfig.def
@ -78,7 +80,7 @@ INCLUDES = \
-DFC_CACHEDIR='"$(FC_CACHEDIR)"' \ -DFC_CACHEDIR='"$(FC_CACHEDIR)"' \
-DFONTCONFIG_PATH='"$(BASECONFIGDIR)"' -DFONTCONFIG_PATH='"$(BASECONFIGDIR)"'
EXTRA_DIST = makealias EXTRA_DIST += makealias
noinst_HEADERS=fcint.h fcftint.h fcdeprecate.h fcstdint.h noinst_HEADERS=fcint.h fcftint.h fcdeprecate.h fcstdint.h
@ -88,7 +90,8 @@ BUILT_SOURCES = $(ALIAS_FILES) \
../fc-case/fccase.h \ ../fc-case/fccase.h \
../fc-glyphname/fcglyphname.h \ ../fc-glyphname/fcglyphname.h \
../fc-lang/fclang.h \ ../fc-lang/fclang.h \
stamp-fcstdint stamp-fcstdint \
fcobjshash.h
noinst_PROGRAMS = fcarch noinst_PROGRAMS = fcarch
@ -99,6 +102,22 @@ noinst_PROGRAMS = fcarch
../fc-lang/fclang.h: ../fc-lang/fclang.h:
cd ../fc-lang && $(MAKE) $(AM_MAKEFLAGS) fclang.h cd ../fc-lang && $(MAKE) $(AM_MAKEFLAGS) fclang.h
fcobjshash.gperf: fcobjshash.gperf.h fcobjs.h
$(AM_V_GEN) $(CPP) -I$(top_srcdir) $< | $(GREP) '^[^#]' | awk ' \
/CUT_OUT_BEGIN/ { no_write=1; next; }; \
/CUT_OUT_END/ { no_write=0; next; }; \
{ if (!no_write) print; next; }; \
' - > $@.tmp && \
mv -f $@.tmp $@
fcobjshash.h: fcobjshash.gperf
$(AM_V_GEN) $(top_srcdir)/missing --run gperf -m 100 $< > $@.tmp && \
mv -f $@.tmp $@
EXTRA_DIST += \
fcobjshash.gperf.h \
fcobjshash.gperf
libfontconfig_la_SOURCES = \ libfontconfig_la_SOURCES = \
fcarch.h \ fcarch.h \
fcatomic.c \ fcatomic.c \
@ -118,6 +137,9 @@ libfontconfig_la_SOURCES = \
fcmatch.c \ fcmatch.c \
fcmatrix.c \ fcmatrix.c \
fcname.c \ fcname.c \
fcobjs.c \
fcobjs.h \
fcobjshash.h \
fcpat.c \ fcpat.c \
fcserialize.c \ fcserialize.c \
fcstat.c \ fcstat.c \

View File

@ -155,7 +155,6 @@ FcFini (void)
if (_fcConfig) if (_fcConfig)
FcConfigDestroy (_fcConfig); FcConfigDestroy (_fcConfig);
FcObjectFini ();
FcCacheFini (); FcCacheFini ();
} }

View File

@ -819,54 +819,14 @@ FcListPatternMatchAny (const FcPattern *p,
/* fcname.c */ /* fcname.c */
/* enum {
* NOTE -- this ordering is part of the cache file format. FC_INVALID_OBJECT = 0,
* It must also match the ordering in fcname.c #define FC_OBJECT(NAME, Type) FC_##NAME##_OBJECT,
*/ #include "fcobjs.h"
#undef FC_OBJECT
#define FC_FAMILY_OBJECT 1 FC_ONE_AFTER_MAX_BASE_OBJECT
#define FC_FAMILYLANG_OBJECT 2 #define FC_MAX_BASE_OBJECT (FC_ONE_AFTER_MAX_BASE_OBJECT - 1)
#define FC_STYLE_OBJECT 3 };
#define FC_STYLELANG_OBJECT 4
#define FC_FULLNAME_OBJECT 5
#define FC_FULLNAMELANG_OBJECT 6
#define FC_SLANT_OBJECT 7
#define FC_WEIGHT_OBJECT 8
#define FC_WIDTH_OBJECT 9
#define FC_SIZE_OBJECT 10
#define FC_ASPECT_OBJECT 11
#define FC_PIXEL_SIZE_OBJECT 12
#define FC_SPACING_OBJECT 13
#define FC_FOUNDRY_OBJECT 14
#define FC_ANTIALIAS_OBJECT 15
#define FC_HINT_STYLE_OBJECT 16
#define FC_HINTING_OBJECT 17
#define FC_VERTICAL_LAYOUT_OBJECT 18
#define FC_AUTOHINT_OBJECT 19
#define FC_GLOBAL_ADVANCE_OBJECT 20 /* deprecated */
#define FC_FILE_OBJECT 21
#define FC_INDEX_OBJECT 22
#define FC_RASTERIZER_OBJECT 23
#define FC_OUTLINE_OBJECT 24
#define FC_SCALABLE_OBJECT 25
#define FC_DPI_OBJECT 26
#define FC_RGBA_OBJECT 27
#define FC_SCALE_OBJECT 28
#define FC_MINSPACE_OBJECT 29
#define FC_CHAR_WIDTH_OBJECT 30
#define FC_CHAR_HEIGHT_OBJECT 31
#define FC_MATRIX_OBJECT 32
#define FC_CHARSET_OBJECT 33
#define FC_LANG_OBJECT 34
#define FC_FONTVERSION_OBJECT 35
#define FC_CAPABILITY_OBJECT 36
#define FC_FONTFORMAT_OBJECT 37
#define FC_EMBOLDEN_OBJECT 38
#define FC_EMBEDDED_BITMAP_OBJECT 39
#define FC_DECORATIVE_OBJECT 40
#define FC_LCD_FILTER_OBJECT 41
#define FC_NAMELANG_OBJECT 42
#define FC_MAX_BASE_OBJECT FC_NAMELANG_OBJECT
FcPrivate FcBool FcPrivate FcBool
FcNameBool (const FcChar8 *v, FcBool *result); FcNameBool (const FcChar8 *v, FcBool *result);
@ -883,12 +843,6 @@ FcObjectName (FcObject object);
FcPrivate FcObjectSet * FcPrivate FcObjectSet *
FcObjectGetSet (void); FcObjectGetSet (void);
FcPrivate FcBool
FcObjectInit (void);
FcPrivate void
FcObjectFini (void);
#define FcObjectCompare(a, b) ((int) a - (int) b) #define FcObjectCompare(a, b) ((int) a - (int) b)
/* fcpat.c */ /* fcpat.c */
@ -1102,4 +1056,21 @@ FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str);
FcPrivate FcChar8 * FcPrivate FcChar8 *
FcStrSerialize (FcSerialize *serialize, const FcChar8 *str); FcStrSerialize (FcSerialize *serialize, const FcChar8 *str);
/* fcobjs.c */
FcPrivate FcObject
FcObjectLookupIdByName (const char *str);
FcPrivate FcObject
FcObjectLookupBuiltinIdByName (const char *str);
FcPrivate const char *
FcObjectLookupOtherNameById (FcObject id);
FcPrivate const FcObjectType *
FcObjectLookupOtherTypeById (FcObject id);
FcPrivate const FcObjectType *
FcObjectLookupOtherTypeByName (const char *str);
#endif /* _FC_INT_H_ */ #endif /* _FC_INT_H_ */

View File

@ -28,209 +28,20 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
/* static const FcObjectType FcObjects[] = {
* Please do not change this list, it is used to initialize the object #define FC_OBJECT(NAME, Type) { FC_##NAME, Type },
* list in this order to match the FC_foo_OBJECT constants. Those #include "fcobjs.h"
* constants are written into cache files. #undef FC_OBJECT
*/
static const FcObjectType _FcBaseObjectTypes[] = {
{ FC_FAMILY, FcTypeString, }, /* 1 */
{ FC_FAMILYLANG, FcTypeString, },
{ FC_STYLE, FcTypeString, },
{ FC_STYLELANG, FcTypeString, },
{ FC_FULLNAME, FcTypeString, },
{ FC_FULLNAMELANG, FcTypeString, },
{ FC_SLANT, FcTypeInteger, },
{ FC_WEIGHT, FcTypeInteger, },
{ FC_WIDTH, FcTypeInteger, },
{ FC_SIZE, FcTypeDouble, },
{ FC_ASPECT, FcTypeDouble, },
{ FC_PIXEL_SIZE, FcTypeDouble, },
{ FC_SPACING, FcTypeInteger, },
{ FC_FOUNDRY, FcTypeString, },
{ FC_ANTIALIAS, FcTypeBool, },
{ FC_HINT_STYLE, FcTypeInteger, },
{ FC_HINTING, FcTypeBool, },
{ FC_VERTICAL_LAYOUT, FcTypeBool, },
{ FC_AUTOHINT, FcTypeBool, },
{ FC_GLOBAL_ADVANCE, FcTypeBool, }, /* deprecated */
{ FC_FILE, FcTypeString, },
{ FC_INDEX, FcTypeInteger, },
{ FC_RASTERIZER, FcTypeString, },
{ FC_OUTLINE, FcTypeBool, },
{ FC_SCALABLE, FcTypeBool, },
{ FC_DPI, FcTypeDouble },
{ FC_RGBA, FcTypeInteger, },
{ FC_SCALE, FcTypeDouble, },
{ FC_MINSPACE, FcTypeBool, },
{ FC_CHAR_WIDTH, FcTypeInteger },
{ FC_CHAR_HEIGHT, FcTypeInteger },
{ FC_MATRIX, FcTypeMatrix },
{ FC_CHARSET, FcTypeCharSet },
{ FC_LANG, FcTypeLangSet },
{ FC_FONTVERSION, FcTypeInteger },
{ FC_CAPABILITY, FcTypeString },
{ FC_FONTFORMAT, FcTypeString },
{ FC_EMBOLDEN, FcTypeBool },
{ FC_EMBEDDED_BITMAP, FcTypeBool },
{ FC_DECORATIVE, FcTypeBool },
{ FC_LCD_FILTER, FcTypeInteger }, /* 41 */
{ FC_NAMELANG, FcTypeString }, /* 42 */
}; };
#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0]) #define NUM_OBJECT_TYPES ((int) (sizeof FcObjects / sizeof FcObjects[0]))
typedef struct _FcObjectTypeList FcObjectTypeList; static const FcObjectType *
struct _FcObjectTypeList {
const FcObjectTypeList *next;
const FcObjectType *types;
int ntypes;
};
static const FcObjectTypeList _FcBaseObjectTypesList = {
0,
_FcBaseObjectTypes,
NUM_OBJECT_TYPES,
};
static const FcObjectTypeList *_FcObjectTypes = &_FcBaseObjectTypesList;
#define OBJECT_HASH_SIZE 31
typedef struct _FcObjectBucket {
struct _FcObjectBucket *next;
FcChar32 hash;
FcObject id;
} FcObjectBucket;
static FcObjectBucket *FcObjectBuckets[OBJECT_HASH_SIZE];
static FcObjectType *FcObjects = (FcObjectType *) _FcBaseObjectTypes;
static int FcObjectsNumber = NUM_OBJECT_TYPES;
static int FcObjectsSize = 0;
static FcBool FcObjectsInited;
static FcObjectType *
FcObjectInsert (const char *name, FcType type)
{
FcObjectType *o;
if (FcObjectsNumber >= FcObjectsSize)
{
int newsize = FcObjectsNumber * 2;
FcObjectType *newobjects;
if (FcObjectsSize)
newobjects = realloc (FcObjects, newsize * sizeof (FcObjectType));
else
{
newobjects = malloc (newsize * sizeof (FcObjectType));
if (newobjects)
memcpy (newobjects, FcObjects,
FcObjectsNumber * sizeof (FcObjectType));
}
if (!newobjects)
return NULL;
FcObjects = newobjects;
FcObjectsSize = newsize;
}
o = &FcObjects[FcObjectsNumber];
o->object = name;
o->type = type;
++FcObjectsNumber;
return o;
}
static FcObject
FcObjectId (FcObjectType *o)
{
return o - FcObjects + 1;
}
static FcObjectType *
FcObjectFindByName (const char *object, FcBool insert)
{
FcChar32 hash = FcStringHash ((const FcChar8 *) object);
FcObjectBucket **p;
FcObjectBucket *b;
FcObjectType *o;
if (!FcObjectsInited)
FcObjectInit ();
for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
{
o = FcObjects + b->id - 1;
if (b->hash == hash && !strcmp (object, (o->object)))
return o;
}
if (!insert)
return NULL;
/*
* Hook it into the hash chain
*/
b = malloc (sizeof(FcObjectBucket));
if (!b)
return NULL;
object = (const char *) FcStrCopy ((FcChar8 *) object);
if (!object) {
free (b);
return NULL;
}
o = FcObjectInsert (object, -1);
b->next = NULL;
b->hash = hash;
b->id = FcObjectId (o);
*p = b;
return o;
}
static FcObjectType *
FcObjectFindById (FcObject object) FcObjectFindById (FcObject object)
{ {
if (1 <= object && object <= FcObjectsNumber) if (1 <= object && object <= NUM_OBJECT_TYPES)
return FcObjects + object - 1; return &FcObjects[object - 1];
return NULL; return FcObjectLookupOtherTypeById (object);
}
static FcBool
FcObjectHashInsert (const FcObjectType *object, FcBool copy)
{
FcChar32 hash = FcStringHash ((const FcChar8 *) object->object);
FcObjectBucket **p;
FcObjectBucket *b;
FcObjectType *o;
if (!FcObjectsInited)
FcObjectInit ();
for (p = &FcObjectBuckets[hash%OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
{
o = FcObjects + b->id - 1;
if (b->hash == hash && !strcmp (object->object, o->object))
return FcFalse;
}
/*
* Hook it into the hash chain
*/
b = malloc (sizeof(FcObjectBucket));
if (!b)
return FcFalse;
if (copy)
{
o = FcObjectInsert (object->object, object->type);
if (!o)
{
free (b);
return FcFalse;
}
}
else
o = (FcObjectType *) object;
b->next = NULL;
b->hash = hash;
b->id = FcObjectId (o);
*p = b;
return FcTrue;
} }
FcBool FcBool
@ -250,13 +61,18 @@ FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
const FcObjectType * const FcObjectType *
FcNameGetObjectType (const char *object) FcNameGetObjectType (const char *object)
{ {
return FcObjectFindByName (object, FcFalse); int id = FcObjectLookupBuiltinIdByName (object);
if (!id)
return FcObjectLookupOtherTypeByName (object);
return &FcObjects[id - 1];
} }
FcBool FcBool
FcObjectValidType (FcObject object, FcType type) FcObjectValidType (FcObject object, FcType type)
{ {
FcObjectType *t = FcObjectFindById (object); const FcObjectType *t = FcObjectFindById (object);
if (t) { if (t) {
switch ((int) t->type) { switch ((int) t->type) {
@ -282,11 +98,7 @@ FcObjectValidType (FcObject object, FcType type)
FcObject FcObject
FcObjectFromName (const char * name) FcObjectFromName (const char * name)
{ {
FcObjectType *o = FcObjectFindByName (name, FcTrue); return FcObjectLookupIdByName (name);
if (o)
return FcObjectId (o);
return 0;
} }
FcObjectSet * FcObjectSet *
@ -297,61 +109,21 @@ FcObjectGetSet (void)
os = FcObjectSetCreate (); os = FcObjectSetCreate ();
for (i = 0; i < FcObjectsNumber; i++) for (i = 0; i < NUM_OBJECT_TYPES; i++)
FcObjectSetAdd (os, FcObjects[i].object); FcObjectSetAdd (os, FcObjects[i].object);
return os; return os;
} }
FcBool
FcObjectInit (void)
{
unsigned int i;
if (FcObjectsInited)
return FcTrue;
FcObjectsInited = FcTrue;
for (i = 0; i < NUM_OBJECT_TYPES; i++)
if (!FcObjectHashInsert (&_FcBaseObjectTypes[i], FcFalse))
return FcFalse;
return FcTrue;
}
void
FcObjectFini (void)
{
int i;
FcObjectBucket *b, *next;
for (i = 0; i < OBJECT_HASH_SIZE; i++)
{
for (b = FcObjectBuckets[i]; b; b = next)
{
next = b->next;
free (b);
}
FcObjectBuckets[i] = 0;
}
for (i = 0; i < FcObjectsNumber; i++)
if (FcObjects[i].type == (unsigned int) -1)
free ((void*) FcObjects[i].object);
if (FcObjects != _FcBaseObjectTypes)
free (FcObjects);
FcObjects = (FcObjectType *) _FcBaseObjectTypes;
FcObjectsNumber = NUM_OBJECT_TYPES;
FcObjectsSize = 0;
FcObjectsInited = FcFalse;
}
const char * const char *
FcObjectName (FcObject object) FcObjectName (FcObject object)
{ {
FcObjectType *o = FcObjectFindById (object); const FcObjectType *o = FcObjectFindById (object);
if (o) if (o)
return o->object; return o->object;
return NULL;
return FcObjectLookupOtherNameById (object);
} }
static const FcConstant _FcBaseConstants[] = { static const FcConstant _FcBaseConstants[] = {
@ -377,7 +149,7 @@ static const FcConstant _FcBaseConstants[] = {
{ (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED }, { (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED },
{ (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED }, { (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED },
{ (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED }, { (FcChar8 *) "condensed", "width", FC_WIDTH_CONDENSED },
{ (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED }, { (FcChar8 *) "semicondensed", "width", FC_WIDTH_SEMICONDENSED },
{ (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL }, { (FcChar8 *) "normal", "width", FC_WIDTH_NORMAL },
{ (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED }, { (FcChar8 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED },
{ (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED }, { (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED },
@ -437,7 +209,7 @@ FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
const FcConstant * const FcConstant *
FcNameGetConstant (const FcChar8 *string) FcNameGetConstant (const FcChar8 *string)
{ {
int i; unsigned int i;
for (i = 0; i < NUM_FC_CONSTANTS; i++) for (i = 0; i < NUM_FC_CONSTANTS; i++)
if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name)) if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name))
@ -754,8 +526,6 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
FcChar8 buf_static[8192]; FcChar8 buf_static[8192];
int i; int i;
FcPatternElt *e; FcPatternElt *e;
const FcObjectTypeList *l;
const FcObjectType *o;
FcStrBufInit (&buf, buf_static, sizeof (buf_static)); FcStrBufInit (&buf, buf_static, sizeof (buf_static));
e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT); e = FcPatternObjectFindElt (pat, FC_FAMILY_OBJECT);
@ -772,28 +542,27 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0)) if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ? (FcChar8 *) FC_ESCAPE_FIXED : 0))
goto bail0; goto bail0;
} }
for (l = _FcObjectTypes; l; l = l->next) for (i = 0; i < NUM_OBJECT_TYPES; i++)
{ {
for (i = 0; i < l->ntypes; i++) FcObject id = i + 1;
const FcObjectType *o;
o = &FcObjects[i];
if (!strcmp (o->object, FC_FAMILY) ||
!strcmp (o->object, FC_SIZE))
continue;
e = FcPatternObjectFindElt (pat, id);
if (e)
{ {
o = &l->types[i]; if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
if (!strcmp (o->object, FC_FAMILY) || goto bail0;
!strcmp (o->object, FC_SIZE)) if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
continue; goto bail0;
if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object)); goto bail0;
if (e) if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ?
{ (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0)) goto bail0;
goto bail0;
if (!FcNameUnparseString (&buf, (FcChar8 *) o->object, escape ? (FcChar8 *) FC_ESCAPE_VARIABLE : 0))
goto bail0;
if (!FcNameUnparseString (&buf, (FcChar8 *) "=", 0))
goto bail0;
if (!FcNameUnparseValueList (&buf, FcPatternEltValues(e), escape ?
(FcChar8 *) FC_ESCAPE_VARIABLE : 0))
goto bail0;
}
} }
} }
return FcStrBufDone (&buf); return FcStrBufDone (&buf);

130
src/fcobjs.c Normal file
View File

@ -0,0 +1,130 @@
/*
* fontconfig/src/fclist.c
*
* Copyright © 2000 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the author(s) not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The authors make no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "fcint.h"
#include "fcobjshash.h"
#include <string.h>
static int next_id = FC_MAX_BASE_OBJECT + 1;
struct FcObjectOtherTypeInfo {
struct FcObjectOtherTypeInfo *next;
FcObjectType object;
int id;
} *other_types;
static FcObjectType *
_FcObjectLookupOtherTypeByName (const char *str, FcObject *id)
{
struct FcObjectOtherTypeInfo *ots, *ot;
/* XXX MT-unsafe */
ots = other_types;
for (ot = ots; ot; ot = ot->next)
if (0 == strcmp (ot->object.object, str))
break;
if (!ot)
{
ot = malloc (sizeof (*ot));
if (!ot)
return NULL;
ot->object.object = strdup (str);
ot->object.type = -1;
ot->id = next_id++; /* MT_unsafe */
ot->next = ot;
other_types = ot;
}
if (id)
*id = ot->id;
return &ot->object;
}
FcObject
FcObjectLookupBuiltinIdByName (const char *str)
{
const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
FcObject id;
if (o)
return o->id;
return 0;
}
FcObject
FcObjectLookupIdByName (const char *str)
{
const struct FcObjectTypeInfo *o = FcObjectTypeLookup (str, strlen (str));
FcObject id;
if (o)
return o->id;
if (_FcObjectLookupOtherTypeByName (str, &id))
return id;
return 0;
}
const char *
FcObjectLookupOtherNameById (FcObject id)
{
/* XXX MT-unsafe */
struct FcObjectOtherTypeInfo *ot;
for (ot = other_types; ot; ot = ot->next)
if (ot->id == id)
return ot->object.object;
return NULL;
}
const FcObjectType *
FcObjectLookupOtherTypeByName (const char *str)
{
return _FcObjectLookupOtherTypeByName (str, NULL);
}
FcPrivate const FcObjectType *
FcObjectLookupOtherTypeById (FcObject id)
{
/* XXX MT-unsafe */
struct FcObjectOtherTypeInfo *ot;
for (ot = other_types; ot; ot = ot->next)
if (ot->id == id)
return &ot->object;
return NULL;
}
#define __fcobjs__
#include "fcaliastail.h"
#undef __fcobjs__

44
src/fcobjs.h Normal file
View File

@ -0,0 +1,44 @@
/* DON'T REORDER! The order is part of the cache signature. */
FC_OBJECT (FAMILY, FcTypeString)
FC_OBJECT (FAMILYLANG, FcTypeString)
FC_OBJECT (STYLE, FcTypeString)
FC_OBJECT (STYLELANG, FcTypeString)
FC_OBJECT (FULLNAME, FcTypeString)
FC_OBJECT (FULLNAMELANG, FcTypeString)
FC_OBJECT (SLANT, FcTypeInteger)
FC_OBJECT (WEIGHT, FcTypeInteger)
FC_OBJECT (WIDTH, FcTypeInteger)
FC_OBJECT (SIZE, FcTypeDouble)
FC_OBJECT (ASPECT, FcTypeDouble)
FC_OBJECT (PIXEL_SIZE, FcTypeDouble)
FC_OBJECT (SPACING, FcTypeInteger)
FC_OBJECT (FOUNDRY, FcTypeString)
FC_OBJECT (ANTIALIAS, FcTypeBool)
FC_OBJECT (HINT_STYLE, FcTypeInteger)
FC_OBJECT (HINTING, FcTypeBool)
FC_OBJECT (VERTICAL_LAYOUT, FcTypeBool)
FC_OBJECT (AUTOHINT, FcTypeBool)
FC_OBJECT (GLOBAL_ADVANCE, FcTypeBool) /* deprecated */
FC_OBJECT (FILE, FcTypeString)
FC_OBJECT (INDEX, FcTypeInteger)
FC_OBJECT (RASTERIZER, FcTypeString)
FC_OBJECT (OUTLINE, FcTypeBool)
FC_OBJECT (SCALABLE, FcTypeBool)
FC_OBJECT (DPI, FcTypeDouble)
FC_OBJECT (RGBA, FcTypeInteger)
FC_OBJECT (SCALE, FcTypeDouble)
FC_OBJECT (MINSPACE, FcTypeBool)
FC_OBJECT (CHAR_WIDTH, FcTypeInteger)
FC_OBJECT (CHAR_HEIGHT, FcTypeInteger)
FC_OBJECT (MATRIX, FcTypeMatrix)
FC_OBJECT (CHARSET, FcTypeCharSet)
FC_OBJECT (LANG, FcTypeLangSet)
FC_OBJECT (FONTVERSION, FcTypeInteger)
FC_OBJECT (CAPABILITY, FcTypeString)
FC_OBJECT (FONTFORMAT, FcTypeString)
FC_OBJECT (EMBOLDEN, FcTypeBool)
FC_OBJECT (EMBEDDED_BITMAP, FcTypeBool)
FC_OBJECT (DECORATIVE, FcTypeBool)
FC_OBJECT (LCD_FILTER, FcTypeInteger)
FC_OBJECT (NAMELANG, FcTypeString)
/* ^-------------- Add new objects here. */

26
src/fcobjshash.gperf.h Normal file
View File

@ -0,0 +1,26 @@
%{
CUT_OUT_BEGIN
#include <fontconfig/fontconfig.h>
CUT_OUT_END
%}
%struct-type
%language=C
%includes
%enum
%readonly-tables
%define slot-name name
%define hash-function-name FcObjectTypeHash
%define lookup-function-name FcObjectTypeLookup
%pic
%define string-pool-name FcObjectTypeNamePool
struct FcObjectTypeInfo {
int name;
int id;
};
%%
#define FC_OBJECT(NAME, Type) FC_##NAME, FC_##NAME##_OBJECT
#include "fcobjs.h"
#undef FC_OBJECT