X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffclang.c;h=be42b58c4694f54747c395ab28011a490a7a4dbc;hb=HEAD;hp=61c4da6615eff6a58a173ac1493323355298c2bf;hpb=8480c6f86327877fce729ebb01b52bd7a40ddfc5;p=fontconfig.git diff --git a/src/fclang.c b/src/fclang.c index 61c4da6..be42b58 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -7,9 +7,9 @@ * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in + * documentation, and that the name of the author(s) not be used in * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no + * specific, written prior permission. The authors make no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * @@ -71,8 +71,22 @@ FcLangSetBitGet (const FcLangSet *ls, return ((ls->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse; } +static void +FcLangSetBitReset (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)); +} + FcLangSet * -FcFreeTypeLangSet (const FcCharSet *charset, +FcFreeTypeLangSet (const FcCharSet *charset, const FcChar8 *exclusiveLang) { int i, j; @@ -85,7 +99,7 @@ FcFreeTypeLangSet (const FcCharSet *charset, ls = FcLangSetCreate (); if (!ls) return 0; - if (FcDebug() & FC_DBG_LANGSET) + if (FcDebug() & FC_DBG_LANGSET) { printf ("font charset"); FcCharSetPrint (charset); @@ -93,7 +107,7 @@ FcFreeTypeLangSet (const FcCharSet *charset, } for (i = 0; i < NUM_LANG_CHAR_SET; i++) { - if (FcDebug() & FC_DBG_LANGSET) + if (FcDebug() & FC_DBG_LANGSET) { printf ("%s charset", fcLangCharSets[i].lang); FcCharSetPrint (&fcLangCharSets[i].charset); @@ -112,7 +126,7 @@ FcFreeTypeLangSet (const FcCharSet *charset, continue; for (j = 0; j < fcLangCharSets[i].charset.num; j++) - if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != + if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != FcCharSetLeaf(exclusiveCharset, j)) continue; } @@ -121,7 +135,7 @@ FcFreeTypeLangSet (const FcCharSet *charset, { if (missing && missing < 10) { - FcCharSet *missed = FcCharSetSubtract (&fcLangCharSets[i].charset, + FcCharSet *missed = FcCharSetSubtract (&fcLangCharSets[i].charset, charset); FcChar32 ucs4; FcChar32 map[FC_CHARSET_MAP_SIZE]; @@ -154,8 +168,8 @@ FcFreeTypeLangSet (const FcCharSet *charset, if (FcDebug() & FC_DBG_SCANV) printf ("\n"); - - + + return ls; } @@ -188,7 +202,7 @@ FcLangCompare (const FcChar8 *s1, const FcChar8 *s2) } /* - * Return FcTrue when super contains sub. + * Return FcTrue when super contains sub. * * super contains sub if super and sub have the same * language and either the same country or one @@ -329,9 +343,9 @@ FcLangSetIndex (const FcChar8 *lang) { int low, high, mid = 0; int cmp = 0; - FcChar8 firstChar = FcToLower(lang[0]); + FcChar8 firstChar = FcToLower(lang[0]); FcChar8 secondChar = firstChar ? FcToLower(lang[1]) : '\0'; - + if (firstChar < 'a') { low = 0; @@ -360,11 +374,11 @@ FcLangSetIndex (const FcChar8 *lang) { /* 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) */ cmp = fcLangCharSets[mid].lang[1] - secondChar; - if (cmp == 0 && - (fcLangCharSets[mid].lang[2] != '\0' || + if (cmp == 0 && + (fcLangCharSets[mid].lang[2] != '\0' || lang[2] != '\0')) { - cmp = FcStrCmpIgnoreCase(fcLangCharSets[mid].lang+2, + cmp = FcStrCmpIgnoreCase(fcLangCharSets[mid].lang+2, lang+2); } } @@ -400,6 +414,23 @@ FcLangSetAdd (FcLangSet *ls, const FcChar8 *lang) return FcStrSetAdd (ls->extra, lang); } +FcBool +FcLangSetDel (FcLangSet *ls, const FcChar8 *lang) +{ + int id; + + id = FcLangSetIndex (lang); + if (id >= 0) + { + FcLangSetBitReset (ls, id); + } + else if (ls->extra) + { + FcStrSetDel (ls->extra, lang); + } + return FcTrue; +} + FcLangResult FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang) { @@ -505,6 +536,7 @@ FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb) /* * Used in computing values -- mustn't allocate any storage + * XXX Not thread-safe */ FcLangSet * FcLangSetPromote (const FcChar8 *lang) @@ -515,6 +547,7 @@ FcLangSetPromote (const FcChar8 *lang) int id; memset (ls.map, '\0', sizeof (ls.map)); + ls.map_size = NUM_LANG_SET_MAP; ls.extra = 0; id = FcLangSetIndex (lang); if (id > 0) @@ -537,9 +570,10 @@ FcChar32 FcLangSetHash (const FcLangSet *ls) { FcChar32 h = 0; - int i; + int i, count; - for (i = 0; i < ls->map_size; 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; @@ -726,7 +760,7 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb) if (missing) { for (j = 0; j < 32; j++) - if (missing & (1 << j)) + if (missing & (1 << j)) { if (!FcLangSetContainsLang (lsa, fcLangCharSets[fcLangCharSetIndicesInv[i*32 + j]].lang)) @@ -777,7 +811,9 @@ 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; } @@ -813,6 +849,37 @@ FcLangSetGetLangs (const FcLangSet *ls) return langs; } +static FcLangSet * +FcLangSetOperate(const FcLangSet *a, + const FcLangSet *b, + FcBool (*func) (FcLangSet *ls, + const FcChar8 *s)) +{ + FcLangSet *langset = FcLangSetCopy (a); + FcStrList *sl = FcStrListCreate (FcLangSetGetLangs (b)); + FcChar8 *str; + + while ((str = FcStrListNext (sl))) + { + func (langset, str); + } + FcStrListDone (sl); + + return langset; +} + +FcLangSet * +FcLangSetUnion (const FcLangSet *a, const FcLangSet *b) +{ + return FcLangSetOperate(a, b, FcLangSetAdd); +} + +FcLangSet * +FcLangSetSubtract (const FcLangSet *a, const FcLangSet *b) +{ + return FcLangSetOperate(a, b, FcLangSetDel); +} + #define __fclang__ #include "fcaliastail.h" #include "fcftaliastail.h"