[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