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:
parent
7c0f79c5fe
commit
d58c31e6dc
|
@ -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 \
|
||||||
|
|
|
@ -155,7 +155,6 @@ FcFini (void)
|
||||||
if (_fcConfig)
|
if (_fcConfig)
|
||||||
FcConfigDestroy (_fcConfig);
|
FcConfigDestroy (_fcConfig);
|
||||||
|
|
||||||
FcObjectFini ();
|
|
||||||
FcCacheFini ();
|
FcCacheFini ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
79
src/fcint.h
79
src/fcint.h
|
@ -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_ */
|
||||||
|
|
315
src/fcname.c
315
src/fcname.c
|
@ -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);
|
||||||
|
|
|
@ -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__
|
|
@ -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. */
|
|
@ -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
|
Loading…
Reference in New Issue