]> git.wh0rd.org - fontconfig.git/commitdiff
Add charset editing feature.
authorAkira TAGOH <akira@tagoh.org>
Mon, 6 Dec 2010 03:10:17 +0000 (12:10 +0900)
committerAkira TAGOH <akira@tagoh.org>
Thu, 9 Dec 2010 02:09:24 +0000 (11:09 +0900)
The syntax to add any characters to the charset table looks like:

<match target="scan">
    <test name="family">
        <string>Buggy Sans</string>
    </test>
    <edit name="charset" mode="assign">
        <plus>
            <name>charset</name>
            <charset>
                <int>0x3220</int>    <!-- PARENTHESIZED IDEOGRAPH ONE -->
            </charset>
        </plus>
    </edit>
</match>

To remove any characters from the charset table:

<match target="scan">
    <test name="family">
        <string>Buggy Sans</string>
    </test>
    <edit name="charset" mode="assign">
        <minus>
            <name>charset</name>
            <charset>
                <int>0x06CC</int>    <!-- ARABIC LETTER FARSI YEH -->
                <int>0x06D2</int>    <!-- ARABIC LETTER YEH BARREE -->
                <int>0x06D3</int>    <!-- ARABIC LETTER YEH BARREE WITH HAMZA ABOVE -->
            </charset>
        </minus>
    </edit>
</match>

You could also use the range element for convenience:

...
            <charset>
                <int>0x06CC</int>    <!-- ARABIC LETTER FARSI YEH -->
                <range>
                    <int>0x06D2</int>    <!-- ARABIC LETTER YEH BARREE -->
                    <int>0x06D3</int>    <!-- ARABIC LETTER YEH BARREE WITH HAMZA ABOVE -->
                </range>
            </charset>
...

fonts.dtd
src/Makefile.am
src/fccfg.c
src/fcdbg.c
src/fcint.h
src/fcxml.c

