diff --git a/src/fccfg.c b/src/fccfg.c index fd87cb6..7b5d693 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -514,42 +514,43 @@ FcConfigPromote (FcValue v, FcValue u) } FcBool -FcConfigCompareValue (const FcValue m_o, +FcConfigCompareValue (const FcValue left_o, FcOp op, - const FcValue v_o) + const FcValue right_o) { - FcValue m = m_o; - FcValue v = v_o; + FcValue left = left_o; + FcValue right = right_o; FcBool ret = FcFalse; - m = FcConfigPromote (m, v); - v = FcConfigPromote (v, m); - if (m.type == v.type) + left = FcConfigPromote (left, right); + right = FcConfigPromote (right, left); + if (left.type == right.type) { - switch (m.type) { + switch (left.type) { case FcTypeInteger: break; /* FcConfigPromote prevents this from happening */ case FcTypeDouble: switch (op) { case FcOpEqual: case FcOpContains: - ret = m.u.d == v.u.d; + case FcOpListing: + ret = left.u.d == right.u.d; break; case FcOpNotEqual: case FcOpNotContains: - ret = m.u.d != v.u.d; + ret = left.u.d != right.u.d; break; case FcOpLess: - ret = m.u.d < v.u.d; + ret = left.u.d < right.u.d; break; case FcOpLessEqual: - ret = m.u.d <= v.u.d; + ret = left.u.d <= right.u.d; break; case FcOpMore: - ret = m.u.d > v.u.d; + ret = left.u.d > right.u.d; break; case FcOpMoreEqual: - ret = m.u.d >= v.u.d; + ret = left.u.d >= right.u.d; break; default: break; @@ -559,11 +560,12 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: - ret = m.u.b == v.u.b; + case FcOpListing: + ret = left.u.b == right.u.b; break; case FcOpNotEqual: case FcOpNotContains: - ret = m.u.b != v.u.b; + ret = left.u.b != right.u.b; break; default: break; @@ -572,16 +574,15 @@ FcConfigCompareValue (const FcValue m_o, case FcTypeString: switch (op) { case FcOpEqual: - ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) == 0; + case FcOpListing: + ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0; break; case FcOpContains: - ret = FcStrStrIgnoreCase (m.u.s, v.u.s) != 0; + ret = FcStrStrIgnoreCase (left.u.s, right.u.s) != 0; break; case FcOpNotEqual: - ret = FcStrCmpIgnoreCase (m.u.s, v.u.s) != 0; - break; case FcOpNotContains: - ret = FcStrStrIgnoreCase (m.u.s, v.u.s) == 0; + ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0; break; default: break; @@ -591,11 +592,12 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: - ret = FcMatrixEqual (m.u.m, v.u.m); + case FcOpListing: + ret = FcMatrixEqual (left.u.m, right.u.m); break; case FcOpNotEqual: case FcOpNotContains: - ret = !FcMatrixEqual (m.u.m, v.u.m); + ret = !FcMatrixEqual (left.u.m, right.u.m); break; default: break; @@ -604,18 +606,19 @@ FcConfigCompareValue (const FcValue m_o, case FcTypeCharSet: switch (op) { case FcOpContains: - /* v contains m if m is a subset of v */ - ret = FcCharSetIsSubset (m.u.c, v.u.c); + case FcOpListing: + /* left contains right if right is a subset of left */ + ret = FcCharSetIsSubset (right.u.c, left.u.c); break; case FcOpNotContains: - /* v contains m if m is a subset of v */ - ret = !FcCharSetIsSubset (m.u.c, v.u.c); + /* left contains right if right is a subset of left */ + ret = !FcCharSetIsSubset (right.u.c, left.u.c); break; case FcOpEqual: - ret = FcCharSetEqual (m.u.c, v.u.c); + ret = FcCharSetEqual (left.u.c, right.u.c); break; case FcOpNotEqual: - ret = !FcCharSetEqual (m.u.c, v.u.c); + ret = !FcCharSetEqual (left.u.c, right.u.c); break; default: break; @@ -624,16 +627,17 @@ FcConfigCompareValue (const FcValue m_o, case FcTypeLangSet: switch (op) { case FcOpContains: - ret = FcLangSetContains (m.u.l, v.u.l); + case FcOpListing: + ret = FcLangSetContains (left.u.l, right.u.l); break; case FcOpNotContains: - ret = FcLangSetContains (m.u.l, v.u.l); + ret = FcLangSetContains (left.u.l, right.u.l); break; case FcOpEqual: - ret = FcLangSetEqual (m.u.l, v.u.l); + ret = FcLangSetEqual (left.u.l, right.u.l); break; case FcOpNotEqual: - ret = !FcLangSetEqual (m.u.l, v.u.l); + ret = !FcLangSetEqual (left.u.l, right.u.l); break; default: break; @@ -643,6 +647,7 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: + case FcOpListing: ret = FcTrue; break; default: @@ -653,11 +658,12 @@ FcConfigCompareValue (const FcValue m_o, switch (op) { case FcOpEqual: case FcOpContains: - ret = m.u.f == v.u.f; + case FcOpListing: + ret = left.u.f == right.u.f; break; case FcOpNotEqual: case FcOpNotContains: - ret = m.u.f != v.u.f; + ret = left.u.f != right.u.f; break; default: break; @@ -748,6 +754,7 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) case FcOpMoreEqual: case FcOpContains: case FcOpNotContains: + case FcOpListing: vl = FcConfigEvaluate (p, e->u.tree.left); vr = FcConfigEvaluate (p, e->u.tree.right); v.type = FcTypeBool; @@ -952,6 +959,7 @@ FcConfigMatchValueList (FcPattern *p, while (e) { + /* Compute the value of the match expression */ if (e->op == FcOpComma) { value = FcConfigEvaluate (p, e->u.tree.left); @@ -965,6 +973,7 @@ FcConfigMatchValueList (FcPattern *p, for (v = values; v; v = v->next) { + /* Compare the pattern value to the match expression value */ if (FcConfigCompareValue (v->value, t->op, value)) { if (!ret) diff --git a/src/fcdbg.c b/src/fcdbg.c index 8d4439b..00c0344 100644 --- a/src/fcdbg.c +++ b/src/fcdbg.c @@ -157,6 +157,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 FcOpInvalid: printf ("Invalid"); break; } } @@ -201,6 +202,7 @@ FcExprPrint (const FcExpr *expr) case FcOpMore: case FcOpMoreEqual: case FcOpContains: + case FcOpListing: case FcOpNotContains: case FcOpPlus: case FcOpMinus: @@ -225,6 +227,7 @@ FcExprPrint (const FcExpr *expr) case FcOpMore: printf ("More"); break; case FcOpMoreEqual: printf ("MoreEqual"); break; case FcOpContains: printf ("Contains"); break; + case FcOpListing: printf ("Listing"); break; case FcOpNotContains: printf ("NotContains"); break; case FcOpPlus: printf ("Plus"); break; case FcOpMinus: printf ("Minus"); break; diff --git a/src/fcint.h b/src/fcint.h index 790f0ba..926111e 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -132,7 +132,8 @@ typedef enum _FcOp { FcOpAssign, FcOpAssignReplace, FcOpPrependFirst, FcOpPrepend, FcOpAppend, FcOpAppendLast, FcOpQuest, - FcOpOr, FcOpAnd, FcOpEqual, FcOpNotEqual, FcOpContains, FcOpNotContains, + FcOpOr, FcOpAnd, FcOpEqual, FcOpNotEqual, + FcOpContains, FcOpListing, FcOpNotContains, FcOpLess, FcOpLessEqual, FcOpMore, FcOpMoreEqual, FcOpPlus, FcOpMinus, FcOpTimes, FcOpDivide, FcOpNot, FcOpComma, FcOpFloor, FcOpCeil, FcOpRound, FcOpTrunc, diff --git a/src/fclang.c b/src/fclang.c index 53f2b59..582b92b 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -144,29 +144,33 @@ FcLangCompare (const FcChar8 *s1, const FcChar8 *s2) } /* - * Return FcTrue when s1 contains s2. + * Return FcTrue when super contains sub. * - * s1 contains s2 if s1 equals s2 or if s1 is a - * language with a country and s2 is just a language + * super contains sub if super and sub have the same + * language and either the same country or one + * is missing the country */ static FcBool -FcLangContains (const FcChar8 *s1, const FcChar8 *s2) +FcLangContains (const FcChar8 *super, const FcChar8 *sub) { FcChar8 c1, c2; for (;;) { - c1 = *s1++; - c2 = *s2++; + c1 = *super++; + c2 = *sub++; c1 = FcToLower (c1); c2 = FcToLower (c2); if (c1 != c2) { - /* see if s1 has a country while s2 is mising one */ + /* see if super has a country while sub is mising one */ if (c1 == '-' && c2 == '\0') return FcTrue; + /* see if sub has a country while super is mising one */ + if (c1 == '\0' && c2 == '-') + return FcTrue; return FcFalse; } else if (!c1) diff --git a/src/fclist.c b/src/fclist.c index 47a2f04..0885c93 100644 --- a/src/fclist.c +++ b/src/fclist.c @@ -120,17 +120,33 @@ FcObjectSetBuild (const char *first, ...) return os; } +/* + * Font must have a containing value for every value in the pattern + */ static FcBool -FcListValueListMatchAny (FcValueList *v1orig, - FcValueList *v2orig) +FcListValueListMatchAny (FcValueList *patOrig, /* pattern */ + FcValueList *fntOrig) /* font */ { - FcValueList *v1, *v2; + FcValueList *pat, *fnt; - for (v1 = v1orig; v1; v1 = v1->next) - for (v2 = v2orig; v2; v2 = v2->next) - if (FcConfigCompareValue (v1->value, FcOpContains, v2->value)) - return FcTrue; - return FcFalse; + for (pat = patOrig; pat; pat = pat->next) + { + for (fnt = fntOrig; fnt; fnt = fnt->next) + { + /* + * make sure the font 'contains' the pattern. + * (OpListing is OpContains except for strings + * where it requires an exact match) + */ + if (FcConfigCompareValue (fnt->value, + FcOpListing, + pat->value)) + break; + } + if (!fnt) + return FcFalse; + } + return FcTrue; } static FcBool @@ -196,7 +212,8 @@ FcListPatternMatchAny (FcPattern *p, e = FcPatternFindElt (font, p->elts[i].object); if (!e) return FcFalse; - if (!FcListValueListMatchAny (p->elts[i].values, e->values)) + if (!FcListValueListMatchAny (p->elts[i].values, /* pat elts */ + e->values)) /* font elts */ return FcFalse; } return FcTrue; @@ -415,7 +432,8 @@ FcFontSetList (FcConfig *config, if (!s) continue; for (f = 0; f < s->nfont; f++) - if (FcListPatternMatchAny (p, s->fonts[f])) + if (FcListPatternMatchAny (p, /* pattern */ + s->fonts[f])) /* font */ if (!FcListAppend (&table, s->fonts[f], os)) goto bail1; } diff --git a/src/fcxml.c b/src/fcxml.c index acb1bac..65af503 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -243,6 +243,7 @@ FcExprDestroy (FcExpr *e) case FcOpMore: case FcOpMoreEqual: case FcOpContains: + case FcOpListing: case FcOpNotContains: case FcOpPlus: case FcOpMinus: