Bug 19128 - Handling whitespace in aliases

Add a new attribute `ignore-blanks' to <test>.
When this is set to "true", any blanks in the string will be ignored
on comparison.  This takes effects for compare="eq" or "not_eq" only.

Also changed the behavior of the comparison on <alias> too.
This commit is contained in:
Akira TAGOH 2012-04-11 19:52:35 +09:00
parent 5ac12c0e94
commit bc4517d8e5
13 changed files with 103 additions and 64 deletions

View File

@ -7,22 +7,22 @@
FreeType very confused as it forces all widths to match.
Undo this magic by disabling the width forcing code -->
<match target="font">
<test name="family"><string>GulimChe</string></test>
<test name="family" compare="eq" ignore-blanks="true"><string>GulimChe</string></test>
<edit name="globaladvance"><bool>false</bool></edit>
</match>
<match target="font">
<test name="family"><string>DotumChe</string></test>
<test name="family" compare="eq" ignore-blanks="true"><string>DotumChe</string></test>
<edit name="globaladvance"><bool>false</bool></edit>
</match>
<match target="font">
<test name="family"><string>BatangChe</string></test>
<test name="family" compare="eq" ignore-blanks="true"><string>BatangChe</string></test>
<edit name="globaladvance"><bool>false</bool></edit>
</match>
<match target="font">
<test name="family"><string>GungsuhChe</string></test>
<test name="family" compare="eq" ignore-blanks="true"><string>GungsuhChe</string></test>
<edit name="globaladvance"><bool>false</bool></edit>
</match>
</fontconfig>

View File

@ -10,7 +10,7 @@
-->
<match target="font">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Bitstream Vera Sans</string>
</test>
<test name="pixelsize" compare="less">
@ -22,7 +22,7 @@
</match>
<match target="font">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Bitstream Vera Serif</string>
</test>
<test name="pixelsize" compare="less">
@ -34,7 +34,7 @@
</match>
<match target="font">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Bitstream Vera Sans Mono</string>
</test>
<test name="pixelsize" compare="less">

View File

@ -5,7 +5,7 @@
<!-- We can't hint CJK fonts well, so turn off hinting for CJK fonts. -->
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Kochi Mincho</string>
</test>
<edit name="hinting" mode="assign">
@ -13,7 +13,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Kochi Gothic</string>
</test>
<edit name="hinting" mode="assign">
@ -21,7 +21,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Sazanami Mincho</string>
</test>
<edit name="hinting" mode="assign">
@ -29,7 +29,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Sazanami Gothic</string>
</test>
<edit name="hinting" mode="assign">
@ -37,7 +37,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Baekmuk Batang</string>
</test>
<edit name="hinting" mode="assign">
@ -45,7 +45,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Baekmuk Dotum</string>
</test>
<edit name="hinting" mode="assign">
@ -53,7 +53,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Baekmuk Gulim</string>
</test>
<edit name="hinting" mode="assign">
@ -61,7 +61,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>Baekmuk Headline</string>
</test>
<edit name="hinting" mode="assign">
@ -69,7 +69,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>AR PL Mingti2L Big5</string>
</test>
<edit name="hinting" mode="assign">
@ -77,7 +77,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>AR PL ShanHeiSun Uni</string>
</test>
<edit name="hinting" mode="assign">
@ -85,7 +85,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>AR PL KaitiM Big5</string>
</test>
<edit name="hinting" mode="assign">
@ -93,7 +93,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>AR PL ZenKai Uni</string>
</test>
<edit name="hinting" mode="assign">
@ -101,7 +101,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>AR PL SungtiL GB</string>
</test>
<edit name="hinting" mode="assign">
@ -109,7 +109,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>AR PL KaitiM GB</string>
</test>
<edit name="hinting" mode="assign">
@ -117,7 +117,7 @@
</edit>
</match>
<match target="font">
<test name="family" compare="eq">
<test name="family" compare="eq" ignore-blanks="true">
<string>ZYSong18030</string>
</test>
<edit name="hinting" mode="assign">

View File

@ -29,13 +29,8 @@
<family>Zapf Dingbats</family>
<accept><family>Dingbats</family></accept>
</alias>
<!-- workaround for Bug#19128 -->
<alias binding="same">
<family>ZapfDingbats</family>
<accept><family>Dingbats</family></accept>
</alias>
<match target="pattern">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Symbol</string>
</test>
<edit name="family" mode="append" binding="same">

View File

@ -181,7 +181,7 @@
<!-- Register the fonts that we actually do have -->
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Elham</string>
</test>
<edit name="foundry">
@ -190,7 +190,7 @@
</match>
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Homa</string>
</test>
<edit name="foundry">
@ -199,7 +199,7 @@
</match>
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Koodak</string>
</test>
<edit name="foundry">
@ -208,7 +208,7 @@
</match>
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Nazli</string>
</test>
<edit name="foundry">
@ -217,7 +217,7 @@
</match>
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Roya</string>
</test>
<edit name="foundry">
@ -226,7 +226,7 @@
</match>
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Terafik</string>
</test>
<edit name="foundry">
@ -235,7 +235,7 @@
</match>
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Titr</string>
</test>
<edit name="foundry">

View File

@ -5,7 +5,7 @@
<!-- Delicious 'heavy' variant says its Medium weight -->
<match target="scan">
<test name="family">
<test name="family" compare="eq" ignore-blanks="true">
<string>Delicious</string>
</test>
<test name="style">

View File

@ -396,7 +396,8 @@ above). 'compare' can be one of "eq", "not_eq", "less", "less_eq", "more", "more
"not_contains". 'qual' may either be the default, "any", in which case the match
succeeds if any value associated with the property matches the test value, or
"all", in which case all of the values associated with the property must
match the test value. When used in a &lt;match target="font"&gt; element,
match the test value. 'ignore-blanks' takes a boolean value. if 'ignore-blanks' is set "true", any blanks in the string will be ignored on its comparison. this takes effects only when compare="eq" or compare="not_eq".
When used in a &lt;match target="font"&gt; element,
the target= attribute in the &lt;test&gt; element selects between matching
the original pattern or the font. "default" selects whichever target the
outer &lt;match&gt; element has selected.

View File

@ -159,6 +159,7 @@
qual (any|all|first|not_first) "any"
name CDATA #REQUIRED
target (pattern|font|default) "default"
ignore-blanks (#PCDATA) "false"
compare (eq|not_eq|less|less_eq|more|more_eq|contains|not_contains) "eq">
<!--

View File

@ -691,12 +691,14 @@ FcConfigPromote (FcValue v, FcValue u)
FcBool
FcConfigCompareValue (const FcValue *left_o,
FcOp op,
FcOp op_,
const FcValue *right_o)
{
FcValue left = FcValueCanonicalize(left_o);
FcValue right = FcValueCanonicalize(right_o);
FcBool ret = FcFalse;
FcOp op = FC_OP_GET_OP (op_);
int flags = FC_OP_GET_FLAGS (op_);
left = FcConfigPromote (left, right);
right = FcConfigPromote (right, left);
@ -751,13 +753,19 @@ FcConfigCompareValue (const FcValue *left_o,
switch (op) {
case FcOpEqual:
case FcOpListing:
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
if (flags & FcOpFlagIgnoreBlanks)
ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) == 0;
else
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0;
break;
case FcOpContains:
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0;
break;
case FcOpNotEqual:
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
if (flags & FcOpFlagIgnoreBlanks)
ret = FcStrCmpIgnoreBlanksAndCase (left.u.s, right.u.s) != 0;
else
ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0;
break;
case FcOpNotContains:
ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0;
@ -872,8 +880,9 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
FcResult r;
FcMatrix *m;
FcChar8 *str;
FcOp op = FC_OP_GET_OP (e->op);
switch (e->op) {
switch (op) {
case FcOpInteger:
v.type = FcTypeInteger;
v.u.i = e->u.ival;
@ -961,7 +970,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
{
switch (vl.type) {
case FcTypeDouble:
switch (e->op) {
switch (op) {
case FcOpPlus:
v.type = FcTypeDouble;
v.u.d = vl.u.d + vr.u.d;
@ -990,7 +999,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
}
break;
case FcTypeBool:
switch (e->op) {
switch (op) {
case FcOpOr:
v.type = FcTypeBool;
v.u.b = vl.u.b || vr.u.b;
@ -1005,7 +1014,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
}
break;
case FcTypeString:
switch (e->op) {
switch (op) {
case FcOpPlus:
v.type = FcTypeString;
str = FcStrPlus (vl.u.s, vr.u.s);
@ -1021,7 +1030,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
}
break;
case FcTypeMatrix:
switch (e->op) {
switch (op) {
case FcOpTimes:
v.type = FcTypeMatrix;
m = malloc (sizeof (FcMatrix));
@ -1042,7 +1051,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
}
break;
case FcTypeCharSet:
switch (e->op) {
switch (op) {
case FcOpPlus:
v.type = FcTypeCharSet;
v.u.c = FcCharSetUnion (vl.u.c, vr.u.c);
@ -1061,7 +1070,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e)
}
break;
case FcTypeLangSet:
switch (e->op) {
switch (op) {
case FcOpPlus:
v.type = FcTypeLangSet;
v.u.l = FcLangSetUnion (vl.u.l, vr.u.l);
@ -1186,7 +1195,7 @@ FcConfigMatchValueList (FcPattern *p,
while (e)
{
/* Compute the value of the match expression */
if (e->op == FcOpComma)
if (FC_OP_GET_OP (e->op) == FcOpComma)
{
value = FcConfigEvaluate (p, e->u.tree.left);
e = e->u.tree.right;
@ -1230,7 +1239,7 @@ FcConfigValues (FcPattern *p, FcExpr *e, FcValueBinding binding)
if (!l)
return 0;
FcMemAlloc (FC_MEM_VALLIST, sizeof (FcValueList));
if (e->op == FcOpComma)
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);
@ -1518,7 +1527,7 @@ FcConfigSubstituteWithPat (FcConfig *config,
break;
}
}
switch (e->op) {
switch (FC_OP_GET_OP (e->op)) {
case FcOpAssign:
/*
* If there was a test, then replace the matched

View File

@ -185,9 +185,18 @@ FcPatternPrint (const FcPattern *p)
printf ("\n");
}
#define FcOpFlagsPrint(_o_) \
{ \
int f = FC_OP_GET_FLAGS (_o_); \
if (f & FcOpFlagIgnoreBlanks) \
printf ("(ignore blanks)"); \
}
void
FcOpPrint (FcOp op)
FcOpPrint (FcOp op_)
{
FcOp op = FC_OP_GET_OP (op_);
switch (op) {
case FcOpInteger: printf ("Integer"); break;
case FcOpDouble: printf ("Double"); break;
@ -208,8 +217,8 @@ FcOpPrint (FcOp op)
case FcOpQuest: printf ("Quest"); break;
case FcOpOr: printf ("Or"); break;
case FcOpAnd: printf ("And"); break;
case FcOpEqual: printf ("Equal"); break;
case FcOpNotEqual: printf ("NotEqual"); break;
case FcOpEqual: printf ("Equal"); FcOpFlagsPrint (op_); break;
case FcOpNotEqual: printf ("NotEqual"); FcOpFlagsPrint (op_); break;
case FcOpLess: printf ("Less"); break;
case FcOpLessEqual: printf ("LessEqual"); break;
case FcOpMore: printf ("More"); break;
@ -227,7 +236,7 @@ FcOpPrint (FcOp op)
case FcOpCeil: printf ("Ceil"); break;
case FcOpRound: printf ("Round"); break;
case FcOpTrunc: printf ("Trunc"); break;
case FcOpListing: printf ("Listing"); break;
case FcOpListing: printf ("Listing"); FcOpFlagsPrint (op_); break;
case FcOpInvalid: printf ("Invalid"); break;
}
}
@ -236,7 +245,7 @@ void
FcExprPrint (const FcExpr *expr)
{
if (!expr) printf ("none");
else switch (expr->op) {
else switch (FC_OP_GET_OP (expr->op)) {
case FcOpInteger: printf ("%d", expr->u.ival); break;
case FcOpDouble: printf ("%g", expr->u.dval); break;
case FcOpString: printf ("\"%s\"", expr->u.sval); break;
@ -287,7 +296,7 @@ FcExprPrint (const FcExpr *expr)
case FcOpComma:
FcExprPrint (expr->u.tree.left);
printf (" ");
switch (expr->op) {
switch (FC_OP_GET_OP (expr->op)) {
case FcOpAssign: printf ("Assign"); break;
case FcOpAssignReplace: printf ("AssignReplace"); break;
case FcOpPrependFirst: printf ("PrependFirst"); break;
@ -296,14 +305,14 @@ FcExprPrint (const FcExpr *expr)
case FcOpAppendLast: printf ("AppendLast"); break;
case FcOpOr: printf ("Or"); break;
case FcOpAnd: printf ("And"); break;
case FcOpEqual: printf ("Equal"); break;
case FcOpNotEqual: printf ("NotEqual"); break;
case FcOpEqual: printf ("Equal"); FcOpFlagsPrint (expr->op); break;
case FcOpNotEqual: printf ("NotEqual"); FcOpFlagsPrint (expr->op); break;
case FcOpLess: printf ("Less"); break;
case FcOpLessEqual: printf ("LessEqual"); break;
case FcOpMore: printf ("More"); break;
case FcOpMoreEqual: printf ("MoreEqual"); break;
case FcOpContains: printf ("Contains"); break;
case FcOpListing: printf ("Listing"); break;
case FcOpListing: printf ("Listing"); FcOpFlagsPrint (expr->op); break;
case FcOpNotContains: printf ("NotContains"); break;
case FcOpPlus: printf ("Plus"); break;
case FcOpMinus: printf ("Minus"); break;

View File

@ -244,6 +244,14 @@ typedef enum _FcOp {
FcOpInvalid
} FcOp;
typedef enum _FcOpFlags {
FcOpFlagIgnoreBlanks = 1 << 0
} FcOpFlags;
#define FC_OP_GET_OP(_x_) ((_x_) & 0xffff)
#define FC_OP_GET_FLAGS(_x_) (((_x_) & 0xffff0000) >> 16)
#define FC_OP(_x_,_f_) (FC_OP_GET_OP (_x_) | ((_f_) << 16))
typedef struct _FcExpr {
FcOp op;
union {

View File

@ -148,7 +148,7 @@ FcListValueListMatchAny (FcValueListPtr patOrig, /* pattern */
* where it requires an exact match)
*/
if (FcConfigCompareValue (&fnt->value,
FcOpListing,
FC_OP (FcOpListing, FcOpFlagIgnoreBlanks),
&pat->value))
break;
}

View File

@ -195,7 +195,7 @@ FcExprDestroy (FcExpr *e)
{
if (!e)
return;
switch (e->op) {
switch (FC_OP_GET_OP (e->op)) {
case FcOpInteger:
break;
case FcOpDouble:
@ -571,7 +571,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type)
if (!expr)
return;
switch (expr->op) {
switch (FC_OP_GET_OP (expr->op)) {
case FcOpInteger:
case FcOpDouble:
FcTypecheckValue (parse, FcTypeDouble, type);
@ -1687,7 +1687,7 @@ FcParseAlias (FcConfigParse *parse)
FcTest *t = FcTestCreate (parse, FcMatchPattern,
FcQualAny,
(FcChar8 *) FC_FAMILY,
FcOpEqual,
FC_OP (FcOpEqual, FcOpFlagIgnoreBlanks),
family);
if (test)
{
@ -1911,6 +1911,8 @@ FcParseTest (FcConfigParse *parse)
FcOp compare;
FcExpr *expr;
FcTest *test;
const FcChar8 *iblanks_string;
int flags = 0;
kind_string = FcConfigGetAttribute (parse, "target");
if (!kind_string)
@ -1968,13 +1970,27 @@ FcParseTest (FcConfigParse *parse)
return;
}
}
iblanks_string = FcConfigGetAttribute (parse, "ignore-blanks");
if (iblanks_string)
{
FcBool f = FcFalse;
if (!FcNameBool (iblanks_string, &f))
{
FcConfigMessage (parse,
FcSevereWarning,
"invalid test ignore-blanks \"%s\"", iblanks_string);
}
if (f)
flags |= FcOpFlagIgnoreBlanks;
}
expr = FcPopBinary (parse, FcOpComma);
if (!expr)
{
FcConfigMessage (parse, FcSevereWarning, "missing test expression");
return;
}
test = FcTestCreate (parse, kind, qual, name, compare, expr);
test = FcTestCreate (parse, kind, qual, name, FC_OP (compare, flags), expr);
if (!test)
{
FcConfigMessage (parse, FcSevereError, "out of memory");