]> git.wh0rd.org - fontconfig.git/blobdiff - src/fclang.c
Add *NeededBytesAlign(), which overestimates the padding which is later
[fontconfig.git] / src / fclang.c
index fabf36a15d7c15584e9a0840c2dbf5948c57c5ed..5518821d003c310e441d98b04a94508d674a3bd4 100644 (file)
@@ -25,8 +25,8 @@
 #include "fcint.h"
 
 typedef struct {
-    FcChar8    *lang;
-    FcCharSet  charset;
+    const FcChar8      *lang;
+    const FcCharSet    charset;
 } FcLangCharSet;
 
 typedef struct {
@@ -44,15 +44,22 @@ struct _FcLangSet {
 #define FcLangSetBitSet(ls, id)        ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f)))
 #define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1)
 
+static FcBool langsets_populated = FcFalse;
+
 FcLangSet *
 FcFreeTypeLangSet (const FcCharSet  *charset, 
                   const FcChar8    *exclusiveLang)
 {
-    int                    i;
+    int                    i, j;
     FcChar32       missing;
     const FcCharSet *exclusiveCharset = 0;
     FcLangSet      *ls;
-    
+
+    if (!langsets_populated)
+    {
+        FcLangCharSetPopulate ();
+        langsets_populated = FcTrue;
+    }
 
     if (exclusiveLang)
        exclusiveCharset = FcCharSetForLang (exclusiveLang);
@@ -67,10 +74,15 @@ FcFreeTypeLangSet (const FcCharSet  *charset,
         * not support other Han languages
         */
        if (exclusiveCharset &&
-           FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang) &&
-           fcLangCharSets[i].charset.leaves != exclusiveCharset->leaves)
+           FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang))
        {
-           continue;
+           if (fcLangCharSets[i].charset.num != exclusiveCharset->num)
+               continue;
+
+           for (j = 0; j < fcLangCharSets[i].charset.num; j++)
+               if (FcCharSetGetLeaf(&fcLangCharSets[i].charset, j) != 
+                   FcCharSetGetLeaf(exclusiveCharset, j))
+                   continue;
        }
        missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset);
         if (FcDebug() & FC_DBG_SCANV)
@@ -183,6 +195,13 @@ FcCharSetForLang (const FcChar8 *lang)
 {
     int                i;
     int                country = -1;
+
+    if (!langsets_populated)
+    {
+        FcLangCharSetPopulate ();
+        langsets_populated = FcTrue;
+    }
+
     for (i = 0; i < NUM_LANG_CHAR_SET; i++)
     {
        switch (FcLangCompare (lang, fcLangCharSets[i].lang)) {
@@ -684,3 +703,91 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb)
     }
     return FcTrue;
 }
+
+static FcLangSet ** langsets = 0;
+static int langset_bank_count = 0, langset_ptr = 0, langset_count = 0;
+
+void
+FcLangSetNewBank (void)
+{
+    langset_count = 0;
+}
+
+/* ideally, should only write one copy of any particular FcLangSet */
+int
+FcLangSetNeededBytes (const FcLangSet *l)
+{
+    langset_count++;
+    return sizeof (FcLangSet);
+}
+
+int
+FcLangSetNeededBytesAlign (void)
+{
+    return __alignof__ (FcLangSet);
+}
+
+static FcBool
+FcLangSetEnsureBank (int bi)
+{
+    if (!langsets || bi >= langset_bank_count)
+    {
+       int new_count = langset_bank_count + 2;
+       int i;
+       FcLangSet** tt;
+       tt = realloc(langsets, new_count * sizeof(FcLangSet *));
+       if (!tt)
+           return FcFalse;
+
+       langsets = tt;
+       for (i = langset_bank_count; i < new_count; i++)
+           langsets[i] = 0; 
+       langset_bank_count = new_count;
+    }
+
+    return FcTrue;
+}
+
+void *
+FcLangSetDistributeBytes (FcCache * metadata, void * block_ptr)
+{
+    int bi = FcCacheBankToIndex(metadata->bank);
+    if (!FcLangSetEnsureBank(bi))
+       return 0;
+
+    block_ptr = ALIGN(block_ptr, FcLangSet);
+    langsets[bi] = block_ptr;
+    block_ptr = (void *)((char *)block_ptr +
+                        langset_count * sizeof(FcLangSet));
+    langset_ptr = 0;
+    metadata->langset_count = langset_count;
+    return block_ptr;
+}
+
+FcLangSet *
+FcLangSetSerialize(int bank, FcLangSet *l)
+{
+    int p = langset_ptr, bi = FcCacheBankToIndex(bank);
+
+    if (!l) return 0;
+
+    langsets[bi][langset_ptr] = *l;
+    langsets[bi][langset_ptr].extra = 0;
+    langset_ptr++;
+    return &langsets[bi][p];
+}
+
+void *
+FcLangSetUnserialize (FcCache metadata, void *block_ptr)
+{
+    int bi = FcCacheBankToIndex(metadata.bank);
+    if (!FcLangSetEnsureBank(bi))
+       return 0;
+
+    FcMemAlloc (FC_MEM_LANGSET, metadata.langset_count * sizeof(FcLangSet));
+    block_ptr = ALIGN(block_ptr, FcLangSet);
+    langsets[bi] = (FcLangSet *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr +
+                        metadata.langset_count * sizeof(FcLangSet));
+    return block_ptr;
+}