X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffclang.c;h=1d62c4e3f52960852614ce8ff4c9e8d4ca8305f1;hb=a3b2426819836ab2454c6a7bad27c382f4a245bf;hp=28b2d9b9c6965755b72b80981da54eafc7d3b1b3;hpb=cd2ec1a940888ebcbd323a8000d2fcced41ddf9e;p=fontconfig.git diff --git a/src/fclang.c b/src/fclang.c index 28b2d9b..1d62c4e 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -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 * @@ -13,22 +13,21 @@ * 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 -#include #include "fcint.h" +#include "fcftint.h" typedef struct { - FcChar8 *lang; - FcCharSet charset; + const FcChar8 lang[8]; + const FcCharSet charset; } FcLangCharSet; typedef struct { @@ -39,12 +38,38 @@ typedef struct { #include "../fc-lang/fclang.h" struct _FcLangSet { + FcStrSet *extra; + FcChar32 map_size; FcChar32 map[NUM_LANG_SET_MAP]; - FcStrSetPtr extra; }; -#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f))) -#define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((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, @@ -54,15 +79,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 +112,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 +127,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 +146,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 +177,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,25 +223,43 @@ 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; + case FcLangDifferentLang: default: break; } } 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 +272,16 @@ FcLangSetCreate (void) return 0; FcMemAlloc (FC_MEM_LANGSET, sizeof (FcLangSet)); memset (ls->map, '\0', sizeof (ls->map)); - ls->extra = FcStrSetPtrCreateDynamic(0); + ls->map_size = NUM_LANG_SET_MAP; + 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); } @@ -245,22 +294,23 @@ FcLangSetCopy (const FcLangSet *ls) new = FcLangSetCreate (); if (!new) goto bail0; - memcpy (new->map, ls->map, sizeof (new->map)); - if (FcStrSetPtrU(ls->extra)) + 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; 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 +391,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 +429,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) { @@ -422,30 +471,32 @@ 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])) { - 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 +515,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 +523,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; } @@ -487,19 +537,20 @@ 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 (FcStrSetPtrU(ls->extra)) - h ^= FcStrSetPtrU(ls->extra)->num; + if (ls->extra) + h ^= ls->extra->num; return h; } FcLangSet * FcNameParseLangSet (const FcChar8 *string) { - FcChar8 lang[32],c; + FcChar8 lang[32], c = 0; int i; FcLangSet *ls; @@ -532,11 +583,12 @@ bail0: FcBool FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls) { - int i, bit; + int i, bit, count; FcChar32 bits; FcBool first = FcTrue; - 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++) { if ((bits = ls->map[i])) { @@ -547,15 +599,15 @@ FcNameUnparseLangSet (FcStrBuf *buf, const FcLangSet *ls) if (!first) if (!FcStrBufChar (buf, '|')) return FcFalse; - if (!FcStrBufString (buf, fcLangCharSets[id].lang)) + if (!FcStrBufString (buf, fcLangCharSets[fcLangCharSetIndicesInv[id]].lang)) return FcFalse; first = FcFalse; } } } - if (FcStrSetPtrU(ls->extra)) + if (ls->extra) { - FcStrList *list = FcStrListCreate (FcStrSetPtrU(ls->extra)); + FcStrList *list = FcStrListCreate (ls->extra); FcChar8 *extra; if (!list) @@ -564,11 +616,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; } @@ -576,17 +635,19 @@ 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; } - 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 +681,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) @@ -646,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) @@ -658,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) @@ -667,18 +730,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 +763,60 @@ 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); + + if (!l_serialize) + return NULL; + 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; } -void -FcLangSetClearStatic (void) +FcStrSet * +FcLangSetGetLangs (const FcLangSet *ls) { - FcStrSetClearStatic(); - langset_ptr = 0; - langset_count = 0; -} + FcStrSet *langs; + int i; -/* should only write one copy of any particular FcLangSet */ -FcBool -FcLangSetPrepareSerialize (FcLangSet *l) -{ - langset_count++; - if (l && FcStrSetPtrU(l->extra)) - return FcStrSetPrepareSerialize (FcStrSetPtrU(l->extra)); - return FcTrue; -} - -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__