$OpenBSD: patch-libs_icu-xetex_layout_KernTable_cpp,v 1.1.1.1 2007/07/17 21:53:34 jasper Exp $ --- libs/icu-xetex/layout/KernTable.cpp.orig Wed Jun 27 09:59:39 2007 +++ libs/icu-xetex/layout/KernTable.cpp Wed Jun 27 10:00:16 2007 @@ -16,8 +16,10 @@ U_NAMESPACE_BEGIN struct PairInfo { - le_uint32 key; // sigh, MSVC compiler gags on union here + le_uint16 left; + le_uint16 right; le_int16 value; // fword, kern value in funits + le_uint32 key() const { return ((le_uint32)SWAPW(left) << 16) | SWAPW(right); } }; #define KERN_PAIRINFO_SIZE 6 @@ -81,9 +83,24 @@ KernTable::KernTable(const LEFontInstance* font, const 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); +#if 0 // don't trust these fields as some old TTF fonts have bad data here searchRange = SWAPW(table->searchRange); entrySelector = SWAPW(table->entrySelector); rangeShift = SWAPW(table->rangeShift); +#else // recompute the binary search header fields + if (nPairs == 0) { // this probably shouldn't happen + searchRange = entrySelector = 0; + } else { + searchRange = 1; + entrySelector = 0; + while (searchRange * 2 <= nPairs) { + searchRange *= 2; + entrySelector += 1; + } + } + rangeShift = (nPairs - searchRange) * KERN_PAIRINFO_SIZE; + searchRange *= KERN_PAIRINFO_SIZE; +#endif pairs = (const PairInfo*)((char*)table + KERN_SUBTABLE_0_HEADER_SIZE); #if DEBUG @@ -103,9 +120,8 @@ KernTable::KernTable(const LEFontInstance* font, const 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; + le_uint16 left = SWAPW(p->left); + le_uint16 right = SWAPW(p->right); if (left < 256 && right < 256) { char c = ids[left]; if (c > 0x20 && c < 0x7f) { @@ -149,10 +165,11 @@ void KernTable::process(LEGlyphStorage& storage) // but it is not in sorted order on win32 platforms because of the endianness difference // so either I have to swap the element each time I examine it, or I have to swap // all the elements ahead of time and store them in the font + // The key() accessor on PairInfo handles the swapping if needed const PairInfo* p = pairs; const PairInfo* tp = (const PairInfo*)((char*)p + rangeShift); - if (key > SWAPL(tp->key)) { + if (key > tp->key()) { p = tp; } @@ -165,7 +182,7 @@ void KernTable::process(LEGlyphStorage& storage) while (probe > KERN_PAIRINFO_SIZE) { probe >>= 1; tp = (const PairInfo*)((char*)p + probe); - le_uint32 tkey = SWAPL(tp->key); + le_uint32 tkey = tp->key(); #if DEBUG fprintf(stdout, " %.3d (%0.8x)\n", ((char*)tp - (char*)pairs)/KERN_PAIRINFO_SIZE, tkey); fflush(stdout);