X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffcxml.c;h=4d07f9d6cdfec1d76628163baa83c5330ec1fa50;hb=d975cdda782bb88c8bb6706889a554b2afb9f939;hp=2bd67bf090236a6db81a5f0a418096f3a5f5669b;hpb=5aaf466d3899842763e746a9c2b745748eb34b48;p=fontconfig.git diff --git a/src/fcxml.c b/src/fcxml.c index 2bd67bf..4d07f9d 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -133,6 +133,18 @@ FcExprCreateBool (FcConfig *config, FcBool b) 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 * FcExprCreateField (FcConfig *config, const char *field) { @@ -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; @@ -741,6 +761,18 @@ FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix) 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 FcVStackPushBool (FcConfigParse *parse, FcBool bool_) { @@ -752,6 +784,20 @@ FcVStackPushBool (FcConfigParse *parse, FcBool bool_) 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 FcVStackPushTest (FcConfigParse *parse, FcTest *test) { @@ -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; @@ -1042,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 @@ -1241,6 +1298,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 +1369,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 +1657,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 +2081,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 +2351,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;