Commit 4f27c1c0 authored by Keith Packard's avatar Keith Packard

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.
parent c641c77d
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
......
......@@ -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);
......
......@@ -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);
......
......@@ -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))
{
......
This diff is collapsed.
......@@ -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, },
......
......@@ -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);
}
......@@ -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);