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
This commit is contained in:
parent
d7e1965aa0
commit
51b0044648
|
@ -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;)*>
|
||||
|
|
57
src/fccfg.c
57
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
|
||||
|
|
19
src/fcdbg.c
19
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
71
src/fcxml.c
71
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;
|
||||
|
@ -864,6 +865,18 @@ FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset)
|
|||
return FcTrue;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -1321,6 +1335,47 @@ FcParseString (FcConfigParse *parse, FcVStackTag tag)
|
|||
FcStrFree (s);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue