[Fontconfig] fontconfig: Branch 'master'

Akira TAGOH tagoh at kemper.freedesktop.org
Thu Jan 31 03:31:28 PST 2013


 fonts.dtd   |    2 +-
 src/fcxml.c |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

New commits:
commit d26fb23c41abd87422778bb38eea39f25ba3dc4a
Author: Akira TAGOH <akira at tagoh.org>
Date:   Fri Jan 25 20:01:24 2013 +0900

    Bug 59385 - Do the right thing for intermixed edit and test elements
    
    This changes allows to have multiple mathcing rules in one <match> block
    in the same order.
    After this changes, the following thing will works as two matching rules:
    
    	<match>
    		<!-- rule 1 -->
    		<test name="family" compare="eq">
    			<string>foo</string>
    		</test>
    		<edit name="foo" mode="append">
    			<string>foo</string>
    		</edit>
    		<!-- rule 2 -->
    		<test name="foo" compare="eq">
    			<string>foo</string>
    		</test>
    		<edit name="foo" mode="append">
    			<string>bar</string>
    		</edit>
    	</match>

diff --git a/fonts.dtd b/fonts.dtd
index def8c21..664467d 100644
--- a/fonts.dtd
+++ b/fonts.dtd
@@ -140,7 +140,7 @@
     if 'target' is 'font', execute the match on the result of a font
     selection.
 -->
-<!ELEMENT match (test*, edit*)>
+<!ELEMENT match (test*, edit*)+>
 <!ATTLIST match
 	  target (pattern|font|scan) "pattern">
 
diff --git a/src/fcxml.c b/src/fcxml.c
index 2a0d088..5981ea9 100644
--- a/src/fcxml.c
+++ b/src/fcxml.c
@@ -2375,6 +2375,11 @@ FcParseEdit (FcConfigParse *parse)
 	FcEditDestroy (edit);
 }
 
+typedef struct FcSubstStack {
+    FcTest *test;
+    FcEdit *edit;
+} FcSubstStack;
+
 static void
 FcParseMatch (FcConfigParse *parse)
 {
@@ -2383,6 +2388,9 @@ FcParseMatch (FcConfigParse *parse)
     FcTest	    *test = 0;
     FcEdit	    *edit = 0;
     FcVStack	    *vstack;
+    FcBool           tested = FcFalse;
+    FcSubstStack    *sstack = NULL;
+    int              len, pos = 0;
 
     kind_name = FcConfigGetAttribute (parse, "target");
     if (!kind_name)
@@ -2401,6 +2409,16 @@ FcParseMatch (FcConfigParse *parse)
 	    return;
 	}
     }
+    len = FcVStackElements(parse);
+    if (len > 0)
+    {
+	sstack = malloc (sizeof (FcSubstStack) * (len + 1));
+	if (!sstack)
+	{
+	    FcConfigMessage (parse, FcSevereError, "out of memory");
+	    return;
+	}
+    }
     while ((vstack = FcVStackPeek (parse)))
     {
 	switch ((int) vstack->tag) {
@@ -2408,8 +2426,22 @@ FcParseMatch (FcConfigParse *parse)
 	    vstack->u.test->next = test;
 	    test = vstack->u.test;
 	    vstack->tag = FcVStackNone;
+	    tested = FcTrue;
 	    break;
 	case FcVStackEdit:
+	    /* due to the reverse traversal, <edit> node appears faster than
+	     * <test> node if any. so we have to deal with it here rather than
+	     * the above in FcVStackTest, and put recipes in reverse order.
+	     */
+	    if (tested)
+	    {
+		sstack[pos].test = test;
+		sstack[pos].edit = edit;
+		pos++;
+		test = NULL;
+		edit = NULL;
+		tested = FcFalse;
+	    }
 	    vstack->u.edit->next = edit;
 	    edit = vstack->u.edit;
 	    vstack->tag = FcVStackNone;
@@ -2428,6 +2460,20 @@ FcParseMatch (FcConfigParse *parse)
     }
     if (!FcConfigAddEdit (parse->config, test, edit, kind))
 	FcConfigMessage (parse, FcSevereError, "out of memory");
+    if (sstack)
+    {
+	int i;
+
+	for (i = 0; i < pos; i++)
+	{
+	    if (!FcConfigAddEdit (parse->config, sstack[pos - i - 1].test, sstack[pos - i - 1].edit, kind))
+	    {
+		FcConfigMessage (parse, FcSevereError, "out of memory");
+		return;
+	    }
+	}
+	free (sstack);
+    }
 }
 
 static void


More information about the Fontconfig mailing list