cmaps.cpp revision 59d709d503bab6e2b61931737e662dd293b40578
1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*************************************************************************** 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 359d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 1998-2013, International Business Machines 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru************************************************************************/ 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 859d709d503bab6e2b61931737e662dd293b40578ccornelius#include "layout/LETypes.h" 959d709d503bab6e2b61931737e662dd293b40578ccornelius#include "layout/LESwaps.h" 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "sfnt.h" 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmaps.h" 1359d709d503bab6e2b61931737e662dd293b40578ccornelius#include <stdio.h> 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SWAPU16(code) ((LEUnicode16) SWAPW(code)) 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SWAPU32(code) ((LEUnicode32) SWAPL(code)) 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Finds the high bit by binary searching 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// through the bits in value. 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querule_int8 highBit(le_uint32 value) 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint8 bit = 0; 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (value >= 1 << 16) { 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value >>= 16; 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bit += 16; 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (value >= 1 << 8) { 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value >>= 8; 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bit += 8; 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (value >= 1 << 4) { 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value >>= 4; 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bit += 4; 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (value >= 1 << 2) { 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value >>= 2; 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bit += 2; 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (value >= 1 << 1) { 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru value >>= 1; 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bit += 1; 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return bit; 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCMAPMapper *CMAPMapper::createUnicodeMapper(const CMAPTable *cmap) 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 i; 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 nSubtables = SWAPW(cmap->numberSubtables); 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CMAPEncodingSubtable *subtable = NULL; 5959d709d503bab6e2b61931737e662dd293b40578ccornelius le_bool found = FALSE; 6059d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 foundPlatformID = 0xFFFF; 6159d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 foundPlatformSpecificID = 0xFFFF; 6259d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint32 foundOffset = 0; 6359d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 foundTable = 0xFFFF; 6459d709d503bab6e2b61931737e662dd293b40578ccornelius // first pass, look for MS table. (preferred?) 6559d709d503bab6e2b61931737e662dd293b40578ccornelius for (i = 0; i < nSubtables && !found; i += 1) { 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i]; 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 6859d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 platformID = SWAPW(esh->platformID); 6959d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 platformSpecificID = SWAPW(esh->platformSpecificID); 7059d709d503bab6e2b61931737e662dd293b40578ccornelius if (platformID == 3) { // microsoft 7159d709d503bab6e2b61931737e662dd293b40578ccornelius switch (platformSpecificID) { 7259d709d503bab6e2b61931737e662dd293b40578ccornelius case 1: // Unicode BMP (UCS-2) 7359d709d503bab6e2b61931737e662dd293b40578ccornelius case 10: // Unicode UCS-4 7459d709d503bab6e2b61931737e662dd293b40578ccornelius foundOffset = SWAPL(esh->encodingOffset); 7559d709d503bab6e2b61931737e662dd293b40578ccornelius foundPlatformID = platformID; 7659d709d503bab6e2b61931737e662dd293b40578ccornelius foundPlatformSpecificID = platformSpecificID; 7759d709d503bab6e2b61931737e662dd293b40578ccornelius found = TRUE; 7859d709d503bab6e2b61931737e662dd293b40578ccornelius foundTable = i; 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 8159d709d503bab6e2b61931737e662dd293b40578ccornelius //default: 8259d709d503bab6e2b61931737e662dd293b40578ccornelius // printf("%s:%d: microsoft (3) platform specific ID %d (wanted 1 or 10) for subtable %d/%d\n", __FILE__, __LINE__, (SWAPW(esh->platformSpecificID)), i, nSubtables); 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 8459d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 8559d709d503bab6e2b61931737e662dd293b40578ccornelius //printf("%s:%d: platform ID %d (wanted 3, microsoft) for subtable %d/%d\n", __FILE__, __LINE__, (SWAPW(esh->platformID)), i, nSubtables); 8659d709d503bab6e2b61931737e662dd293b40578ccornelius } 8759d709d503bab6e2b61931737e662dd293b40578ccornelius } 8859d709d503bab6e2b61931737e662dd293b40578ccornelius 8959d709d503bab6e2b61931737e662dd293b40578ccornelius // second pass, allow non MS table 9059d709d503bab6e2b61931737e662dd293b40578ccornelius // first pass, look for MS table. (preferred?) 9159d709d503bab6e2b61931737e662dd293b40578ccornelius for (i = 0; i < nSubtables && !found; i += 1) { 9259d709d503bab6e2b61931737e662dd293b40578ccornelius const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i]; 9359d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 platformID = SWAPW(esh->platformID); 9459d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 platformSpecificID = SWAPW(esh->platformSpecificID); 9559d709d503bab6e2b61931737e662dd293b40578ccornelius //printf("%s:%d: table %d/%d has platform:specific %d:%d\n", __FILE__, __LINE__, i, nSubtables, platformID, platformSpecificID); 9659d709d503bab6e2b61931737e662dd293b40578ccornelius switch(platformID) { 9759d709d503bab6e2b61931737e662dd293b40578ccornelius case 0: // Unicode platform 9859d709d503bab6e2b61931737e662dd293b40578ccornelius switch(platformSpecificID) { 9959d709d503bab6e2b61931737e662dd293b40578ccornelius case 0: 10059d709d503bab6e2b61931737e662dd293b40578ccornelius case 1: 10159d709d503bab6e2b61931737e662dd293b40578ccornelius case 2: 10259d709d503bab6e2b61931737e662dd293b40578ccornelius case 3: 10359d709d503bab6e2b61931737e662dd293b40578ccornelius foundOffset = SWAPL(esh->encodingOffset); 10459d709d503bab6e2b61931737e662dd293b40578ccornelius foundPlatformID = platformID; 10559d709d503bab6e2b61931737e662dd293b40578ccornelius foundPlatformSpecificID = platformSpecificID; 10659d709d503bab6e2b61931737e662dd293b40578ccornelius foundTable = i; 10759d709d503bab6e2b61931737e662dd293b40578ccornelius found = TRUE; 10859d709d503bab6e2b61931737e662dd293b40578ccornelius break; 10959d709d503bab6e2b61931737e662dd293b40578ccornelius 11059d709d503bab6e2b61931737e662dd293b40578ccornelius default: printf("Error: table %d (psid %d) is unknown. Skipping.\n", i, platformSpecificID); break; 11159d709d503bab6e2b61931737e662dd293b40578ccornelius } 11259d709d503bab6e2b61931737e662dd293b40578ccornelius break; 11359d709d503bab6e2b61931737e662dd293b40578ccornelius 11459d709d503bab6e2b61931737e662dd293b40578ccornelius //default: 11559d709d503bab6e2b61931737e662dd293b40578ccornelius //printf("Skipping platform id %d\n", platformID); 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12059d709d503bab6e2b61931737e662dd293b40578ccornelius if (found) 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 12259d709d503bab6e2b61931737e662dd293b40578ccornelius subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + foundOffset); 12359d709d503bab6e2b61931737e662dd293b40578ccornelius //printf("%s:%d: using subtable #%d/%d type %d:%d\n", __FILE__, __LINE__, foundTable, nSubtables, foundPlatformID, foundPlatformSpecificID); 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 12559d709d503bab6e2b61931737e662dd293b40578ccornelius printf("%s:%d: could not find subtable.\n", __FILE__, __LINE__); 12659d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12959d709d503bab6e2b61931737e662dd293b40578ccornelius le_uint16 tableFormat = SWAPW(subtable->format); 13059d709d503bab6e2b61931737e662dd293b40578ccornelius //printf("%s:%d: table format %d\n", __FILE__, __LINE__, tableFormat); 13159d709d503bab6e2b61931737e662dd293b40578ccornelius 13259d709d503bab6e2b61931737e662dd293b40578ccornelius switch (tableFormat) { 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 4: 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable); 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 12: 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const CMAPFormat12Encoding *encoding = (const CMAPFormat12Encoding *) subtable; 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups)); 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14759d709d503bab6e2b61931737e662dd293b40578ccornelius printf("%s:%d: Unknown format %x.\n", __FILE__, __LINE__, (SWAPW(subtable->format))); 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCMAPFormat4Mapper::CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header) 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : CMAPMapper(cmap) 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 segCount = SWAPW(header->segCountX2) / 2; 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fEntrySelector = SWAPW(header->entrySelector); 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fRangeShift = SWAPW(header->rangeShift) / 2; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fEndCodes = &header->endCodes[0]; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fStartCodes = &header->endCodes[segCount + 1]; // + 1 for reservedPad... 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fIdDelta = &fStartCodes[segCount]; 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fIdRangeOffset = &fIdDelta[segCount]; 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEGlyphID CMAPFormat4Mapper::unicodeToGlyph(LEUnicode32 unicode32) const 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (unicode32 >= 0x10000) { 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LEUnicode16 unicode = (LEUnicode16) unicode32; 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 index = 0; 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 probe = 1 << fEntrySelector; 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TTGlyphID result = 0; 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SWAPU16(fStartCodes[fRangeShift]) <= unicode) { 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru index = fRangeShift; 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (probe > (1 << 0)) { 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru probe >>= 1; 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SWAPU16(fStartCodes[index + probe]) <= unicode) { 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru index += probe; 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (unicode >= SWAPU16(fStartCodes[index]) && unicode <= SWAPU16(fEndCodes[index])) { 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fIdRangeOffset[index] == 0) { 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = (TTGlyphID) unicode; 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 offset = unicode - SWAPU16(fStartCodes[index]); 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]); 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &fIdRangeOffset[index] + rangeOffset); 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = SWAPW(glyphIndexTable[offset]); 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result += SWAPW(fIdDelta[index]); 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = 0; 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return LE_SET_GLYPH(0, result); 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCMAPFormat4Mapper::~CMAPFormat4Mapper() 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // parent destructor does it all 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCMAPGroupMapper::CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups) 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : CMAPMapper(cmap), fGroups(groups) 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_uint8 bit = highBit(nGroups); 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fPower = 1 << bit; 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fRangeOffset = nGroups - fPower; 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLEGlyphID CMAPGroupMapper::unicodeToGlyph(LEUnicode32 unicode32) const 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 probe = fPower; 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru le_int32 range = 0; 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SWAPU32(fGroups[fRangeOffset].startCharCode) <= unicode32) { 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru range = fRangeOffset; 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (probe > (1 << 0)) { 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru probe >>= 1; 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SWAPU32(fGroups[range + probe].startCharCode) <= unicode32) { 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru range += probe; 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (SWAPU32(fGroups[range].startCharCode) <= unicode32 && SWAPU32(fGroups[range].endCharCode) >= unicode32) { 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (LEGlyphID) (SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode)); 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCMAPGroupMapper::~CMAPGroupMapper() 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // parent destructor does it all 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 248