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
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
EXTRA_DIST =
|
||||
|
||||
if OS_WIN32
|
||||
|
||||
export_symbols = -export-symbols fontconfig.def
|
||||
|
@ -78,7 +80,7 @@ INCLUDES = \
|
|||
-DFC_CACHEDIR='"$(FC_CACHEDIR)"' \
|
||||
-DFONTCONFIG_PATH='"$(BASECONFIGDIR)"'
|
||||
|
||||
EXTRA_DIST = makealias
|
||||
EXTRA_DIST += makealias
|
||||
|
||||
noinst_HEADERS=fcint.h fcftint.h fcdeprecate.h fcstdint.h
|
||||
|
||||
|
@ -88,7 +90,8 @@ BUILT_SOURCES = $(ALIAS_FILES) \
|
|||
../fc-case/fccase.h \
|
||||
../fc-glyphname/fcglyphname.h \
|
||||
../fc-lang/fclang.h \
|
||||
stamp-fcstdint
|
||||
stamp-fcstdint \
|
||||
fcobjshash.h
|
||||
|
||||
noinst_PROGRAMS = fcarch
|
||||
|
||||
|
@ -99,6 +102,22 @@ noinst_PROGRAMS = fcarch
|
|||
../fc-lang/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 = \
|
||||
fcarch.h \
|
||||
fcatomic.c \
|
||||
|
@ -118,6 +137,9 @@ libfontconfig_la_SOURCES = \
|
|||
fcmatch.c \
|
||||
fcmatrix.c \
|
||||
fcname.c \
|
||||
fcobjs.c \
|
||||
fcobjs.h \
|
||||
fcobjshash.h \
|
||||
fcpat.c \
|
||||
fcserialize.c \
|
||||
fcstat.c \
|
||||
|
|
|
@ -155,7 +155,6 @@ FcFini (void)
|
|||
if (_fcConfig)
|
||||
FcConfigDestroy (_fcConfig);
|
||||
|
||||
FcObjectFini ();
|
||||
FcCacheFini ();
|
||||
}
|
||||
|
||||
|
|
79
src/fcint.h
79
src/fcint.h
|
@ -819,54 +819,14 @@ FcListPatternMatchAny (const FcPattern *p,
|
|||
|
||||
/* fcname.c */
|
||||
|
||||
/*
|
||||
* NOTE -- this ordering is part of the cache file format.
|
||||
* It must also match the ordering in fcname.c
|
||||
*/
|
||||
|
||||
#define FC_FAMILY_OBJECT 1
|
||||
#define FC_FAMILYLANG_OBJECT 2
|
||||
#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
|
||||
enum {
|
||||
FC_INVALID_OBJECT = 0,
|
||||
#define FC_OBJECT(NAME, Type) FC_##NAME##_OBJECT,
|
||||
#include "fcobjs.h"
|
||||
#undef FC_OBJECT
|
||||
FC_ONE_AFTER_MAX_BASE_OBJECT
|
||||
#define FC_MAX_BASE_OBJECT (FC_ONE_AFTER_MAX_BASE_OBJECT - 1)
|
||||
};
|
||||
|
||||
FcPrivate FcBool
|
||||
FcNameBool (const FcChar8 *v, FcBool *result);
|
||||
|
@ -883,12 +843,6 @@ FcObjectName (FcObject object);
|
|||
FcPrivate FcObjectSet *
|
||||
FcObjectGetSet (void);
|
||||
|
||||
FcPrivate FcBool
|
||||
FcObjectInit (void);
|
||||
|
||||
FcPrivate void
|
||||
FcObjectFini (void);
|
||||
|
||||
#define FcObjectCompare(a, b) ((int) a - (int) b)
|
||||
|
||||
/* fcpat.c */
|
||||
|
@ -1102,4 +1056,21 @@ FcStrSerializeAlloc (FcSerialize *serialize, const FcChar8 *str);
|
|||
FcPrivate FcChar8 *
|
||||
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_ */
|
||||
|
|
315
src/fcname.c
315
src/fcname.c
|
@ -28,209 +28,20 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Please do not change this list, it is used to initialize the object
|
||||
* list in this order to match the FC_foo_OBJECT constants. Those
|
||||
* constants are written into cache files.
|
||||
*/
|
||||
|
||||
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 */
|
||||
static const FcObjectType FcObjects[] = {
|
||||
#define FC_OBJECT(NAME, Type) { FC_##NAME, Type },
|
||||
#include "fcobjs.h"
|
||||
#undef FC_OBJECT
|
||||
};
|
||||
|
||||
#define NUM_OBJECT_TYPES (sizeof _FcBaseObjectTypes / sizeof _FcBaseObjectTypes[0])
|
||||
#define NUM_OBJECT_TYPES ((int) (sizeof FcObjects / sizeof FcObjects[0]))
|
||||
|
||||
typedef struct _FcObjectTypeList FcObjectTypeList;
|
||||
|
||||
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 *
|
||||
static const FcObjectType *
|
||||
FcObjectFindById (FcObject object)
|
||||
{
|
||||
if (1 <= object && object <= FcObjectsNumber)
|
||||
return FcObjects + object - 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
if (1 <= object && object <= NUM_OBJECT_TYPES)
|
||||
return &FcObjects[object - 1];
|
||||
return FcObjectLookupOtherTypeById (object);
|
||||
}
|
||||
|
||||
FcBool
|
||||
|
@ -250,13 +61,18 @@ FcNameUnregisterObjectTypes (const FcObjectType *types, int ntypes)
|
|||
const FcObjectType *
|
||||
FcNameGetObjectType (const char *object)
|
||||
{
|
||||
return FcObjectFindByName (object, FcFalse);
|
||||
int id = FcObjectLookupBuiltinIdByName (object);
|
||||
|
||||
if (!id)
|
||||
return FcObjectLookupOtherTypeByName (object);
|
||||
|
||||
return &FcObjects[id - 1];
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcObjectValidType (FcObject object, FcType type)
|
||||
{
|
||||
FcObjectType *t = FcObjectFindById (object);
|
||||
const FcObjectType *t = FcObjectFindById (object);
|
||||
|
||||
if (t) {
|
||||
switch ((int) t->type) {
|
||||
|
@ -282,11 +98,7 @@ FcObjectValidType (FcObject object, FcType type)
|
|||
FcObject
|
||||
FcObjectFromName (const char * name)
|
||||
{
|
||||
FcObjectType *o = FcObjectFindByName (name, FcTrue);
|
||||
|
||||
if (o)
|
||||
return FcObjectId (o);
|
||||
return 0;
|
||||
return FcObjectLookupIdByName (name);
|
||||
}
|
||||
|
||||
FcObjectSet *
|
||||
|
@ -297,61 +109,21 @@ FcObjectGetSet (void)
|
|||
|
||||
|
||||
os = FcObjectSetCreate ();
|
||||
for (i = 0; i < FcObjectsNumber; i++)
|
||||
for (i = 0; i < NUM_OBJECT_TYPES; i++)
|
||||
FcObjectSetAdd (os, FcObjects[i].object);
|
||||
|
||||
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 *
|
||||
FcObjectName (FcObject object)
|
||||
{
|
||||
FcObjectType *o = FcObjectFindById (object);
|
||||
const FcObjectType *o = FcObjectFindById (object);
|
||||
|
||||
if (o)
|
||||
return o->object;
|
||||
return NULL;
|
||||
|
||||
return FcObjectLookupOtherNameById (object);
|
||||
}
|
||||
|
||||
static const FcConstant _FcBaseConstants[] = {
|
||||
|
@ -377,7 +149,7 @@ static const FcConstant _FcBaseConstants[] = {
|
|||
{ (FcChar8 *) "ultracondensed", "width", FC_WIDTH_ULTRACONDENSED },
|
||||
{ (FcChar8 *) "extracondensed", "width", FC_WIDTH_EXTRACONDENSED },
|
||||
{ (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 *) "semiexpanded", "width", FC_WIDTH_SEMIEXPANDED },
|
||||
{ (FcChar8 *) "expanded", "width", FC_WIDTH_EXPANDED },
|
||||
|
@ -437,7 +209,7 @@ FcNameUnregisterConstants (const FcConstant *consts, int nconsts)
|
|||
const FcConstant *
|
||||
FcNameGetConstant (const FcChar8 *string)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < NUM_FC_CONSTANTS; i++)
|
||||
if (!FcStrCmpIgnoreCase (string, _FcBaseConstants[i].name))
|
||||
|
@ -754,8 +526,6 @@ FcNameUnparseEscaped (FcPattern *pat, FcBool escape)
|
|||
FcChar8 buf_static[8192];
|
||||
int i;
|
||||
FcPatternElt *e;
|
||||
const FcObjectTypeList *l;
|
||||
const FcObjectType *o;
|
||||
|
||||
FcStrBufInit (&buf, buf_static, sizeof (buf_static));
|
||||
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))
|
||||
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 (!strcmp (o->object, FC_FAMILY) ||
|
||||
!strcmp (o->object, FC_SIZE))
|
||||
continue;
|
||||
|
||||
e = FcPatternObjectFindElt (pat, FcObjectFromName (o->object));
|
||||
if (e)
|
||||
{
|
||||
if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
|
||||
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;
|
||||
}
|
||||
if (!FcNameUnparseString (&buf, (FcChar8 *) ":", 0))
|
||||
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);
|
||||
|
|
|
@ -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