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 } 269