]> git.wh0rd.org - fontconfig.git/blobdiff - src/fccharset.c
Include $(top_srcdir), $(top_srcdir)/src before anything else.
[fontconfig.git] / src / fccharset.c
index 6c6f0f5d79b247f32824a75aaa9d952562f87a48..e0a09612859857e4bd557d3ebff890b62f2d8c0f 100644 (file)
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-#include <stdlib.h>
 #include "fcint.h"
+#include <stdlib.h>
 
 /* #define CHECK */
 
 /* #define CHATTY */
 
-static FcCharSet * charsets = 0;
-static FcChar16 * numbers = 0;
-static int charset_ptr, charset_count;
+static FcCharSet ** charsets = 0;
+static FcChar16 ** numbers = 0;
+static int charset_bank_count = 0, charset_ptr, charset_count;
 static int charset_numbers_ptr, charset_numbers_count;
-static FcCharLeaf * leaves = 0;
+static FcCharLeaf ** leaves = 0;
 static int charset_leaf_ptr, charset_leaf_count;
-static int * leaf_idx = 0;
+static int ** leaf_idx = 0;
 static int charset_leaf_idx_ptr, charset_leaf_idx_count;
 
+extern const FcChar16 langBankNumbers[];
+extern const FcCharLeaf        langBankLeaves[];
+extern const int langBankLeafIdx[];
+
+static FcBool
+FcCharSetEnsureBank (int bi);
+
 void
-FcCharSetClearStatic()
+FcLangCharSetPopulate (void)
 {
-    charsets = 0;
-    numbers = 0;
-    charset_ptr = 0; charset_count = 0;
-    leaves = 0;
-    charset_leaf_ptr = 0; charset_leaf_count = 0;
-    leaf_idx = 0;
-    charset_leaf_idx_ptr = 0; charset_leaf_idx_count = 0;
+    int bi = FcCacheBankToIndexMTF (FC_BANK_LANGS);
+    FcCharSetEnsureBank (bi);
+    charsets[bi] = 0;
+    numbers[bi] = (FcChar16 *)langBankNumbers;
+    leaves[bi] = (FcCharLeaf *)langBankLeaves;
+    leaf_idx[bi] = (int *)langBankLeafIdx;
 }
 
 FcCharSet *
@@ -61,7 +67,7 @@ FcCharSetCreate (void)
     FcMemAlloc (FC_MEM_CHARSET, sizeof (FcCharSet));
     fcs->ref = 1;
     fcs->num = 0;
-    fcs->storage = FcStorageDynamic;
+    fcs->bank = FC_BANK_DYNAMIC;
     fcs->u.dyn.leaves = 0;
     fcs->u.dyn.numbers = 0;
     return fcs;
@@ -76,18 +82,6 @@ FcCharSetNew (void)
     return FcCharSetCreate ();
 }
 
