[Fontconfig] fontconfig: Branch 'master' - 2 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Sun Dec 30 17:10:05 PST 2012


 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 at behdad.org>
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 at behdad.org>
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);


More information about the Fontconfig mailing list