Update contrib.
2 *******************************************************************************
4 * Copyright (C) 1999-2003, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: PortableFontInstance.cpp
10 * created on: 11/22/1999
11 * created by: Eric R. Mader
16 #include "layout/LETypes.h"
17 #include "layout/LEFontInstance.h"
18 #include "layout/LESwaps.h"
20 #include "PortableFontInstance.h"
27 // Finds the high bit by binary searching
28 // through the bits in n.
30 le_int8 PortableFontInstance::highBit(le_int32 value)
38 if (value >= 1 << 16) {
43 if (value >= 1 << 8) {
48 if (value >= 1 << 4) {
53 if (value >= 1 << 2) {
58 if (value >= 1 << 1) {
67 PortableFontInstance::PortableFontInstance(char *fileName, float pointSize, LEErrorCode &status)
68 : fFile(NULL), fUnitsPerEM(0), fPointSize(pointSize), fAscent(0), fDescent(0), fLeading(0),
69 fDirectory(NULL), fCMAPMapper(NULL), fHMTXTable(NULL), fNumGlyphs(0), fNumLongHorMetrics(0)
71 if (LE_FAILURE(status)) {
76 fFile = fopen(fileName, "rb");
79 status = LE_FONT_FILE_NOT_FOUND_ERROR;
83 // read in the directory
84 SFNTDirectory tempDir;
86 fread(&tempDir, sizeof tempDir, 1, fFile);
88 le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
89 const LETag headTag = LE_HEAD_TABLE_TAG;
90 const LETag hheaTag = LE_HHEA_TABLE_TAG;
91 const HEADTable *headTable = NULL;
92 const HHEATable *hheaTable = NULL;
93 le_uint16 numTables = 0;
95 fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
97 if (fDirectory == NULL) {
98 status = LE_MEMORY_ALLOCATION_ERROR;
102 fseek(fFile, 0L, SEEK_SET);
103 fread((void *) fDirectory, sizeof(char), dirSize, fFile);
106 // We calculate these numbers 'cause some fonts
107 // have bogus values for them in the directory header.
109 numTables = SWAPW(fDirectory->numTables);
110 fDirPower = 1 << highBit(numTables);
111 fDirExtra = numTables - fDirPower;
113 // read unitsPerEm from 'head' table
114 headTable = (const HEADTable *) readFontTable(headTag);
116 if (headTable == NULL) {
117 status = LE_MISSING_FONT_TABLE_ERROR;
121 fUnitsPerEM = SWAPW(headTable->unitsPerEm);
122 deleteTable(headTable);
124 hheaTable = (HHEATable *) readFontTable(hheaTag);
126 if (hheaTable == NULL) {
127 status = LE_MISSING_FONT_TABLE_ERROR;
131 fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
132 fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
133 fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
135 fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
137 deleteTable((void *) hheaTable);
139 fCMAPMapper = findUnicodeMapper();
141 if (fCMAPMapper == NULL) {
142 status = LE_MISSING_FONT_TABLE_ERROR;
154 PortableFontInstance::~PortableFontInstance()
159 deleteTable(fHMTXTable);
163 LE_DELETE_ARRAY(fDirectory);
167 void PortableFontInstance::deleteTable(const void *table) const
169 LE_DELETE_ARRAY(table);
172 const DirectoryEntry *PortableFontInstance::findTable(LETag tag) const
174 if (fDirectory != NULL) {
176 le_uint16 probe = fDirPower;
178 if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag) {
182 while (probe > (1 << 0)) {
185 if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag) {
190 if (SWAPL(fDirectory->tableDirectory[table].tag) == tag) {
191 return &fDirectory->tableDirectory[table];
198 const void *PortableFontInstance::readTable(LETag tag, le_uint32 *length) const
200 const DirectoryEntry *entry = findTable(tag);
207 *length = SWAPL(entry->length);
209 void *table = LE_NEW_ARRAY(char, *length);
212 fseek(fFile, SWAPL(entry->offset), SEEK_SET);
213 fread(table, sizeof(char), *length, fFile);
219 const void *PortableFontInstance::getFontTable(LETag tableTag) const
221 return FontTableCache::find(tableTag);
224 const void *PortableFontInstance::readFontTable(LETag tableTag) const
228 return readTable(tableTag, &len);
231 CMAPMapper *PortableFontInstance::findUnicodeMapper()
233 LETag cmapTag = LE_CMAP_TABLE_TAG;
234 const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
240 return CMAPMapper::createUnicodeMapper(cmap);
244 void PortableFontInstance::getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const
246 TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyph);
248 if (fHMTXTable == NULL) {
249 LETag maxpTag = LE_MAXP_TABLE_TAG;
250 LETag hmtxTag = LE_HMTX_TABLE_TAG;
251 const MAXPTable *maxpTable = (MAXPTable *) readFontTable(maxpTag);
252 PortableFontInstance *realThis = (PortableFontInstance *) this;
254 if (maxpTable != NULL) {
255 realThis->fNumGlyphs = SWAPW(maxpTable->numGlyphs);
256 deleteTable(maxpTable);
259 realThis->fHMTXTable = (const HMTXTable *) readFontTable(hmtxTag);
262 le_uint16 index = ttGlyph;
264 if (ttGlyph >= fNumGlyphs || fHMTXTable == NULL) {
265 advance.fX = advance.fY = 0;
269 if (ttGlyph >= fNumLongHorMetrics) {
270 index = fNumLongHorMetrics - 1;
273 advance.fX = xUnitsToPoints(SWAPW(fHMTXTable->hMetrics[index].advanceWidth));
277 le_bool PortableFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const