]> git.wh0rd.org Git - fontconfig.git/commitdiff
Implement new semantics for Contains and LISTING:
authorKeith Packard <keithp@keithp.com>
Sun, 20 Jul 2003 16:06:18 +0000 (16:06 +0000)
committerKeith Packard <keithp@keithp.com>
Sun, 20 Jul 2003 16:06:18 +0000 (16:06 +0000)
LISTING requires that the font Contain all of the pattern values, where
    Contain is redefined for strings to mean precise matching (so that
    Courier 10 Pitch doesn't list Courier fonts)
"Contains" for lang means both langs have the same language and either the
    same country or one is missing the country

src/fccfg.c
src/fcdbg.c
src/fcint.h
src/fclang.c
src/fclist.c
src/fcxml.c

index fd87cb6ea0d0578d071a08b4ac61cc0888c3d0ff..7b5d693b4a54f97bcd8c87c4b58f94a9534f6e85 100644 (file)
@@ -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)
index 8d4439b944b7931c01f73606e4ca78fa0bfcfabf..00c034470db2273d45960fe41c0472810abe12e0 100644 (file)
@@ -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;
index 790f0ba0f05d07aee6a04416a18433009d5d4e90..926111e8fc08398f4cfb441b75a4ae401af4f3e9 100644 (file)
@@ -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,
index 53f2b5982b47400ca6a2ce986fb91b0953cddb17..582b92b54f9054789eb231f5eea5d09ac013b4f9 100644 (file)
@@ -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)
index 47a2f04dc675ea315ed110053b704f46faadc74c..0885c933dd592547cb5b6ebd30ea03fbe6aa362b 100644 (file)
@@ -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;
     }
index acb1bac6df9b13aad291986dbcc7e8c0d0aae844..65af5039b99f1ead14d8d4085e1e623122fa0ef8 100644 (file)
@@ -243,6 +243,7 @@ FcExprDestroy (FcExpr *e)
     case FcOpMore:
     case FcOpMoreEqual:
     case FcOpContains:
+    case FcOpListing:
     case FcOpNotContains:
     case FcOpPlus:
     case FcOpMinus: