1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/***************************************************************************
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Copyright (C) 1998-2003, International Business Machines
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*   Corporation and others.  All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)************************************************************************/
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "LETypes.h"
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "LESwaps.h"
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "sfnt.h"
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmaps.h"
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SWAPU16(code) ((LEUnicode16) SWAPW(code))
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SWAPU32(code) ((LEUnicode32) SWAPL(code))
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Finds the high bit by binary searching
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// through the bits in value.
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)le_int8 highBit(le_uint32 value)
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint8 bit = 0;
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (value >= 1 << 16) {
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value >>= 16;
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        bit += 16;
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (value >= 1 << 8) {
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value >>= 8;
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        bit += 8;
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (value >= 1 << 4) {
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value >>= 4;
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        bit += 4;
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (value >= 1 << 2) {
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value >>= 2;
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        bit += 2;
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (value >= 1 << 1) {
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        value >>= 1;
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        bit += 1;
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return bit;
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CMAPMapper *CMAPMapper::createUnicodeMapper(const CMAPTable *cmap)
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint16 i;
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint16 nSubtables = SWAPW(cmap->numberSubtables);
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const CMAPEncodingSubtable *subtable = NULL;
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint32 offset1 = 0, offset10 = 0;
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (i = 0; i < nSubtables; i += 1) {
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const CMAPEncodingSubtableHeader *esh = &cmap->encodingSubtableHeaders[i];
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (SWAPW(esh->platformID) == 3) {
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            switch (SWAPW(esh->platformSpecificID)) {
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case 1:
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                offset1 = SWAPL(esh->encodingOffset);
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case 10:
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                offset10 = SWAPL(esh->encodingOffset);
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (offset10 != 0)
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset10);
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else if (offset1 != 0) {
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        subtable = (const CMAPEncodingSubtable *) ((const char *) cmap + offset1);
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return NULL;
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (SWAPW(subtable->format)) {
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case 4:
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return new CMAPFormat4Mapper(cmap, (const CMAPFormat4Encoding *) subtable);
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case 12:
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        const CMAPFormat12Encoding *encoding = (const CMAPFormat12Encoding *) subtable;
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return new CMAPGroupMapper(cmap, encoding->groups, SWAPL(encoding->nGroups));
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    default:
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return NULL;
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CMAPFormat4Mapper::CMAPFormat4Mapper(const CMAPTable *cmap, const CMAPFormat4Encoding *header)
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    : CMAPMapper(cmap)
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint16 segCount = SWAPW(header->segCountX2) / 2;
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fEntrySelector = SWAPW(header->entrySelector);
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fRangeShift = SWAPW(header->rangeShift) / 2;
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fEndCodes = &header->endCodes[0];
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fStartCodes = &header->endCodes[segCount + 1]; // + 1 for reservedPad...
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fIdDelta = &fStartCodes[segCount];
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fIdRangeOffset = &fIdDelta[segCount];
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)LEGlyphID CMAPFormat4Mapper::unicodeToGlyph(LEUnicode32 unicode32) const
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unicode32 >= 0x10000) {
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return 0;
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    LEUnicode16 unicode = (LEUnicode16) unicode32;
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint16 index = 0;
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint16 probe = 1 << fEntrySelector;
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TTGlyphID result = 0;
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (SWAPU16(fStartCodes[fRangeShift]) <= unicode) {
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        index = fRangeShift;
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (probe > (1 << 0)) {
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        probe >>= 1;
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (SWAPU16(fStartCodes[index + probe]) <= unicode) {
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            index += probe;
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (unicode >= SWAPU16(fStartCodes[index]) && unicode <= SWAPU16(fEndCodes[index])) {
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (fIdRangeOffset[index] == 0) {
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result = (TTGlyphID) unicode;
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        } else {
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            le_uint16 offset = unicode - SWAPU16(fStartCodes[index]);
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            le_uint16 rangeOffset = SWAPW(fIdRangeOffset[index]);
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            le_uint16 *glyphIndexTable = (le_uint16 *) ((char *) &fIdRangeOffset[index] + rangeOffset);
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            result = SWAPW(glyphIndexTable[offset]);
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        result += SWAPW(fIdDelta[index]);
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } else {
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        result = 0;
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return LE_SET_GLYPH(0, result);
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CMAPFormat4Mapper::~CMAPFormat4Mapper()
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // parent destructor does it all
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CMAPGroupMapper::CMAPGroupMapper(const CMAPTable *cmap, const CMAPGroup *groups, le_uint32 nGroups)
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    : CMAPMapper(cmap), fGroups(groups)
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_uint8 bit = highBit(nGroups);
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fPower = 1 << bit;
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fRangeOffset = nGroups - fPower;
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)LEGlyphID CMAPGroupMapper::unicodeToGlyph(LEUnicode32 unicode32) const
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_int32 probe = fPower;
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    le_int32 range = 0;
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (SWAPU32(fGroups[fRangeOffset].startCharCode) <= unicode32) {
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        range = fRangeOffset;
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (probe > (1 << 0)) {
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        probe >>= 1;
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (SWAPU32(fGroups[range + probe].startCharCode) <= unicode32) {
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            range += probe;
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (SWAPU32(fGroups[range].startCharCode) <= unicode32 && SWAPU32(fGroups[range].endCharCode) >= unicode32) {
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return (LEGlyphID) (SWAPU32(fGroups[range].startGlyphCode) + unicode32 - SWAPU32(fGroups[range].startCharCode));
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return 0;
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)CMAPGroupMapper::~CMAPGroupMapper()
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // parent destructor does it all
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
201