]> git.wh0rd.org - fontconfig.git/blobdiff - src/fclang.c
[lang] Fix serializing LangSet from older versions
[fontconfig.git] / src / fclang.c
index 9d1858de2031dd01afba970ed3e3ddee195c417f..1d62c4e3f52960852614ce8ff4c9e8d4ca8305f1 100644 (file)
@@ -38,12 +38,38 @@ typedef struct {
 #include "../fc-lang/fclang.h"
 
 struct _FcLangSet {
-    FcChar32   map[NUM_LANG_SET_MAP];
     FcStrSet   *extra;
+    FcChar32    map_size;
+    FcChar32   map[NUM_LANG_SET_MAP];
 };
 
-#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)
+static void
+FcLangSetBitSet (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));
+}
+
+static FcBool
+FcLangSetBitGet (const FcLangSet *ls,
+                unsigned int     id)
+{
+  int bucket;
+
+  id = fcLangCharSetIndices[id];
+  bucket = id >> 5;
+  if (bucket >= ls->map_size)
+    return FcFalse;
+
+  return ((ls->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse;
+}
 
 FcLangSet *
 FcFreeTypeLangSet (const FcCharSet  *charset, 
@@ -61,7 +87,7 @@ FcFreeTypeLangSet (const FcCharSet  *charset,
        return 0;
     if (FcDebug() & FC_DBG_LANGSET) 
     {
-       printf ("font charset\n");
+       printf ("font charset");
        FcCharSetPrint (charset);
        printf ("\n");
     }
@@ -69,7 +95,7 @@ FcFreeTypeLangSet (const FcCharSet  *charset,
     {
        if (FcDebug() & FC_DBG_LANGSET) 
        {
-           printf ("%s charset\n", fcLangCharSets[i].lang);
+           printf ("%s charset", fcLangCharSets[i].lang);
            FcCharSetPrint (&fcLangCharSets[i].charset);
            printf ("\n");
        }
@@ -210,6 +236,7 @@ FcLangGetCharSet (const FcChar8 *lang)
        case FcLangDifferentTerritory:
            if (country == -1)
                country = i;
+       case FcLangDifferentLang:
        default:
            break;
        }
@@ -245,6 +272,7 @@ FcLangSetCreate (void)
        return 0;
     FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet));
     memset (ls->map, '\0', sizeof (ls->map));
+    ls->map_size = NUM_LANG_SET_MAP;
     ls->extra = 0;
     return ls;
 }
@@ -266,7 +294,8 @@ FcLangSetCopy (const FcLangSet *ls)
     new = FcLangSetCreate ();
     if (!new)
        goto bail0;
-    memcpy (new->map, ls->map, sizeof (new->map));
+    memset (new->map, '\0', sizeof (new->map));
+    memcpy (new->map, ls->map, FC_MIN (sizeof (new->map), ls->map_size * sizeof (ls->map[0])));
     if (ls->extra)
     {
        FcStrList       *list;
@@ -442,15 +471,17 @@ FcLangSetCompareStrSet (const FcLangSet *ls, FcStrSet *set)
 FcLangResult
 FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb)
 {
-    int                    i, j;
+    int                    i, j, count;
     FcLangResult    best, r;
 
-    for (i = 0; i < NUM_LANG_SET_MAP; i++)
+    count = FC_MIN (lsa->map_size, lsb->map_size);
+    count = FC_MIN (NUM_LANG_SET_MAP, count);
+    for (i = 0; i < count; i++)
        if (lsa->map[i] & lsb->map[i])
            return FcLangEqual;
     best = FcLangDifferentLang;
     for (j = 0; j < NUM_COUNTRY_SET; j++)
-       for (i = 0; i < NUM_LANG_SET_MAP; i++)
+       for (i = 0; i < count; i++)
            if ((lsa->map[i] & fcLangCountrySets[j][i]) &&
                (lsb->map[i] & fcLangCountrySets[j][i]))
            {
@@ -506,9 +537,10 @@ FcChar32
 FcLangSetHash (const FcLangSet *ls)
 {
     FcChar32   h = 0;
-    int                i;
+    int                i, count;
 
-    for (i = 0; i < NUM_LANG_SET_MAP; i++)
+    count = FC_MIN (ls->map_size, NUM_LANG_SET_MAP);
+    for (i = 0; i < count; i++)
        h ^= ls->map[i];
     if (ls->extra)
        h ^= ls->extra->num;
@@ -518,7 +550,7 @@ FcLangSetHash (const FcLangSet *ls)
 FcLangSet *
 FcNameParseLangSet (const FcChar8 *string)
 {
-    FcChar8        lang[32],c;
+    FcChar8        lang[32], c = 0;
     int i;
     FcLangSet      *ls;
 
@@ -551,20 +583,28 @@ bail0:
 FcBool
 FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls)
 {
-    int                i;
+    int                i, bit, count;
+    FcChar32   bits;
     FcBool     first = FcTrue;
 
-    for (i = 0; i < NUM_LANG_CHAR_SET; i++)
-       if (FcLangSetBitGet (ls, i))
-           {
-               if (!first)
-                   if (!FcStrBufChar (buf, '|'))
+    count = FC_MIN (ls->map_size, NUM_LANG_SET_MAP);
+    for (i = 0; i < count; 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[fcLangCharSetIndicesInv[id]].lang))
                        return FcFalse;
-               if (!FcStrBufString (buf, fcLangCharSets[i].lang))
-                   return FcFalse;
-               first = FcFalse;
-           }
-
+                   first = FcFalse;
+               }
+       }
+    }
     if (ls->extra)
     {
        FcStrList   *list = FcStrListCreate (ls->extra);
@@ -595,9 +635,11 @@ FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls)
 FcBool
 FcLangSetEqual (const FcLangSet *lsa, const FcLangSet *lsb)
 {
-    int            i;
+    int            i, count;
 
-    for (i = 0; i < NUM_LANG_SET_MAP; i++)
+    count = FC_MIN (lsa->map_size, lsb->map_size);
+    count = FC_MIN (NUM_LANG_SET_MAP, count);
+    for (i = 0; i < count; i++)
     {
        if (lsa->map[i] != lsb->map[i])
            return FcFalse;
@@ -665,7 +707,7 @@ FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang)
 FcBool
 FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
 {
-    int                    i, j;
+    int                    i, j, count;
     FcChar32       missing;
 
     if (FcDebug() & FC_DBG_MATCHV)
@@ -677,7 +719,9 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
     /*
      * check bitmaps for missing language support
      */
-    for (i = 0; i < NUM_LANG_SET_MAP; i++)
+    count = FC_MIN (lsa->map_size, lsb->map_size);
+    count = FC_MIN (NUM_LANG_SET_MAP, count);
+    for (i = 0; i < count; i++)
     {
        missing = lsb->map[i] & ~lsa->map[i];
        if (missing)
@@ -686,10 +730,10 @@ 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;
                    }
                }
@@ -734,7 +778,10 @@ FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l)
 
     if (!l_serialize)
        return NULL;
-    *l_serialize = *l;
+    memset (l_serialize->map, '\0', sizeof (l_serialize->map));
+    memcpy (l_serialize->map, l->map, FC_MIN (sizeof (l_serialize->map), l->map_size * sizeof (l->map[0])));
+    l_serialize->map_size = NUM_LANG_SET_MAP;
+    l_serialize->extra = NULL; /* We don't serialize ls->extra */
     return l_serialize;
 }