[Fontconfig] fontconfig: Branch 'master' - 10 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Tue Dec 28 01:01:33 PST 2010
configure.in | 2
doc/fclangset.fncs | 30 +++++
doc/fontconfig-user.sgml | 12 ++
fontconfig/fontconfig.h | 9 +
fonts.dtd | 11 +
src/Makefile.am | 4
src/fccfg.c | 43 +++++++
src/fcdbg.c | 8 +
src/fcint.h | 10 +
src/fclang.c | 62 ++++++++++
src/fcxml.c | 277 +++++++++++++++++++++++++++++++++++++++++++----
11 files changed, 441 insertions(+), 27 deletions(-)
New commits:
commit e63f90ce74d1f2c1e22959cb2ed97120eff3867f
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Dec 28 02:58:16 2010 -0600
Doc nit
diff --git a/doc/fclangset.fncs b/doc/fclangset.fncs
index fd1634f..8f9678e 100644
--- a/doc/fclangset.fncs
+++ b/doc/fclangset.fncs
@@ -62,7 +62,7 @@ two or three letter language from ISO 639 and Tt is a territory from ISO
@FUNC@ FcLangSetDel
@TYPE1@ FcLangSet * @ARG1@ ls
@TYPE2@ const FcChar8 * @ARG2@ lang
- at PURPOSE@ remove a language from a langset
+ at PURPOSE@ delete a language from a langset
@DESC@
<parameter>lang</parameter> is removed from <parameter>ls</parameter>.
<parameter>lang</parameter> should be of the form Ll-Tt where Ll is a
@@ -85,7 +85,7 @@ Returns a set including only those languages found in either <parameter>ls_a</pa
@TYPE2@ const FcLangSet * @ARG2@ ls_b
@PURPOSE@ Subtract langsets
@DESC@
-Returns a set including only those languages found in <parameter>ls_a</parameter> but not <parameter>ls_b</parameter>.
+Returns a set including only those languages found in <parameter>ls_a</parameter> but not in <parameter>ls_b</parameter>.
@@
@RET@ FcLangResult
commit 43bf659eedb3eeff75d219864af475dcadcf6983
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Dec 28 02:55:31 2010 -0600
Skip <range> elements with begin > end
diff --git a/src/fcxml.c b/src/fcxml.c
index 1aa3e4c..ff30b7b 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -1148,10 +1148,13 @@ FcParseBlank (FcConfigParse *parse)
goto bail;
break;
case FcVStackRange:
- for (i = v->u.range.begin; i <= v->u.range.end; i++)
+ if (v->u.range.begin <= v->u.range.end)
{
- if (!FcBlanksAdd (parse->config->blanks, i))
- goto bail;
+ for (i = v->u.range.begin; i <= v->u.range.end; i++)
+ {
+ if (!FcBlanksAdd (parse->config->blanks, i))
+ goto bail;
+ }
}
break;
default:
@@ -1428,14 +1431,17 @@ FcParseCharSet (FcConfigParse *parse)
n++;
break;
case FcVStackRange:
- for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++)
+ if (vstack->u.range.begin <= vstack->u.range.end)
{
- if (!FcCharSetAddChar (charset, i))
- {
- FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
- }
- else
- n++;
+ for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++)
+ {
+ if (!FcCharSetAddChar (charset, i))
+ {
+ FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
+ }
+ else
+ n++;
+ }
}
break;
default:
commit 8c625aa01f0ad95b1c06acb079921c209906f3b4
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Dec 28 02:52:06 2010 -0600
Add <range> support for <blank> into the DTD
diff --git a/fonts.dtd b/fonts.dtd
index d9d4b22..5f072ee 100644
--- a/fonts.dtd
+++ b/fonts.dtd
@@ -63,7 +63,7 @@
the set of valid Unicode chars. This idea
was borrowed from Mozilla
-->
-<!ELEMENT blank (int)*>
+<!ELEMENT blank (int|range)*>
<!--
Aliases are just a special case for multiple match elements
commit 549c9962a48cd728116c8f39db31c58043236ff0
Merge: 30fd4fa... fa269cf...
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Dec 28 02:50:16 2010 -0600
Allow editing charset and lang in target="scan"
Merge commit 'fa269cf812ee304534b0e4c44662202496008db0'
Fixes:
Bug 31969 - Can't modify charset in target="scan"
Bug 23758 - Can't modify lang in target="scan"
commit 30fd4fac9ca2238f84608c23836cab219640d9c1
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Dec 28 01:28:39 2010 -0600
Bump version
diff --git a/configure.in b/configure.in
index 5d92b5f..d128fb0 100644
--- a/configure.in
+++ b/configure.in
@@ -33,7 +33,7 @@ dnl This is the package version number, not the shared library
dnl version. This same version number must appear in fontconfig/fontconfig.h
dnl Yes, it is a pain to synchronize version numbers. Unfortunately, it's
dnl not possible to extract the version number here from fontconfig.h
-AM_INIT_AUTOMAKE(fontconfig, 2.8.0)
+AM_INIT_AUTOMAKE(fontconfig, 2.8.90)
m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
AM_MAINTAINER_MODE
commit fa269cf812ee304534b0e4c44662202496008db0
Author: Akira TAGOH <akira at tagoh.org>
Date: Thu Dec 9 11:57:24 2010 +0900
add some documents
diff --git a/doc/fclangset.fncs b/doc/fclangset.fncs
index f9d578e..fd1634f 100644
--- a/doc/fclangset.fncs
+++ b/doc/fclangset.fncs
@@ -58,6 +58,36 @@ two or three letter language from ISO 639 and Tt is a territory from ISO
3166.
@@
+ at RET@ FcBool
+ at FUNC@ FcLangSetDel
+ at TYPE1@ FcLangSet * @ARG1@ ls
+ at TYPE2@ const FcChar8 * @ARG2@ lang
+ at PURPOSE@ remove a language from a langset
+ at DESC@
+<parameter>lang</parameter> is removed from <parameter>ls</parameter>.
+<parameter>lang</parameter> should be of the form Ll-Tt where Ll is a
+two or three letter language from ISO 639 and Tt is a territory from ISO
+3166.
+@@
+
+ at RET@ FcLangSet *
+ at FUNC@ FcLangSetUnion
+ at TYPE1@ const FcLangSet * @ARG1@ ls_a
+ at TYPE2@ const FcLangSet * @ARG2@ ls_b
+ at PURPOSE@ Add langsets
+ at DESC@
+Returns a set including only those languages found in either <parameter>ls_a</parameter> or <parameter>ls_b</parameter>.
+@@
+
+ at RET@ FcLangSet *
+ at FUNC@ FcLangSetSubtract
+ at TYPE1@ const FcLangSet * @ARG1@ ls_a
+ at TYPE2@ const FcLangSet * @ARG2@ ls_b
+ at PURPOSE@ Subtract langsets
+ at DESC@
+Returns a set including only those languages found in <parameter>ls_a</parameter> but not <parameter>ls_b</parameter>.
+@@
+
@RET@ FcLangResult
@FUNC@ FcLangSetCompare
@TYPE1@ const FcLangSet * @ARG1@ ls_a
diff --git a/doc/fontconfig-user.sgml b/doc/fontconfig-user.sgml
index ce6f158..b870825 100644
--- a/doc/fontconfig-user.sgml
+++ b/doc/fontconfig-user.sgml
@@ -440,6 +440,10 @@ representation.
This element holds at least one <literal><int></literal> element of
an Unicode code point or more.
</para></refsect2>
+ <refsect2><title><literal><langset></literal></title><para>
+This element holds at least one <literal><string></literal> element of
+a RFC-3066-style languages or more.
+ </para></refsect2>
<refsect2><title><literal><name></literal></title><para>
Holds a property name. Evaluates to the first value from the property of
the font, not the pattern.
commit 3c862aad9f49be4b098cb679a67449c85b58f1f5
Author: Akira TAGOH <akira at tagoh.org>
Date: Mon Dec 6 12:38:18 2010 +0900
Add editing langset feature.
The syntax to add any langset to the langset table looks like:
<match target="scan">
<test name="family">
<string>Buggy Sans</string>
</test>
<edit name="lang" mode="assign">
<plus>
<name>lang</name>
<langset>
<string>zh-cn</string>
<string>zh-tw</string>
</langset>
</plus>
</edit>
</match>
To remove any langset from the langset table:
<match target="scan">
<test name="family">
<string>Buggy Sans</string>
</test>
<edit name="lang" mode="assign">
<minus>
<name>lang</name>
<langset>
<string>ja</string>
</langset>
</minus>
</edit>
</match>
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 260955d..29a6ed4 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -584,6 +584,9 @@ FcLangSetCopy (const FcLangSet *ls);
FcPublic FcBool
FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang);
+FcPublic FcBool
+FcLangSetDel (FcLangSet *ls, const FcChar8 *lang);
+
FcPublic FcLangResult
FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang);
@@ -602,6 +605,12 @@ FcLangSetHash (const FcLangSet *ls);
FcPublic FcStrSet *
FcLangSetGetLangs (const FcLangSet *ls);
+FcLangSet *
+FcLangSetUnion (const FcLangSet *a, const FcLangSet *b);
+
+FcLangSet *
+FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b);
+
/* fclist.c */
FcPublic FcObjectSet *
FcObjectSetCreate (void);
diff --git a/fonts.dtd b/fonts.dtd
index 5f21e35..d9d4b22 100644
--- a/fonts.dtd
+++ b/fonts.dtd
@@ -107,7 +107,7 @@
<!ELEMENT pattern (patelt)*>
-<!ENTITY % constant 'int|double|string|matrix|bool|charset|const'>
+<!ENTITY % constant 'int|double|string|matrix|bool|charset|langset|const'>
<!ELEMENT patelt (%constant;)*>
<!ATTLIST patelt
@@ -122,7 +122,7 @@
<!ELEMENT family (#PCDATA)>
<!ATTLIST family xml:space (default|preserve) 'preserve'>
-<!ENTITY % expr 'int|double|string|matrix|bool|charset
+<!ENTITY % expr 'int|double|string|matrix|bool|charset|langset
|name|const
|or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains
|plus|minus|times|divide|not|if|floor|ceil|round|trunc'>
@@ -198,6 +198,7 @@
<!ELEMENT bool (#PCDATA)>
<!ELEMENT charset (int|range)*>
<!ELEMENT range (int,int)>
+<!ELEMENT langset (string)*>
<!ELEMENT name (#PCDATA)>
<!ATTLIST name xml:space (default|preserve) 'preserve'>
<!ELEMENT const (#PCDATA)>
diff --git a/src/fccfg.c b/src/fccfg.c
index ad9f7d2..6812781 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -897,6 +897,11 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
v.u.c = e->u.cval;
v = FcValueSave (v);
break;
+ case FcOpLangSet:
+ v.type = FcTypeLangSet;
+ v.u.l = e->u.lval;
+ v = FcValueSave (v);
+ break;
case FcOpBool:
v.type = FcTypeBool;
v.u.b = e->u.bval;
@@ -1055,6 +1060,25 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break;
}
break;
+ case FcTypeLangSet:
+ switch (e->op) {
+ case FcOpPlus:
+ v.type = FcTypeLangSet;
+ v.u.l = FcLangSetUnion (vl.u.l, vr.u.l);
+ if (!v.u.l)
+ v.type = FcTypeVoid;
+ break;
+ case FcOpMinus:
+ v.type = FcTypeLangSet;
+ v.u.l = FcLangSetSubtract (vl.u.l, vr.u.l);
+ if (!v.u.l)
+ v.type = FcTypeVoid;
+ break;
+ default:
+ v.type = FcTypeVoid;
+ break;
+ }
+ break;
default:
v.type = FcTypeVoid;
break;
diff --git a/src/fcdbg.c b/src/fcdbg.c
index 79e1953..cf2ff08 100644
--- a/src/fcdbg.c
+++ b/src/fcdbg.c
@@ -163,6 +163,7 @@ FcOpPrint (FcOp op)
case FcOpRange: printf ("Range"); break;
case FcOpBool: printf ("Bool"); break;
case FcOpCharSet: printf ("CharSet"); break;
+ case FcOpLangSet: printf ("LangSet"); break;
case FcOpField: printf ("Field"); break;
case FcOpConst: printf ("Const"); break;
case FcOpAssign: printf ("Assign"); break;
@@ -214,6 +215,11 @@ FcExprPrint (const FcExpr *expr)
case FcOpRange: break;
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
case FcOpCharSet: printf ("charset\n"); break;
+ case FcOpLangSet:
+ printf ("langset:");
+ FcLangSetPrint(expr->u.lval);
+ printf ("\n");
+ break;
case FcOpNil: printf ("nil\n"); break;
case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break;
case FcOpConst: printf ("%s", expr->u.constant); break;
diff --git a/src/fcint.h b/src/fcint.h
index 9519fff..3da6ec4 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -216,7 +216,7 @@ struct _FcPattern {
fs->fonts[i])
typedef enum _FcOp {
- FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet,
+ FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet, FcOpLangSet,
FcOpNil,
FcOpField, FcOpConst,
FcOpAssign, FcOpAssignReplace,
@@ -239,6 +239,7 @@ typedef struct _FcExpr {
FcMatrix *mval;
FcBool bval;
FcCharSet *cval;
+ FcLangSet *lval;
FcObject object;
FcChar8 *constant;
struct {
diff --git a/src/fclang.c b/src/fclang.c
index 1c78328..be42b58 100644
--- a/src/fclang.c
+++ b/src/fclang.c
@@ -71,6 +71,20 @@ FcLangSetBitGet (const FcLangSet *ls,
return ((ls->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse;
}
+static void
+FcLangSetBitReset (FcLangSet *ls,
+ unsigned int id)
+{
+ int bucket;
+
+ id = fcLangCharSetIndices[id];
+ bucket = id >> 5;
+ if (bucket >= ls->map_size)
+ return; /* shouldn't happen really */
+
+ ls->map[bucket] &= ~((FcChar32) 1 << (id & 0x1f));
+}
+
FcLangSet *
FcFreeTypeLangSet (const FcCharSet *charset,
const FcChar8 *exclusiveLang)
@@ -400,6 +414,23 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
return FcStrSetAdd (ls->extra, lang);
}
+FcBool
+FcLangSetDel (FcLangSet *ls, const FcChar8 *lang)
+{
+ int id;
+
+ id = FcLangSetIndex (lang);
+ if (id >= 0)
+ {
+ FcLangSetBitReset (ls, id);
+ }
+ else if (ls->extra)
+ {
+ FcStrSetDel (ls->extra, lang);
+ }
+ return FcTrue;
+}
+
FcLangResult
FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang)
{
@@ -818,6 +849,37 @@ FcLangSetGetLangs (const FcLangSet *ls)
return langs;
}
+static FcLangSet *
+FcLangSetOperate(const FcLangSet *a,
+ const FcLangSet *b,
+ FcBool (*func) (FcLangSet *ls,
+ const FcChar8 *s))
+{
+ FcLangSet *langset = FcLangSetCopy (a);
+ FcStrList *sl = FcStrListCreate (FcLangSetGetLangs (b));
+ FcChar8 *str;
+
+ while ((str = FcStrListNext (sl)))
+ {
+ func (langset, str);
+ }
+ FcStrListDone (sl);
+
+ return langset;
+}
+
+FcLangSet *
+FcLangSetUnion (const FcLangSet *a, const FcLangSet *b)
+{
+ return FcLangSetOperate(a, b, FcLangSetAdd);
+}
+
+FcLangSet *
+FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b)
+{
+ return FcLangSetOperate(a, b, FcLangSetDel);
+}
+
#define __fclang__
#include "fcaliastail.h"
#include "fcftaliastail.h"
diff --git a/src/fcxml.c b/src/fcxml.c
index 4d07f9d..1aa3e4c 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -146,6 +146,18 @@ FcExprCreateCharSet (FcConfig *config, FcCharSet *charset)
}
static FcExpr *
+FcExprCreateLangSet (FcConfig *config, FcLangSet *langset)
+{
+ FcExpr *e = FcConfigAllocExpr (config);
+ if (e)
+ {
+ e->op = FcOpLangSet;
+ e->u.lval = FcLangSetCopy (langset);
+ }
+ return e;
+}
+
+static FcExpr *
FcExprCreateField (FcConfig *config, const char *field)
{
FcExpr *e = FcConfigAllocExpr (config);
@@ -202,6 +214,9 @@ FcExprDestroy (FcExpr *e)
case FcOpCharSet:
FcCharSetDestroy (e->u.cval);
break;
+ case FcOpLangSet:
+ FcLangSetDestroy (e->u.lval);
+ break;
case FcOpBool:
break;
case FcOpField:
@@ -294,6 +309,7 @@ typedef enum _FcElement {
FcElementRange,
FcElementBool,
FcElementCharSet,
+ FcElementLangSet,
FcElementName,
FcElementConst,
FcElementOr,
@@ -356,6 +372,7 @@ static const struct {
{ "range", FcElementRange },
{ "bool", FcElementBool },
{ "charset", FcElementCharSet },
+ { "langset", FcElementLangSet },
{ "name", FcElementName },
{ "const", FcElementConst },
{ "or", FcElementOr },
@@ -420,6 +437,7 @@ typedef enum _FcVStackTag {
FcVStackRange,
FcVStackBool,
FcVStackCharSet,
+ FcVStackLangSet,
FcVStackTest,
FcVStackExpr,
@@ -439,6 +457,7 @@ typedef struct _FcVStack {
FcRange range;
FcBool bool_;
FcCharSet *charset;
+ FcLangSet *langset;
FcTest *test;
FcQual qual;
@@ -571,6 +590,9 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
case FcOpCharSet:
FcTypecheckValue (parse, FcTypeCharSet, type);
break;
+ case FcOpLangSet:
+ FcTypecheckValue (parse, FcTypeLangSet, type);
+ break;
case FcOpNil:
break;
case FcOpField:
@@ -799,6 +821,20 @@ FcVStackPushCharSet (FcConfigParse *parse, FcCharSet *charset)
}
static FcBool
+FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset)
+{
+ FcVStack *vstack;
+ if (!langset)
+ return FcFalse;
+ vstack = FcVStackCreateAndPush (parse);
+ if (!vstack)
+ return FcFalse;
+ vstack->u.langset = langset;
+ vstack->tag = FcVStackLangSet;
+ return FcTrue;
+}
+
+static FcBool
FcVStackPushTest (FcConfigParse *parse, FcTest *test)
{
FcVStack *vstack = FcVStackCreateAndPush (parse);
@@ -895,6 +931,9 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
case FcVStackCharSet:
FcCharSetDestroy (vstack->u.charset);
break;
+ case FcVStackLangSet:
+ FcLangSetDestroy (vstack->u.langset);
+ break;
case FcVStackTest:
FcTestDestroy (vstack->u.test);
break;
@@ -1411,6 +1450,36 @@ FcParseCharSet (FcConfigParse *parse)
FcCharSetDestroy (charset);
}
+static void
+FcParseLangSet (FcConfigParse *parse)
+{
+ FcVStack *vstack;
+ FcLangSet *langset = FcLangSetCreate ();
+ int n = 0;
+
+ while ((vstack = FcVStackPeek (parse)))
+ {
+ switch (vstack->tag) {
+ case FcVStackString:
+ if (!FcLangSetAdd (langset, vstack->u.string))
+ {
+ FcConfigMessage (parse, FcSevereWarning, "invalid langset: %s", vstack->u.string);
+ }
+ else
+ n++;
+ break;
+ default:
+ FcConfigMessage (parse, FcSevereError, "invalid element in langset");
+ break;
+ }
+ FcVStackPopAndDestroy (parse);
+ }
+ if (n > 0)
+ FcVStackPushLangSet (parse, langset);
+ else
+ FcLangSetDestroy (langset);
+}
+
static FcBool
FcConfigLexBinding (FcConfigParse *parse,
const FcChar8 *binding_string,
@@ -1665,6 +1734,9 @@ FcPopExpr (FcConfigParse *parse)
case FcVStackCharSet:
expr = FcExprCreateCharSet (parse->config, vstack->u.charset);
break;
+ case FcVStackLangSet:
+ expr = FcExprCreateLangSet (parse->config, vstack->u.langset);
+ break;
case FcVStackTest:
break;
case FcVStackExpr:
@@ -2086,6 +2158,11 @@ FcPopValue (FcConfigParse *parse)
if (value.u.c)
value.type = FcTypeCharSet;
break;
+ case FcVStackLangSet:
+ value.u.l = FcLangSetCopy (vstack->u.langset);
+ if (value.u.l)
+ value.type = FcTypeLangSet;
+ break;
default:
FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
vstack->tag);
@@ -2360,6 +2437,9 @@ FcEndElement(void *userData, const XML_Char *name)
case FcElementCharSet:
FcParseCharSet (parse);
break;
+ case FcElementLangSet:
+ FcParseLangSet (parse);
+ break;
case FcElementSelectfont:
break;
case FcElementAcceptfont:
commit d975cdda782bb88c8bb6706889a554b2afb9f939
Author: Akira TAGOH <akira at tagoh.org>
Date: Mon Dec 6 12:18:23 2010 +0900
Add the range support in blank element
diff --git a/src/fcxml.c b/src/fcxml.c
index 94e2d4b..4d07f9d 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -1092,30 +1092,37 @@ FcStartElement(void *userData, const XML_Char *name, const XML_Char **attr)
static void
FcParseBlank (FcConfigParse *parse)
{
- int n = FcVStackElements (parse);
+ int n = FcVStackElements (parse);
+ FcChar32 i;
while (n-- > 0)
{
FcVStack *v = FcVStackFetch (parse, n);
- if (v->tag != FcVStackInteger)
- FcConfigMessage (parse, FcSevereError, "non-integer blank");
- else
+ if (!parse->config->blanks)
{
+ parse->config->blanks = FcBlanksCreate ();
if (!parse->config->blanks)
- {
- parse->config->blanks = FcBlanksCreate ();
- if (!parse->config->blanks)
- {
- FcConfigMessage (parse, FcSevereError, "out of memory");
- break;
- }
- }
+ goto bail;
+ }
+ switch (v->tag) {
+ case FcVStackInteger:
if (!FcBlanksAdd (parse->config->blanks, v->u.integer))
+ goto bail;
+ break;
+ case FcVStackRange:
+ for (i = v->u.range.begin; i <= v->u.range.end; i++)
{
- FcConfigMessage (parse, FcSevereError, "out of memory");
- break;
+ if (!FcBlanksAdd (parse->config->blanks, i))
+ goto bail;
}
+ break;
+ default:
+ FcConfigMessage (parse, FcSevereError, "invalid element in blank");
+ break;
}
}
+ return;
+ bail:
+ FcConfigMessage (parse, FcSevereError, "out of memory");
}
static void
commit 51e352a1bde91348888202539639a5a2d0d506d4
Author: Akira TAGOH <akira at tagoh.org>
Date: Thu Dec 9 11:32:26 2010 +0900
add some document for range and charset.
diff --git a/doc/fontconfig-user.sgml b/doc/fontconfig-user.sgml
index 219d906..ce6f158 100644
--- a/doc/fontconfig-user.sgml
+++ b/doc/fontconfig-user.sgml
@@ -432,6 +432,14 @@ instead of -.5).
This element holds the four <literal><double></literal> elements of an affine
transformation.
</para></refsect2>
+ <refsect2><title><literal><range></literal></title><para>
+This element holds the two <literal><int></literal> elements of a range
+representation.
+ </para></refsect2>
+ <refsect2><title><literal><charset></literal></title><para>
+This element holds at least one <literal><int></literal> element of
+an Unicode code point or more.
+ </para></refsect2>
<refsect2><title><literal><name></literal></title><para>
Holds a property name. Evaluates to the first value from the property of
the font, not the pattern.
commit 857b7efe1e301f670329c6836da52fbab8c5df66
Author: Akira TAGOH <akira at tagoh.org>
Date: Mon Dec 6 12:10:17 2010 +0900
Add charset editing feature.
The syntax to add any characters to the charset table looks like:
<match target="scan">
<test name="family">
<string>Buggy Sans</string>
</test>
<edit name="charset" mode="assign">
<plus>
<name>charset</name>
<charset>
<int>0x3220</int> <!-- PARENTHESIZED IDEOGRAPH ONE -->
</charset>
</plus>
</edit>
</match>
To remove any characters from the charset table:
<match target="scan">
<test name="family">
<string>Buggy Sans</string>
</test>
<edit name="charset" mode="assign">
<minus>
<name>charset</name>
<charset>
<int>0x06CC</int> <!-- ARABIC LETTER FARSI YEH -->
<int>0x06D2</int> <!-- ARABIC LETTER YEH BARREE -->
<int>0x06D3</int> <!-- ARABIC LETTER YEH BARREE WITH HAMZA ABOVE -->
</charset>
</minus>
</edit>
</match>
You could also use the range element for convenience:
...
<charset>
<int>0x06CC</int> <!-- ARABIC LETTER FARSI YEH -->
<range>
<int>0x06D2</int> <!-- ARABIC LETTER YEH BARREE -->
<int>0x06D3</int> <!-- ARABIC LETTER YEH BARREE WITH HAMZA ABOVE -->
</range>
</charset>
...
diff --git a/fonts.dtd b/fonts.dtd
index cbdfdab..5f21e35 100644
--- a/fonts.dtd
+++ b/fonts.dtd
@@ -196,8 +196,8 @@
<!ATTLIST string xml:space (default|preserve) 'preserve'>
<!ELEMENT matrix (double,double,double,double)>
<!ELEMENT bool (#PCDATA)>
-<!ELEMENT charset (#PCDATA)>
-<!ATTLIST charset xml:space (default|preserve) 'preserve'>
+<!ELEMENT charset (int|range)*>
+<!ELEMENT range (int,int)>
<!ELEMENT name (#PCDATA)>
<!ATTLIST name xml:space (default|preserve) 'preserve'>
<!ELEMENT const (#PCDATA)>
diff --git a/src/Makefile.am b/src/Makefile.am
index 59b9c75..96500b4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -140,7 +140,7 @@ PUBLIC_FILES = \
$(top_srcdir)/fontconfig/fontconfig.h \
$(top_srcdir)/src/fcdeprecate.h \
$(top_srcdir)/fontconfig/fcprivate.h
-
+
PUBLIC_FT_FILES = \
$(top_srcdir)/fontconfig/fcfreetype.h
@@ -160,7 +160,7 @@ fontconfig.def: $(PUBLIC_FILES) $(PUBLIC_FT_FILES)
echo Generating $@
(echo EXPORTS; \
(cat $(PUBLIC_FILES) $(PUBLIC_FT_FILES) || echo 'FcERROR ()' ) | \
- grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$$//' -e 's/^/ /' | \
+ grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$$//' -e 's/^/ /' | \
sort; \
echo LIBRARY libfontconfig- at LIBT_CURRENT_MINUS_AGE@.dll; \
echo VERSION @LIBT_CURRENT at .@LIBT_REVISION@) >$@
diff --git a/src/fccfg.c b/src/fccfg.c
index 19a9fef..ad9f7d2 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -1036,6 +1036,25 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break;
}
break;
+ case FcTypeCharSet:
+ switch (e->op) {
+ case FcOpPlus:
+ v.type = FcTypeCharSet;
+ v.u.c = FcCharSetUnion (vl.u.c, vr.u.c);
+ if (!v.u.c)
+ v.type = FcTypeVoid;
+ break;
+ case FcOpMinus:
+ v.type = FcTypeCharSet;
+ v.u.c = FcCharSetSubtract (vl.u.c, vr.u.c);
+ if (!v.u.c)
+ v.type = FcTypeVoid;
+ break;
+ default:
+ v.type = FcTypeVoid;
+ break;
+ }
+ break;
default:
v.type = FcTypeVoid;
break;
diff --git a/src/fcdbg.c b/src/fcdbg.c
index fc3b596..79e1953 100644
--- a/src/fcdbg.c
+++ b/src/fcdbg.c
@@ -160,6 +160,7 @@ FcOpPrint (FcOp op)
case FcOpDouble: printf ("Double"); break;
case FcOpString: printf ("String"); break;
case FcOpMatrix: printf ("Matrix"); break;
+ case FcOpRange: printf ("Range"); break;
case FcOpBool: printf ("Bool"); break;
case FcOpCharSet: printf ("CharSet"); break;
case FcOpField: printf ("Field"); break;
@@ -210,6 +211,7 @@ FcExprPrint (const FcExpr *expr)
expr->u.mval->xy,
expr->u.mval->yx,
expr->u.mval->yy); break;
+ case FcOpRange: break;
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
case FcOpCharSet: printf ("charset\n"); break;
case FcOpNil: printf ("nil\n"); break;
diff --git a/src/fcint.h b/src/fcint.h
index 2bc7878..9519fff 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -216,7 +216,7 @@ struct _FcPattern {
fs->fonts[i])
typedef enum _FcOp {
- FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet,
+ FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet,
FcOpNil,
FcOpField, FcOpConst,
FcOpAssign, FcOpAssignReplace,
@@ -507,6 +507,13 @@ typedef struct _FcFileTime {
typedef struct _FcCharMap FcCharMap;
+typedef struct _FcRange FcRange;
+
+struct _FcRange {
+ FcChar32 begin;
+ FcChar32 end;
+};
+
/* fcblanks.c */
/* fccache.c */
diff --git a/src/fcxml.c b/src/fcxml.c
index 2bd67bf..94e2d4b 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -134,6 +134,18 @@ FcExprCreateBool (FcConfig *config, FcBool b)
}
static FcExpr *
+FcExprCreateCharSet (FcConfig *config, FcCharSet *charset)
+{
+ FcExpr *e = FcConfigAllocExpr (config);
+ if (e)
+ {
+ e->op = FcOpCharSet;
+ e->u.cval = FcCharSetCopy (charset);
+ }
+ return e;
+}
+
+static FcExpr *
FcExprCreateField (FcConfig *config, const char *field)
{
FcExpr *e = FcConfigAllocExpr (config);
@@ -185,6 +197,8 @@ FcExprDestroy (FcExpr *e)
case FcOpMatrix:
FcMatrixFree (e->u.mval);
break;
+ case FcOpRange:
+ break;
case FcOpCharSet:
FcCharSetDestroy (e->u.cval);
break;
@@ -277,8 +291,9 @@ typedef enum _FcElement {
FcElementDouble,
FcElementString,
FcElementMatrix,
+ FcElementRange,
FcElementBool,
- FcElementCharset,
+ FcElementCharSet,
FcElementName,
FcElementConst,
FcElementOr,
@@ -338,8 +353,9 @@ static const struct {
{ "double", FcElementDouble },
{ "string", FcElementString },
{ "matrix", FcElementMatrix },
+ { "range", FcElementRange },
{ "bool", FcElementBool },
- { "charset", FcElementCharset },
+ { "charset", FcElementCharSet },
{ "name", FcElementName },
{ "const", FcElementConst },
{ "or", FcElementOr },
@@ -401,7 +417,9 @@ typedef enum _FcVStackTag {
FcVStackInteger,
FcVStackDouble,
FcVStackMatrix,
+ FcVStackRange,
FcVStackBool,
+ FcVStackCharSet,
FcVStackTest,
FcVStackExpr,
@@ -418,7 +436,9 @@ typedef struct _FcVStack {
int integer;
double _double;
FcMatrix *matrix;
+ FcRange range;
FcBool bool_;
+ FcCharSet *charset;
FcTest *test;
FcQual qual;
@@ -742,6 +762,18 @@ FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix)
}
static FcBool
+FcVStackPushRange (FcConfigParse *parse, FcRange *range)
+{
+ FcVStack *vstack = FcVStackCreateAndPush (parse);
+ if (!vstack)
+ return FcFalse;
+ vstack->u.range.begin = range->begin;
+ vstack->u.range.end = range->end;
+ vstack->tag = FcVStackRange;
+ return FcTrue;
+}
+
+static FcBool
FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
{
FcVStack *vstack = FcVStackCreateAndPush (parse);
@@ -753,6 +785,20 @@ FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
}
static FcBool
+FcVStackPushCharSet (FcConfigParse *parse, FcCharSet *charset)
+{
+ FcVStack *vstack;
+ if (!charset)
+ return FcFalse;
+ vstack = FcVStackCreateAndPush (parse);
+ if (!vstack)
+ return FcFalse;
+ vstack->u.charset = charset;
+ vstack->tag = FcVStackCharSet;
+ return FcTrue;
+}
+
+static FcBool
FcVStackPushTest (FcConfigParse *parse, FcTest *test)
{
FcVStack *vstack = FcVStackCreateAndPush (parse);
@@ -843,8 +889,12 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
case FcVStackMatrix:
FcMatrixFree (vstack->u.matrix);
break;
+ case FcVStackRange:
case FcVStackBool:
break;
+ case FcVStackCharSet:
+ FcCharSetDestroy (vstack->u.charset);
+ break;
case FcVStackTest:
FcTestDestroy (vstack->u.test);
break;
@@ -1241,6 +1291,49 @@ FcParseMatrix (FcConfigParse *parse)
FcVStackPushMatrix (parse, &m);
}
+static void
+FcParseRange (FcConfigParse *parse)
+{
+ FcVStack *vstack;
+ FcRange r;
+ FcChar32 n;
+ int count = 1;
+
+ while ((vstack = FcVStackPeek (parse)))
+ {
+ if (count < 0)
+ {
+ FcConfigMessage (parse, FcSevereError, "too many elements in range");
+ return;
+ }
+ switch (vstack->tag) {
+ case FcVStackInteger:
+ n = vstack->u.integer;
+ break;
+ default:
+ FcConfigMessage (parse, FcSevereError, "invalid element in range");
+ break;
+ }
+ if (count == 1)
+ r.end = n;
+ else
+ r.begin = n;
+ count--;
+ FcVStackPopAndDestroy (parse);
+ }
+ if (count < 0)
+ {
+ if (r.begin > r.end)
+ {
+ FcConfigMessage (parse, FcSevereError, "invalid range");
+ return;
+ }
+ FcVStackPushRange (parse, &r);
+ }
+ else
+ FcConfigMessage (parse, FcSevereError, "invalid range");
+}
+
static FcBool
FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool_)
{
@@ -1269,6 +1362,48 @@ FcParseBool (FcConfigParse *parse)
FcStrBufDestroy (&parse->pstack->str);
}
+static void
+FcParseCharSet (FcConfigParse *parse)
+{
+ FcVStack *vstack;
+ FcCharSet *charset = FcCharSetCreate ();
+ FcChar32 i;
+ int n = 0;
+
+ while ((vstack = FcVStackPeek (parse)))
+ {
+ switch (vstack->tag) {
+ case FcVStackInteger:
+ if (!FcCharSetAddChar (charset, vstack->u.integer))
+ {
+ FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", vstack->u.integer);
+ }
+ else
+ n++;
+ break;
+ case FcVStackRange:
+ for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++)
+ {
+ if (!FcCharSetAddChar (charset, i))
+ {
+ FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
+ }
+ else
+ n++;
+ }
+ break;
+ default:
+ FcConfigMessage (parse, FcSevereError, "invalid element in charset");
+ break;
+ }
+ FcVStackPopAndDestroy (parse);
+ }
+ if (n > 0)
+ FcVStackPushCharSet (parse, charset);
+ else
+ FcCharSetDestroy (charset);
+}
+
static FcBool
FcConfigLexBinding (FcConfigParse *parse,
const FcChar8 *binding_string,
@@ -1515,9 +1650,14 @@ FcPopExpr (FcConfigParse *parse)
case FcVStackMatrix:
expr = FcExprCreateMatrix (parse->config, vstack->u.matrix);
break;
+ case FcVStackRange:
+ break;
case FcVStackBool:
expr = FcExprCreateBool (parse->config, vstack->u.bool_);
break;
+ case FcVStackCharSet:
+ expr = FcExprCreateCharSet (parse->config, vstack->u.charset);
+ break;
case FcVStackTest:
break;
case FcVStackExpr:
@@ -1934,6 +2074,11 @@ FcPopValue (FcConfigParse *parse)
value.u.b = vstack->u.bool_;
value.type = FcTypeBool;
break;
+ case FcVStackCharSet:
+ value.u.c = FcCharSetCopy (vstack->u.charset);
+ if (value.u.c)
+ value.type = FcTypeCharSet;
+ break;
default:
FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
vstack->tag);
@@ -2199,11 +2344,14 @@ FcEndElement(void *userData, const XML_Char *name)
case FcElementMatrix:
FcParseMatrix (parse);
break;
+ case FcElementRange:
+ FcParseRange (parse);
+ break;
case FcElementBool:
FcParseBool (parse);
break;
- case FcElementCharset:
-/* FcParseCharset (parse); */
+ case FcElementCharSet:
+ FcParseCharSet (parse);
break;
case FcElementSelectfont:
break;
More information about the Fontconfig
mailing list