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"
This commit is contained in:
Behdad Esfahbod 2010-12-28 02:50:16 -06:00
commit 549c9962a4
10 changed files with 433 additions and 25 deletions

View File

@ -58,6 +58,36 @@ two or three letter language from ISO 639 and Tt is a territory from ISO
3166. 3166.
@@ @@
@RET@ FcBool
@FUNC@ FcLangSetDel
@TYPE1@ FcLangSet * @ARG1@ ls
@TYPE2@ const FcChar8 * @ARG2@ lang
@PURPOSE@ remove 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
two or three letter language from ISO 639 and Tt is a territory from ISO
3166.
@@
@RET@ FcLangSet *
@FUNC@ FcLangSetUnion
@TYPE1@ const FcLangSet * @ARG1@ ls_a
@TYPE2@ const FcLangSet * @ARG2@ ls_b
@PURPOSE@ Add langsets
@DESC@
Returns a set including only those languages found in either <parameter>ls_a</parameter> or <parameter>ls_b</parameter>.
@@
@RET@ FcLangSet *
@FUNC@ FcLangSetSubtract
@TYPE1@ const FcLangSet * @ARG1@ ls_a
@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>.
@@
@RET@ FcLangResult @RET@ FcLangResult
@FUNC@ FcLangSetCompare @FUNC@ FcLangSetCompare
@TYPE1@ const FcLangSet * @ARG1@ ls_a @TYPE1@ const FcLangSet * @ARG1@ ls_a

View File

@ -431,6 +431,18 @@ instead of -.5).
<refsect2><title><literal>&lt;matrix&gt;</literal></title><para> <refsect2><title><literal>&lt;matrix&gt;</literal></title><para>
This element holds the four <literal>&lt;double&gt;</literal> elements of an affine This element holds the four <literal>&lt;double&gt;</literal> elements of an affine
transformation. transformation.
</para></refsect2>
<refsect2><title><literal>&lt;range&gt;</literal></title><para>
This element holds the two <literal>&lt;int&gt;</literal> elements of a range
representation.
</para></refsect2>
<refsect2><title><literal>&lt;charset&gt;</literal></title><para>
This element holds at least one <literal>&lt;int&gt;</literal> element of
an Unicode code point or more.
</para></refsect2>
<refsect2><title><literal>&lt;langset&gt;</literal></title><para>
This element holds at least one <literal>&lt;string&gt;</literal> element of
a RFC-3066-style languages or more.
</para></refsect2> </para></refsect2>
<refsect2><title><literal>&lt;name&gt;</literal></title><para> <refsect2><title><literal>&lt;name&gt;</literal></title><para>
Holds a property name. Evaluates to the first value from the property of Holds a property name. Evaluates to the first value from the property of

View File

@ -584,6 +584,9 @@ FcLangSetCopy (const FcLangSet *ls);
FcPublic FcBool FcPublic FcBool
FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang); FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang);
FcPublic FcBool
FcLangSetDel (FcLangSet *ls, const FcChar8 *lang);
FcPublic FcLangResult FcPublic FcLangResult
FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang); FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang);
@ -602,6 +605,12 @@ FcLangSetHash (const FcLangSet *ls);
FcPublic FcStrSet * FcPublic FcStrSet *
FcLangSetGetLangs (const FcLangSet *ls); FcLangSetGetLangs (const FcLangSet *ls);
FcLangSet *
FcLangSetUnion (const FcLangSet *a, const FcLangSet *b);
FcLangSet *
FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b);
/* fclist.c */ /* fclist.c */
FcPublic FcObjectSet * FcPublic FcObjectSet *
FcObjectSetCreate (void); FcObjectSetCreate (void);

View File

