Fix wrong edit position
authorAkira TAGOH <akira@tagoh.org>
Mon, 5 Aug 2013 11:04:13 +0000 (20:04 +0900)
committerAkira TAGOH <akira@tagoh.org>
Tue, 6 Aug 2013 04:05:53 +0000 (13:05 +0900)
src/fccfg.c
src/fcint.h
src/fcobjs.c

index 7ea94b8..afb03f6 100644 (file)
@@ -674,12 +674,21 @@ FcConfigAddRule (FcConfig *config,
     num = 0;
     for (r = rule; r; r = r->next)
     {
-       if (r->type == FcRuleTest)
+       switch (r->type)
        {
+       case FcRuleTest:
            if (r->u.test &&
                r->u.test->kind == FcMatchDefault)
                r->u.test->kind = kind;
-           num++;
+           if (r->u.test->object > FC_MAX_BASE_OBJECT)
+               num++;
+           break;
+       case FcRuleEdit:
+           if (r->u.edit->object > FC_MAX_BASE_OBJECT)
+               num++;
+           break;
+       default:
+           break;
        }
     }
     if (config->maxObjects < num)
@@ -1486,11 +1495,15 @@ FcConfigSubstituteWithPat (FcConfig    *config,
     FcValue v;
     FcSubst        *s;
     FcRule          *r;
-    FcValueList            *l, *value = NULL;
+    FcValueList            *l, **value = NULL;
     FcPattern      *m;
     FcStrSet       *strs;
-    FcPatternElt    *elt = NULL;
     FcObject       object = FC_INVALID_OBJECT;
+    FcPatternElt    **elt = NULL;
+    int                    i, nobjs;
+    FcBool         retval = FcTrue;
+
+#define FC_OBJ_ID(_n_) ((_n_) > FC_MAX_BASE_OBJECT ? ((_n_) - FC_EXT_OBJ_INDEX) : (_n_))
 
     if (!config)
     {
@@ -1535,6 +1548,20 @@ FcConfigSubstituteWithPat (FcConfig    *config,
        return FcFalse;
     }
 
+    nobjs = FC_MAX_BASE_OBJECT + config->maxObjects + 2;
+    value = (FcValueList **) malloc (SIZEOF_VOID_P * nobjs);
+    if (!value)
+    {
+       retval = FcFalse;
+       goto bail1;
+    }
+    elt = (FcPatternElt **) malloc (SIZEOF_VOID_P * nobjs);
+    if (!elt)
+    {
+       retval = FcFalse;
+       goto bail1;
+    }
+
     if (FcDebug () & FC_DBG_EDIT)
     {
        printf ("FcConfigSubstitute ");
@@ -1543,6 +1570,11 @@ FcConfigSubstituteWithPat (FcConfig    *config,
     for (; s; s = s->next)
     {
        r = s->rule;
+       for (i = 0; i < nobjs; i++)
+       {
+           elt[i] = NULL;
+           value[i] = NULL;
+       }
        for (; r; r = r->next)
        {
            switch (r->type) {
@@ -1550,6 +1582,7 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                /* shouldn't be reached */
                break;
            case FcRuleTest:
+               object = FC_OBJ_ID (r->u.test->object);
                /*
                 * Check the tests to see if
                 * they all match the pattern
@@ -1564,18 +1597,16 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                else
                    m = p;
                if (m)
-                   elt = FcPatternObjectFindElt (m, r->u.test->object);
-               else
-                   elt = NULL;
+                   elt[object] = FcPatternObjectFindElt (m, r->u.test->object);
                /*
                 * If there's no such field in the font,
                 * then FcQualAll matches while FcQualAny does not
                 */
-               if (!elt)
+               if (!elt[object])
                {
                    if (r->u.test->qual == FcQualAll)
                    {
-                       value = NULL;
+                       value[object] = NULL;
                        continue;
                    }
                    else
@@ -1589,18 +1620,18 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                 * Check to see if there is a match, mark the location
                 * to apply match-relative edits
                 */
-               value = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt->values);
-               if (!value ||
-                   (r->u.test->qual == FcQualFirst && value != elt->values) ||
-                   (r->u.test->qual == FcQualNotFirst && value == elt->values))
+               value[object] = FcConfigMatchValueList (m, p_pat, kind, r->u.test, elt[object]->values);
+               if (!value[object] ||
+                   (r->u.test->qual == FcQualFirst && value[object] != elt[object]->values) ||
+                   (r->u.test->qual == FcQualNotFirst && value[object] == elt[object]->values))
                {
                    if (FcDebug () & FC_DBG_EDIT)
                        printf ("No match\n");
                    goto bail;
                }
-               object = r->u.test->object;
                break;
            case FcRuleEdit:
+               object = FC_OBJ_ID (r->u.edit->object);
                if (FcDebug () & FC_DBG_EDIT)
                {
                    printf ("Substitute ");
@@ -1611,13 +1642,6 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                 * Evaluate the list of expressions
                 */
                l = FcConfigValues (p, p_pat,kind,  r->u.edit->expr, r->u.edit->binding);
-               /*
-                * Locate any test associated with this field, skipping
-                * tests associated with the pattern when substituting in
-                * the font
-                */
-               if (object != r->u.edit->object)
-                   value = NULL;
 
                switch (FC_OP_GET_OP (r->u.edit->op)) {
                case FcOpAssign:
@@ -1625,25 +1649,25 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                     * If there was a test, then replace the matched
                     * value with the new list of values
                     */
-                   if (value)
+                   if (value[object])
                    {
-                       FcValueList     *thisValue = value;
+                       FcValueList     *thisValue = value[object];
                        FcValueList     *nextValue = thisValue;
 
                        /*
                         * Append the new list of values after the current value
                         */
-                       FcConfigAdd (&elt->values, thisValue, FcTrue, l, r->u.edit->object);
+                       FcConfigAdd (&elt[object]->values, thisValue, FcTrue, l, r->u.edit->object);
                        /*
                         * Delete the marked value
                         */
                        if (thisValue)
-                           FcConfigDel (&elt->values, thisValue);
+                           FcConfigDel (&elt[object]->values, thisValue);
                        /*
                         * Adjust a pointer into the value list to ensure
                         * future edits occur at the same place
                         */
-                       value = nextValue;
+                       value[object] = nextValue;
                        break;
                    }
                    /* fall through ... */
@@ -1658,12 +1682,12 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                     * Adjust a pointer into the value list as they no
                     * longer point to anything valid
                     */
-                   value = NULL;
+                   value[object] = NULL;
                    break;
                case FcOpPrepend:
-                   if (value)
+                   if (value[object])
                    {
-                       FcConfigAdd (&elt->values, value, FcFalse, l, r->u.edit->object);
+                       FcConfigAdd (&elt[object]->values, value[object], FcFalse, l, r->u.edit->object);
                        break;
                    }
                    /* fall through ... */
@@ -1671,9 +1695,9 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                    FcConfigPatternAdd (p, r->u.edit->object, l, FcFalse);
                    break;
                case FcOpAppend:
-                   if (value)
+                   if (value[object])
                    {
-                       FcConfigAdd (&elt->values, value, FcTrue, l, r->u.edit->object);
+                       FcConfigAdd (&elt[object]->values, value[object], FcTrue, l, r->u.edit->object);
                        break;
                    }
                    /* fall through ... */
@@ -1681,9 +1705,9 @@ FcConfigSubstituteWithPat (FcConfig    *config,
                    FcConfigPatternAdd (p, r->u.edit->object, l, FcTrue);
                    break;
                case FcOpDelete:
-                   if (value)
+                   if (value[object])
                    {
-                       FcConfigDel (&elt->values, value);
+                       FcConfigDel (&elt[object]->values, value[object]);
                        break;
                    }
                    /* fall through ... */
@@ -1715,7 +1739,15 @@ FcConfigSubstituteWithPat (FcConfig    *config,
        printf ("FcConfigSubstitute done");
        FcPatternPrint (p);
     }
-    return FcTrue;
+bail1:
+    if (elt)
+       free (elt);
+    if (value)
+       free (value);
+
+#undef FC_OBJ_ID
+
+    return retval;
 }
 
 FcBool
index fe523fb..52c47a1 100644 (file)
@@ -174,6 +174,11 @@ typedef struct _FcValueList {
                        
 typedef int FcObject;
 
+/* The 1000 is to leave some room for future added internal objects, such
+ * that caches from newer fontconfig can still be used with older fontconfig
+ * without getting confused. */
+#define FC_EXT_OBJ_INDEX       1000
+
 typedef struct _FcPatternElt *FcPatternEltPtr;
 
 /*
index 1d3af73..bad9824 100644 (file)
@@ -37,7 +37,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len);
 /* The 1000 is to leave some room for future added internal objects, such
  * that caches from newer fontconfig can still be used with older fontconfig
  * without getting confused. */
-static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + 1000;
+static fc_atomic_int_t next_id = FC_MAX_BASE_OBJECT + FC_EXT_OBJ_INDEX;
 struct FcObjectOtherTypeInfo {
     struct FcObjectOtherTypeInfo *next;
     FcObjectType object;