]> git.wh0rd.org - fontconfig.git/blobdiff - src/fclang.c
Add consts to variables so as to move arrays into .rodata.
[fontconfig.git] / src / fclang.c
index 1fa4dd66bf87b1a2c0a4df0a5bfafc8b650182c9..a10641edf953c89586dc9aa03f87879b1712384a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * $RCSId: xc/lib/fontconfig/src/fclang.c,v 1.7 2002/08/26 23:34:31 keithp Exp $
  *
- * Copyright © 2002 Keith Packard
+ * Copyright Â© 2002 Keith Packard
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -25,8 +25,8 @@
 #include "fcint.h"
 
 typedef struct {
-    FcChar8    *lang;
-    FcCharSet  charset;
+    const FcChar8      *lang;
+    const FcCharSet    charset;
 } FcLangCharSet;
 
 typedef struct {
@@ -48,7 +48,7 @@ FcLangSet *
 FcFreeTypeLangSet (const FcCharSet  *charset, 
                   const FcChar8    *exclusiveLang)
 {
-    int                    i;
+    int                    i, j;
     FcChar32       missing;
     const FcCharSet *exclusiveCharset = 0;
     FcLangSet      *ls;
@@ -67,10 +67,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)
@@ -144,29 +149,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)
@@ -259,9 +268,10 @@ bail0:
 static int
 FcLangSetIndex (const FcChar8 *lang)
 {
-    int            low, high, mid;
-    int            cmp;
+    int            low, high, mid = 0;
+    int            cmp = 0;
     FcChar8 firstChar = FcToLower(lang[0]); 
+    FcChar8 secondChar = firstChar ? FcToLower(lang[1]) : '\0';
     
     if (firstChar < 'a')
     {
@@ -290,22 +300,14 @@ FcLangSetIndex (const FcChar8 *lang)
        else
        {   /* fast path for resolving 2-letter languages (by far the most common) after
             * finding the first char (probably already true because of the hash table) */
-           FcChar8 secondChar = FcToLower(lang[1]);
-           if (fcLangCharSets[mid].lang[1] > secondChar) /* check second chars */
-           {
-               high = mid - 1;
-               continue;
-           }
-           else if (fcLangCharSets[mid].lang[1] < secondChar)
+           cmp = fcLangCharSets[mid].lang[1] - secondChar;
+           if (cmp == 0 && 
+               (fcLangCharSets[mid].lang[2] != '\0' || 
+                lang[2] != '\0'))
            {
-               low = mid + 1;
-               continue;
+               cmp = FcStrCmpIgnoreCase(fcLangCharSets[mid].lang+2, 
+                                        lang+2);
            }
-           else if (fcLangCharSets[mid].lang[2] == '\0' && lang[2] == '\0')
-               return mid;
-
-           else /* identical through the first two charcters, but at least one string didn't end there */
-               cmp = FcStrCmpIgnoreCase(fcLangCharSets[mid].lang+2, lang+2);
        }
        if (cmp == 0)
            return mid;
@@ -582,7 +584,6 @@ static FcBool
 FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang)
 {
     int                    id;
-    FcLangResult    r;
     int                    i;
 
     id = FcLangSetIndex (lang);
@@ -613,7 +614,6 @@ FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang)
     {
        FcStrList       *list = FcStrListCreate (ls->extra);
        FcChar8         *extra;
-       FcLangResult    r;
        
        if (list)
        {
@@ -689,3 +689,83 @@ 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);
+}
+
+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;
+
+    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));
+    langsets[bi] = (FcLangSet *)block_ptr;
+    block_ptr = (void *)((char *)block_ptr +
+                        metadata.langset_count * sizeof(FcLangSet));
+    return block_ptr;
+}