c38e2b1143d24e263f5c9d19078ebf545e62bbd9
[platform/upstream/harfbuzz.git] / src / hb-icu-le / PortableFontInstance.cpp
1 /*
2  *******************************************************************************
3  *
4  *   Copyright (C) 1999-2008, International Business Machines
5  *   Corporation and others.  All Rights Reserved.
6  *
7  *******************************************************************************
8  *   file name:  PortableFontInstance.cpp
9  *
10  *   created on: 11/22/1999
11  *   created by: Eric R. Mader
12  */
13
14 #include <stdio.h>
15
16 #include "layout/LETypes.h"
17 #include "layout/LEFontInstance.h"
18 #include "layout/LESwaps.h"
19
20 #include "PortableFontInstance.h"
21
22 #include "letest.h"
23 #include "sfnt.h"
24
25 #include <string.h>
26
27
28 PortableFontInstance::PortableFontInstance(hb_face_t *face, float xScale, float yScale, LEErrorCode &status)
29     : fFace(face), fXScale(xScale), fYScale(yScale), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
30       fNAMETable(NULL), fNameCount(0), fNameStringOffset(0), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
31 {
32     if (LE_FAILURE(status)) {
33         return;
34     }
35
36     const LETag hheaTag = LE_HHEA_TABLE_TAG;
37     const HHEATable *hheaTable = NULL;
38
39     fUnitsPerEM = hb_face_get_upem (face);
40
41     hheaTable = (HHEATable *) getFontTable(hheaTag);
42
43     if (hheaTable == NULL) {
44         status = LE_MISSING_FONT_TABLE_ERROR;
45         return;
46     }
47
48     fAscent  = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
49     fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
50     fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
51
52     fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
53
54     fCMAPMapper = findUnicodeMapper();
55
56     if (fCMAPMapper == NULL) {
57         status = LE_MISSING_FONT_TABLE_ERROR;
58         return;
59     }
60 }
61
62 PortableFontInstance::~PortableFontInstance()
63 {
64     if (fCMAPMapper)
65         delete fCMAPMapper;
66 }
67
68 const void *PortableFontInstance::getFontTable(LETag tableTag) const
69 {
70     return FontTableCache::find(tableTag);
71 }
72
73 hb_blob_t *PortableFontInstance::readFontTable(LETag tableTag) const
74 {
75   return hb_face_reference_table(fFace, tableTag);
76 }
77
78 CMAPMapper *PortableFontInstance::findUnicodeMapper()
79 {
80     LETag cmapTag = LE_CMAP_TABLE_TAG;
81     const CMAPTable *cmap = (CMAPTable *) getFontTable(cmapTag);
82
83     if (cmap == NULL) {
84         return NULL;
85     }
86
87     return CMAPMapper::createUnicodeMapper(cmap);
88 }
89
90 const char *PortableFontInstance::getNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
91 {
92     if (fNAMETable == NULL) {
93         LETag nameTag = LE_NAME_TABLE_TAG;
94         PortableFontInstance *realThis = (PortableFontInstance *) this;
95
96         realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag);
97
98         if (realThis->fNAMETable != NULL) {
99             realThis->fNameCount        = SWAPW(realThis->fNAMETable->count);
100             realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
101         }
102     }
103
104     for(le_int32 i = 0; i < fNameCount; i += 1) {
105         const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
106         
107         if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
108             SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
109             char *name = ((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset);
110             le_uint16 length = SWAPW(nameRecord->length);
111             char *result = NEW_ARRAY(char, length + 2);
112
113             ARRAY_COPY(result, name, length);
114             result[length] = result[length + 1] = 0;
115
116             return result;
117         }
118     }
119
120     return NULL;
121 }
122
123 const LEUnicode16 *PortableFontInstance::getUnicodeNameString(le_uint16 nameID, le_uint16 platformID, le_uint16 encodingID, le_uint16 languageID) const
124 {
125     if (fNAMETable == NULL) {
126         LETag nameTag = LE_NAME_TABLE_TAG;
127         PortableFontInstance *realThis = (PortableFontInstance *) this;
128
129         realThis->fNAMETable = (const NAMETable *) getFontTable(nameTag);
130
131         if (realThis->fNAMETable != NULL) {
132             realThis->fNameCount        = SWAPW(realThis->fNAMETable->count);
133             realThis->fNameStringOffset = SWAPW(realThis->fNAMETable->stringOffset);
134         }
135     }
136
137     for(le_int32 i = 0; i < fNameCount; i += 1) {
138         const NameRecord *nameRecord = &fNAMETable->nameRecords[i];
139         
140         if (SWAPW(nameRecord->platformID) == platformID && SWAPW(nameRecord->encodingID) == encodingID &&
141             SWAPW(nameRecord->languageID) == languageID && SWAPW(nameRecord->nameID) == nameID) {
142             LEUnicode16 *name = (LEUnicode16 *) (((char *) fNAMETable) + fNameStringOffset + SWAPW(nameRecord->offset));
143             le_uint16 length = SWAPW(nameRecord->length) / 2;
144             LEUnicode16 *result = NEW_ARRAY(LEUnicode16, length + 2);
145
146             for (le_int32 c = 0; c < length; c += 1) {
147                 result[c] = SWAPW(name[c]);
148             }
149
150             result[length] = 0;
151
152             return result;
153         }
154     }
155
156     return NULL;
157 }
158
159 void PortableFontInstance::deleteNameString(const char *name) const
160 {
161     DELETE_ARRAY(name);
162 }
163
164 void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const
165 {
166     DELETE_ARRAY(name);
167 }
168
169 void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
170 {
171     TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
172
173     if (fHMTXTable == NULL) {
174         LETag maxpTag = LE_MAXP_TABLE_TAG;
175         LETag hmtxTag = LE_HMTX_TABLE_TAG;
176         const MAXPTable *maxpTable = (MAXPTable *) getFontTable(maxpTag);
177         PortableFontInstance *realThis = (PortableFontInstance *) this;
178
179         if (maxpTable != NULL) {
180             realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
181         }
182
183         realThis->fHMTXTable = (const HMTXTable *) getFontTable(hmtxTag);
184     }
185
186     le_uint16 index = ttGlyph;
187
188     if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
189         advance.fX = advance.fY = 0;
190         return;
191     }
192
193     if (ttGlyph >= fNumLongHorMetrics) {
194         index = fNumLongHorMetrics - 1;
195     }
196
197     advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
198     advance.fY = 0;
199 }
200
201 le_bool PortableFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
202 {
203     return FALSE;
204 }
205
206 le_int32 PortableFontInstance::getUnitsPerEM() const
207 {
208     return fUnitsPerEM;
209 }
210
211 le_uint32 PortableFontInstance::getFontChecksum() const
212 {
213     return 0;
214 }
215
216 le_int32 PortableFontInstance::getAscent() const
217 {
218     return fAscent;
219 }
220
221 le_int32 PortableFontInstance::getDescent() const
222 {
223     return fDescent;
224 }
225
226 le_int32 PortableFontInstance::getLeading() const
227 {
228     return fLeading;
229 }
230
231 // We really want to inherit this method from the superclass, but some compilers
232 // issue a warning if we don't implement it...
233 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper, le_bool filterZeroWidth) const
234 {
235     return LEFontInstance::mapCharToGlyph(ch, mapper, filterZeroWidth);
236 }
237
238 // We really want to inherit this method from the superclass, but some compilers
239 // issue a warning if we don't implement it...
240 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
241 {
242     return LEFontInstance::mapCharToGlyph(ch, mapper);
243 }
244
245 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const
246 {
247     return fCMAPMapper->unicodeToGlyph(ch);
248 }
249
250 float PortableFontInstance::getXPixelsPerEm() const
251 {
252     return fXScale;
253 }
254
255 float PortableFontInstance::getYPixelsPerEm() const
256 {
257     return fYScale;
258 }
259
260 float PortableFontInstance::getScaleFactorX() const
261 {
262     return 1.0;
263 }
264
265 float PortableFontInstance::getScaleFactorY() const
266 {
267     return 1.0;
268 }