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
PortableFontInstance(hb_face_t * face,float xScale,float yScale,LEErrorCode & status)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
~PortableFontInstance()62 PortableFontInstance::~PortableFontInstance()
63 {
64 if (fCMAPMapper)
65 delete fCMAPMapper;
66 }
67
getFontTable(LETag tableTag) const68 const void *PortableFontInstance::getFontTable(LETag tableTag) const
69 {
70 return FontTableCache::find(tableTag);
71 }
72
readFontTable(LETag tableTag) const73 hb_blob_t *PortableFontInstance::readFontTable(LETag tableTag) const
74 {
75 return hb_face_reference_table(fFace, tableTag);
76 }
77
findUnicodeMapper()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
getNameString(le_uint16 nameID,le_uint16 platformID,le_uint16 encodingID,le_uint16 languageID) const90 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
getUnicodeNameString(le_uint16 nameID,le_uint16 platformID,le_uint16 encodingID,le_uint16 languageID) const123 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
deleteNameString(const char * name) const159 void PortableFontInstance::deleteNameString(const char *name) const
160 {
161 DELETE_ARRAY(name);
162 }
163
deleteNameString(const LEUnicode16 * name) const164 void PortableFontInstance::deleteNameString(const LEUnicode16 *name) const
165 {
166 DELETE_ARRAY(name);
167 }
168
getGlyphAdvance(LEGlyphID glyph,LEPoint & advance) const169 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
getGlyphPoint(LEGlyphID,le_int32,LEPoint &) const201 le_bool PortableFontInstance::getGlyphPoint(LEGlyphID /*glyph*/, le_int32 /*pointNumber*/, LEPoint &/*point*/) const
202 {
203 return FALSE;
204 }
205
getUnitsPerEM() const206 le_int32 PortableFontInstance::getUnitsPerEM() const
207 {
208 return fUnitsPerEM;
209 }
210
getFontChecksum() const211 le_uint32 PortableFontInstance::getFontChecksum() const
212 {
213 return 0;
214 }
215
getAscent() const216 le_int32 PortableFontInstance::getAscent() const
217 {
218 return fAscent;
219 }
220
getDescent() const221 le_int32 PortableFontInstance::getDescent() const
222 {
223 return fDescent;
224 }
225
getLeading() const226 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...
mapCharToGlyph(LEUnicode32 ch,const LECharMapper * mapper,le_bool filterZeroWidth) const233 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...
mapCharToGlyph(LEUnicode32 ch,const LECharMapper * mapper) const240 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
241 {
242 return LEFontInstance::mapCharToGlyph(ch, mapper);
243 }
244
mapCharToGlyph(LEUnicode32 ch) const245 LEGlyphID PortableFontInstance::mapCharToGlyph(LEUnicode32 ch) const
246 {
247 return fCMAPMapper->unicodeToGlyph(ch);
248 }
249
getXPixelsPerEm() const250 float PortableFontInstance::getXPixelsPerEm() const
251 {
252 return fXScale;
253 }
254
getYPixelsPerEm() const255 float PortableFontInstance::getYPixelsPerEm() const
256 {
257 return fYScale;
258 }
259
getScaleFactorX() const260 float PortableFontInstance::getScaleFactorX() const
261 {
262 return 1.0;
263 }
264
getScaleFactorY() const265 float PortableFontInstance::getScaleFactorY() const
266 {
267 return 1.0;
268 }
269