fonts.dtd | 3 +- src/fccfg.c | 57 ++++++++++++++++++++++++--------------------- src/fcdbg.c | 19 +++++++++++---- src/fcint.h | 9 ++++++- src/fcxml.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- 5 files changed, 122 insertions(+), 41 deletions(-) New commits: commit 1fbb0b3b15774c187c697a80fb3c89bc1f3e0006 Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Sun Dec 30 19:08:42 2012 -0600 Don't warn if an unknown element is used in an expression The type will be resolved at runtime... For example, we can do this now without getting a warning: <match target="font"> <test name="scalable" compare="eq"> <bool>false</bool> </test> <edit name="pixelsizefixupfactor" mode="assign"> <divide> <name target="pattern">pixelsize</name> <name target="font" >pixelsize</name> </divide> </edit> <edit name="matrix" mode="assign"> <times> <name>matrix</name> <matrix> <name>pixelsizefixupfactor</name> <double>0</double> <double>0</double> <name>pixelsizefixupfactor</name> </matrix> </times> </edit> <edit name="size" mode="assign"> <divide> <name>size</name> <name>pixelsizefixupfactor</name> </divide> </edit> </match> Previously the last edit was generating: Fontconfig warning: "/home/behdad/.local/etc/fonts/conf.d/00-scale-bitmap-fonts.conf", line 29: saw unknown, expected number diff --git a/src/fcxml.c b/src/fcxml.c index d31caf5..cf9c8dd 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -594,6 +594,10 @@ FcTypecheckValue (FcConfigParse *parse, FcType value, FcType type) return; if (type == (FcType) -1) return; + /* It's perfectly fine to use user-define elements in expressions, + * so don't warn in that case. */ + if (value == (FcType) -1) + return; FcConfigMessage (parse, FcSevereWarning, "saw %s, expected %s", FcTypeName (value), FcTypeName (type)); } commit 51b0044648e00025cf20014b19aaceed7beeed75 Author: Behdad Esfahbod <behdad@xxxxxxxxxx> Date: Sat Dec 29 23:58:38 2012 -0500 Allow target="font/pattern/default" in <name> elements Based on idea from Raimund Steger. For example, one can do something like this: <match target="font"> <test name="scalable" compare="eq"> <bool>false</bool> </test> <edit name="pixelsizefixupfactor" mode="assign"> <divide> <name target="pattern">pixelsize</name> <name target="font" >pixelsize</name> </divide> </edit> <edit name="matrix" mode="assign"> <times> <name>matrix</name> <matrix> <name>pixelsizefixupfactor</name> <double>0</double> <double>0</double> <name>pixelsizefixupfactor</name> </matrix> </times> </edit> </match> Part of work to make bitmap font scaling possible. See thread discussion: http://lists.freedesktop.org/archives/fontconfig/2012-December/004498.html diff --git a/fonts.dtd b/fonts.dtd index 6b33e75..def8c21 100644 --- a/fonts.dtd +++ b/fonts.dtd @@ -207,7 +207,8 @@ <!ELEMENT range (int,int)> <!ELEMENT langset (string)*> <!ELEMENT name (#PCDATA)> -<!ATTLIST name xml:space (default|preserve) 'preserve'> +<!ATTLIST name xml:space (default|preserve) 'preserve' + target (default|font|pattern) 'default'> <!ELEMENT const (#PCDATA)> <!ATTLIST const xml:space (default|preserve) 'preserve'> <!ELEMENT or (%expr;)*> diff --git a/src/fccfg.c b/src/fccfg.c index 97345be..1454f33 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -867,7 +867,7 @@ FcConfigCompareValue (const FcValue *left_o, #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; @@ -894,10 +894,10 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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) { @@ -927,7 +927,10 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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); @@ -939,13 +942,13 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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; @@ -960,8 +963,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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); @@ -973,8 +976,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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) @@ -1109,7 +1112,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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; @@ -1122,7 +1125,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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; @@ -1138,7 +1141,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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; @@ -1154,7 +1157,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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; @@ -1170,7 +1173,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) 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; @@ -1194,6 +1197,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) static FcValueList * FcConfigMatchValueList (FcPattern *p, + FcPattern *p_pat, + FcMatchKind kind, FcTest *t, FcValueList *values) { @@ -1207,12 +1212,12 @@ FcConfigMatchValueList (FcPattern *p, /* 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; } @@ -1239,7 +1244,7 @@ FcConfigMatchValueList (FcPattern *p, } static FcValueList * -FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) +FcConfigValues (FcPattern *p, FcPattern *p_pat, FcMatchKind kind, FcExpr *e, FcValueBinding binding) { FcValueList *l; @@ -1250,12 +1255,12 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding) 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; @@ -1503,7 +1508,7 @@ FcConfigSubstituteWithPat (FcConfig *config, * 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) @@ -1527,7 +1532,7 @@ FcConfigSubstituteWithPat (FcConfig *config, /* * 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 diff --git a/src/fcdbg.c b/src/fcdbg.c index 5b8d3da..20fc6c8 100644 --- a/src/fcdbg.c +++ b/src/fcdbg.c @@ -43,10 +43,10 @@ _FcValuePrint (const FcValue v) printf ("\"%s\"", v.u.s); break; case FcTypeBool: - printf ("%s", v.u.b ? "FcTrue" : "FcFalse"); + printf ("%s", v.u.b ? "True" : "False"); break; case FcTypeMatrix: - printf ("(%f %f; %f %f)", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); + printf ("[%g %g; %g %g]", v.u.m->xx, v.u.m->xy, v.u.m->yx, v.u.m->yy); break; case FcTypeCharSet: /* XXX */ FcCharSetPrint (v.u.c); @@ -254,10 +254,10 @@ FcExprPrint (const FcExpr *expr) FcExprPrint (expr->u.mexpr->xx); printf (" "); FcExprPrint (expr->u.mexpr->xy); - printf (" "); + printf ("; "); FcExprPrint (expr->u.mexpr->yx); printf (" "); - FcExprPrint (expr->u.mexpr->yx); + FcExprPrint (expr->u.mexpr->yy); printf ("]"); break; case FcOpRange: break; @@ -269,7 +269,16 @@ FcExprPrint (const FcExpr *expr) printf ("\n"); break; case FcOpNil: printf ("nil\n"); break; - case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break; + case FcOpField: printf ("%s ", FcObjectName(expr->u.name.object)); + switch ((int) expr->u.name.kind) { + case FcMatchPattern: + printf ("(pattern) "); + break; + case FcMatchFont: + printf ("(font) "); + break; + } + break; case FcOpConst: printf ("%s", expr->u.constant); break; case FcOpQuest: FcExprPrint (expr->u.tree.left); diff --git a/src/fcint.h b/src/fcint.h index 652f52d..68074f0 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -227,6 +227,12 @@ typedef struct _FcExprMatrix { struct _FcExpr *xx, *xy, *yx, *yy; } FcExprMatrix; +typedef struct _FcExprName { + FcObject object; + FcMatchKind kind; +} FcExprName; + + typedef struct _FcExpr { FcOp op; union { @@ -237,7 +243,8 @@ typedef struct _FcExpr { FcBool bval; FcCharSet *cval; FcLangSet *lval; - FcObject object; + + FcExprName name; const FcChar8 *constant; struct { struct _FcExpr *left, *right; diff --git a/src/fcxml.c b/src/fcxml.c index 21666d0..d31caf5 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -187,13 +187,13 @@ FcExprCreateLangSet (FcConfig *config, FcLangSet *langset) } 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; } @@ -453,9 +453,9 @@ typedef enum _FcVStackTag { FcVStackString, FcVStackFamily, - FcVStackField, FcVStackConstant, FcVStackGlob, + FcVStackName, FcVStackPattern, FcVStackPrefer, @@ -489,6 +489,7 @@ typedef struct _FcVStack { FcBool bool_; FcCharSet *charset; FcLangSet *langset; + FcExprName name; FcTest *test; FcQual qual; @@ -631,7 +632,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type) 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; @@ -865,6 +866,18 @@ FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset) } 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); @@ -938,10 +951,11 @@ FcVStackPopAndDestroy (FcConfigParse *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); @@ -1322,6 +1336,47 @@ FcParseString (FcConfigParse *parse, FcVStackTag tag) } 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; @@ -1722,8 +1777,8 @@ FcPopExpr (FcConfigParse *parse) 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); @@ -2619,7 +2674,7 @@ FcEndElement(void *userData, const XML_Char *name FC_UNUSED) FcParsePatelt (parse); break; case FcElementName: - FcParseString (parse, FcVStackField); + FcParseName (parse); break; case FcElementConst: FcParseString (parse, FcVStackConstant); _______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig