Add editing langset feature.

The syntax to add any langset to the langset table looks like:

<match target="scan">
    <test name="family">
        <string>Buggy Sans</string>
    </test>
    <edit name="lang" mode="assign">
        <plus>
            <name>lang</name>
            <langset>
                <string>zh-cn</string>
                <string>zh-tw</string>
            </langset>
        </plus>
    </edit>
</match>

To remove any langset from the langset table:

<match target="scan">
    <test name="family">
        <string>Buggy Sans</string>
    </test>
    <edit name="lang" mode="assign">
        <minus>
            <name>lang</name>
            <langset>
                <string>ja</string>
            </langset>
        </minus>
    </edit>
</match>
This commit is contained in:
Akira TAGOH 2010-12-06 12:38:18 +09:00
parent d975cdda78
commit 3c862aad9f
7 changed files with 186 additions and 3 deletions

View File

@ -584,6 +584,9 @@ FcLangSetCopy (const FcLangSet *ls);
FcPublic FcBool
FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang);
FcPublic FcBool
FcLangSetDel (FcLangSet *ls, const FcChar8 *lang);
FcPublic FcLangResult
FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang);
@ -602,6 +605,12 @@ FcLangSetHash (const FcLangSet *ls);
FcPublic FcStrSet *
FcLangSetGetLangs (const FcLangSet *ls);
FcLangSet *
FcLangSetUnion (const FcLangSet *a, const FcLangSet *b);
FcLangSet *
FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b);
/* fclist.c */
FcPublic FcObjectSet *
FcObjectSetCreate (void);

View File

@ -107,7 +107,7 @@
<!ELEMENT pattern (patelt)*>
<!ENTITY % constant 'int|double|string|matrix|bool|charset|const'>
<!ENTITY % constant 'int|double|string|matrix|bool|charset|langset|const'>
<!ELEMENT patelt (%constant;)*>
<!ATTLIST patelt
@ -122,7 +122,7 @@
<!ELEMENT family (#PCDATA)>
<!ATTLIST family xml:space (default|preserve) 'preserve'>
<!ENTITY % expr 'int|double|string|matrix|bool|charset
<!ENTITY % expr 'int|double|string|matrix|bool|charset|langset
|name|const
|or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains
|plus|minus|times|divide|not|if|floor|ceil|round|trunc'>
@ -198,6 +198,7 @@
<!ELEMENT bool (#PCDATA)>
<!ELEMENT charset (int|range)*>
<!ELEMENT range (int,int)>
<!ELEMENT langset (string)*>
<!ELEMENT name (#PCDATA)>
<!ATTLIST name xml:space (default|preserve) 'preserve'>
<!ELEMENT const (#PCDATA)>

View File

@ -897,6 +897,11 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
v.u.c = e->u.cval;
v = FcValueSave (v);
break;
case FcOpLangSet:
v.type = FcTypeLangSet;
v.u.l = e->u.lval;
v = FcValueSave (v);
break;
case FcOpBool:
v.type = FcTypeBool;
v.u.b = e->u.bval;
@ -1055,6 +1060,25 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
break;
}
break;
case FcTypeLangSet:
switch (e->op) {
case FcOpPlus:
v.type = FcTypeLangSet;
v.u.l = FcLangSetUnion (vl.u.l, vr.u.l);
if (!v.u.l)
v.type = FcTypeVoid;
break;
case FcOpMinus:
v.type = FcTypeLangSet;
v.u.l = FcLangSetSubtract (vl.u.l, vr.u.l);
if (!v.u.l)
v.type = FcTypeVoid;
break;
default:
v.type = FcTypeVoid;
break;
}
break;
default:
v.type = FcTypeVoid;
break;

View File

@ -163,6 +163,7 @@ FcOpPrint (FcOp op)
case FcOpRange: printf ("Range"); break;
case FcOpBool: printf ("Bool"); break;
case FcOpCharSet: printf ("CharSet"); break;
case FcOpLangSet: printf ("LangSet"); break;
case FcOpField: printf ("Field"); break;
case FcOpConst: printf ("Const"); break;
case FcOpAssign: printf ("Assign"); break;
@ -214,6 +215,11 @@ FcExprPrint (const FcExpr *expr)
case FcOpRange: break;
case FcOpBool: printf ("%s", expr->u.bval ? "true" : "false"); break;
case FcOpCharSet: printf ("charset\n"); break;
case FcOpLangSet:
printf ("langset:");
FcLangSetPrint(expr->u.lval);
printf ("\n");
break;
case FcOpNil: printf ("nil\n"); break;
case FcOpField: printf ("%s", FcObjectName(expr->u.object)); break;
case FcOpConst: printf ("%s", expr->u.constant); break;

View File

@ -216,7 +216,7 @@ struct _FcPattern {
fs->fonts[i])
typedef enum _FcOp {
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet,
FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet, FcOpLangSet,
FcOpNil,
FcOpField, FcOpConst,
FcOpAssign, FcOpAssignReplace,
@ -239,6 +239,7 @@ typedef struct _FcExpr {
FcMatrix *mval;
FcBool bval;
FcCharSet *cval;
FcLangSet *lval;
FcObject object;
FcChar8 *constant;
struct {

View File

@ -71,6 +71,20 @@ FcLangSetBitGet (const FcLangSet *ls,
return ((ls->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse;
}
static void
FcLangSetBitReset (FcLangSet *ls,
unsigned int id)
{
int bucket;
id = fcLangCharSetIndices[id];
bucket = id >> 5;
if (bucket >= ls->map_size)
return; /* shouldn't happen really */
ls->map[bucket] &= ~((FcChar32) 1 << (id & 0x1f));
}
FcLangSet *
FcFreeTypeLangSet (const FcCharSet *charset,
const FcChar8 *exclusiveLang)
@ -400,6 +414,23 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
return FcStrSetAdd (ls->extra, lang);
}
FcBool
FcLangSetDel (FcLangSet *ls, const FcChar8 *lang)
{
int id;
id = FcLangSetIndex (lang);
if (id >= 0)
{
FcLangSetBitReset (ls, id);
}
else if (ls->extra)
{
FcStrSetDel (ls->extra, lang);
}
return FcTrue;
}
FcLangResult
FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang)
{
@ -818,6 +849,37 @@ FcLangSetGetLangs (const FcLangSet *ls)
return langs;
}
static FcLangSet *
FcLangSetOperate(const FcLangSet *a,
const FcLangSet *b,
FcBool (*func) (FcLangSet *ls,
const FcChar8 *s))
{
FcLangSet *langset = FcLangSetCopy (a);
FcStrList *sl = FcStrListCreate (FcLangSetGetLangs (b));
FcChar8 *str;
while ((str = FcStrListNext (sl)))
{
func (langset, str);
}
FcStrListDone (sl);
return langset;
}
FcLangSet *
FcLangSetUnion (const FcLangSet *a, const FcLangSet *b)
{
return FcLangSetOperate(a, b, FcLangSetAdd);
}
FcLangSet *
FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b)
{
return FcLangSetOperate(a, b, FcLangSetDel);
}
#define __fclang__
#include "fcaliastail.h"
#include "fcftaliastail.h"

View File

@ -145,6 +145,18 @@ FcExprCreateCharSet (FcConfig *config, FcCharSet *charset)
return e;
}
static FcExpr *
FcExprCreateLangSet (FcConfig *config, FcLangSet *langset)
{
FcExpr *e = FcConfigAllocExpr (config);
if (e)
{
e->op = FcOpLangSet;
e->u.lval = FcLangSetCopy (langset);
}
return e;
}
static FcExpr *
FcExprCreateField (FcConfig *config, const char *field)
{
@ -202,6 +214,9 @@ FcExprDestroy (FcExpr *e)
case FcOpCharSet:
FcCharSetDestroy (e->u.cval);
break;
case FcOpLangSet:
FcLangSetDestroy (e->u.lval);
break;
case FcOpBool:
break;
case FcOpField:
@ -294,6 +309,7 @@ typedef enum _FcElement {
FcElementRange,
FcElementBool,
FcElementCharSet,
FcElementLangSet,
FcElementName,
FcElementConst,
FcElementOr,
@ -356,6 +372,7 @@ static const struct {
{ "range", FcElementRange },
{ "bool", FcElementBool },
{ "charset", FcElementCharSet },
{ "langset", FcElementLangSet },
{ "name", FcElementName },
{ "const", FcElementConst },
{ "or", FcElementOr },
@ -420,6 +437,7 @@ typedef enum _FcVStackTag {
FcVStackRange,
FcVStackBool,
FcVStackCharSet,
FcVStackLangSet,
FcVStackTest,
FcVStackExpr,
@ -439,6 +457,7 @@ typedef struct _FcVStack {
FcRange range;
FcBool bool_;
FcCharSet *charset;
FcLangSet *langset;
FcTest *test;
FcQual qual;
@ -571,6 +590,9 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
case FcOpCharSet:
FcTypecheckValue (parse, FcTypeCharSet, type);
break;
case FcOpLangSet:
FcTypecheckValue (parse, FcTypeLangSet, type);
break;
case FcOpNil:
break;
case FcOpField:
@ -798,6 +820,20 @@ FcVStackPushCharSet (FcConfigParse *parse, FcCharSet *charset)
return FcTrue;
}
static FcBool
FcVStackPushLangSet (FcConfigParse *parse, FcLangSet *langset)
{
FcVStack *vstack;
if (!langset)
return FcFalse;
vstack = FcVStackCreateAndPush (parse);
if (!vstack)
return FcFalse;
vstack->u.langset = langset;
vstack->tag = FcVStackLangSet;
return FcTrue;
}
static FcBool
FcVStackPushTest (FcConfigParse *parse, FcTest *test)
{
@ -895,6 +931,9 @@ FcVStackPopAndDestroy (FcConfigParse *parse)
case FcVStackCharSet:
FcCharSetDestroy (vstack->u.charset);
break;
case FcVStackLangSet:
FcLangSetDestroy (vstack->u.langset);
break;
case FcVStackTest:
FcTestDestroy (vstack->u.test);
break;
@ -1411,6 +1450,36 @@ FcParseCharSet (FcConfigParse *parse)
FcCharSetDestroy (charset);
}
static void
FcParseLangSet (FcConfigParse *parse)
{
FcVStack *vstack;
FcLangSet *langset = FcLangSetCreate ();
int n = 0;
while ((vstack = FcVStackPeek (parse)))
{
switch (vstack->tag) {
case FcVStackString:
if (!FcLangSetAdd (langset, vstack->u.string))
{
FcConfigMessage (parse, FcSevereWarning, "invalid langset: %s", vstack->u.string);
}
else
n++;
break;
default:
FcConfigMessage (parse, FcSevereError, "invalid element in langset");
break;
}
FcVStackPopAndDestroy (parse);
}
if (n > 0)
FcVStackPushLangSet (parse, langset);
else
FcLangSetDestroy (langset);
}
static FcBool
FcConfigLexBinding (FcConfigParse *parse,
const FcChar8 *binding_string,
@ -1665,6 +1734,9 @@ FcPopExpr (FcConfigParse *parse)
case FcVStackCharSet:
expr = FcExprCreateCharSet (parse->config, vstack->u.charset);
break;
case FcVStackLangSet:
expr = FcExprCreateLangSet (parse->config, vstack->u.langset);
break;
case FcVStackTest:
break;
case FcVStackExpr:
@ -2086,6 +2158,11 @@ FcPopValue (FcConfigParse *parse)
if (value.u.c)
value.type = FcTypeCharSet;
break;
case FcVStackLangSet:
value.u.l = FcLangSetCopy (vstack->u.langset);
if (value.u.l)
value.type = FcTypeLangSet;
break;
default:
FcConfigMessage (parse, FcSevereWarning, "unknown pattern element %d",
vstack->tag);
@ -2360,6 +2437,9 @@ FcEndElement(void *userData, const XML_Char *name)
case FcElementCharSet:
FcParseCharSet (parse);
break;
case FcElementLangSet:
FcParseLangSet (parse);
break;
case FcElementSelectfont:
break;
case FcElementAcceptfont: