]> git.wh0rd.org - fontconfig.git/blobdiff - src/fclang.c
Bug 23419 - "contains" expression seems not working on the fontconfig rule
[fontconfig.git] / src / fclang.c
index 28b2d9b9c6965755b72b80981da54eafc7d3b1b3..6a3b7b5e3dbd44a71d9b54ae44a51561ea5556a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $RCSId: xc/lib/fontconfig/src/fclang.c,v 1.7 2002/08/26 23:34:31 keithp Exp $
+ * fontconfig/src/fclang.c
  *
  * Copyright © 2002 Keith Packard
  *
  * representations about the suitability of this software for any purpose.  It
  * is provided "as is" without express or implied warranty.
  *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <fcntl.h>
-#include <sys/mman.h>
 #include "fcint.h"
+#include "fcftint.h"
 
 typedef struct {
-    FcChar8    *lang;
-    FcCharSet  charset;
+    const FcChar8      lang[8];
+    const FcCharSet    charset;
 } FcLangCharSet;
 
 typedef struct {
@@ -40,11 +39,11 @@ typedef struct {
 
 struct _FcLangSet {
     FcChar32   map[NUM_LANG_SET_MAP];
-    FcStrSetPtr        extra;
+    FcStrSet   *extra;
 };
 
-#define FcLangSetBitSet(ls, id)        ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
-#define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
+#define FcLangSetBitSet(ls, id)        ((ls)->map[(fcLangCharSetIndices[id])>>5] |= ((FcChar32) 1 << ((fcLangCharSetIndices[id]) & 0x1f)))
+#define FcLangSetBitGet(ls, id) (((ls)->map[(fcLangCharSetIndices[id])>>5] >> ((fcLangCharSetIndices[id]) & 0x1f)) & 1)
 
 FcLangSet *
 FcFreeTypeLangSet (const FcCharSet  *charset, 
@@ -54,15 +53,27 @@ FcFreeTypeLangSet (const FcCharSet  *charset,
     FcChar32       missing;
     const FcCharSet *exclusiveCharset = 0;
     FcLangSet      *ls;
-    
 
     if (exclusiveLang)
-       exclusiveCharset = FcCharSetForLang (exclusiveLang);
+       exclusiveCharset = FcLangGetCharSet (exclusiveLang);
     ls = FcLangSetCreate ();
     if (!ls)
        return 0;
+    if (FcDebug() & FC_DBG_LANGSET) 
+    {
+       printf ("font charset");
+       FcCharSetPrint (charset);
+       printf ("\n");
+    }
     for (i = 0; i < NUM_LANG_CHAR_SET; i++)
     {
+       if (FcDebug() & FC_DBG_LANGSET) 
+       {
+           printf ("%s charset", fcLangCharSets[i].lang);
+           FcCharSetPrint (&fcLangCharSets[i].charset);
+           printf ("\n");
+       }
+       
        /*
         * Check for Han charsets to make fonts
         * which advertise support for a single language
@@ -75,8 +86,8 @@ FcFreeTypeLangSet (const FcCharSet  *charset,
                continue;
 
            for (j = 0; j < fcLangCharSets[i].charset.num; j++)
-               if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) != 
-                   FcCharSetGetLeaf(exclusiveCharset, j))
+               if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != 
+                   FcCharSetLeaf(exclusiveCharset, j))
                    continue;
        }
        missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
@@ -90,7 +101,7 @@ FcFreeTypeLangSet (const FcCharSet  *charset,
                FcChar32    map[FC_CHARSET_MAP_SIZE];
                FcChar32    next;
 
-               printf ("\n%s(%d) ", fcLangCharSets[i].lang, missing);
+               printf ("\n%s(%u) ", fcLangCharSets[i].lang, missing);
                printf ("{");
                for (ucs4 = FcCharSetFirstPage (missed, map, &next);
                     ucs4 != FC_CHARSET_DONE;
@@ -109,7 +120,7 @@ FcFreeTypeLangSet (const FcCharSet  *charset,
                FcCharSetDestroy (missed);
            }
            else
-               printf ("%s(%d) ", fcLangCharSets[i].lang, missing);
+               printf ("%s(%u) ", fcLangCharSets[i].lang, missing);
        }
        if (!missing)
            FcLangSetBitSet (ls, i);
@@ -140,13 +151,13 @@ FcLangCompare (const FcChar8 *s1, const FcChar8 *s2)
        if (c1 != c2)
        {
            if (FcLangEnd (c1) && FcLangEnd (c2))
-               result = FcLangDifferentCountry;
+               result = FcLangDifferentTerritory;
            return result;
        }
        else if (!c1)
            return FcLangEqual;
        else if (c1 == '-')
-           result = FcLangDifferentCountry;
+           result = FcLangDifferentTerritory;
     }
 }
 
@@ -186,16 +197,17 @@ FcLangContains (const FcChar8 *super, const FcChar8 *sub)
 }
 
 const FcCharSet *
-FcCharSetForLang (const FcChar8 *lang)
+FcLangGetCharSet (const FcChar8 *lang)
 {
     int                i;
     int                country = -1;
+
     for (i = 0; i < NUM_LANG_CHAR_SET; i++)
     {
        switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
        case FcLangEqual:
            return &fcLangCharSets[i].charset;
-       case FcLangDifferentCountry:
+       case FcLangDifferentTerritory:
            if (country == -1)
                country = i;
        default:
@@ -204,7 +216,23 @@ FcCharSetForLang (const FcChar8 *lang)
     }
     if (country == -1)
        return 0;
-    return &fcLangCharSets[i].charset;
+    return &fcLangCharSets[country].charset;
+}
+
+FcStrSet *
+FcGetLangs (void)
+{
+    FcStrSet *langs;
+    int        i;
+
+    langs = FcStrSetCreate();
+    if (!langs)
+       return 0;
+
+    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
+       FcStrSetAdd (langs, fcLangCharSets[i].lang);
+
+    return langs;
 }
 
 FcLangSet *
@@ -217,22 +245,15 @@ FcLangSetCreate (void)
        return 0;
     FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet));
     memset (ls->map, '\0', sizeof (ls->map));
-    ls->extra = FcStrSetPtrCreateDynamic(0);
+    ls->extra = 0;
     return ls;
 }
 
-void
-FcLangSetPtrDestroy (FcLangSetPtr li)
-{
-    if (li.storage == FcStorageDynamic)
-       FcLangSetDestroy(FcLangSetPtrU(li));
-}
-
 void
 FcLangSetDestroy (FcLangSet *ls)
 {
-    if (FcStrSetPtrU(ls->extra))
-       FcStrSetDestroy (FcStrSetPtrU(ls->extra));
+    if (ls->extra)
+       FcStrSetDestroy (ls->extra);
     FcMemFree (FC_MEM_LANGSET, sizeof (FcLangSet));
     free (ls);
 }
@@ -246,21 +267,21 @@ FcLangSetCopy (const FcLangSet *ls)
     if (!new)
        goto bail0;
     memcpy (new->map, ls->map, sizeof (new->map));
-    if (FcStrSetPtrU(ls->extra))
+    if (ls->extra)
     {
        FcStrList       *list;
        FcChar8         *extra;
        
-       new->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
-       if (!FcStrSetPtrU(new->extra))
+       new->extra = FcStrSetCreate ();
+       if (!new->extra)
            goto bail1;
 
-       list = FcStrListCreate (FcStrSetPtrU(ls->extra));
+       list = FcStrListCreate (ls->extra);     
        if (!list)
            goto bail1;
        
        while ((extra = FcStrListNext (list)))
-           if (!FcStrSetAdd (FcStrSetPtrU(new->extra), extra))
+           if (!FcStrSetAdd (new->extra, extra))
            {
                FcStrListDone (list);
                goto bail1;
@@ -341,13 +362,13 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang)
        FcLangSetBitSet (ls, id);
        return FcTrue;
     }
-    if (!FcStrSetPtrU(ls->extra))
+    if (!ls->extra)
     {
-       ls->extra = FcStrSetPtrCreateDynamic(FcStrSetCreate ());
-       if (!FcStrSetPtrU(ls->extra))
+       ls->extra = FcStrSetCreate ();
+       if (!ls->extra)
            return FcFalse;
     }
-    return FcStrSetAdd (FcStrSetPtrU(ls->extra), lang);
+    return FcStrSetAdd (ls->extra, lang);
 }
 
 FcLangResult
@@ -379,11 +400,10 @@ FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang)
        if (FcLangSetBitGet (ls, i) && r < best)
            best = r;
     }
-    if (FcStrSetPtrU(ls->extra))
+    if (ls->extra)
     {
-       FcStrList       *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
+       FcStrList       *list = FcStrListCreate (ls->extra);
        FcChar8         *extra;
-       FcLangResult    r;
        
        if (list)
        {
@@ -434,18 +454,18 @@ FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb)
            if ((lsa->map[i] & fcLangCountrySets[j][i]) &&
                (lsb->map[i] & fcLangCountrySets[j][i]))
            {
-               best = FcLangDifferentCountry;
+               best = FcLangDifferentTerritory;
                break;
            }
-    if (FcStrSetPtrU(lsa->extra))
+    if (lsa->extra)
     {
-       r = FcLangSetCompareStrSet (lsb, FcStrSetPtrU(lsa->extra));
+       r = FcLangSetCompareStrSet (lsb, lsa->extra);
        if (r < best)
            best = r;
     }
-    if (best > FcLangEqual && FcStrSetPtrU(lsb->extra))
+    if (best > FcLangEqual && lsb->extra)
     {
-       r = FcLangSetCompareStrSet (lsa, FcStrSetPtrU(lsb->extra));
+       r = FcLangSetCompareStrSet (lsa, lsb->extra);
        if (r < best)
            best = r;
     }
@@ -464,7 +484,7 @@ FcLangSetPromote (const FcChar8 *lang)
     int                        id;
 
     memset (ls.map, '\0', sizeof (ls.map));
-    ls.extra = FcStrSetPtrCreateDynamic(0);
+    ls.extra = 0;
     id = FcLangSetIndex (lang);
     if (id > 0)
     {
@@ -472,11 +492,10 @@ FcLangSetPromote (const FcChar8 *lang)
     }
     else
     {
-       ls.extra = FcStrSetPtrCreateDynamic(&strs);
+       ls.extra = &strs;
        strs.num = 1;
        strs.size = 1;
-       strs.storage = FcStorageDynamic;
-       strs.u.strs = &str;
+       strs.strs = &str;
        strs.ref = 1;
        str = (FcChar8 *) lang;
     }
@@ -491,8 +510,8 @@ FcLangSetHash (const FcLangSet *ls)
 
     for (i = 0; i < NUM_LANG_SET_MAP; i++)
        h ^= ls->map[i];
-    if (FcStrSetPtrU(ls->extra))
-       h ^= FcStrSetPtrU(ls->extra)->num;
+    if (ls->extra)
+       h ^= ls->extra->num;
     return h;
 }
 
@@ -532,30 +551,23 @@ bail0:
 FcBool
 FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls)
 {
-    int                i, bit;
-    FcChar32   bits;
+    int                i;
     FcBool     first = FcTrue;
 
-    for (i = 0; i < NUM_LANG_SET_MAP; i++)
-    {
-       if ((bits = ls->map[i]))
-       {
-           for (bit = 0; bit <= 31; bit++)
-               if (bits & (1 << bit))
-               {
-                   int id = (i << 5) | bit;
-                   if (!first)
-                       if (!FcStrBufChar (buf, '|'))
-                           return FcFalse;
-                   if (!FcStrBufString (buf, fcLangCharSets[id].lang))
+    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
+       if (FcLangSetBitGet (ls, i))
+           {
+               if (!first)
+                   if (!FcStrBufChar (buf, '|'))
                        return FcFalse;
-                   first = FcFalse;
-               }
-       }
-    }
-    if (FcStrSetPtrU(ls->extra))
+               if (!FcStrBufString (buf, fcLangCharSets[i].lang))
+                   return FcFalse;
+               first = FcFalse;
+           }
+
+    if (ls->extra)
     {
-       FcStrList   *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
+       FcStrList   *list = FcStrListCreate (ls->extra);
        FcChar8     *extra;
 
        if (!list)
@@ -564,11 +576,18 @@ FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls)
        {
            if (!first)
                if (!FcStrBufChar (buf, '|'))
+                {
+                    FcStrListDone (list);
                    return FcFalse;
+                }
            if (!FcStrBufString (buf, extra))
-               return FcFalse;
+                {
+                    FcStrListDone (list);
+                    return FcFalse;
+                }
            first = FcFalse;
        }
+        FcStrListDone (list);
     }
     return FcTrue;
 }
@@ -583,10 +602,10 @@ FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb)
        if (lsa->map[i] != lsb->map[i])
            return FcFalse;
     }
-    if (!FcStrSetPtrU(lsa->extra) && !FcStrSetPtrU(lsb->extra))
+    if (!lsa->extra && !lsb->extra)
        return FcTrue;
-    if (FcStrSetPtrU(lsa->extra) && FcStrSetPtrU(lsb->extra))
-       return FcStrSetEqual (FcStrSetPtrU(lsa->extra), FcStrSetPtrU(lsb->extra));
+    if (lsa->extra && lsb->extra)
+       return FcStrSetEqual (lsa->extra, lsb->extra);
     return FcFalse;
 }
 
@@ -620,9 +639,9 @@ FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang)
            FcLangContains (fcLangCharSets[i].lang, lang))
            return FcTrue;
     }
-    if (FcStrSetPtrU(ls->extra))
+    if (ls->extra)
     {
-       FcStrList       *list = FcStrListCreate (FcStrSetPtrU(ls->extra));
+       FcStrList       *list = FcStrListCreate (ls->extra);
        FcChar8         *extra;
        
        if (list)
@@ -667,18 +686,18 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
                if (missing & (1 << j)) 
                {
                    if (!FcLangSetContainsLang (lsa,
-                                               fcLangCharSets[i*32 + j].lang))
+                                               fcLangCharSets[fcLangCharSetIndicesInv[i*32 + j]].lang))
                    {
                        if (FcDebug() & FC_DBG_MATCHV)
-                           printf ("\tMissing bitmap %s\n", fcLangCharSets[i*32+j].lang);
+                           printf ("\tMissing bitmap %s\n", fcLangCharSets[fcLangCharSetIndicesInv[i*32+j]].lang);
                        return FcFalse;
                    }
                }
        }
     }
-    if (FcStrSetPtrU(lsb->extra))
+    if (lsb->extra)
     {
-       FcStrList   *list = FcStrListCreate (FcStrSetPtrU(lsb->extra));
+       FcStrList   *list = FcStrListCreate (lsb->extra);
        FcChar8     *extra;
 
        if (list)
@@ -700,77 +719,57 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
     return FcTrue;
 }
 
-static FcLangSet * langsets = 0;
-static int langset_ptr = 0, langset_count = 0;
-
-FcLangSet *
-FcLangSetPtrU (FcLangSetPtr li)
+FcBool
+FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l)
 {
-    switch (li.storage)
-    {
-    case FcStorageDynamic:
-       return li.u.dyn;
-    case FcStorageStatic:
-       return &langsets[li.u.stat];
-    default:
-       return 0;
-
-    }
+    if (!FcSerializeAlloc (serialize, l, sizeof (FcLangSet)))
+       return FcFalse;
+    return FcTrue;
 }
 
-FcLangSetPtr
-FcLangSetPtrCreateDynamic (FcLangSet *li)
+FcLangSet *
+FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l)
 {
-    FcLangSetPtr new;
-    new.storage = FcStorageDynamic;
-    new.u.dyn = li;
-    return new;
-}
+    FcLangSet  *l_serialize = FcSerializePtr (serialize, l);
 
-void
-FcLangSetClearStatic (void)
-{
-    FcStrSetClearStatic();
-    langset_ptr = 0;
-    langset_count = 0;
+    if (!l_serialize)
+       return NULL;
+    *l_serialize = *l;
+    return l_serialize;
 }
 
-/* should only write one copy of any particular FcLangSet */
-FcBool
-FcLangSetPrepareSerialize (FcLangSet *l)
+FcStrSet *
+FcLangSetGetLangs (const FcLangSet *ls)
 {
-    langset_count++;
-    if (l && FcStrSetPtrU(l->extra))
-       return FcStrSetPrepareSerialize (FcStrSetPtrU(l->extra));
-    return FcTrue;
-}
+    FcStrSet *langs;
+    int              i;
 
-FcLangSetPtr
-FcLangSetSerialize(FcLangSet *l)
-{
-    FcLangSetPtr new;
-    int p = langset_ptr;
+    langs = FcStrSetCreate();
+    if (!langs)
+       return 0;
 
-    if (!l) return FcLangSetPtrCreateDynamic(0);
+    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
+       if (FcLangSetBitGet (ls, i))
+           FcStrSetAdd (langs, fcLangCharSets[i].lang);
 
-    if (!langsets)
+    if (ls->extra)
     {
-       FcLangSet* t;
-       t = (FcLangSet *)malloc(langset_count * sizeof(FcLangSet));
-       if (!t)
-           return FcLangSetPtrCreateDynamic(0);
-       langsets = t;
-       langset_ptr = 0;
+       FcStrList       *list = FcStrListCreate (ls->extra);
+       FcChar8         *extra;
+
+       if (list)
+       {
+           while ((extra = FcStrListNext (list)))
+               FcStrSetAdd (langs, extra);
+
+           FcStrListDone (list);
+       }
     }
 
-    langsets[langset_ptr] = *l;
-    if (FcStrSetPtrU(l->extra))
-       langsets[langset_ptr].extra = 
-           FcStrSetSerialize(FcStrSetPtrU(l->extra));
-    else
-       langsets[langset_ptr].extra = FcStrSetPtrCreateDynamic(0);
-    langset_ptr++;
-    new.storage = FcStorageStatic;
-    new.u.stat = p;
-    return new;
+    return langs;
 }
+
+#define __fclang__
+#include "fcaliastail.h"
+#include "fcftaliastail.h"
+#undef __fclang__