aboutsummaryrefslogtreecommitdiff
path: root/fontconfig/src/fcxml.c
diff options
context:
space:
mode:
Diffstat (limited to 'fontconfig/src/fcxml.c')
-rw-r--r--fontconfig/src/fcxml.c108
1 files changed, 84 insertions, 24 deletions
diff --git a/fontconfig/src/fcxml.c b/fontconfig/src/fcxml.c
index ec79b8723..9f4c2b062 100644
--- a/fontconfig/src/fcxml.c
+++ b/fontconfig/src/fcxml.c
@@ -169,6 +169,18 @@ FcExprCreateMatrix (FcConfig *config, const FcExprMatrix *matrix)
}
static FcExpr *
+FcExprCreateRange (FcConfig *config, FcRange *range)
+{
+ FcExpr *e = FcConfigAllocExpr (config);
+ if (e)
+ {
+ e->op = FcOpRange;
+ e->u.rval = FcRangeCopy (range);
+ }
+ return e;
+}
+
+static FcExpr *
FcExprCreateBool (FcConfig *config, FcBool b)
{
FcExpr *e = FcConfigAllocExpr (config);
@@ -258,6 +270,7 @@ FcExprDestroy (FcExpr *e)
FcExprMatrixFree (e->u.mexpr);
break;
case FcOpRange:
+ FcRangeDestroy (e->u.rval);
break;
case FcOpCharSet:
FcCharSetDestroy (e->u.cval);
@@ -503,7 +516,7 @@ typedef struct _FcVStack {
int integer;
double _double;
FcExprMatrix *matrix;
- FcRange range;
+ FcRange *range;
FcBool bool_;
FcCharSet *charset;
FcLangSet *langset;
@@ -593,6 +606,8 @@ FcTypeName (FcType type)
return "FT_Face";
case FcTypeLangSet:
return "langset";
+ case FcTypeRange:
+ return "range";
default:
return "unknown";
}
@@ -608,7 +623,9 @@ FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type)
if (value != type)
{
if ((value == FcTypeLangSet && type == FcTypeString) ||
- (value == FcTypeString && type == FcTypeLangSet))
+ (value == FcTypeString && type == FcTypeLangSet) ||
+ (value == FcTypeInteger && type == FcTypeRange) ||
+ (value == FcTypeDouble && type == FcTypeRange))
return;
if (type == FcTypeUnknown)
return;
@@ -651,6 +668,9 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
case FcOpLangSet:
FcTypecheckValue (parse, FcTypeLangSet, type);
break;
+ case FcOpRange:
+ FcTypecheckValue (parse, FcTypeRange, type);
+ break;
case FcOpNil:
break;
case FcOpField:
@@ -865,11 +885,10 @@ FcVStackPushMatrix (FcConfigParse *parse, FcExprMatrix *matrix)
static FcBool
FcVStackPushRange (FcConfigParse *parse, FcRange *range)
{
- FcVStack *vstack = FcVStackCreateAndPush (parse);
+ FcVStack *vstack = FcVStackCreateAndPush (parse);
if (!vstack)
return FcFalse;
- vstack->u.range.begin = range->begin;
- vstack->u.range.end = range->end;
+ vstack->u.range = range;
vstack->tag = FcVStackRange;
return FcTrue;
}
@@ -1017,9 +1036,11 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
case FcVStackMatrix:
FcExprMatrixFreeShallow (vstack->u.matrix);
break;
- case FcVStackRange:
case FcVStackBool:
break;
+ case FcVStackRange:
+ FcRangeDestroy (vstack->u.range);
+ break;
case FcVStackCharSet:
FcCharSetDestroy (vstack->u.charset);
break;
@@ -1232,7 +1253,9 @@ static void
FcParseBlank (FcConfigParse *parse)
{
int n = FcVStackElements (parse);
- FcChar32 i;
+ FcChar32 i, begin, end;
+ FcRange r;
+
while (n-- > 0)
{
FcVStack *v = FcVStackFetch (parse, n);
@@ -1248,9 +1271,12 @@ FcParseBlank (FcConfigParse *parse)
goto bail;
break;
case FcVStackRange:
- if (v->u.range.begin <= v->u.range.end)
+ r = FcRangeCanonicalize (v->u.range);
+ begin = (FcChar32)r.u.d.begin;
+ end = (FcChar32)r.u.d.end;
+ if (begin <= end)
{
- for (i = v->u.range.begin; i <= v->u.range.end; i++)
+ for (i = begin; i <= end; i++)
{
if (!FcBlanksAdd (parse->config->blanks, i))
goto bail;
@@ -1463,9 +1489,11 @@ static void
FcParseRange (FcConfigParse *parse)
{
FcVStack *vstack;
- FcRange r = {0, 0};
- FcChar32 n;
+ FcRange *r;
+ FcChar32 n[2] = {0, 0};
int count = 1;
+ double d[2] = {0.0L, 0.0L};
+ FcBool dflag = FcFalse;
while ((vstack = FcVStackPeek (parse)))
{
@@ -1476,31 +1504,52 @@ FcParseRange (FcConfigParse *parse)
}
switch ((int) vstack->tag) {
case FcVStackInteger:
- n = vstack->u.integer;
+ if (dflag)
+ d[count] = (double)vstack->u.integer;
+ else
+ n[count] = vstack->u.integer;
+ break;
+ case FcVStackDouble:
+ if (count == 0 && !dflag)
+ d[1] = (double)n[1];
+ d[count] = vstack->u._double;
+ dflag = FcTrue;
break;
default:
FcConfigMessage (parse, FcSevereError, "invalid element in range");
- n = 0;
+ if (dflag)
+ d[count] = 0.0L;
+ else
+ n[count] = 0;
break;
}
- if (count == 1)
- r.end = n;
- else
- r.begin = n;
count--;
FcVStackPopAndDestroy (parse);
}
- if (count < 0)
+ if (count >= 0)
+ {
+ FcConfigMessage (parse, FcSevereError, "invalid range");
+ return;
+ }
+ if (dflag)
{
- if (r.begin > r.end)
+ if (d[0] > d[1])
{
FcConfigMessage (parse, FcSevereError, "invalid range");
return;
}
- FcVStackPushRange (parse, &r);
+ r = FcRangeCreateDouble (d[0], d[1]);
}
else
- FcConfigMessage (parse, FcSevereError, "invalid range");
+ {
+ if (n[0] > n[1])
+ {
+ FcConfigMessage (parse, FcSevereError, "invalid range");
+ return;
+ }
+ r = FcRangeCreateInteger (n[0], n[1]);
+ }
+ FcVStackPushRange (parse, r);
}
static FcBool
@@ -1536,7 +1585,8 @@ FcParseCharSet (FcConfigParse *parse)
{
FcVStack *vstack;
FcCharSet *charset = FcCharSetCreate ();
- FcChar32 i;
+ FcChar32 i, begin, end;
+ FcRange r;
int n = 0;
while ((vstack = FcVStackPeek (parse)))
@@ -1551,9 +1601,13 @@ FcParseCharSet (FcConfigParse *parse)
n++;
break;
case FcVStackRange:
- if (vstack->u.range.begin <= vstack->u.range.end)
+ r = FcRangeCanonicalize (vstack->u.range);
+ begin = (FcChar32)r.u.d.begin;
+ end = (FcChar32)r.u.d.end;
+
+ if (begin <= end)
{
- for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++)
+ for (i = begin; i <= end; i++)
{
if (!FcCharSetAddChar (charset, i))
{
@@ -1888,6 +1942,7 @@ FcPopExpr (FcConfigParse *parse)
expr = FcExprCreateMatrix (parse->config, vstack->u.matrix);
break;
case FcVStackRange:
+ expr = FcExprCreateRange (parse->config, vstack->u.range);
break;
case FcVStackBool:
expr = FcExprCreateBool (parse->config, vstack->u.bool_);
@@ -2654,6 +2709,11 @@ FcPopValue (FcConfigParse *parse)
if (value.u.l)
value.type = FcTypeLangSet;
break;
+ case FcVStackRange:
+ value.u.r = FcRangeCopy (vstack->u.range);
+ if (value.u.r)
+ value.type = FcTypeRange;
+ break;
default:
FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
vstack->tag);