index cbdfdab3fb5675e159b482a1f5ed21f87e71156b..5f21e350ce7cabdf1b283ef3e525700c5a9ec806 100644 (file)
--- a/fonts.dtd
+++ b/fonts.dtd
 <!ATTLIST string xml:space (default|preserve) 'preserve'>
 <!ELEMENT matrix (double,double,double,double)>
 <!ELEMENT bool (#PCDATA)>
-<!ELEMENT charset (#PCDATA)>
-<!ATTLIST charset xml:space (default|preserve) 'preserve'>
+<!ELEMENT charset (int|range)*>
+<!ELEMENT range (int,int)>
 <!ELEMENT name (#PCDATA)>
 <!ATTLIST name xml:space (default|preserve) 'preserve'>
 <!ELEMENT const (#PCDATA)>
index 59b9c75bade50ff1db13eeec042d790d7853353f..96500b43e9b331b3c7abe06094184850a8f65114 100644 (file)
@@ -140,7 +140,7 @@ PUBLIC_FILES = \
        $(top_srcdir)/fontconfig/fontconfig.h \
        $(top_srcdir)/src/fcdeprecate.h \
        $(top_srcdir)/fontconfig/fcprivate.h
-       
+
 PUBLIC_FT_FILES = \
        $(top_srcdir)/fontconfig/fcfreetype.h
 
@@ -160,7 +160,7 @@ fontconfig.def: $(PUBLIC_FILES) $(PUBLIC_FT_FILES)
        echo Generating $@
        (echo EXPORTS; \
        (cat $(PUBLIC_FILES) $(PUBLIC_FT_FILES) || echo 'FcERROR ()' ) | \
-       grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$$//' -e 's/^/      /' | \
+       grep '^Fc[^ ]* *(' | sed -e 's/ *(.*$$//' -e 's/^/      /' | \
        sort; \
        echo LIBRARY libfontconfig-@LIBT_CURRENT_MINUS_AGE@.dll; \
        echo VERSION @LIBT_CURRENT@.@LIBT_REVISION@) >$@
index 19a9fefbdaa9cb34011b7913aba8834ddb08a11a..ad9f7d2060b5c1a3c81e24c2c34203161a64443b 100644 (file)
@@ -1036,6 +1036,25 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
                    break;
                }
                break;
+           case FcTypeCharSet:
+               switch (e->op) {
+               case FcOpPlus:
+                   v.type = FcTypeCharSet;
+                   v.u.c = FcCharSetUnion (vl.u.c, vr.u.c);
+                   if (!v.u.c)
+                       v.type = FcTypeVoid;
+                   break;
+               case FcOpMinus:
+                   v.type = FcTypeCharSet;
+                   v.u.c = FcCharSetSubtract (vl.u.c, vr.u.c);
+                   if (!v.u.c)
+                       v.type = FcTypeVoid;
+                   break;
+               default:
+                   v.type = FcTypeVoid;
+                   break;
+               }
+               break;
            default:
                v.type = FcTypeVoid;
                break;
index fc3b59602a3994f8dd56041d76ddef3bc21180c2..79e195349a5fb1e8219fafff7193f9b799c704dc 100644 (file)
@@ -160,6 +160,7 @@ FcOpPrint (FcOp op)
     case FcOpDouble: printf ("Double"); break;
     case FcOpString: printf ("String"); break;
     case FcOpMatrix: printf ("Matrix"); break;
+    case FcOpRange: printf ("Range"); break;
     case FcOpBool: printf ("Bool"); break;
     case FcOpCharSet: printf ("CharSet"); break;
     case FcOpField: printf ("Field"); break;
@@ -210,6 +211,7 @@ FcExprPrint (const FcExpr *expr)
                              expr->u.mval->xy,
                              expr->u.mval->yx,
                              expr->u.mval->yy); break;
+    case FcOpRange: break;
     case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
     case FcOpCharSet: printf ("charset\n"); break;
     case FcOpNil: printf ("nil\n"); break;
index 2bc7878c1ab652dd35ce10679dd063b73479791c..9519fff7e2d4faa6b96c28d858157535bfc0e127 100644 (file)
@@ -216,7 +216,7 @@ struct _FcPattern {
                                 fs->fonts[i])
                                                
 typedef enum _FcOp {
-    FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpBool, FcOpCharSet,
+    FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet,
     FcOpNil,
     FcOpField, FcOpConst,
     FcOpAssign, FcOpAssignReplace,
@@ -507,6 +507,13 @@ typedef struct _FcFileTime {
 
 typedef struct _FcCharMap FcCharMap;
 
+typedef struct _FcRange            FcRange;
+
+struct _FcRange {
+    FcChar32 begin;
+    FcChar32 end;
+};
+
 /* fcblanks.c */
 
 /* fccache.c */
index 2bd67bf090236a6db81a5f0a418096f3a5f5669b..94e2d4b66f38e704deaf6cf5307dda0593e09c05 100644 (file)
@@ -133,6 +133,18 @@ FcExprCreateBool (FcConfig *config, FcBool b)
     return e;
 }
 
+static FcExpr *
+FcExprCreateCharSet (FcConfig *config, FcCharSet *charset)
+{
+    FcExpr *e = FcConfigAllocExpr (config);
+    if (e)
+    {
+       e->op = FcOpCharSet;
+       e->u.cval = FcCharSetCopy (charset);
+    }
+    return e;
+}
+
 static FcExpr *
 FcExprCreateField (FcConfig *config, const char *field)
 {
@@ -185,6 +197,8 @@ FcExprDestroy (FcExpr *e)
     case FcOpMatrix:
        FcMatrixFree (e->u.mval);
        break;
+    case FcOpRange:
+       break;
     case FcOpCharSet:
        FcCharSetDestroy (e->u.cval);
        break;
@@ -277,8 +291,9 @@ typedef enum _FcElement {
     FcElementDouble,
     FcElementString,
     FcElementMatrix,
+    FcElementRange,
     FcElementBool,
-    FcElementCharset,
+    FcElementCharSet,
     FcElementName,
     FcElementConst,
     FcElementOr,
@@ -338,8 +353,9 @@ static const struct {
     { "double",                FcElementDouble },
     { "string",                FcElementString },
     { "matrix",                FcElementMatrix },
+    { "range",         FcElementRange },
     { "bool",          FcElementBool },
-    { "charset",       FcElementCharset },
+    { "charset",       FcElementCharSet },
     { "name",          FcElementName },
     { "const",         FcElementConst },
     { "or",            FcElementOr },
@@ -401,7 +417,9 @@ typedef enum _FcVStackTag {
     FcVStackInteger,
     FcVStackDouble,
     FcVStackMatrix,
+    FcVStackRange,
     FcVStackBool,
+    FcVStackCharSet,
 
     FcVStackTest,
     FcVStackExpr,
@@ -418,7 +436,9 @@ typedef struct _FcVStack {
        int             integer;
        double          _double;
        FcMatrix        *matrix;
+       FcRange         range;
        FcBool          bool_;
+       FcCharSet       *charset;
 
        FcTest          *test;
        FcQual          qual;
@@ -741,6 +761,18 @@ FcVStackPushMatrix (FcConfigParse *parse, FcMatrix *matrix)
     return FcTrue;
 }
 
+static FcBool
+FcVStackPushRange (FcConfigParse *parse, FcRange *range)
+{
+    FcVStack   *vstack = FcVStackCreateAndPush (parse);
+    if (!vstack)
+       return FcFalse;
+    vstack->u.range.begin = range->begin;
+    vstack->u.range.end = range->end;
+    vstack->tag = FcVStackRange;
+    return FcTrue;
+}
+
 static FcBool
 FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
 {
@@ -752,6 +784,20 @@ FcVStackPushBool (FcConfigParse *parse, FcBool bool_)
     return FcTrue;
 }
 
+static FcBool
+FcVStackPushCharSet (FcConfigParse *parse, FcCharSet *charset)
+{
+    FcVStack   *vstack;
+    if (!charset)
+       return FcFalse;
+    vstack = FcVStackCreateAndPush (parse);
+    if (!vstack)
+       return FcFalse;
+    vstack->u.charset = charset;
+    vstack->tag = FcVStackCharSet;
+    return FcTrue;
+}
+
 static FcBool
 FcVStackPushTest (FcConfigParse *parse, FcTest *test)
 {
@@ -843,8 +889,12 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
     case FcVStackMatrix:
        FcMatrixFree (vstack->u.matrix);
        break;
+    case FcVStackRange:
     case FcVStackBool:
        break;
+    case FcVStackCharSet:
+       FcCharSetDestroy (vstack->u.charset);
+       break;
     case FcVStackTest:
        FcTestDestroy (vstack->u.test);
        break;
@@ -1241,6 +1291,49 @@ FcParseMatrix (FcConfigParse *parse)
        FcVStackPushMatrix (parse, &m);
 }
 
+static void
+FcParseRange (FcConfigParse *parse)
+{
+    FcVStack   *vstack;
+    FcRange    r;
+    FcChar32   n;
+    int                count = 1;
+
+    while ((vstack = FcVStackPeek (parse)))
+    {
+       if (count < 0)
+       {
+           FcConfigMessage (parse, FcSevereError, "too many elements in range");
+           return;
+       }
+       switch (vstack->tag) {
+       case FcVStackInteger:
+           n = vstack->u.integer;
+           break;
+       default:
+           FcConfigMessage (parse, FcSevereError, "invalid element in range");
+           break;
+       }
+       if (count == 1)
+           r.end = n;
+       else
+           r.begin = n;
+       count--;
+       FcVStackPopAndDestroy (parse);
+    }
+    if (count < 0)
+    {
+       if (r.begin > r.end)
+       {
+           FcConfigMessage (parse, FcSevereError, "invalid range");
+           return;
+       }
+       FcVStackPushRange (parse, &r);
+    }
+    else
+       FcConfigMessage (parse, FcSevereError, "invalid range");
+}
+
 static FcBool
 FcConfigLexBool (FcConfigParse *parse, const FcChar8 *bool_)
 {
@@ -1269,6 +1362,48 @@ FcParseBool (FcConfigParse *parse)
     FcStrBufDestroy (&parse->pstack->str);
 }
 
+static void
+FcParseCharSet (FcConfigParse *parse)
+{
+    FcVStack   *vstack;
+    FcCharSet  *charset = FcCharSetCreate ();
+    FcChar32   i;
+    int n = 0;
+
+    while ((vstack = FcVStackPeek (parse)))
+    {
+       switch (vstack->tag) {
+       case FcVStackInteger:
+           if (!FcCharSetAddChar (charset, vstack->u.integer))
+           {
+               FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", vstack->u.integer);
+           }
+           else
+               n++;
+           break;
+       case FcVStackRange:
+           for (i = vstack->u.range.begin; i <= vstack->u.range.end; i++)
+           {
+               if (!FcCharSetAddChar (charset, i))
+               {
+                   FcConfigMessage (parse, FcSevereWarning, "invalid character: 0x%04x", i);
+               }
+               else
+                   n++;
+           }
+           break;
+       default:
+               FcConfigMessage (parse, FcSevereError, "invalid element in charset");
+               break;
+       }
+       FcVStackPopAndDestroy (parse);
+    }
+    if (n > 0)
+           FcVStackPushCharSet (parse, charset);
+    else
+           FcCharSetDestroy (charset);
+}
+
 static FcBool
 FcConfigLexBinding (FcConfigParse   *parse,
                    const FcChar8   *binding_string,
@@ -1515,9 +1650,14 @@ FcPopExpr (FcConfigParse *parse)
     case FcVStackMatrix:
        expr = FcExprCreateMatrix (parse->config, vstack->u.matrix);
        break;
+    case FcVStackRange:
+       break;
     case FcVStackBool:
        expr = FcExprCreateBool (parse->config, vstack->u.bool_);
        break;
+    case FcVStackCharSet:
+       expr = FcExprCreateCharSet (parse->config, vstack->u.charset);
+       break;
     case FcVStackTest:
        break;
     case FcVStackExpr:
@@ -1934,6 +2074,11 @@ FcPopValue (FcConfigParse *parse)
        value.u.b = vstack->u.bool_;
        value.type = FcTypeBool;
        break;
+    case FcVStackCharSet:
+       value.u.c = FcCharSetCopy (vstack->u.charset);
+       if (value.u.c)
+           value.type = FcTypeCharSet;
+       break;
     default:
        FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
                         vstack->tag);
@@ -2199,11 +2344,14 @@ FcEndElement(void *userData, const XML_Char *name)
     case FcElementMatrix:
        FcParseMatrix (parse);
        break;
+    case FcElementRange:
+       FcParseRange (parse);
+       break;
     case FcElementBool:
        FcParseBool (parse);
        break;
-    case FcElementCharset:
-/*     FcParseCharset (parse); */
+    case FcElementCharSet:
+       FcParseCharSet (parse);
        break;
     case FcElementSelectfont:
        break;