X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/73c04bcfe1096173b00431f0cdc742894b15eef0..4d9eefca008a7bc544144ef830fa144ce89deaa0:/icuSources/layout/KernTable.cpp diff --git a/icuSources/layout/KernTable.cpp b/icuSources/layout/KernTable.cpp index fc6a6f7d..45ce091d 100644 --- a/icuSources/layout/KernTable.cpp +++ b/icuSources/layout/KernTable.cpp @@ -1,7 +1,7 @@ /* * @(#)KernTable.cpp 1.1 04/10/13 * - * (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved + * (C) Copyright IBM Corp. 2004-2007 - All Rights Reserved * */ @@ -10,6 +10,7 @@ #include "LEGlyphStorage.h" #include "LESwaps.h" +#include "OpenTypeUtilities.h" #include @@ -18,11 +19,14 @@ U_NAMESPACE_BEGIN struct PairInfo { - le_uint32 key; // sigh, MSVC compiler gags on union here + le_uint16 left; // left glyph of kern pair + le_uint16 right; // right glyph of kern pair le_int16 value; // fword, kern value in funits }; #define KERN_PAIRINFO_SIZE 6 +#define SWAP_KEY(p) (((le_uint32) SWAPW((p)->left) << 16) | SWAPW((p)->right)) + struct Subtable_0 { le_uint16 nPairs; le_uint16 searchRange; @@ -91,51 +95,67 @@ KernTable::KernTable(const LEFontInstance* font, const void* tableData) if (header->version == 0 && SWAPW(header->nTables) > 0) { const SubtableHeader* subhead = (const SubtableHeader*)((char*)tableData + KERN_TABLE_HEADER_SIZE); + if (subhead->version == 0) { coverage = SWAPW(subhead->coverage); + if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning - const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE); - nPairs = SWAPW(table->nPairs); - searchRange = SWAPW(table->searchRange); - entrySelector = SWAPW(table->entrySelector); - rangeShift = SWAPW(table->rangeShift); - pairs = (const PairInfo*)((char*)table + KERN_SUBTABLE_0_HEADER_SIZE); + const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE); + + nPairs = SWAPW(table->nPairs); + +#if 0 // some old fonts have bad values here... + searchRange = SWAPW(table->searchRange); + entrySelector = SWAPW(table->entrySelector); + rangeShift = SWAPW(table->rangeShift); +#else + entrySelector = OpenTypeUtilities::highBit(nPairs); + searchRange = (1 << entrySelector) * KERN_PAIRINFO_SIZE; + rangeShift = (nPairs * KERN_PAIRINFO_SIZE) - searchRange; +#endif + + pairs = (const PairInfo*)((char*)table + KERN_SUBTABLE_0_HEADER_SIZE); #if DEBUG - fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs); - fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift); - - { - // dump part of the pair list - char ids[256]; - for (int i = 256; --i >= 0;) { - LEGlyphID id = font->mapCharToGlyph(i); - if (id < 256) { - ids[id] = (char)i; - } - } - - const PairInfo* p = pairs; - for (i = 0; i < nPairs; ++i, p = (const PairInfo*)((char*)p+KERN_PAIRINFO_SIZE)) { - le_uint32 k = SWAPL(p->key); - le_uint16 left = (k >> 16) & 0xffff; - le_uint16 right = k & 0xffff; - if (left < 256 && right < 256) { - char c = ids[left]; - if (c > 0x20 && c < 0x7f) { - fprintf(stderr, "%c/", c & 0xff); - } else { - fprintf(stderr, "%0.2x/", c & 0xff); - } - c = ids[right]; - if (c > 0x20 && c < 0x7f) { - fprintf(stderr, "%c ", c & 0xff); - } else { - fprintf(stderr, "%0.2x ", c & 0xff); - } - } - } - } + fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs); + fprintf(stderr, " searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift); + + { + // dump part of the pair list + char ids[256]; + + for (int i = 256; --i >= 0;) { + LEGlyphID id = font->mapCharToGlyph(i); + + if (id < 256) { + ids[id] = (char)i; + } + } + + const PairInfo* p = pairs; + + for (i = 0; i < nPairs; ++i, p = (const PairInfo*)((char*)p+KERN_PAIRINFO_SIZE)) { + le_uint16 left = p->left; + le_uint16 right = p->right; + + if (left < 256 && right < 256) { + char c = ids[left]; + + if (c > 0x20 && c < 0x7f) { + fprintf(stderr, "%c/", c & 0xff); + } else { + printf(stderr, "%0.2x/", c & 0xff); + } + + c = ids[right]; + if (c > 0x20 && c < 0x7f) { + fprintf(stderr, "%c ", c & 0xff); + } else { + fprintf(stderr, "%0.2x ", c & 0xff); + } + } + } + } #endif } } @@ -154,6 +174,7 @@ void KernTable::process(LEGlyphStorage& storage) le_uint32 key = storage[0]; // no need to mask off high bits float adjust = 0; + for (int i = 1, e = storage.getGlyphCount(); i < e; ++i) { key = key << 16 | (storage[i] & 0xffff); @@ -164,8 +185,9 @@ void KernTable::process(LEGlyphStorage& storage) const PairInfo* p = pairs; const PairInfo* tp = (const PairInfo*)((char*)p + rangeShift); - if (key > SWAPL(tp->key)) { - p = tp; + + if (key > SWAP_KEY(tp)) { + p = tp; } #if DEBUG @@ -173,30 +195,34 @@ void KernTable::process(LEGlyphStorage& storage) #endif le_uint32 probe = searchRange; + while (probe > KERN_PAIRINFO_SIZE) { probe >>= 1; tp = (const PairInfo*)((char*)p + probe); - le_uint32 tkey = SWAPL(tp->key); + + le_uint32 tkey = SWAP_KEY(tp); #if DEBUG fprintf(stdout, " %.3d (%0.8x)\n", ((char*)tp - (char*)pairs)/KERN_PAIRINFO_SIZE, tkey); #endif if (tkey <= key) { - if (tkey == key) { - le_int16 value = SWAPW(tp->value); + if (tkey == key) { + le_int16 value = SWAPW(tp->value); #if DEBUG - fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n", - storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value)); - fflush(stdout); + fprintf(stdout, "binary found kerning pair %x:%x at %d, value: 0x%x (%g)\n", + storage[i-1], storage[i], i, value & 0xffff, font->xUnitsToPoints(value)); + fflush(stdout); #endif - adjust += font->xUnitsToPoints(value); - break; - } - p = tp; + adjust += font->xUnitsToPoints(value); + break; + } + + p = tp; } } storage.adjustPosition(i, adjust, 0, success); } + storage.adjustPosition(storage.getGlyphCount(), adjust, 0, success); } }