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@xxxxxxxxxx> 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; _______________________________________________ Fontconfig mailing list Fontconfig@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/fontconfig