#define FcDoubleTrunc(d) ((d) >= 0 ? _FcDoubleFloor (d) : -_FcDoubleFloor (-(d)))
static FcValue
-FcConfigEvaluate (FcPattern *p, FcExpr *e)
+FcConfigEvaluate (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e)
{
FcValue v, vl, vr;
FcResult r;
FcMatrix m;
FcValue xx, xy, yx, yy;
v.type = FcTypeMatrix;
- xx = FcConfigPromote (FcConfigEvaluate (p, e->u.mexpr->xx), v);
- xy = FcConfigPromote (FcConfigEvaluate (p, e->u.mexpr->xy), v);
- yx = FcConfigPromote (FcConfigEvaluate (p, e->u.mexpr->yx), v);
- yy = FcConfigPromote (FcConfigEvaluate (p, e->u.mexpr->yy), v);
+ xx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xx), v);
+ xy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->xy), v);
+ yx = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yx), v);
+ yy = FcConfigPromote (FcConfigEvaluate (p, p_pat, kind, e->u.mexpr->yy), v);
if (xx.type == FcTypeDouble && xy.type == FcTypeDouble &&
yx.type == FcTypeDouble && yy.type == FcTypeDouble)
{
v.u.b = e->u.bval;
break;
case FcOpField:
- r = FcPatternObjectGet (p, e->u.object, 0, &v);
+ if (kind == FcMatchFont && e->u.name.kind == FcMatchPattern)
+ r = FcPatternObjectGet (p_pat, e->u.name.object, 0, &v);
+ else
+ r = FcPatternObjectGet (p, e->u.name.object, 0, &v);
if (r != FcResultMatch)
v.type = FcTypeVoid;
v = FcValueSave (v);
v.type = FcTypeVoid;
break;
case FcOpQuest:
- vl = FcConfigEvaluate (p, e->u.tree.left);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
if (vl.type == FcTypeBool)
{
if (vl.u.b)
- v = FcConfigEvaluate (p, e->u.tree.right->u.tree.left);
+ v = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right->u.tree.left);
else
- v = FcConfigEvaluate (p, e->u.tree.right->u.tree.right);
+ v = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right->u.tree.right);
}
else
v.type = FcTypeVoid;
case FcOpContains:
case FcOpNotContains:
case FcOpListing:
- vl = FcConfigEvaluate (p, e->u.tree.left);
- vr = FcConfigEvaluate (p, e->u.tree.right);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
+ vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right);
v.type = FcTypeBool;
v.u.b = FcConfigCompareValue (&vl, e->op, &vr);
FcValueDestroy (vl);
case FcOpMinus:
case FcOpTimes:
case FcOpDivide:
- vl = FcConfigEvaluate (p, e->u.tree.left);
- vr = FcConfigEvaluate (p, e->u.tree.right);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
+ vr = FcConfigEvaluate (p, p_pat, kind, e->u.tree.right);
vl = FcConfigPromote (vl, vr);
vr = FcConfigPromote (vr, vl);
if (vl.type == vr.type)
FcValueDestroy (vr);
break;
case FcOpNot:
- vl = FcConfigEvaluate (p, e->u.tree.left);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
switch ((int) vl.type) {
case FcTypeBool:
v.type = FcTypeBool;
FcValueDestroy (vl);
break;
case FcOpFloor:
- vl = FcConfigEvaluate (p, e->u.tree.left);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
switch ((int) vl.type) {
case FcTypeInteger:
v = vl;
FcValueDestroy (vl);
break;
case FcOpCeil:
- vl = FcConfigEvaluate (p, e->u.tree.left);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
switch ((int) vl.type) {
case FcTypeInteger:
v = vl;
FcValueDestroy (vl);
break;
case FcOpRound:
- vl = FcConfigEvaluate (p, e->u.tree.left);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
switch ((int) vl.type) {
case FcTypeInteger:
v = vl;
FcValueDestroy (vl);
break;
case FcOpTrunc:
- vl = FcConfigEvaluate (p, e->u.tree.left);
+ vl = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
switch ((int) vl.type) {
case FcTypeInteger:
v = vl;
static FcValueList *
FcConfigMatchValueList (FcPattern *p,
+ FcPattern *p_pat,
+ FcMatchKind kind,
FcTest *t,
FcValueList *values)
{
/* Compute the value of the match expression */
if (FC_OP_GET_OP (e->op) == FcOpComma)
{
- value = FcConfigEvaluate (p, e->u.tree.left);
+ value = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
e = e->u.tree.right;
}
else
{
- value = FcConfigEvaluate (p, e);
+ value = FcConfigEvaluate (p, p_pat, kind, e);
e = 0;
}
}
static FcValueList *
-FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
+FcConfigValues (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e, FcValueBinding binding)
{
FcValueList *l;
return 0;
if (FC_OP_GET_OP (e->op) == FcOpComma)
{
- l->value = FcConfigEvaluate (p, e->u.tree.left);
- l->next = FcConfigValues (p, e->u.tree.right, binding);
+ l->value = FcConfigEvaluate (p, p_pat, kind, e->u.tree.left);
+ l->next = FcConfigValues (p, p_pat, kind, e->u.tree.right, binding);
}
else
{
- l->value = FcConfigEvaluate (p, e);
+ l->value = FcConfigEvaluate (p, p_pat, kind, e);
l->next = NULL;
}
l->binding = binding;
* Check to see if there is a match, mark the location
* to apply match-relative edits
*/
- st[i].value = FcConfigMatchValueList (m, t, st[i].elt->values);
+ st[i].value = FcConfigMatchValueList (m, p_pat, kind, t, st[i].elt->values);
if (!st[i].value)
break;
if (t->qual == FcQualFirst && st[i].value != st[i].elt->values)
/*
* Evaluate the list of expressions
*/
- l = FcConfigValues (p, e->expr, e->binding);
+ l = FcConfigValues (p, p_pat,kind, e->expr, e->binding);
/*
* Locate any test associated with this field, skipping
* tests associated with the pattern when substituting in
}
static FcExpr *
-FcExprCreateField (FcConfig *config, const char *field)
+FcExprCreateName (FcConfig *config, FcExprName name)
{
FcExpr *e = FcConfigAllocExpr (config);
if (e)
{
e->op = FcOpField;
- e->u.object = FcObjectFromName (field);
+ e->u.name = name;
}
return e;
}
FcVStackString,
FcVStackFamily,
- FcVStackField,
FcVStackConstant,
FcVStackGlob,
+ FcVStackName,
FcVStackPattern,
FcVStackPrefer,
FcBool bool_;
FcCharSet *charset;
FcLangSet *langset;
+ FcExprName name;
FcTest *test;
FcQual qual;
case FcOpNil:
break;
case FcOpField:
- o = FcNameGetObjectType (FcObjectName (expr->u.object));
+ o = FcNameGetObjectType (FcObjectName (expr->u.name.object));
if (o)
FcTypecheckValue (parse, o->type, type);
break;
}
static FcBool
+FcVStackPushName (FcConfigParse *parse, FcMatchKind kind, FcObject object)
+{
+ FcVStack *vstack = FcVStackCreateAndPush (parse);
+ if (!vstack)
+ return FcFalse;
+ vstack->u.name.object = object;
+ vstack->u.name.kind = kind;
+ vstack->tag = FcVStackName;
+ return FcTrue;
+}
+
+static FcBool
FcVStackPushTest (FcConfigParse *parse, FcTest *test)
{
FcVStack *vstack = FcVStackCreateAndPush (parse);
switch (vstack->tag) {
case FcVStackNone:
break;
+ case FcVStackName:
+ break;
case FcVStackFamily:
break;
case FcVStackString:
- case FcVStackField:
case FcVStackConstant:
case FcVStackGlob:
FcStrFree (vstack->u.string);
}
static void
+FcParseName (FcConfigParse *parse)
+{
+ const FcChar8 *kind_string;
+ FcMatchKind kind;
+ FcChar8 *s;
+ FcObject object;
+
+ kind_string = FcConfigGetAttribute (parse, "target");
+ if (!kind_string)
+ kind = FcMatchDefault;
+ else
+ {
+ if (!strcmp ((char *) kind_string, "pattern"))
+ kind = FcMatchPattern;
+ else if (!strcmp ((char *) kind_string, "font"))
+ kind = FcMatchFont;
+ else if (!strcmp ((char *) kind_string, "default"))
+ kind = FcMatchDefault;
+ else
+ {
+ FcConfigMessage (parse, FcSevereWarning, "invalid name target \"%s\"", kind_string);
+ return;
+ }
+ }
+
+ if (!parse->pstack)
+ return;
+ s = FcStrBufDone (&parse->pstack->str);
+ if (!s)
+ {
+ FcConfigMessage (parse, FcSevereError, "out of memory");
+ return;
+ }
+ object = FcObjectFromName ((const char *) s);
+
+ FcVStackPushName (parse, kind, object);
+
+ FcStrFree (s);
+}
+
+static void
FcParseMatrix (FcConfigParse *parse)
{
FcExprMatrix m;
case FcVStackFamily:
expr = FcExprCreateString (parse->config, vstack->u.string);
break;
- case FcVStackField:
- expr = FcExprCreateField (parse->config, (char *) vstack->u.string);
+ case FcVStackName:
+ expr = FcExprCreateName (parse->config, vstack->u.name);
break;
case FcVStackConstant:
expr = FcExprCreateConst (parse->config, vstack->u.string);
FcParsePatelt (parse);
break;
case FcElementName:
- FcParseString (parse, FcVStackField);
+ FcParseName (parse);
break;
case FcElementConst:
FcParseString (parse, FcVStackConstant);