-void
-FcCharSetPtrDestroy (FcCharSetPtr fcs)
-{
-    FcCharSetDestroy (FcCharSetPtrU(fcs));
-    if (fcs.storage == FcStorageDynamic && 
-       FcCharSetPtrU(fcs)->ref != FC_REF_CONSTANT)
-    {
-       free (fcs.u.dyn);
-       FcMemFree (FC_MEM_CHARSET, sizeof(FcCharSet));
-    }
-}
-
 void
 FcCharSetDestroy (FcCharSet *fcs)
 {
@@ -96,7 +90,7 @@ FcCharSetDestroy (FcCharSet *fcs)
        return;
     if (--fcs->ref > 0)
        return;
-    if (fcs->storage == FcStorageDynamic)
+    if (fcs->bank == FC_BANK_DYNAMIC)
     {
        for (i = 0; i < fcs->num; i++)
        {
@@ -172,8 +166,9 @@ FcCharSetPutLeaf (FcCharSet *fcs,
     ucs4 >>= 8;
     if (ucs4 >= 0x10000)
        return FcFalse;
-    if (fcs->storage == FcStorageStatic)
+    if (fcs->bank != FC_BANK_DYNAMIC)
     {
+        /* convert to dynamic */
        int i;
 
        leaves = malloc ((fcs->num + 1) * sizeof (FcCharLeaf *));
@@ -182,14 +177,20 @@ FcCharSetPutLeaf (FcCharSet       *fcs,
        FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcCharLeaf *));
        numbers = malloc ((fcs->num + 1) * sizeof (FcChar16));
        if (!numbers)
+        {
+           free (leaves);
            return FcFalse;
+        }
        FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16));
 
        for (i = 0; i < fcs->num; i++)
            leaves[i] = FcCharSetGetLeaf(fcs, i);
        memcpy (numbers, FcCharSetGetNumbers(fcs), 
                fcs->num * sizeof (FcChar16));
-       fcs->storage = FcStorageDynamic;
+
+       fcs->bank = FC_BANK_DYNAMIC;
+       fcs->u.dyn.leaves = leaves;
+       fcs->u.dyn.numbers = numbers;
     }
     else
     {
@@ -263,14 +264,15 @@ FcCharSetInsertLeaf (FcCharSet *fcs, FcChar32 ucs4, FcCharLeaf *leaf)
     if (pos >= 0)
     {
        FcMemFree (FC_MEM_CHARLEAF, sizeof (FcCharLeaf));
-       if (fcs->storage == FcStorageDynamic)
+       if (fcs->bank == FC_BANK_DYNAMIC)
        {
            free (fcs->u.dyn.leaves[pos]);
            fcs->u.dyn.leaves[pos] = leaf;
        }
        else
        {
-           leaves[leaf_idx[fcs->u.stat.leafidx_offset]+pos] = *leaf;
+           int bi = FcCacheBankToIndex(fcs->bank);
+           leaves[bi][leaf_idx[fcs->bank][fcs->u.stat.leafidx_offset]+pos] = *leaf;
        }
        return FcTrue;
     }
@@ -372,6 +374,7 @@ FcCharSetIterStart (const FcCharSet *fcs, FcCharSetIter *iter)
     FcCharSetDump (fcs);
 #endif
     iter->ucs4 = 0;
+    iter->pos = 0;
     FcCharSetIterSet (fcs, iter);
 }
 
@@ -625,7 +628,7 @@ FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b)
            int         i = 256/32;
            if (ai.ucs4 == bi.ucs4)
            {
-               FcChar32        *bm = bi.leaf->map;;
+               FcChar32        *bm = bi.leaf->map;
                while (i--)
                    count += FcCharSetPopCount (*am++ & ~*bm++);
            }
@@ -1017,7 +1020,7 @@ FcCharSetHash (FcCharSet *fcs)
     int                i;
 
     /* hash in leaves */
-    for (i = 0; i < fcs->num * sizeof (FcCharLeaf *) / sizeof (FcChar32); i++)
+    for (i = 0; i < fcs->num * (int) (sizeof (FcCharLeaf *) / sizeof (FcChar32)); i++)
        hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetGetLeaf(fcs, i)->map);
     /* hash in numbers */
     for (i = 0; i < fcs->num; i++)
@@ -1072,8 +1075,8 @@ FcCharSetFreezeBase (FcCharSet *fcs)
     
     ent->set.ref = FC_REF_CONSTANT;
     ent->set.num = fcs->num;
