X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffccharset.c;h=df1d2b538ff9434ece57756a0b42351d5a6a4080;hb=HEAD;hp=43aa22c46d873ccc55288047a222db1dba07bd3d;hpb=bc5e487f2a1ad9946aa5c6e19cd75794fc38d530;p=fontconfig.git diff --git a/src/fccharset.c b/src/fccharset.c index 43aa22c..df1d2b5 100644 --- a/src/fccharset.c +++ b/src/fccharset.c @@ -1,5 +1,5 @@ /* - * $RCSId: xc/lib/fontconfig/src/fccharset.c,v 1.18 2002/08/22 07:36:44 keithp Exp $ + * fontconfig/src/fccharset.c * * Copyright © 2001 Keith Packard * @@ -7,15 +7,15 @@ * 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. * - * 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 @@ -43,9 +43,6 @@ FcCharSetCreate (void) return fcs; } -FcCharSet * -FcCharSetNew (void); - FcCharSet * FcCharSetNew (void) { @@ -56,9 +53,12 @@ void FcCharSetDestroy (FcCharSet *fcs) { int i; - + if (fcs->ref == FC_REF_CONSTANT) + { + FcCacheObjectDereference (fcs); return; + } if (--fcs->ref > 0) return; for (i = 0; i < fcs->num; i++) @@ -68,11 +68,9 @@ FcCharSetDestroy (FcCharSet *fcs) } if (fcs->num) { + /* the numbers here are estimates */ FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t)); free (FcCharSetLeaves (fcs)); - } - if (fcs->num) - { FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16)); free (FcCharSetNumbers (fcs)); } @@ -81,38 +79,50 @@ FcCharSetDestroy (FcCharSet *fcs) } /* - * Locate the leaf containing the specified char, return - * its index if it exists, otherwise return negative of + * Search for the leaf containing with the specified num. + * Return its index if it exists, otherwise return negative of * the (position + 1) where it should be inserted */ + static int -FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4) +FcCharSetFindLeafForward (const FcCharSet *fcs, int start, FcChar16 num) { FcChar16 *numbers = FcCharSetNumbers(fcs); FcChar16 page; - int low = 0; + int low = start; int high = fcs->num - 1; if (!numbers) return -1; - ucs4 >>= 8; while (low <= high) { int mid = (low + high) >> 1; page = numbers[mid]; - if (page == ucs4) + if (page == num) return mid; - if (page < ucs4) + if (page < num) low = mid + 1; else high = mid - 1; } - if (high < 0 || (high < fcs->num && numbers[high] < ucs4)) + if (high < 0 || (high < fcs->num && numbers[high] < num)) high++; return -(high + 1); } +/* + * Locate the leaf containing the specified char, return + * its index if it exists, otherwise return negative of + * the (position + 1) where it should be inserted + */ + +static int +FcCharSetFindLeafPos (const FcCharSet *fcs, FcChar32 ucs4) +{ + return FcCharSetFindLeafForward (fcs, 0, ucs4 >> 8); +} + static FcCharLeaf * FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4) { @@ -122,10 +132,12 @@ FcCharSetFindLeaf (const FcCharSet *fcs, FcChar32 ucs4) return 0; } +#define FC_IS_ZERO_OR_POWER_OF_TWO(x) (!((x) & ((x)-1))) + static FcBool -FcCharSetPutLeaf (FcCharSet *fcs, +FcCharSetPutLeaf (FcCharSet *fcs, FcChar32 ucs4, - FcCharLeaf *leaf, + FcCharLeaf *leaf, int pos) { intptr_t *leaves = FcCharSetLeaves (fcs); @@ -134,44 +146,50 @@ FcCharSetPutLeaf (FcCharSet *fcs, ucs4 >>= 8; if (ucs4 >= 0x10000) return FcFalse; - if (!fcs->num) - leaves = malloc (sizeof (*leaves)); - else + + if (FC_IS_ZERO_OR_POWER_OF_TWO (fcs->num)) { - intptr_t *new_leaves = realloc (leaves, (fcs->num + 1) * - sizeof (*leaves)); - intptr_t distance = (intptr_t) new_leaves - (intptr_t) leaves; - + if (!fcs->num) + { + unsigned int alloced = 8; + leaves = malloc (alloced * sizeof (*leaves)); + numbers = malloc (alloced * sizeof (*numbers)); + FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*leaves)); + FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*numbers)); + } + else + { + unsigned int alloced = fcs->num; + intptr_t *new_leaves, distance; + + FcMemFree (FC_MEM_CHARSET, alloced * sizeof (*leaves)); + FcMemFree (FC_MEM_CHARSET, alloced * sizeof (*numbers)); + + alloced *= 2; + new_leaves = realloc (leaves, alloced * sizeof (*leaves)); + numbers = realloc (numbers, alloced * sizeof (*numbers)); + + FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*leaves)); + FcMemAlloc (FC_MEM_CHARSET, alloced * sizeof (*numbers)); + + distance = (intptr_t) new_leaves - (intptr_t) leaves; if (new_leaves && distance) { int i; - for (i = 0; i < fcs->num; i++) new_leaves[i] -= distance; } leaves = new_leaves; + } + + if (!leaves || !numbers) + return FcFalse; + + fcs->leaves_offset = FcPtrToOffset (fcs, leaves); + fcs->numbers_offset = FcPtrToOffset (fcs, numbers); } - if (!leaves) - return FcFalse; - - if (fcs->num) - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (intptr_t)); - FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (intptr_t)); - fcs->leaves_offset = FcPtrToOffset (fcs, leaves); - - if (!fcs->num) - numbers = malloc (sizeof (FcChar16)); - else - numbers = realloc (numbers, (fcs->num + 1) * sizeof (FcChar16)); - if (!numbers) - return FcFalse; - - if (fcs->num) - FcMemFree (FC_MEM_CHARSET, fcs->num * sizeof (FcChar16)); - FcMemAlloc (FC_MEM_CHARSET, (fcs->num + 1) * sizeof (FcChar16)); - fcs->numbers_offset = FcPtrToOffset (fcs, numbers); - - memmove (leaves + pos + 1, leaves + pos, + + memmove (leaves + pos + 1, leaves + pos, (fcs->num - pos) * sizeof (*leaves)); memmove (numbers + pos + 1, numbers + pos, (fcs->num - pos) * sizeof (*numbers)); @@ -195,11 +213,11 @@ FcCharSetFindLeafCreate (FcCharSet *fcs, FcChar32 ucs4) pos = FcCharSetFindLeafPos (fcs, ucs4); if (pos >= 0) return FcCharSetLeaf(fcs, pos); - + leaf = calloc (1, sizeof (FcCharLeaf)); if (!leaf) return 0; - + pos = -pos - 1; if (!FcCharSetPutLeaf (fcs, ucs4, leaf, pos)) { @@ -233,7 +251,7 @@ FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4) { FcCharLeaf *leaf; FcChar32 *b; - + if (fcs->ref == FC_REF_CONSTANT) return FcFalse; leaf = FcCharSetFindLeafCreate (fcs, ucs4); @@ -244,6 +262,23 @@ FcCharSetAddChar (FcCharSet *fcs, FcChar32 ucs4) return FcTrue; } +FcBool +FcCharSetDelChar (FcCharSet *fcs, FcChar32 ucs4) +{ + FcCharLeaf *leaf; + FcChar32 *b; + + if (fcs->ref == FC_REF_CONSTANT) + return FcFalse; + leaf = FcCharSetFindLeaf (fcs, ucs4); + if (!leaf) + return FcTrue; + b = &leaf->map[(ucs4 & 0xff) >> 5]; + *b &= ~(1 << (ucs4 & 0x1f)); + /* We don't bother removing the leaf if it's empty */ + return FcTrue; +} + /* * An iterator for the leaves of a charset */ @@ -309,6 +344,8 @@ FcCharSetCopy (FcCharSet *src) { if (src->ref != FC_REF_CONSTANT) src->ref++; + else + FcCacheObjectReference (src); return src; } @@ -317,7 +354,7 @@ FcCharSetEqual (const FcCharSet *a, const FcCharSet *b) { FcCharSetIter ai, bi; int i; - + if (a == b) return FcTrue; for (FcCharSetIterStart (a, &ai), FcCharSetIterStart (b, &bi); @@ -450,6 +487,57 @@ FcCharSetUnion (const FcCharSet *a, const FcCharSet *b) return FcCharSetOperate (a, b, FcCharSetUnionLeaf, FcTrue, FcTrue); } +FcBool +FcCharSetMerge (FcCharSet *a, const FcCharSet *b, FcBool *changed) +{ + int ai = 0, bi = 0; + FcChar16 an, bn; + + if (a->ref == FC_REF_CONSTANT) { + if (changed) + *changed = FcFalse; + return FcFalse; + } + + if (changed) { + *changed = !FcCharSetIsSubset(b, a); + if (!*changed) + return FcTrue; + } + + while (bi < b->num) + { + an = ai < a->num ? FcCharSetNumbers(a)[ai] : ~0; + bn = FcCharSetNumbers(b)[bi]; + + if (an < bn) + { + ai = FcCharSetFindLeafForward (a, ai + 1, bn); + if (ai < 0) + ai = -ai - 1; + } + else + { + FcCharLeaf *bl = FcCharSetLeaf(b, bi); + if (bn < an) + { + if (!FcCharSetAddLeaf (a, bn << 8, bl)) + return FcFalse; + } + else + { + FcCharLeaf *al = FcCharSetLeaf(a, ai); + FcCharSetUnionLeaf (al, al, bl); + } + + ai++; + bi++; + } + } + + return FcTrue; +} + static FcBool FcCharSetSubtractLeaf (FcCharLeaf *result, const FcCharLeaf *al, @@ -482,10 +570,14 @@ FcCharSetHasChar (const FcCharSet *fcs, FcChar32 ucs4) static FcChar32 FcCharSetPopCount (FcChar32 c1) { +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) + return __builtin_popcount (c1); +#else /* hackmem 169 */ FcChar32 c2 = (c1 >> 1) & 033333333333; c2 = c1 - c2 - ((c2 >> 1) & 033333333333); return (((c2 + (c2 >> 3)) & 030707070707) % 077); +#endif } FcChar32 @@ -493,7 +585,7 @@ FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b) { FcCharSetIter ai, bi; FcChar32 count = 0; - + FcCharSetIterStart (a, &ai); FcCharSetIterStart (b, &bi); while (ai.leaf && bi.leaf) @@ -506,7 +598,7 @@ FcCharSetIntersectCount (const FcCharSet *a, const FcCharSet *b) while (i--) count += FcCharSetPopCount (*am++ & *bm++); FcCharSetIterNext (a, &ai); - } + } else if (ai.ucs4 < bi.ucs4) { ai.ucs4 = bi.ucs4; @@ -526,7 +618,7 @@ FcCharSetCount (const FcCharSet *a) { FcCharSetIter ai; FcChar32 count = 0; - + for (FcCharSetIterStart (a, &ai); ai.leaf; FcCharSetIterNext (a, &ai)) { int i = 256/32; @@ -543,7 +635,7 @@ FcCharSetSubtractCount (const FcCharSet *a, const FcCharSet *b) { FcCharSetIter ai, bi; FcChar32 count = 0; - + FcCharSetIterStart (a, &ai); FcCharSetIterStart (b, &bi); while (ai.leaf) @@ -582,7 +674,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) { int ai, bi; FcChar16 an, bn; - + if (a == b) return FcTrue; bi = 0; ai = 0; @@ -597,7 +689,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) { FcChar32 *am = FcCharSetLeaf(a, ai)->map; FcChar32 *bm = FcCharSetLeaf(b, bi)->map; - + if (am != bm) { int i = 256/32; @@ -618,29 +710,9 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) return FcFalse; else { - int low = bi + 1; - int high = b->num - 1; - - /* - * Search for page 'an' in 'b' - */ - while (low <= high) - { - int mid = (low + high) >> 1; - bn = FcCharSetNumbers(b)[mid]; - if (bn == an) - { - high = mid; - break; - } - if (bn < an) - low = mid + 1; - else - high = mid - 1; - } - bi = high; - while (bi < b->num && FcCharSetNumbers(b)[bi] < an) - bi++; + bi = FcCharSetFindLeafForward (b, bi + 1, an); + if (bi < 0) + bi = -bi - 1; } } /* @@ -655,7 +727,7 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b) */ FcChar32 -FcCharSetNextPage (const FcCharSet *a, +FcCharSetNextPage (const FcCharSet *a, FcChar32 map[FC_CHARSET_MAP_SIZE], FcChar32 *next) { @@ -666,7 +738,7 @@ FcCharSetNextPage (const FcCharSet *a, FcCharSetIterSet (a, &ai); if (!ai.leaf) return FC_CHARSET_DONE; - + /* * Save current information */ @@ -682,7 +754,7 @@ FcCharSetNextPage (const FcCharSet *a, } FcChar32 -FcCharSetFirstPage (const FcCharSet *a, +FcCharSetFirstPage (const FcCharSet *a, FcChar32 map[FC_CHARSET_MAP_SIZE], FcChar32 *next) { @@ -693,9 +765,7 @@ FcCharSetFirstPage (const FcCharSet *a, /* * old coverage API, rather hard to use correctly */ -FcChar32 -FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result); - + FcChar32 FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result) { @@ -719,7 +789,7 @@ FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result) /* * ASCII representation of charsets. - * + * * Each leaf is represented as 9 32-bit values, the code of the first character followed * by 8 32 bit values for the leaf itself. Each value is encoded as 5 ASCII characters, * only 85 different values are used to avoid control characters as well as the other @@ -728,38 +798,38 @@ FcCharSetCoverage (const FcCharSet *a, FcChar32 page, FcChar32 *result) */ static const unsigned char charToValue[256] = { - /* "" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\b" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\020" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\030" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* " " */ 0xff, 0x00, 0xff, 0x01, 0x02, 0x03, 0x04, 0xff, - /* "(" */ 0x05, 0x06, 0x07, 0x08, 0xff, 0xff, 0x09, 0x0a, - /* "0" */ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, - /* "8" */ 0x13, 0x14, 0xff, 0x15, 0x16, 0xff, 0x17, 0x18, - /* "@" */ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - /* "H" */ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - /* "P" */ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - /* "X" */ 0x31, 0x32, 0x33, 0x34, 0xff, 0x35, 0x36, 0xff, - /* "`" */ 0xff, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, - /* "h" */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, - /* "p" */ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, - /* "x" */ 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0xff, - /* "\200" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\210" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\220" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\230" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\240" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\250" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\260" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\270" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\300" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\310" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\320" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\330" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\340" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\350" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\360" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - /* "\370" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\b" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\020" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\030" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* " " */ 0xff, 0x00, 0xff, 0x01, 0x02, 0x03, 0x04, 0xff, + /* "(" */ 0x05, 0x06, 0x07, 0x08, 0xff, 0xff, 0x09, 0x0a, + /* "0" */ 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + /* "8" */ 0x13, 0x14, 0xff, 0x15, 0x16, 0xff, 0x17, 0x18, + /* "@" */ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + /* "H" */ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + /* "P" */ 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + /* "X" */ 0x31, 0x32, 0x33, 0x34, 0xff, 0x35, 0x36, 0xff, + /* "`" */ 0xff, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + /* "h" */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + /* "p" */ 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + /* "x" */ 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0xff, + /* "\200" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\210" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\220" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\230" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\240" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\250" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\260" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\270" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\300" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\310" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\320" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\330" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\340" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\350" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\360" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + /* "\370" */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; static const FcChar8 valueToChar[0x55] = { @@ -782,7 +852,7 @@ FcCharSetParseValue (FcChar8 *string, FcChar32 *value) int i; FcChar32 v; FcChar32 c; - + if (*string == ' ') { v = 0; @@ -953,7 +1023,7 @@ FcNameUnparseCharSet (FcStrBuf *buf, const FcCharSet *c) FcCharSetDestroy (check); } #endif - + return FcTrue; } @@ -1040,7 +1110,7 @@ FcCharSetFreezeLeaf (FcCharSetFreezer *freezer, FcCharLeaf *leaf) FcChar32 hash = FcCharLeafHash (leaf); FcCharLeafEnt **bucket = &freezer->leaf_hash_table[hash % FC_CHAR_LEAF_HASH_SIZE]; FcCharLeafEnt *ent; - + for (ent = *bucket; ent; ent = ent->next) { if (ent->hash == hash && !memcmp (&ent->leaf, leaf, sizeof (FcCharLeaf))) @@ -1064,8 +1134,8 @@ FcCharSetHash (FcCharSet *fcs) int i; /* hash in leaves */ - for (i = 0; i < fcs->num * (int) (sizeof (FcCharLeaf *) / sizeof (FcChar32)); i++) - hash = ((hash << 1) | (hash >> 31)) ^ (FcChar32)(FcCharSetLeaf(fcs, i)->map); + for (i = 0; i < fcs->num; i++) + hash = ((hash << 1) | (hash >> 31)) ^ FcCharLeafHash (FcCharSetLeaf(fcs,i)); /* hash in numbers */ for (i = 0; i < fcs->num; i++) hash = ((hash << 1) | (hash >> 31)) ^ *FcCharSetNumbers(fcs); @@ -1077,7 +1147,7 @@ FcCharSetFreezeOrig (FcCharSetFreezer *freezer, const FcCharSet *orig, const FcC { FcCharSetOrigEnt **bucket = &freezer->orig_hash_table[((uintptr_t) orig) & FC_CHAR_SET_HASH_SIZE]; FcCharSetOrigEnt *ent; - + ent = malloc (sizeof (FcCharSetOrigEnt)); if (!ent) return FcFalse; @@ -1101,7 +1171,7 @@ FcCharSetFreezeBase (FcCharSetFreezer *freezer, FcCharSet *fcs, const FcCharSet { if (ent->hash == hash && ent->set.num == fcs->num && - !memcmp (FcCharSetNumbers(&ent->set), + !memcmp (FcCharSetNumbers(&ent->set), FcCharSetNumbers(fcs), fcs->num * sizeof (FcChar16))) { @@ -1123,9 +1193,9 @@ FcCharSetFreezeBase (FcCharSetFreezer *freezer, FcCharSet *fcs, const FcCharSet if (!ent) return 0; FcMemAlloc (FC_MEM_CHARSET, size); - + freezer->charsets_allocated++; - + ent->set.ref = FC_REF_CONSTANT; ent->set.num = fcs->num; if (fcs->num) @@ -1135,13 +1205,13 @@ FcCharSetFreezeBase (FcCharSetFreezer *freezer, FcCharSet *fcs, const FcCharSet ent->set.leaves_offset = sizeof (ent->set); ent->set.numbers_offset = (ent->set.leaves_offset + fcs->num * sizeof (intptr_t)); - + ent_leaves = FcCharSetLeaves (&ent->set); for (i = 0; i < fcs->num; i++) ent_leaves[i] = FcPtrToOffset (ent_leaves, FcCharSetLeaf (fcs, i)); - memcpy (FcCharSetNumbers (&ent->set), - FcCharSetNumbers (fcs), + memcpy (FcCharSetNumbers (&ent->set), + FcCharSetNumbers (fcs), fcs->num * sizeof (FcChar16)); } else @@ -1162,14 +1232,14 @@ FcCharSetFindFrozen (FcCharSetFreezer *freezer, const FcCharSet *orig) { FcCharSetOrigEnt **bucket = &freezer->orig_hash_table[((uintptr_t) orig) & FC_CHAR_SET_HASH_SIZE]; FcCharSetOrigEnt *ent; - + for (ent = *bucket; ent; ent = ent->next) if (ent->orig == orig) return ent->frozen; return NULL; } -static const FcCharSet * +const FcCharSet * FcCharSetFreeze (FcCharSetFreezer *freezer, const FcCharSet *fcs) { FcCharSet *b; @@ -1177,10 +1247,6 @@ FcCharSetFreeze (FcCharSetFreezer *freezer, const FcCharSet *fcs) FcCharLeaf *l; int i; - n = FcCharSetFindFrozen (freezer, fcs); - if (n) - return n; - b = FcCharSetCreate (); if (!b) goto bail0; @@ -1217,7 +1283,7 @@ bail0: return n; } -static FcCharSetFreezer * +FcCharSetFreezer * FcCharSetFreezerCreate (void) { FcCharSetFreezer *freezer; @@ -1243,6 +1309,9 @@ FcCharSetFreezerDestroy (FcCharSetFreezer *freezer) for (ent = freezer->set_hash_table[i]; ent; ent = next) { next = ent->next; + FcMemFree (FC_MEM_CHARSET, (sizeof (FcCharSetEnt) + + ent->set.num * sizeof (FcCharLeaf *) + + ent->set.num * sizeof (FcChar16))); free (ent); } } @@ -1258,7 +1327,10 @@ FcCharSetFreezerDestroy (FcCharSetFreezer *freezer) } for (i = 0; i < freezer->leaf_block_count; i++) + { free (freezer->leaf_blocks[i]); + FcMemFree (FC_MEM_CHARLEAF, FC_CHAR_LEAF_BLOCK * sizeof (FcCharLeafEnt)); + } free (freezer->leaf_blocks); free (freezer); @@ -1270,7 +1342,7 @@ FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs) intptr_t *leaves; FcChar16 *numbers; int i; - + if (cs->ref != FC_REF_CONSTANT) { if (!serialize->cs_freezer) @@ -1279,12 +1351,15 @@ FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs) if (!serialize->cs_freezer) return FcFalse; } + if (FcCharSetFindFrozen (serialize->cs_freezer, cs)) + return FcTrue; + cs = FcCharSetFreeze (serialize->cs_freezer, cs); } - + leaves = FcCharSetLeaves (cs); numbers = FcCharSetNumbers (cs); - + if (!FcSerializeAlloc (serialize, cs, sizeof (FcCharSet))) return FcFalse; if (!FcSerializeAlloc (serialize, leaves, cs->num * sizeof (intptr_t))) @@ -1297,7 +1372,7 @@ FcCharSetSerializeAlloc (FcSerialize *serialize, const FcCharSet *cs) return FcFalse; return FcTrue; } - + FcCharSet * FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) { @@ -1313,11 +1388,11 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) if (!cs) return NULL; } - + cs_serialized = FcSerializePtr (serialize, cs); if (!cs_serialized) return NULL; - + cs_serialized->ref = FC_REF_CONSTANT; cs_serialized->num = cs->num; @@ -1327,7 +1402,7 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) leaves_serialized = FcSerializePtr (serialize, leaves); if (!leaves_serialized) return NULL; - + cs_serialized->leaves_offset = FcPtrToOffset (cs_serialized, leaves_serialized); @@ -1335,10 +1410,10 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) numbers_serialized = FcSerializePtr (serialize, numbers); if (!numbers) return NULL; - + cs_serialized->numbers_offset = FcPtrToOffset (cs_serialized, numbers_serialized); - + for (i = 0; i < cs->num; i++) { leaf = FcCharSetLeaf (cs, i); @@ -1346,7 +1421,7 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) if (!leaf_serialized) return NULL; *leaf_serialized = *leaf; - leaves_serialized[i] = FcPtrToOffset (leaves_serialized, + leaves_serialized[i] = FcPtrToOffset (leaves_serialized, leaf_serialized); numbers_serialized[i] = numbers[i]; } @@ -1356,6 +1431,9 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) cs_serialized->leaves_offset = 0; cs_serialized->numbers_offset = 0; } - + return cs_serialized; } +#define __fccharset__ +#include "fcaliastail.h" +#undef __fccharset__