Commit d58c31e6 authored by Behdad Esfahbod's avatar Behdad Esfahbod

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.
parent 7c0f79c5
......@@ -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 ();
}
......
......@@ -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_ */
This diff is collapsed.
/*
* 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__
/* 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. */
%{
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment