diff options
Diffstat (limited to 'src/fcscript.c')
-rw-r--r-- | src/fcscript.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/src/fcscript.c b/src/fcscript.c new file mode 100644 index 00000000..cb630cb5 --- /dev/null +++ b/src/fcscript.c @@ -0,0 +1,247 @@ +/* + * fontconfig/src/fcscript.c + * + * 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 + * 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 the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * 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. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * 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 "fcint.h" +#include "fcftint.h" + +/* Objects MT-safe for readonly access. */ + +typedef struct { + const FcChar8 script[8]; + const FcCharSet charset; +} FcScriptCharSet; + +#include "../fc-script/fcscript.h" + +struct _FcScriptSet { + FcChar32 map_size; + FcChar32 map[NUM_SCRIPT_SET_MAP]; +}; + +static void +FcScriptSetBitSet (FcScriptSet *ss, + unsigned int id) +{ + unsigned int bucket; + + id = fcScriptCharSetIndices[id]; + bucket = id >> 5; + if (bucket >= ss->map_size) + return; /* shouldn't happen really */ + + ss->map[bucket] |= ((FcChar32) 1 << (id & 0x1f)); +} + +static FcBool +FcScriptSetBitGet (const FcScriptSet *ss, + unsigned int id) +{ + unsigned int bucket; + + id = fcScriptCharSetIndices[id]; + bucket = id >> 5; + if (bucket >= ss->map_size) + return FcFalse; + + return ((ss->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse; +} + +static void +FcScriptSetBitReset (FcScriptSet *ss, + unsigned int id) +{ + unsigned int bucket; + + id = fcScriptCharSetIndices[id]; + bucket = id >> 5; + if (bucket >= ss->map_size) + return; /* shouldn't happen really */ + + ss->map[bucket] &= ~((FcChar32) 1 << (id & 0x1f)); +} + +FcScriptSet * +FcFreeTypeScriptSet (const FcCharSet *charset) +{ + static const int threshold = 60; + int i, j, avail; + FcChar32 missing, count; + FcScriptSet *ss; + + ss = FcScriptSetCreate (); + if (!ss) + return 0; + if (FcDebug() & FC_DBG_SCRIPTSET) + { + printf ("font scriptset"); + FcCharSetPrint (charset); + printf ("\n"); + } + for (i = 0; i < NUM_SCRIPT_CHAR_SET; i++) + { + if (FcDebug() & FC_DBG_SCRIPTSET) + { + printf ("%s charset", fcScriptCharSets[i].script); + FcCharSetPrint (&fcScriptCharSets[i].charset); + printf ("\n"); + } + +#if 0 + /* + * 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)) + { + 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; + } +#endif + count = FcCharSetCount (&fcScriptCharSets[i].charset); + missing = FcCharSetSubtractCount (&fcScriptCharSets[i].charset, charset); + avail = (count - missing) * 100 / count; + if (FcDebug() & FC_DBG_SCANV) + { + if (avail < threshold && missing < 10) + { + FcCharSet *missed = FcCharSetSubtract (&fcScriptCharSets[i].charset, + charset); + FcChar32 ucs4; + FcChar32 map[FC_CHARSET_MAP_SIZE]; + FcChar32 next; + + printf ("\n%s(%u) ", fcScriptCharSets[i].script, missing); + printf ("{"); + for (ucs4 = FcCharSetFirstPage (missed, map, &next); + ucs4 != FC_CHARSET_DONE; + ucs4 = FcCharSetNextPage (missed, map, &next)) + { + int i, j; + for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) + if (map[i]) + { + for (j = 0; j < 32; j++) + if (map[i] & (1 << j)) + printf (" %04x", ucs4 + i * 32 + j); + } + } + printf (" }\n\t"); + FcCharSetDestroy (missed); + } + else + printf ("%s(%u) ", fcScriptCharSets[i].script, missing); + } + if (avail >= threshold) + FcScriptSetBitSet (ss, i); + } + + if (FcDebug() & FC_DBG_SCANV) + printf ("\n"); + + printf ("scriptset:\n"); + FcScriptSetPrint (ss); + printf ("\n"); + + return ss; +} + +const FcCharSet * +FcScriptGetCharSet (const FcChar8 *script) +{ + int i; + + for (i = 0; i < NUM_SCRIPT_CHAR_SET; i++) + { + if (FcStrCmpIgnoreCase (script, fcScriptCharSets[i].script) == 0) + { + volatile FcCharSet *cs = &fcScriptCharSets[i].charset; + printf("%p\n", cs); +// __asm__ volatile("int $03"); + return cs; +// return &fcScriptCharSets[i].charset; + } + } + + return NULL; +} + +FcScriptSet * +FcScriptSetCreate (void) +{ + FcScriptSet *ss; + + ss = malloc (sizeof (FcScriptSet)); + if (!ss) + return NULL; + memset (ss->map, '\0', sizeof (ss->map)); + ss->map_size = NUM_SCRIPT_SET_MAP; + + return ss; +} + +void +FcScriptSetDestroy (FcScriptSet *ss) +{ + free (ss); +} + +FcBool +FcNameUnparseScriptSet (FcStrBuf *buf, const FcScriptSet *ss) +{ + int i, bit, count; + FcChar32 bits; + FcBool first = FcTrue; + + count = FC_MIN (ss->map_size, NUM_SCRIPT_SET_MAP); + for (i = 0; i < count; i++) + { + if ((bits = ss->map[i])) + { + for (bit = 0; bit <= 31; bit++) + if (bits & (1 << bit)) + { + int id = (i << 5) | bit; + if (!first) + if (!FcStrBufChar (buf, '|')) + return FcFalse; + if (!FcStrBufString (buf, fcScriptCharSets[fcScriptCharSetIndicesInv[id]].script)) + return FcFalse; + first = FcFalse; + } + } + } + return FcTrue; +} + +#define __fcscript__ +#include "fcaliastail.h" +#include "fcftaliastail.h" +#undef __fcscript__ |