@ -107,7 +107,7 @@
<!ELEMENT pattern (patelt)*> <!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;)*> <!ELEMENT patelt (%constant;)*>
<!ATTLIST patelt <!ATTLIST patelt
@ -122,7 +122,7 @@
<!ELEMENT family (#PCDATA)> <!ELEMENT family (#PCDATA)>
<!ATTLIST family xml:space (default|preserve) 'preserve'> <!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 |name|const
|or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains |or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains
|plus|minus|times|divide|not|if|floor|ceil|round|trunc'> |plus|minus|times|divide|not|if|floor|ceil|round|trunc'>
@ -196,8 +196,9 @@
<!ATTLIST string xml:space (default|preserve) 'preserve'> <!ATTLIST string xml:space (default|preserve) 'preserve'>
<!ELEMENT matrix (double,double,double,double)> <!ELEMENT matrix (double,double,double,double)>
<!ELEMENT bool (#PCDATA)> <!ELEMENT bool (#PCDATA)>
<!ELEMENT charset (#PCDATA)> <!ELEMENT charset (int|range)*>
<!ATTLIST charset xml:space (default|preserve) 'preserve'> <!ELEMENT range (int,int)>
<!ELEMENT langset (string)*>
<!ELEMENT name (#PCDATA)> <!ELEMENT name (#PCDATA)>
<!ATTLIST name xml:space (default|preserve) 'preserve'> <!ATTLIST name xml:space (default|preserve) 'preserve'>
<!ELEMENT const (#PCDATA)> <!ELEMENT const (#PCDATA)>

View File

@ -140,7 +140,7 @@ PUBLIC_FILES = \
$(top_srcdir)/fontconfig/fontconfig.h \ $(top_srcdir)/fontconfig/fontconfig.h \
$(top_srcdir)/src/fcdeprecate.h \ $(top_srcdir)/src/fcdeprecate.h \
$(top_srcdir)/fontconfig/fcprivate.h $(top_srcdir)/fontconfig/fcprivate.h
PUBLIC_FT_FILES = \ PUBLIC_FT_FILES = \
$(top_srcdir)/fontconfig/fcfreetype.h $(top_srcdir)/fontconfig/fcfreetype.h
@ -160,7 +160,7 @@ fontconfig.def: $(PUBLIC_FILES) $(PUBLIC_FT_FILES)
echo Generating $@ echo Generating $@
(echo EXPORTS; \ (echo EXPORTS; \
(cat $(PUBLIC_FILES) $(PUBLIC_FT_FILES) || echo 'FcERROR ()' ) | \ (cat $(PUBLIC_FILES) $(PUBLIC_FT_FILES) || echo 'FcERROR ()' ) | \
grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$$//' -e 's/^/ /' | \ grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$$//' -e 's/^/ /' | \
sort; \ sort; \
echo LIBRARY libfontconfig-@LIBT_CURRENT_MINUS_AGE@.dll; \ echo LIBRARY libfontconfig-@LIBT_CURRENT_MINUS_AGE@.dll; \
echo VERSION @LIBT_CURRENT@.@LIBT_REVISION@) >$@ echo VERSION @LIBT_CURRENT@.@LIBT_REVISION@) >$@

View File

@ -897,6 +897,11 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
v.u.c = e->u.cval; v.u.c = e->u.cval;
v = FcValueSave (v); v = FcValueSave (v);
break; break;
case FcOpLangSet:
v.type = FcTypeLangSet;
v.u.l = e->u.lval;
v = FcValueSave (v);
break;
case FcOpBool: case FcOpBool:
v.type = FcTypeBool; v.type = FcTypeBool;
v.u.b = e->u.bval; v.u.b = e->u.bval;
@ -1036,6 +1041,44 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break; break;
} }
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;
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: default:
v.type = FcTypeVoid; v.type = FcTypeVoid;
break; break;

View File

@ -160,8 +160,10 @@ FcOpPrint (FcOp op)
case FcOpDouble: printf ("Double"); break; case FcOpDouble: printf ("Double"); break;
case FcOpString: printf ("String"); break; case FcOpString: printf ("String"); break;
case FcOpMatrix: printf ("Matrix"); break; case FcOpMatrix: printf ("Matrix"); break;
case FcOpRange: printf ("Range"); break;
case FcOpBool: printf ("Bool"); break; case FcOpBool: printf ("Bool"); break;
case FcOpCharSet: printf ("CharSet"); break; case FcOpCharSet: printf ("CharSet"); break;
case FcOpLangSet: printf ("LangSet"); break;
case FcOpField: printf ("Field"); break; case FcOpField: printf ("Field"); break;
case FcOpConst: printf ("Const"); break; case FcOpConst: printf ("Const"); break;
case FcOpAssign: printf ("Assign"); break; case FcOpAssign: printf ("Assign"); break;
@ -210,8 +212,14 @@ FcExprPrint (const FcExpr *expr)
expr->u.mval->xy, expr->u.mval->xy,
expr->u.mval->yx, expr->u.mval->yx,
expr->u.mval->yy); break; expr->u.mval->yy); break;
case FcOpRange: break;
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break; case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
case FcOpCharSet: printf ("charset\n"); 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 FcOpNil: printf ("nil\n"); break;
case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break; case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break;
case FcOpConst: printf ("%s", expr->u.constant); break; case FcOpConst: printf ("%s", expr->u.constant); break;

View File

@ -220,7 +220,7 @@ struct _FcPattern {
fs->fonts[i]) fs->fonts[i])
typedef enum _FcOp { typedef enum _FcOp {
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet, FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet, FcOpLangSet,
FcOpNil, FcOpNil,
FcOpField, FcOpConst, FcOpField, FcOpConst,
FcOpAssign, FcOpAssignReplace, FcOpAssign, FcOpAssignReplace,
@ -243,6 +243,7 @@ typedef struct _FcExpr {
FcMatrix *mval; FcMatrix *mval;
FcBool bval; FcBool bval;
FcCharSet *cval; FcCharSet *cval;
FcLangSet *lval;
FcObject object; FcObject object;
FcChar8 *constant; FcChar8 *constant;
struct { struct {
@ -511,6 +512,13 @@ typedef struct _FcFileTime {
typedef struct _FcCharMap FcCharMap; typedef struct _FcCharMap FcCharMap;
typedef struct _FcRange FcRange;
struct _FcRange {
FcChar32 begin;
FcChar32 end;
};
/* fcblanks.c */ /* fcblanks.c */
/* fccache.c */ /* fccache.c */

View File

@ -71,6 +71,20 @@ FcLangSetBitGet (const FcLangSet *ls,
return ((ls->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse; 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 * FcLangSet *
FcFreeTypeLangSet (const FcCharSet *charset, FcFreeTypeLangSet (const FcCharSet *charset,
const FcChar8 *exclusiveLang) const FcChar8 *exclusiveLang)
@ -400,6 +414,23 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
return FcStrSetAdd (ls->extra, 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 FcLangResult
FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang) FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang)
{ {
@ -818,6 +849,37 @@ FcLangSetGetLangs (const FcLangSet *ls)
return langs; 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__ #define __fclang__
#include "fcaliastail.h" #include "fcaliastail.h"
#include "fcftaliastail.h" #include "fcftaliastail.h"

View File

@ -133,6 +133,30 @@ FcExprCreateBool (FcConfig *config, FcBool b)
return e; return e;
} }
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 *
FcExprCreateLangSet (FcConfig *config, FcLangSet *langset)
{
FcExpr *e = FcConfigAllocExpr (config);
if (e)
{
e->op = FcOpLangSet;
e->u.lval = FcLangSetCopy (langset);
}
return e;
}
static FcExpr * static FcExpr *
FcExprCreateField (FcConfig *config, const char *field) FcExprCreateField (FcConfig *config, const char *field)
{ {
@ -185,9 +209,14 @@ FcExprDestroy (FcExpr *e)
case FcOpMatrix: case FcOpMatrix:
FcMatrixFree (e->u.mval); FcMatrixFree (e->u.mval);
break; break;
case FcOpRange:
break;
case FcOpCharSet: case FcOpCharSet:
FcCharSetDestroy (e->u.cval); FcCharSetDestroy (e->u.cval);
break; break;
case FcOpLangSet:
FcLangSetDestroy (e->u.lval);
break;
case FcOpBool: case FcOpBool:
break; break;
case FcOpField: case FcOpField:
@ -277,8 +306,10 @@ typedef enum _FcElement {
FcElementDouble, FcElementDouble,
FcElementString, FcElementString,
FcElementMatrix, FcElementMatrix,
FcElementRange,
FcElementBool, FcElementBool,
FcElementCharset, FcElementCharSet,
FcElementLangSet,
FcElementName, FcElementName,
FcElementConst, FcElementConst,
FcElementOr, FcElementOr,
@ -338,8 +369,10 @@ static const struct {
{ "double", FcElementDouble }, { "double", FcElementDouble },
{ "string", FcElementString }, { "string", FcElementString },
{ "matrix", FcElementMatrix }, { "matrix", FcElementMatrix },
{ "range", FcElementRange },
{ "bool", FcElementBool }, { "bool", FcElementBool },
{ "charset", FcElementCharset }, { "charset", FcElementCharSet },
{ "langset", FcElementLangSet },
{ "name", FcElementName }, { "name", FcElementName },
{ "const", FcElementConst }, { "const", FcElementConst },
{ "or", FcElementOr }, { "or", FcElementOr },
@ -401,7 +434,10 @@ typedef enum _FcVStackTag {
FcVStackInteger, FcVStackInteger,
FcVStackDouble, FcVStackDouble,
FcVStackMatrix, FcVStackMatrix,
FcVStackRange,
FcVStackBool, FcVStackBool,
FcVStackCharSet,
FcVStackLangSet,
FcVStackTest, FcVStackTest,
FcVStackExpr, FcVStackExpr,
@ -418,7 +454,10 @@ typedef struct _FcVStack {
int integer; int integer;
double _double; double _double;
FcMatrix *matrix; FcMatrix *matrix;
FcRange range;
FcBool bool_; FcBool bool_;
FcCharSet *charset;
FcLangSet *langset;
FcTest *test; FcTest *test;
FcQual qual; FcQual qual;
@ -551,6 +590,9 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
case FcOpCharSet: case FcOpCharSet:
FcTypecheckValue (parse, FcTypeCharSet, type); FcTypecheckValue (parse, FcTypeCharSet, type);
break; break;
case FcOpLangSet:
FcTypecheckValue (parse, FcTypeLangSet, type);
break;
case FcOpNil: case FcOpNil:
break; break;
case FcOpField: case FcOpField:
@ -741,6 +783,18 @@ FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix)
return FcTrue; return FcTrue;
} }
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 static FcBool
FcVStackPushBool (FcConfigParse *parse, FcBool bool_) FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
{ {
@ -752,6 +806,34 @@ FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
return FcTrue; return FcTrue;
} }
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
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 static FcBool
FcVStackPushTest (FcConfigParse *parse, FcTest *test) FcVStackPushTest (FcConfigParse *parse, FcTest *test)
{ {
@ -843,8 +925,15 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
case FcVStackMatrix: case FcVStackMatrix:
FcMatrixFree (vstack->u.matrix); FcMatrixFree (vstack->u.matrix);
break; break;
case FcVStackRange:
case FcVStackBool: case FcVStackBool:
break; break;
case FcVStackCharSet:
FcCharSetDestroy (vstack->u.charset);
break;
case FcVStackLangSet:
FcLangSetDestroy (vstack->u.langset);
break;
case FcVStackTest: case FcVStackTest:
FcTestDestroy (vstack->u.test); FcTestDestroy (vstack->u.test);
break; break;
@ -1042,30 +1131,37 @@ FcStartElement(void *userData, const XML_Char *name, const XML_Char **attr)
static void static void
FcParseBlank (FcConfigParse *parse) FcParseBlank (FcConfigParse *parse)
{ {
int n = FcVStackElements (parse); int n = FcVStackElements (parse);
FcChar32 i;
while (n-- > 0) while (n-- > 0)
{ {
FcVStack *v = FcVStackFetch (parse, n); FcVStack *v = FcVStackFetch (parse, n);
if (v->tag != FcVStackInteger) if (!parse->config->blanks)
FcConfigMessage (parse, FcSevereError, "non-integer blank");
else
{ {
parse->config->blanks = FcBlanksCreate ();
if (!parse->config->blanks) if (!parse->config->blanks)
{ goto bail;
parse->config->blanks = FcBlanksCreate (); }
if (!parse->config->blanks) switch (v->tag) {
{ case FcVStackInteger:
FcConfigMessage (parse, FcSevereError, "out of memory");
break;
}
}
if (!FcBlanksAdd (parse->config->blanks, v->u.integer)) 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"); if (!FcBlanksAdd (parse->config->blanks, i))
break; goto bail;
} }
break;
default:
FcConfigMessage (parse, FcSevereError, "invalid element in blank");
break;
} }
} }
return;
bail:
FcConfigMessage (parse, FcSevereError, "out of memory");
} }
static void static void
@ -1241,6 +1337,49 @@ FcParseMatrix (FcConfigParse *parse)
FcVStackPushMatrix (parse, &m); 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 static FcBool
FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool_) FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool_)
{ {
@ -1269,6 +1408,78 @@ FcParseBool (FcConfigParse *parse)
FcStrBufDestroy (&parse->pstack->str); 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 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 static FcBool
FcConfigLexBinding (FcConfigParse *parse, FcConfigLexBinding (FcConfigParse *parse,
const FcChar8 *binding_string, const FcChar8 *binding_string,
@ -1515,9 +1726,17 @@ FcPopExpr (FcConfigParse *parse)
case FcVStackMatrix: case FcVStackMatrix:
expr = FcExprCreateMatrix (parse->config, vstack->u.matrix); expr = FcExprCreateMatrix (parse->config, vstack->u.matrix);
break; break;
case FcVStackRange:
break;
case FcVStackBool: case FcVStackBool:
expr = FcExprCreateBool (parse->config, vstack->u.bool_); expr = FcExprCreateBool (parse->config, vstack->u.bool_);
break; break;
case FcVStackCharSet:
expr = FcExprCreateCharSet (parse->config, vstack->u.charset);
break;
case FcVStackLangSet:
expr = FcExprCreateLangSet (parse->config, vstack->u.langset);
break;
case FcVStackTest: case FcVStackTest:
break; break;
case FcVStackExpr: case FcVStackExpr:
@ -1934,6 +2153,16 @@ FcPopValue (FcConfigParse *parse)
value.u.b = vstack->u.bool_; value.u.b = vstack->u.bool_;
value.type = FcTypeBool; value.type = FcTypeBool;
break; break;
case FcVStackCharSet:
value.u.c = FcCharSetCopy (vstack->u.charset);
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: default:
FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d", FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
vstack->tag); vstack->tag);
@ -2199,11 +2428,17 @@ FcEndElement(void *userData, const XML_Char *name)
case FcElementMatrix: case FcElementMatrix:
FcParseMatrix (parse); FcParseMatrix (parse);
break; break;
case FcElementRange:
FcParseRange (parse);
break;
case FcElementBool: case FcElementBool:
FcParseBool (parse); FcParseBool (parse);
break; break;
case FcElementCharset: case FcElementCharSet:
/* FcParseCharset (parse); */ FcParseCharSet (parse);
break;
case FcElementLangSet:
FcParseLangSet (parse);
break; break;
case FcElementSelectfont: case FcElementSelectfont:
break; break;