Move existing fonts.conf to fonts.conf.bak
Add detection of iconv Document new selectfont elements Switch to UTF-8 in comment Add fullname, and family/style/fullname language entries Respect selectfont/*/glob Add support for selectfont Add multi-lingual family/style/fullname support Expose FcListPatternMatchAny (which selectfont/*/pattern uses) Add new FcPatternRemove/FcPatternAppend. FcObjectStaticName stores computed pattern element names which are required to be static.
This commit is contained in:
parent
c641c77d6f
commit
4f27c1c0a3
47
ChangeLog
47
ChangeLog
|
@ -1,3 +1,50 @@
|
|||
2004-12-04 Keith Packard <keithp@keithp.com>
|
||||
|
||||
* Makefile.am:
|
||||
Move existing fonts.conf to fonts.conf.bak
|
||||
|
||||
* configure.in:
|
||||
Add detection of iconv
|
||||
|
||||
* doc/fcpattern.fncs:
|
||||
* doc/fontconfig-devel.sgml:
|
||||
* doc/fontconfig-user.sgml:
|
||||
* fonts.dtd:
|
||||
Document new selectfont elements
|
||||
|
||||
* fc-lang/nb.orth:
|
||||
Switch to UTF-8 in comment
|
||||
|
||||
* fontconfig/fontconfig.h:
|
||||
* src/fcname.c:
|
||||
Add fullname, and family/style/fullname language entries
|
||||
|
||||
* src/fccache.c: (FcCacheFontSetAdd):
|
||||
* src/fcdir.c: (FcFileScanConfig):
|
||||
Respect selectfont/*/glob
|
||||
|
||||
* src/fcint.h:
|
||||
* src/fccfg.c: (FcConfigCreate), (FcConfigDestroy),
|
||||
(FcConfigCompareValue), (FcConfigPatternsAdd),
|
||||
(FcConfigPatternsMatch), (FcConfigAcceptFont):
|
||||
* src/fcxml.c: (FcElementMap), (FcVStackDestroy),
|
||||
(FcVStackPushPattern), (FcPopExpr), (FcParseAcceptRejectFont),
|
||||
(FcPopValue), (FcParsePatelt), (FcParsePattern), (FcEndElement):
|
||||
Add support for selectfont
|
||||
|
||||
* src/fcfreetype.c: (FcSfntNameTranscode), (FcSfntNameLanguage),
|
||||
(FcStringInPatternElement), (FcFreeTypeQuery):
|
||||
Add multi-lingual family/style/fullname support
|
||||
|
||||
* src/fclist.c: (FcListPatternMatchAny):
|
||||
Expose FcListPatternMatchAny (which selectfont/*/pattern uses)
|
||||
|
||||
* src/fcpat.c: (FcPatternRemove), (FcPatternAppend),
|
||||
(FcObjectStaticName):
|
||||
Add new FcPatternRemove/FcPatternAppend.
|
||||
FcObjectStaticName stores computed pattern element names which
|
||||
are required to be static.
|
||||
|
||||
2004-09-09 "NAKAMURA Ken'ichi" <nakamura@sbp.fp.a.u-tokyo.ac.jp>
|
||||
|
||||
reviewed by: keithp
|
||||
|
|
13
Makefile.am
13
Makefile.am
|
@ -37,10 +37,21 @@ pkgconfigdir=$(libdir)/pkgconfig
|
|||
pkgconfig_DATA = fontconfig.pc
|
||||
|
||||
configdir=$(CONFDIR)
|
||||
config_DATA=fonts.conf fonts.dtd
|
||||
config_DATA=fonts.dtd
|
||||
|
||||
install-data-local:
|
||||
$(mkinstalldirs) $(DESTDIR)$(configdir)
|
||||
if [ -f $(DESTDIR)$(configdir)/fonts.conf ]; then \
|
||||
echo "backing up existing $(DESTDIR)$(configdir)/fonts.conf"; \
|
||||
mv $(DESTDIR)$(configdir)/fonts.conf $(DESTDIR)$(configdir)/fonts.conf.bak; \
|
||||
fi
|
||||
if [ -f $(srcdir)/fonts.conf ]; then \
|
||||
echo " $(INSTALL_DATA) $(srcdir)/fonts.conf $(DESTDIR)$(configdir)/fonts.conf"; \
|
||||
$(INSTALL_DATA) $(srcdir)/fonts.conf $(DESTDIR)$(configdir)/fonts.conf; \
|
||||
else if [ -f fonts.conf ]; then \
|
||||
echo " $(INSTALL_DATA) fonts.conf $(DESTDIR)$(configdir)/fonts.conf"; \
|
||||
$(INSTALL_DATA) fonts.conf $(DESTDIR)$(configdir)/fonts.conf; \
|
||||
fi; fi
|
||||
if [ -f $(DESTDIR)$(configdir)/local.conf ]; then \
|
||||
echo "not overwriting existing $(DESTDIR)$(configdir)/local.conf"; \
|
||||
else if [ -f $(srcdir)/local.conf ]; then \
|
||||
|
|
|
@ -91,7 +91,7 @@ dnl ==========================================================================
|
|||
# Checks for header files.
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h])
|
||||
AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h iconv.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
|
@ -99,7 +99,7 @@ AC_TYPE_PID_T
|
|||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_VPRINTF
|
||||
AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long])
|
||||
AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr strtol getopt getopt_long iconv])
|
||||
|
||||
#
|
||||
# Checks for FreeType
|
||||
|
@ -324,7 +324,7 @@ esac
|
|||
|
||||
AC_SUBST(FC_FONTPATH)
|
||||
|
||||
FC_FONTDATE=`date`
|
||||
FC_FONTDATE=`LC_ALL=C date`
|
||||
|
||||
AC_SUBST(FC_FONTDATE)
|
||||
|
||||
|
|
|
@ -262,6 +262,17 @@ Deletes all values associated with the property `object', returning
|
|||
whether the property existed or not.
|
||||
@@
|
||||
|
||||
@RET@ FcBool
|
||||
@FUNC@ FcPatternRemove
|
||||
@TYPE1@ FcPattern * @ARG1@ p
|
||||
@TYPE2@ const char * @ARG2@ object
|
||||
@TYPE3@ int @ARG3@ id
|
||||
@PURPOSE@ Remove one object of the specified type from the pattern
|
||||
@DESC@
|
||||
Removes the value associated with the property `object' at position `id', returning
|
||||
whether the property existed and had a value at that position or not.
|
||||
@@
|
||||
|
||||
@RET@ void
|
||||
@FUNC@ FcPatternPrint
|
||||
@TYPE1@ const FcPattern * @ARG1@ p
|
||||
|
|
|
@ -127,11 +127,20 @@ convenience for the applications rendering mechanism.
|
|||
<programlisting>
|
||||
Property Definitions
|
||||
|
||||
Property CPP Symbol Type Description
|
||||
Property CPP Symbol Type Description
|
||||
----------------------------------------------------
|
||||
family FC_FAMILY String Font family name
|
||||
family FC_FAMILY String Font family names
|
||||
familylang FC_FAMILYLANG String Language cooresponding to
|
||||
each family name
|
||||
style FC_STYLE String Font style. Overrides weight
|
||||
and slant
|
||||
stylelang FC_STYLELANG String Language cooresponding to
|
||||
each style name
|
||||
fullname FC_FULLNAME String Font face full name where
|
||||
different from family and
|
||||
family + style
|
||||
fullnamelang FC_FULLNAMELANG String Language cooresponding to
|
||||
each fullname
|
||||
slant FC_SLANT Int Italic, oblique or roman
|
||||
weight FC_WEIGHT Int Light, medium, demibold,
|
||||
bold or black
|
||||
|
|
|
@ -91,8 +91,12 @@ convenience for the applications rendering mechanism.
|
|||
<programlisting>
|
||||
Property Type Description
|
||||
--------------------------------------------------------------
|
||||
family String Font family name
|
||||
family String Font family names
|
||||
familylang String Languages cooresponding to each family
|
||||
style String Font style. Overrides weight and slant
|
||||
stylelang String Languages cooresponding to each style
|
||||
fullname String Font full names (often includes style)
|
||||
fullnamelang String Languages cooresponding to each fullname
|
||||
slant Int Italic, oblique or roman
|
||||
weight Int Light, medium, demibold, bold or black
|
||||
size Double Point size
|
||||
|
@ -283,6 +287,43 @@ The <sgmltag>rescan</> element holds an <sgmltag>int</> element which indicates
|
|||
interval between automatic checks for font configuration changes.
|
||||
Fontconfig will validate all of the configuration files and directories and
|
||||
automatically rebuild the internal datastructures when this interval passes.
|
||||
</para></refsect2>
|
||||
<refsect2><title><sgmltag>selectfont</></title><para>
|
||||
This element is used to black/white list fonts from being listed or matched
|
||||
against. It holds acceptfont and rejectfont elements.
|
||||
</para></refsect2>
|
||||
<refsect2><title><sgmltag>acceptfont</></title><para>
|
||||
Fonts matched by an acceptfont element are "whitelisted"; such fonts are
|
||||
explicitly included in the set of fonts used to resolve list and match
|
||||
requests; including them in this list protects them from being "blacklisted"
|
||||
by a rejectfont element. Acceptfont elements include glob and pattern
|
||||
elements which are used to match fonts.
|
||||
</para></refsect2>
|
||||
<refsect2><title><sgmltag>rejectfont</></title><para>
|
||||
Fonts matched by an rejectfont element are "blacklisted"; such fonts are
|
||||
excluded from the set of fonts used to resolve list and match requests as if
|
||||
they didn't exist in the system. Rejectfont elements include glob and
|
||||
pattern elements which are used to match fonts.
|
||||
</para></refsect2>
|
||||
<refsect2><title><sgmltag>glob</></title><para>
|
||||
Glob elements hold shell-style filename matching patterns (including ? and
|
||||
*) which match fonts based on their complete pathnames. This can be used to
|
||||
exclude a set of directories (/usr/share/fonts/uglyfont*), or particular
|
||||
font file types (*.pcf.gz), but the latter mechanism relies rather heavily
|
||||
on filenaming conventions which can't be relied upon.
|
||||
</para></refsect2>
|
||||
<refsect2><title><sgmltag>pattern</></title><para>
|
||||
Pattern elements perform list-style matching on incoming fonts; that is,
|
||||
they hold a list of elements and associated values. If all of those
|
||||
elements have a matching value, then the pattern matches the font. This can
|
||||
be used to select fonts based on attributes of the font (scalable, bold,
|
||||
etc), which is a more reliable mechanism than using file extensions.
|
||||
Pattern elements include patelt elements.
|
||||
<refsect2><title><sgmltag>patelt name="property"</></title><para>
|
||||
Patelt elements hold a single pattern element and list of values. They must
|
||||
have a 'name' attribute which indicates the pattern element name. Patelt
|
||||
elements include int, double, string, matrix, bool, charset and const
|
||||
elements.
|
||||
</para></refsect2>
|
||||
<refsect2><title><sgmltag>match target="pattern"</></title><para>
|
||||
This element holds first a (possibly empty) list of <sgmltag>test</> elements and then
|
||||
|
|
|
@ -21,5 +21,5 @@
|
|||
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# Norwegian Bokmål (NB)
|
||||
# Norwegian Bokmäl (NB)
|
||||
include no.orth
|
||||
|
|
|
@ -89,6 +89,10 @@ typedef int FcBool;
|
|||
#define FC_CHARSET "charset" /* CharSet */
|
||||
#define FC_LANG "lang" /* String RFC 3066 langs */
|
||||
#define FC_FONTVERSION "fontversion" /* Int from 'head' table */
|
||||
#define FC_FULLNAME "fullname" /* String */
|
||||
#define FC_FAMILYLANG "familylang" /* String RFC 3066 langs */
|
||||
#define FC_STYLELANG "stylelang" /* String RFC 3066 langs */
|
||||
#define FC_FULLNAMELANG "fullnamelang" /* String RFC 3066 langs */
|
||||
|
||||
#define FC_DIR_CACHE_FILE "fonts.cache-"FC_CACHE_VERSION
|
||||
#define FC_USER_CACHE_FILE ".fonts.cache-"FC_CACHE_VERSION
|
||||
|
@ -683,6 +687,9 @@ FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v);
|
|||
FcBool
|
||||
FcPatternDel (FcPattern *p, const char *object);
|
||||
|
||||
FcBool
|
||||
FcPatternRemove (FcPattern *p, const char *object, int id);
|
||||
|
||||
FcBool
|
||||
FcPatternAddInteger (FcPattern *p, const char *object, int i);
|
||||
|
||||
|
|
19
fonts.dtd
19
fonts.dtd
|
@ -3,6 +3,7 @@
|
|||
cache |
|
||||
include |
|
||||
config |
|
||||
selectfont |
|
||||
match |
|
||||
alias)* >
|
||||
|
||||
|
@ -80,6 +81,24 @@
|
|||
-->
|
||||
<!ELEMENT rescan (int)>
|
||||
|
||||
<!--
|
||||
Edit list of available fonts at startup/reload time
|
||||
-->
|
||||
<!ELEMENT selectfont (rejectfont | acceptfont)* >
|
||||
|
||||
<!ELEMENT rejectfont (glob | pattern)*>
|
||||
|
||||
<!ELEMENT acceptfont (glob | pattern)*>
|
||||
|
||||
<!ELEMENT glob (#PCDATA)>
|
||||
|
||||
<!ELEMENT pattern (patelt)*>
|
||||
|
||||
<!ELEMENT patelt (constant)*>
|
||||
<!ATTLIST patelt
|
||||
name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT constant (int|double|string|matrix|bool|charset|const)>
|
||||
|
||||
<!ELEMENT alias (family*, prefer?, accept?, default?)>
|
||||
<!ELEMENT prefer (family)*>
|
||||
|
|
|
@ -297,7 +297,7 @@ FcCacheFontSetAdd (FcFontSet *set,
|
|||
if (FcDebug () & FC_DBG_CACHEV)
|
||||
printf (" dir cache file \"%s\"\n", file);
|
||||
ret = FcPatternAddString (font, FC_FILE, path);
|
||||
if (ret)
|
||||
if (ret && (!config || FcConfigAcceptFont (config, font)))
|
||||
{
|
||||
frozen = FcPatternFreeze (font);
|
||||
ret = (frozen != 0);
|
||||
|
|
55
src/fccfg.c
55
src/fccfg.c
|
@ -67,10 +67,18 @@ FcConfigCreate (void)
|
|||
if (!config->rejectGlobs)
|
||||
goto bail5;
|
||||
|
||||
config->acceptPatterns = FcFontSetCreate ();
|
||||
if (!config->acceptPatterns)
|
||||
goto bail6;
|
||||
|
||||
config->rejectPatterns = FcFontSetCreate ();
|
||||
if (!config->rejectPatterns)
|
||||
goto bail7;
|
||||
|
||||
config->cache = 0;
|
||||
if (FcConfigHome())
|
||||
if (!FcConfigSetCache (config, (FcChar8 *) ("~/" FC_USER_CACHE_FILE)))
|
||||
goto bail6;
|
||||
goto bail8;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (config->cache == 0)
|
||||
|
@ -110,6 +118,10 @@ FcConfigCreate (void)
|
|||
|
||||
return config;
|
||||
|
||||
bail8:
|
||||
FcFontSetDestroy (config->rejectPatterns);
|
||||
bail7:
|
||||
FcFontSetDestroy (config->acceptPatterns);
|
||||
bail6:
|
||||
FcStrSetDestroy (config->rejectGlobs);
|
||||
bail5:
|
||||
|
@ -207,6 +219,8 @@ FcConfigDestroy (FcConfig *config)
|
|||
FcStrSetDestroy (config->configFiles);
|
||||
FcStrSetDestroy (config->acceptGlobs);
|
||||
FcStrSetDestroy (config->rejectGlobs);
|
||||
FcFontSetDestroy (config->acceptPatterns);
|
||||
FcFontSetDestroy (config->rejectPatterns);
|
||||
|
||||
if (config->blanks)
|
||||
FcBlanksDestroy (config->blanks);
|
||||
|
@ -665,7 +679,7 @@ FcConfigCompareValue (const FcValue left_o,
|
|||
ret = FcLangSetContains (left.u.l, right.u.l);
|
||||
break;
|
||||
case FcOpNotContains:
|
||||
ret = FcLangSetContains (left.u.l, right.u.l);
|
||||
ret = !FcLangSetContains (left.u.l, right.u.l);
|
||||
break;
|
||||
case FcOpEqual:
|
||||
ret = FcLangSetEqual (left.u.l, right.u.l);
|
||||
|
@ -1837,3 +1851,40 @@ FcConfigAcceptFilename (FcConfig *config,
|
|||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Manage font-pattern based font source selectors
|
||||
*/
|
||||
|
||||
FcBool
|
||||
FcConfigPatternsAdd (FcConfig *config,
|
||||
FcPattern *pattern,
|
||||
FcBool accept)
|
||||
{
|
||||
FcFontSet *set = accept ? config->acceptPatterns : config->rejectPatterns;
|
||||
|
||||
return FcFontSetAdd (set, pattern);
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcConfigPatternsMatch (const FcFontSet *patterns,
|
||||
const FcPattern *font)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < patterns->nfont; i++)
|
||||
if (FcListPatternMatchAny (patterns->fonts[i], font))
|
||||
return FcTrue;
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcConfigAcceptFont (FcConfig *config,
|
||||
const FcPattern *font)
|
||||
{
|
||||
if (FcConfigPatternsMatch (config->acceptPatterns, font))
|
||||
return FcTrue;
|
||||
if (FcConfigPatternsMatch (config->rejectPatterns, font))
|
||||
return FcFalse;
|
||||
return FcTrue;
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ FcFileScanConfig (FcFontSet *set,
|
|||
/*
|
||||
* Add the font
|
||||
*/
|
||||
if (font)
|
||||
if (font && (!config || FcConfigAcceptFont (config, font)))
|
||||
{
|
||||
if (!FcFontSetAdd (set, font))
|
||||
{
|
||||
|
|
1097
src/fcfreetype.c
1097
src/fcfreetype.c
File diff suppressed because it is too large
Load Diff
21
src/fcint.h
21
src/fcint.h
|
@ -329,6 +329,8 @@ struct _FcConfig {
|
|||
*/
|
||||
FcStrSet *acceptGlobs;
|
||||
FcStrSet *rejectGlobs;
|
||||
FcFontSet *acceptPatterns;
|
||||
FcFontSet *rejectPatterns;
|
||||
/*
|
||||
* The set of fonts loaded from the listed directories; the
|
||||
* order within the set does not determine the font selection,
|
||||
|
@ -465,6 +467,15 @@ FcBool
|
|||
FcConfigAcceptFilename (FcConfig *config,
|
||||
const FcChar8 *filename);
|
||||
|
||||
FcBool
|
||||
FcConfigPatternsAdd (FcConfig *config,
|
||||
FcPattern *pattern,
|
||||
FcBool accept);
|
||||
|
||||
FcBool
|
||||
FcConfigAcceptFont (FcConfig *config,
|
||||
const FcPattern *font);
|
||||
|
||||
/* fccharset.c */
|
||||
FcCharSet *
|
||||
FcCharSetFreeze (FcCharSet *cs);
|
||||
|
@ -639,6 +650,10 @@ FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls);
|
|||
|
||||
/* fclist.c */
|
||||
|
||||
FcBool
|
||||
FcListPatternMatchAny (const FcPattern *p,
|
||||
const FcPattern *font);
|
||||
|
||||
/* fcmatch.c */
|
||||
|
||||
/* fcname.c */
|
||||
|
@ -669,6 +684,12 @@ FcPatternFreeze (FcPattern *p);
|
|||
void
|
||||
FcPatternThawAll (void);
|
||||
|
||||
FcBool
|
||||
FcPatternAppend (FcPattern *p, FcPattern *s);
|
||||
|
||||
const char *
|
||||
FcObjectStaticName (const char *name);
|
||||
|
||||
/* fcrender.c */
|
||||
|
||||
/* fcmatrix.c */
|
||||
|
|
|
@ -200,9 +200,9 @@ FcListPatternEqual (FcPattern *p1,
|
|||
* FcTrue iff all objects in "p" match "font"
|
||||
*/
|
||||
|
||||
static FcBool
|
||||
FcListPatternMatchAny (FcPattern *p,
|
||||
FcPattern *font)
|
||||
FcBool
|
||||
FcListPatternMatchAny (const FcPattern *p,
|
||||
const FcPattern *font)
|
||||
{
|
||||
int i;
|
||||
FcPatternElt *e;
|
||||
|
|
|
@ -30,7 +30,11 @@
|
|||
|
||||
static const FcObjectType _FcBaseObjectTypes[] = {
|
||||
{ FC_FAMILY, FcTypeString, },
|
||||
{ FC_FAMILYLANG, FcTypeString, },
|
||||
{ FC_STYLE, FcTypeString, },
|
||||
{ FC_STYLELANG, FcTypeString, },
|
||||
{ FC_FULLNAME, FcTypeString, },
|
||||
{ FC_FULLNAMELANG, FcTypeString, },
|
||||
{ FC_SLANT, FcTypeInteger, },
|
||||
{ FC_WEIGHT, FcTypeInteger, },
|
||||
{ FC_WIDTH, FcTypeInteger, },
|
||||
|
|
73
src/fcpat.c
73
src/fcpat.c
|
@ -849,6 +849,31 @@ FcPatternDel (FcPattern *p, const char *object)
|
|||
return FcTrue;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcPatternRemove (FcPattern *p, const char *object, int id)
|
||||
{
|
||||
FcPatternElt *e;
|
||||
FcValueList **prev, *l;
|
||||
|
||||
e = FcPatternFindElt (p, object);
|
||||
if (!e)
|
||||
return FcFalse;
|
||||
for (prev = &e->values; (l = *prev); prev = &l->next)
|
||||
{
|
||||
if (!id)
|
||||
{
|
||||
*prev = l->next;
|
||||
l->next = 0;
|
||||
FcValueListDestroy (l);
|
||||
if (!e->values)
|
||||
FcPatternDel (p, object);
|
||||
return FcTrue;
|
||||
}
|
||||
id--;
|
||||
}
|
||||
return FcFalse;
|
||||
}
|
||||
|
||||
FcBool
|
||||
FcPatternAddInteger (FcPattern *p, const char *object, int i)
|
||||
{
|
||||
|
@ -1139,3 +1164,51 @@ FcPatternBuild (FcPattern *orig, ...)
|
|||
va_end (va);
|
||||
return orig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add all of the elements in 's' to 'p'
|
||||
*/
|
||||
FcBool
|
||||
FcPatternAppend (FcPattern *p, FcPattern *s)
|
||||
{
|
||||
int i;
|
||||
FcPatternElt *e;
|
||||
FcValueList *v;
|
||||
|
||||
for (i = 0; i < s->num; i++)
|
||||
{
|
||||
e = &s->elts[i];
|
||||
for (v = e->values; v; v = v->next)
|
||||
{
|
||||
if (!FcPatternAddWithBinding (p, e->object,
|
||||
v->value, v->binding, FcTrue))
|
||||
return FcFalse;
|
||||
}
|
||||
}
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
const char *
|
||||
FcObjectStaticName (const char *name)
|
||||
{
|
||||
#define OBJECT_HASH_SIZE 31
|
||||
static struct objectBucket {
|
||||
struct objectBucket *next;
|
||||
FcChar32 hash;
|
||||
} *buckets[OBJECT_HASH_SIZE];
|
||||
FcChar32 hash = FcStringHash ((const FcChar8 *) name);
|
||||
struct objectBucket **p;
|
||||
struct objectBucket *b;
|
||||
|
||||
for (p = &buckets[hash % OBJECT_HASH_SIZE]; (b = *p); p = &(b->next))
|
||||
if (b->hash == hash && !strcmp (name, (char *) (b + 1)))
|
||||
return (char *) (b + 1);
|
||||
b = malloc (sizeof (struct objectBucket) + strlen (name) + 1);
|
||||
if (!b)
|
||||
return NULL;
|
||||
b->next = 0;
|
||||
b->hash = hash;
|
||||
strcpy ((char *) (b + 1), name);
|
||||
*p = b;
|
||||
return (char *) (b + 1);
|
||||
}
|
||||
|
|
162
src/fcxml.c
162
src/fcxml.c
|
@ -323,6 +323,8 @@ typedef enum _FcElement {
|
|||
FcElementAcceptfont,
|
||||
FcElementRejectfont,
|
||||
FcElementGlob,
|
||||
FcElementPattern,
|
||||
FcElementPatelt,
|
||||
|
||||
FcElementTest,
|
||||
FcElementEdit,
|
||||
|
@ -384,6 +386,8 @@ FcElementMap (const XML_Char *name)
|
|||
{ "acceptfont", FcElementAcceptfont },
|
||||
{ "rejectfont", FcElementRejectfont },
|
||||
{ "glob", FcElementGlob },
|
||||
{ "pattern", FcElementPattern },
|
||||
{ "patelt", FcElementPatelt },
|
||||
|
||||
{ "test", FcElementTest },
|
||||
{ "edit", FcElementEdit },
|
||||
|
@ -441,6 +445,7 @@ typedef enum _FcVStackTag {
|
|||
FcVStackField,
|
||||
FcVStackConstant,
|
||||
FcVStackGlob,
|
||||
FcVStackPattern,
|
||||
|
||||
FcVStackPrefer,
|
||||
FcVStackAccept,
|
||||
|
@ -473,6 +478,8 @@ typedef struct _FcVStack {
|
|||
FcOp op;
|
||||
FcExpr *expr;
|
||||
FcEdit *edit;
|
||||
|
||||
FcPattern *pattern;
|
||||
} u;
|
||||
} FcVStack;
|
||||
|
||||
|
@ -560,6 +567,9 @@ FcVStackDestroy (FcVStack *vstack)
|
|||
case FcVStackGlob:
|
||||
FcStrFree (vstack->u.string);
|
||||
break;
|
||||
case FcVStackPattern:
|
||||
FcPatternDestroy (vstack->u.pattern);
|
||||
break;
|
||||
case FcVStackInteger:
|
||||
case FcVStackDouble:
|
||||
break;
|
||||
|
@ -688,6 +698,18 @@ FcVStackPushEdit (FcConfigParse *parse, FcEdit *edit)
|
|||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcBool
|
||||
FcVStackPushPattern (FcConfigParse *parse, FcPattern *pattern)
|
||||
{
|
||||
FcVStack *vstack = FcVStackCreate ();
|
||||
if (!vstack)
|
||||
return FcFalse;
|
||||
vstack->u.pattern = pattern;
|
||||
vstack->tag = FcVStackPattern;
|
||||
FcVStackPush (parse, vstack);
|
||||
return FcTrue;
|
||||
}
|
||||
|
||||
static FcVStack *
|
||||
FcVStackFetch (FcConfigParse *parse, int off)
|
||||
{
|
||||
|
@ -1321,6 +1343,8 @@ FcPopExpr (FcConfigParse *parse)
|
|||
break;
|
||||
case FcVStackEdit:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
FcVStackDestroy (vstack);
|
||||
return expr;
|
||||
|
@ -1675,6 +1699,16 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
|
|||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
}
|
||||
break;
|
||||
case FcVStackPattern:
|
||||
if (!FcConfigPatternsAdd (parse->config,
|
||||
vstack->u.pattern,
|
||||
element == FcElementAcceptfont))
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
}
|
||||
else
|
||||
vstack->tag = FcVStackNone;
|
||||
break;
|
||||
default:
|
||||
FcConfigMessage (parse, FcSevereWarning, "bad font selector");
|
||||
break;
|
||||
|
@ -1683,6 +1717,128 @@ FcParseAcceptRejectFont (FcConfigParse *parse, FcElement element)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static FcValue
|
||||
FcPopValue (FcConfigParse *parse)
|
||||
{
|
||||
FcVStack *vstack = FcVStackPop (parse);
|
||||
FcValue value;
|
||||
|
||||
value.type = FcTypeVoid;
|
||||
|
||||
if (!vstack)
|
||||
return value;
|
||||
|
||||
switch (vstack->tag) {
|
||||
case FcVStackString:
|
||||
value.u.s = FcStrCopy (vstack->u.string);
|
||||
if (value.u.s)
|
||||
value.type = FcTypeString;
|
||||
break;
|
||||
case FcVStackConstant:
|
||||
if (FcNameConstant (vstack->u.string, &value.u.i))
|
||||
value.type = FcTypeInteger;
|
||||
break;
|
||||
case FcVStackInteger:
|
||||
value.u.i = vstack->u.integer;
|
||||
value.type = FcTypeInteger;
|
||||
break;
|
||||
case FcVStackDouble:
|
||||
value.u.d = vstack->u._double;
|
||||
value.type = FcTypeInteger;
|
||||
break;
|
||||
case FcVStackMatrix:
|
||||
value.u.m = FcMatrixCopy (vstack->u.matrix);
|
||||
if (value.u.m)
|
||||
value.type = FcTypeMatrix;
|
||||
break;
|
||||
case FcVStackBool:
|
||||
value.u.b = vstack->u.bool;
|
||||
value.type = FcTypeBool;
|
||||
break;
|
||||
default:
|
||||
FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
|
||||
vstack->tag);
|
||||
break;
|
||||
}
|
||||
FcVStackDestroy (vstack);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
FcParsePatelt (FcConfigParse *parse)
|
||||
{
|
||||
FcValue value;
|
||||
FcPattern *pattern = FcPatternCreate ();
|
||||
const char *name;
|
||||
|
||||
if (!pattern)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
name = FcConfigGetAttribute (parse, "name");
|
||||
if (!name)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereWarning, "missing pattern element name");
|
||||
return;
|
||||
}
|
||||
name = FcObjectStaticName (name);
|
||||
if (!name)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
value = FcPopValue (parse);
|
||||
if (value.type == FcTypeVoid)
|
||||
break;
|
||||
if (!FcPatternAdd (pattern, name, value, FcTrue))
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FcVStackPushPattern (parse, pattern);
|
||||
}
|
||||
|
||||
static void
|
||||
FcParsePattern (FcConfigParse *parse)
|
||||
{
|
||||
FcVStack *vstack;
|
||||
FcPattern *pattern = FcPatternCreate ();
|
||||
|
||||
if (!pattern)
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
while ((vstack = FcVStackPop (parse)))
|
||||
{
|
||||
switch (vstack->tag) {
|
||||
case FcVStackPattern:
|
||||
if (!FcPatternAppend (pattern, vstack->u.pattern))
|
||||
{
|
||||
FcConfigMessage (parse, FcSevereError, "out of memory");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FcConfigMessage (parse, FcSevereWarning, "unknown pattern element");
|
||||
break;
|
||||
}
|
||||
FcVStackDestroy (vstack);
|
||||
}
|
||||
|
||||
FcVStackPushPattern (parse, pattern);
|
||||
}
|
||||
|
||||
static void
|
||||
FcEndElement(void *userData, const XML_Char *name)
|
||||
{
|
||||
|
@ -1814,6 +1970,12 @@ FcEndElement(void *userData, const XML_Char *name)
|
|||
case FcElementGlob:
|
||||
FcParseString (parse, FcVStackGlob);
|
||||
break;
|
||||
case FcElementPattern:
|
||||
FcParsePattern (parse);
|
||||
break;
|
||||
case FcElementPatelt:
|
||||
FcParsePatelt (parse);
|
||||
break;
|
||||
case FcElementName:
|
||||
FcParseString (parse, FcVStackField);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue