[Fontconfig] fontconfig: Branch 'master'
Behdad Esfahbod
behdad at kemper.freedesktop.org
Sat Dec 29 18:44:16 PST 2012
fonts.dtd | 2 -
src/fccfg.c | 24 ++++++++++++--
src/fcdbg.c | 16 ++++++---
src/fcint.h | 6 +++
src/fcxml.c | 97 ++++++++++++++++++++++++++++++++++--------------------------
5 files changed, 94 insertions(+), 51 deletions(-)
New commits:
commit 4f6767470f52b287a2923e7e6d8de5fae1993f67
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Dec 29 21:39:06 2012 -0500
Parse matrices of expressions
Previously a <matrix> element could only accept four <double> literals.
It now accepts full expressions, which can in turn poke into the
pattern, do math, etc.
diff --git a/fonts.dtd b/fonts.dtd
index 4a309a9..6b33e75 100644
--- a/fonts.dtd
+++ b/fonts.dtd
@@ -201,7 +201,7 @@
<!ATTLIST double xml:space (default|preserve) 'preserve'>
<!ELEMENT string (#PCDATA)>
<!ATTLIST string xml:space (default|preserve) 'preserve'>
-<!ELEMENT matrix (double,double,double,double)>
+<!ELEMENT matrix ((%expr;), (%expr;), (%expr;), (%expr;))>
<!ELEMENT bool (#PCDATA)>
<!ELEMENT charset (int|range)*>
<!ELEMENT range (int,int)>
diff --git a/src/fccfg.c b/src/fccfg.c
index f94f0e0..68f9946 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -897,9 +897,27 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
v = FcValueSave (v);
break;
case FcOpMatrix:
- v.type = FcTypeMatrix;
- v.u.m = e->u.mval;
- v = FcValueSave (v);
+ {
+ FcMatrix m;
+ v.type = FcTypeMatrix;
+ FcValue xx, xy, yx, yy;
+ 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);
+ if (xx.type == FcTypeDouble && xy.type == FcTypeDouble &&
+ yx.type == FcTypeDouble && yy.type == FcTypeDouble)
+ {
+ m.xx = xx.u.d;
+ m.xy = xy.u.d;
+ m.yx = yx.u.d;
+ m.yy = yy.u.d;
+ v.u.m = &m;
+ }
+ else
+ v.type = FcTypeVoid;
+ v = FcValueSave (v);
+ }
break;
case FcOpCharSet:
v.type = FcTypeCharSet;
diff --git a/src/fcdbg.c b/src/fcdbg.c
index a1ed2b2..5b8d3da 100644
--- a/src/fcdbg.c
+++ b/src/fcdbg.c
@@ -249,11 +249,17 @@ FcExprPrint (const FcExpr *expr)
case FcOpInteger: printf ("%d", expr->u.ival); break;
case FcOpDouble: printf ("%g", expr->u.dval); break;
case FcOpString: printf ("\"%s\"", expr->u.sval); break;
- case FcOpMatrix: printf ("[%g %g %g %g]",
- expr->u.mval->xx,
- expr->u.mval->xy,
- expr->u.mval->yx,
- expr->u.mval->yy); break;
+ case FcOpMatrix:
+ printf ("[");
+ FcExprPrint (expr->u.mexpr->xx);
+ printf (" ");
+ FcExprPrint (expr->u.mexpr->xy);
+ printf (" ");
+ FcExprPrint (expr->u.mexpr->yx);
+ printf (" ");
+ FcExprPrint (expr->u.mexpr->yx);
+ printf ("]");
+ break;
case FcOpRange: break;
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
case FcOpCharSet: printf ("charset\n"); break;
diff --git a/src/fcint.h b/src/fcint.h
index 87c7b9a..9dc1aa7 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -251,13 +251,17 @@ typedef enum _FcOpFlags {
#define FC_OP_GET_FLAGS(_x_) (((_x_) & 0xffff0000) >> 16)
#define FC_OP(_x_,_f_) (FC_OP_GET_OP (_x_) | ((_f_) << 16))
+typedef struct _FcExprMatrix {
+ struct _FcExpr *xx, *xy, *yx, *yy;
+} FcExprMatrix;
+
typedef struct _FcExpr {
FcOp op;
union {
int ival;
double dval;
const FcChar8 *sval;
- FcMatrix *mval;
+ FcExprMatrix *mexpr;
FcBool bval;
FcCharSet *cval;
FcLangSet *lval;
diff --git a/src/fcxml.c b/src/fcxml.c
index 5cb9b2b..0ab590b 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -105,14 +105,48 @@ FcExprCreateString (FcConfig *config, const FcChar8 *s)
return e;
}
+static FcExprMatrix *
+FcExprMatrixCopyShallow (const FcExprMatrix *matrix)
+{
+ FcExprMatrix *m = malloc (sizeof (FcExprMatrix));
+ if (m)
+ {
+ *m = *matrix;
+ }
+ return m;
+}
+
+static void
+FcExprMatrixFreeShallow (FcExprMatrix *m)
+{
+ if (!m)
+ return;
+
+ free (m);
+}
+
+static void
+FcExprMatrixFree (FcExprMatrix *m)
+{
+ if (!m)
+ return;
+
+ FcExprDestroy (m->xx);
+ FcExprDestroy (m->xy);
+ FcExprDestroy (m->yx);
+ FcExprDestroy (m->yy);
+
+ free (m);
+}
+
static FcExpr *
-FcExprCreateMatrix (FcConfig *config, const FcMatrix *m)
+FcExprCreateMatrix (FcConfig *config, const FcExprMatrix *matrix)
{
FcExpr *e = FcConfigAllocExpr (config);
if (e)
{
e->op = FcOpMatrix;
- e->u.mval = FcMatrixCopy (m);
+ e->u.mexpr = FcExprMatrixCopyShallow (matrix);
}
return e;
}
@@ -204,7 +238,7 @@ FcExprDestroy (FcExpr *e)
FcSharedStrFree (e->u.sval);
break;
case FcOpMatrix:
- FcMatrixFree (e->u.mval);
+ FcExprMatrixFree (e->u.mexpr);
break;
case FcOpRange:
break;
@@ -451,7 +485,7 @@ typedef struct _FcVStack {
int integer;
double _double;
- FcMatrix *matrix;
+ FcExprMatrix *matrix;
FcRange range;
FcBool bool_;
FcCharSet *charset;
@@ -516,6 +550,10 @@ FcConfigMessage (FcConfigParse *parse, FcConfigSeverity severe, const char *fmt,
}
+static FcExpr *
+FcPopExpr (FcConfigParse *parse);
+
+
static const char *
FcTypeName (FcType type)
{
@@ -767,16 +805,13 @@ FcVStackPushDouble (FcConfigParse *parse, double _double)
}
static FcBool
-FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix)
+FcVStackPushMatrix (FcConfigParse *parse, FcExprMatrix *matrix)
{
FcVStack *vstack;
- matrix = FcMatrixCopy (matrix);
- if (!matrix)
- return FcFalse;
vstack = FcVStackCreateAndPush (parse);
if (!vstack)
return FcFalse;
- vstack->u.matrix = matrix;
+ vstack->u.matrix = FcExprMatrixCopyShallow (matrix);
vstack->tag = FcVStackMatrix;
return FcTrue;
}
@@ -921,7 +956,7 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
case FcVStackDouble:
break;
case FcVStackMatrix:
- FcMatrixFree (vstack->u.matrix);
+ FcExprMatrixFreeShallow (vstack->u.matrix);
break;
case FcVStackRange:
case FcVStackBool:
@@ -1304,38 +1339,18 @@ static void
FcParseMatrix (FcConfigParse *parse)
{
FcVStack *vstack;
- enum { m_done, m_xx, m_xy, m_yx, m_yy } matrix_state = m_yy;
- FcMatrix m;
+ FcExprMatrix m;
+ int i;
- while ((vstack = FcVStackPeek (parse)))
- {
- double v;
- switch (vstack->tag) {
- case FcVStackInteger:
- v = vstack->u.integer;
- break;
- case FcVStackDouble:
- v = vstack->u._double;
- break;
- default:
- FcConfigMessage (parse, FcSevereError, "non-double matrix element");
- v = 1.0;
- break;
- }
- switch (matrix_state) {
- case m_xx: m.xx = v; break;
- case m_xy: m.xy = v; break;
- case m_yx: m.yx = v; break;
- case m_yy: m.yy = v; break;
- default: break;
- }
- FcVStackPopAndDestroy (parse);
- matrix_state--;
- }
- if (matrix_state != m_done)
- FcConfigMessage (parse, FcSevereError, "wrong number of matrix elements");
+ m.yy = FcPopExpr (parse);
+ m.yx = FcPopExpr (parse);
+ m.xy = FcPopExpr (parse);
+ m.xx = FcPopExpr (parse);
+
+ if (FcPopExpr (parse))
+ FcConfigMessage (parse, FcSevereError, "wrong number of matrix elements");
else
- FcVStackPushMatrix (parse, &m);
+ FcVStackPushMatrix (parse, &m);
}
static void
@@ -2426,7 +2441,7 @@ FcPopValue (FcConfigParse *parse)
value.type = FcTypeDouble;
break;
case FcVStackMatrix:
- value.u.m = FcMatrixCopy (vstack->u.matrix);
+ value.u.m = FcExprMatrixCopyShallow (vstack->u.matrix);
if (value.u.m)
value.type = FcTypeMatrix;
break;
More information about the Fontconfig
mailing list