-    ent->set.storage = fcs->storage;
-    if (fcs->storage == FcStorageDynamic)
+    ent->set.bank = fcs->bank;
+    if (fcs->bank == FC_BANK_DYNAMIC)
     {
        if (fcs->num)
        {
@@ -1145,7 +1148,7 @@ FcCharSetFreeze (FcCharSet *fcs)
     }
     n = FcCharSetFreezeBase (b);
 bail1:
-    if (b->storage == FcStorageDynamic)
+    if (b->bank == FC_BANK_DYNAMIC)
     {
        if (b->u.dyn.leaves)
        {
@@ -1222,7 +1225,7 @@ FcNameParseCharSet (FcChar8 *string)
 #endif
     n = FcCharSetFreezeBase (c);
 bail1:
-    if (c->storage == FcStorageDynamic)
+    if (c->bank == FC_BANK_DYNAMIC)
     {
        if (c->u.dyn.leaves)
        {
@@ -1314,115 +1317,175 @@ FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c)
     return FcTrue;
 }
 
-
-FcCharSet *
-FcCharSetPtrU (FcCharSetPtr ci)
+void
+FcCharSetNewBank(void)
 {
-    switch (ci.storage)
-    {
-    case FcStorageDynamic:
-       return ci.u.dyn;
-    case FcStorageStatic:
-       return &charsets[ci.u.stat];
-    default:
-       return 0;
-    }
+    charset_count = 0;
+    charset_numbers_count = 0;
+    charset_leaf_count = 0;
+    charset_leaf_idx_count = 0;
 }
 
-FcCharSetPtr
-FcCharSetPtrCreateDynamic(FcCharSet *c)
+int
+FcCharSetNeededBytes (const FcCharSet *c)
 {
-    FcCharSetPtr new;
+    /* yes, there's redundancy */
+    charset_count++;
+    charset_leaf_idx_count += c->num;
+    charset_leaf_count += c->num;
+    charset_numbers_count += c->num;
+    return sizeof (FcCharSet) + 
+       sizeof (int) * c->num +         /* leaf_idx */
+       sizeof (FcCharLeaf) * c->num +  /* leaf */
+       sizeof (FcChar16) * c->num;     /* number */
+}
 
-    new.storage = FcStorageDynamic;
-    new.u.dyn = c;
-    return new;
+int
+FcCharSetNeededBytesAlign (void)
+{
+    return fc_alignof (FcCharSet) + fc_alignof (int) + 
+       fc_alignof (FcCharLeaf) + fc_alignof (FcChar16);
 }
 
-FcBool
-FcCharSetPrepareSerialize(FcCharSet *c)
+static FcBool
+FcCharSetEnsureBank (int bi)
 {
-    /* note the redundancy */
-    charset_count++;
-    charset_leaf_idx_count++;
-    charset_leaf_count += c->num;
-    charset_numbers_count += c->num;
+    if (!charsets || charset_bank_count <= bi)
+    {
+       int new_count = charset_bank_count + 2;
+       FcCharSet ** cs;
+       FcChar16 ** n;
+       FcCharLeaf ** lvs;
+       int ** lvi;
+       int i;
+       
+       cs = realloc(charsets, sizeof(FcCharSet*) * new_count);
+       if (!cs) return 0;
+       n = realloc(numbers, sizeof(FcChar16*) * new_count);
+       if (!n) return 0;
+       lvs = realloc(leaves, sizeof(FcCharLeaf*) * new_count);
+       if (!lvs) return 0;
+       lvi = realloc(leaf_idx, sizeof(int*) * new_count);
+       if (!lvi) return 0;
+
+       charsets = cs; numbers = n; leaves = lvs; leaf_idx = lvi;
+       for (i = charset_bank_count; i < new_count; i++)
+       {
+           charsets[i] = 0;
+           numbers[i] = 0;
+           leaves[i] = 0;
+           leaf_idx[i] = 0;
+       }
+       charset_bank_count = new_count;
+    }
     return FcTrue;
 }
 
-FcCharSetPtr
-FcCharSetSerialize(FcCharSet *c)
+void *
+FcCharSetDistributeBytes (FcCache * metadata, void * block_ptr)
+{
+    int bi = FcCacheBankToIndex(metadata->bank);
+    if (!FcCharSetEnsureBank(bi))
+       return 0;
+
+    block_ptr = ALIGN (block_ptr, FcCharSet);
+    charsets[bi] = (FcCharSet *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr + 
+                    (sizeof (FcCharSet) * charset_count));
+    block_ptr = ALIGN (block_ptr, FcChar16);
+    numbers[bi] = (FcChar16 *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr + 
+                    (sizeof(FcChar16) * charset_numbers_count));
+    block_ptr = ALIGN (block_ptr, FcCharLeaf);
+    leaves[bi] = (FcCharLeaf *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr +
+                    (sizeof(FcCharLeaf) * charset_leaf_count));
+    block_ptr = ALIGN (block_ptr, int);
+    leaf_idx[bi] = (int *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr +
+                    (sizeof(int) * charset_leaf_idx_count));
+
+    metadata->charset_count = charset_count;
+    metadata->charset_numbers_count = charset_numbers_count;
+    metadata->charset_leaf_count = charset_leaf_count;
+    metadata->charset_leaf_idx_count = charset_leaf_idx_count;
+    charset_ptr = 0; charset_leaf_ptr = 0;
+    charset_leaf_idx_ptr = 0; charset_numbers_ptr = 0;
+    return block_ptr;
+}
+
+FcCharSet *
+FcCharSetSerialize(int bank, FcCharSet *c)
 {
     int i;
-    FcCharSetPtr newp;
     FcCharSet new;
+    int bi = FcCacheBankToIndex(bank), cp = charset_ptr;
 
-    if (!charsets)
-    {
-       charsets = malloc(sizeof(FcCharSet) * charset_count);
-       if (!charsets) goto bail;
-       numbers = malloc(sizeof(FcChar16) * charset_numbers_count);
-       if (!numbers) goto bail1;
-       leaves = malloc(sizeof(FcCharLeaf) * charset_leaf_count);
-       if (!leaves) goto bail2;
-       leaf_idx = malloc(sizeof(int)*charset_leaf_idx_count);
-       if (!leaf_idx) goto bail3;
-    }
-
-    new.ref = c->ref;
-    new.storage = FcStorageStatic;
-    new.u.stat.leafidx_offset = charset_leaf_ptr;
+    new.ref = FC_REF_CONSTANT;
+    new.bank = bank;
+    new.u.stat.leafidx_offset = charset_leaf_idx_ptr;
     new.u.stat.numbers_offset = charset_numbers_ptr;
+    new.num = c->num;
 
-    newp.storage = FcStorageStatic;
-    newp.u.stat = charset_ptr;
-    charsets[charset_ptr++] = new;
+    charsets[bi][charset_ptr++] = new;
 
-    leaf_idx[charset_leaf_idx_ptr++] = charset_leaf_ptr;
     for (i = 0; i < c->num; i++)
     {
-       memcpy (&leaves[charset_leaf_ptr++], 
+       leaf_idx[bi][charset_leaf_idx_ptr++] = charset_leaf_ptr;
+       memcpy (&leaves[bi][charset_leaf_ptr++], 
                c->u.dyn.leaves[i], sizeof(FcCharLeaf));
-       numbers[charset_numbers_ptr++] = c->u.dyn.numbers[i];
+       numbers[bi][charset_numbers_ptr++] = c->u.dyn.numbers[i];
     }
 
-    return newp;
+    return &charsets[bi][cp];
+}
 
- bail3: 
-    free (leaves);
- bail2:
-    free (numbers);
- bail1:
-    free (charsets);
- bail:
-    return FcCharSetPtrCreateDynamic(0);
+void *
+FcCharSetUnserialize (FcCache *metadata, void *block_ptr)
+{
+    int bi = FcCacheBankToIndex(metadata->bank);
+    if (!FcCharSetEnsureBank(bi))
+       return 0;
+
+    block_ptr = ALIGN (block_ptr, FcCharSet);
+    charsets[bi] = (FcCharSet *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr + 
+                    (sizeof (FcCharSet) * metadata->charset_count));
+    block_ptr = ALIGN (block_ptr, FcChar16);
+    numbers[bi] = (FcChar16 *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr + 
+                    (sizeof(FcChar16) * metadata->charset_numbers_count));
+    block_ptr = ALIGN (block_ptr, FcCharLeaf);
+    leaves[bi] = (FcCharLeaf *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr +
+                    (sizeof(FcCharLeaf) * metadata->charset_leaf_count));
+    block_ptr = ALIGN (block_ptr, int);
+    leaf_idx[bi] = (int *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr +
+                    (sizeof(int) * metadata->charset_leaf_idx_count));
+
+    return block_ptr;
 }
 
 FcCharLeaf *
 FcCharSetGetLeaf(const FcCharSet *c, int i)
 {
-    switch (c->storage)
-    {
-    case FcStorageDynamic:
+    int bi;
+    if (c->bank == FC_BANK_DYNAMIC)
        return c->u.dyn.leaves[i];
-    case FcStorageStatic:
-       return &leaves[leaf_idx[c->u.stat.leafidx_offset]+i];
-    default:
-       return 0;
-    }
+    bi = FcCacheBankToIndex(c->bank);
+
+    return &leaves[bi][leaf_idx[bi][c->u.stat.leafidx_offset+i]];
 }
 
 FcChar16 *
 FcCharSetGetNumbers(const FcCharSet *c)
 {
-    switch (c->storage)
-    {
-    case FcStorageDynamic:
+    int bi;
+    if (c->bank == FC_BANK_DYNAMIC)
        return c->u.dyn.numbers;
-    case FcStorageStatic:
-       return &numbers[c->u.stat.numbers_offset];
-    default:
-       return 0;
-    }
+    bi = FcCacheBankToIndex(c->bank);
+
+    return &numbers[bi][c->u.stat.numbers_offset];
 }