Update contrib.
1 /***************************************************************************
3 * Copyright (C) 1998-2003, International Business Machines
4 * Corporation and others. All Rights Reserved.
6 ************************************************************************/
14 #define SWAPU16(code) ((LEUnicode16) SWAPW(code))
15 #define SWAPU32(code) ((LEUnicode32) SWAPL(code))
18 // Finds the high bit by binary searching
19 // through the bits in value.
21 le_int8 highBit(le_uint32 value)
25 if (value >= 1 << 16) {
30 if (value >= 1 << 8) {
35 if (value >= 1 << 4) {
40 if (value >= 1 << 2) {
45 if (value >= 1 << 1) {
53 CMAPMapper *CMAPMapper::createUnicodeMapper(const CMAPTable *cmap)
56 le_uint16 nSubtables = SWAPW(cmap->numberSubtables);
57 const CMAPEncodingSubtable *subtable = NULL;
58 le_uint32 offset1 = 0, offset10 = 0;
60 for (i = 0; i < nSubtables; i += 1) {
61 const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
63 if (SWAPW(esh->platformID) == 3) {
64 switch (SWAPW(esh->platformSpecificID)) {
66 offset1 = SWAPL(esh->encodingOffset);
70 offset10 = SWAPL(esh->encodingOffset);
79 subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset10);
80 } else if (offset1 != 0) {
81 subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset1);
86 switch (SWAPW(subtable->format)) {
88 return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable);
92 const CMAPFormat12Encoding *encoding = (const CMAPFormat12Encoding *) subtable;
94 return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups));
104 CMAPFormat4Mapper::CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header)
107 le_uint16 segCount = SWAPW(header->segCountX2) / 2;
109 fEntrySelector = SWAPW(header->entrySelector);
110 fRangeShift = SWAPW(header->rangeShift) / 2;
111 fEndCodes = &header->endCodes[0];
112 fStartCodes = &header->endCodes[segCount + 1]; // + 1 for reservedPad...
113 fIdDelta = &fStartCodes[segCount];
114 fIdRangeOffset = &fIdDelta[segCount];
117 LEGlyphID CMAPFormat4Mapper::unicodeToGlyph(LEUnicode32 unicode32) const
119 if (unicode32 >= 0x10000) {
123 LEUnicode16 unicode = (LEUnicode16) unicode32;
125 le_uint16 probe = 1 << fEntrySelector;
126 TTGlyphID result = 0;
128 if (SWAPU16(fStartCodes[fRangeShift]) <= unicode) {
132 while (probe > (1 << 0)) {
135 if (SWAPU16(fStartCodes[index + probe]) <= unicode) {
140 if (unicode >= SWAPU16(fStartCodes[index]) && unicode <= SWAPU16(fEndCodes[index])) {
141 if (fIdRangeOffset[index] == 0) {
142 result = (TTGlyphID) unicode;
144 le_uint16 offset = unicode - SWAPU16(fStartCodes[index]);
145 le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]);
146 le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &fIdRangeOffset[index] + rangeOffset);
148 result = SWAPW(glyphIndexTable[offset]);
151 result += SWAPW(fIdDelta[index]);
156 return LE_SET_GLYPH(0, result);
159 CMAPFormat4Mapper::~CMAPFormat4Mapper()
161 // parent destructor does it all
164 CMAPGroupMapper::CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups)
165 : CMAPMapper(cmap), fGroups(groups)
167 le_uint8 bit = highBit(nGroups);
169 fRangeOffset = nGroups - fPower;
172 LEGlyphID CMAPGroupMapper::unicodeToGlyph(LEUnicode32 unicode32) const
174 le_int32 probe = fPower;
177 if (SWAPU32(fGroups[fRangeOffset].startCharCode) <= unicode32) {
178 range = fRangeOffset;
181 while (probe > (1 << 0)) {
184 if (SWAPU32(fGroups[range + probe].startCharCode) <= unicode32) {
189 if (SWAPU32(fGroups[range].startCharCode) <= unicode32 && SWAPU32(fGroups[range].endCharCode) >= unicode32) {
190 return (LEGlyphID) (SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode));
196 CMAPGroupMapper::~CMAPGroupMapper()
198 // parent destructor does it all