X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffclang.c;h=ab7ae5381b6d020da2305594d3dd543e491088b4;hb=c5f0a65b36bc863d67bbf1f334262c35445ce610;hp=521aa91526dba666d479d2425dc1a58e0fabbe5d;hpb=793e946c2f90b5617ec39c64679630b4e2f2d3ad;p=fontconfig.git diff --git a/src/fclang.c b/src/fclang.c index 521aa91..ab7ae53 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -1,7 +1,7 @@ /* - * $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 + * 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 @@ -13,9 +13,9 @@ * 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 @@ -23,10 +23,11 @@ */ #include "fcint.h" +#include "fcftint.h" typedef struct { - FcChar8 *lang; - FcCharSet charset; + const FcChar8 lang[8]; + const FcCharSet charset; } FcLangCharSet; typedef struct { @@ -41,36 +42,53 @@ struct _FcLangSet { FcStrSet *extra; }; -#define FcLangSetBitSet(ls, id) ((ls)->map[(id)>>5] |= ((FcChar32) 1 << ((id) & 0x1f))) -#define FcLangSetBitGet(ls, id) (((ls)->map[(id)>>5] >> ((id) & 0x1f)) & 1) +#define FcLangSetBitSet(ls, id) ((ls)->map[(fcLangCharSetIndices[id])>>5] |= ((FcChar32) 1 << ((fcLangCharSetIndices[id]) & 0x1f))) +#define FcLangSetBitGet(ls, id) (((ls)->map[(fcLangCharSetIndices[id])>>5] >> ((fcLangCharSetIndices[id]) & 0x1f)) & 1) FcLangSet * FcFreeTypeLangSet (const FcCharSet *charset, const FcChar8 *exclusiveLang) { - int i; + int i, j; 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 * 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 (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != + FcCharSetLeaf(exclusiveCharset, j)) + continue; } missing = FcCharSetSubtractCount (&fcLangCharSets[i].charset, charset); if (FcDebug() & FC_DBG_SCANV) @@ -83,7 +101,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; @@ -102,7 +120,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); @@ -133,40 +151,44 @@ 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; } } /* - * 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) @@ -175,16 +197,17 @@ FcLangContains (const FcChar8 *s1, const FcChar8 *s2) } 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; default: @@ -193,7 +216,23 @@ FcCharSetForLang (const FcChar8 *lang) } 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 * @@ -259,9 +298,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 +330,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 + cmp = fcLangCharSets[mid].lang[1] - secondChar; + if (cmp == 0 && + (fcLangCharSets[mid].lang[2] != '\0' || + lang[2] != '\0')) { - high = mid - 1; - continue; + cmp = FcStrCmpIgnoreCase(fcLangCharSets[mid].lang+2, + lang+2); } - else if (fcLangCharSets[mid].lang[1] < secondChar) - { - low = mid + 1; - continue; - } - 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; @@ -372,7 +404,6 @@ FcLangSetHasLang (const FcLangSet *ls, const FcChar8 *lang) { FcStrList *list = FcStrListCreate (ls->extra); FcChar8 *extra; - FcLangResult r; if (list) { @@ -423,7 +454,7 @@ FcLangSetCompare (const FcLangSet *lsa, const FcLangSet *lsb) if ((lsa->map[i] & fcLangCountrySets[j][i]) && (lsb->map[i] & fcLangCountrySets[j][i])) { - best = FcLangDifferentCountry; + best = FcLangDifferentTerritory; break; } if (lsa->extra) @@ -535,7 +566,7 @@ 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; } @@ -552,11 +583,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; } @@ -582,7 +620,6 @@ static FcBool FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang) { int id; - FcLangResult r; int i; id = FcLangSetIndex (lang); @@ -613,7 +650,6 @@ FcLangSetContainsLang (const FcLangSet *ls, const FcChar8 *lang) { FcStrList *list = FcStrListCreate (ls->extra); FcChar8 *extra; - FcLangResult r; if (list) { @@ -657,10 +693,10 @@ 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; } } @@ -689,3 +725,58 @@ FcLangSetContains (const FcLangSet *lsa, const FcLangSet *lsb) } return FcTrue; } + +FcBool +FcLangSetSerializeAlloc (FcSerialize *serialize, const FcLangSet *l) +{ + if (!FcSerializeAlloc (serialize, l, sizeof (FcLangSet))) + return FcFalse; + return FcTrue; +} + +FcLangSet * +FcLangSetSerialize(FcSerialize *serialize, const FcLangSet *l) +{ + FcLangSet *l_serialize = FcSerializePtr (serialize, l); + + if (!l_serialize) + return NULL; + *l_serialize = *l; + return l_serialize; +} + +FcStrSet * +FcLangSetGetLangs (const FcLangSet *ls) +{ + FcStrSet *langs; + int i; + + langs = FcStrSetCreate(); + if (!langs) + return 0; + + for (i = 0; i < NUM_LANG_CHAR_SET; i++) + if (FcLangSetBitGet (ls, i)) + FcStrSetAdd (langs, fcLangCharSets[i].lang); + + if (ls->extra) + { + FcStrList *list = FcStrListCreate (ls->extra); + FcChar8 *extra; + + if (list) + { + while ((extra = FcStrListNext (list))) + FcStrSetAdd (langs, extra); + + FcStrListDone (list); + } + } + + return langs; +} + +#define __fclang__ +#include "fcaliastail.h" +#include "fcftaliastail.h" +#undef __fclang__