Update contrib.
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * Symbian implementation of LEFontInstance
27 #include "layout/LETypes.h"
28 #include "layout/LEFontInstance.h"
29 #include "layout/LESwaps.h"
31 #include "SymbianFontInstance.h"
34 // Finds the high bit by binary searching
35 // through the bits in n.
37 le_int8 SymbianFontInstance::highBit(le_int32 value)
79 // This is used to build a shaper which does not require the rasteriser
80 // to support table access. This is required for interworking testing.
81 // #define TRUETYPE_EXTENSION_NOT_SUPPORTED
82 #ifndef TRUETYPE_EXTENSION_NOT_SUPPORTED
85 SymbianFontInstance::SymbianFontInstance(CBitmapFont *aBitmapFont,
86 LEErrorCode &status, le_bool aKeepGlyphOfZWJ)
87 : fFile(NULL), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
88 fDirectory(NULL), fCMAPMapper(NULL), fHMTXTable(0), fNumGlyphs(0),
89 fNumLongHorMetrics(0), iFont(aBitmapFont), iKeepGlyphOfZWJ(aKeepGlyphOfZWJ)
92 // get the OpenFont details
93 if (!aBitmapFont->IsOpenFont())
95 // the font supplied was not a Openfont so ..
96 status = LE_ILLEGAL_ARGUMENT_ERROR;
100 COpenFont* font = aBitmapFont->OpenFont();
102 // get the extended interface
104 font->ExtendedInterface(KUidOpenFontShapingExtension, ext);
105 MOpenFontShapingExtension* extensionInterface
106 = reinterpret_cast<MOpenFontShapingExtension*>(ext);
108 font->ExtendedInterface(KUidOpenFontTrueTypeExtension, ext);
109 MOpenFontTrueTypeExtension* trueTypeExtensionInterface
110 = reinterpret_cast<MOpenFontTrueTypeExtension*>(ext);
112 /* Currently if the trueTypeExtensionInterface is not available the
113 truetype tables are accessed directly rather than via the rasteriser */
114 if (!extensionInterface /* || !trueTypeExtensionInterface*/)
116 // this rasterizer does not support the required interface
117 // so do not bother to shape
118 status = LE_ILLEGAL_ARGUMENT_ERROR;
122 iTrueTypeExtensionInterface = trueTypeExtensionInterface;
123 iExtensionInterface = extensionInterface;
125 // get the font file name from the COpenFontFile in the COpenFont
126 TBuf8<KMaxFileName> fontFileName;
127 fontFileName.Copy(font->File()->FileName());
128 fontFileName.ZeroTerminate();
130 /* get the font metrics via the rasterizer */
131 MOpenFontShapingExtension::TExtensionFontMetrics fontMetrics;
132 extensionInterface->GetExtensionFontMetrics(fontMetrics);
134 /* The number of font design units per em. */
135 fUnitsPerEM = fontMetrics.iUnitsPerEm;
137 /* The size of the font's em square in pixels. */
138 fXPixelsPerEm = fontMetrics.iXPixelsPerEm;
139 fYPixelsPerEm = fontMetrics.iYPixelsPerEm;
141 /* Scaling factors, pixels per font unit. */
142 fDeviceScaleY = fontMetrics.iYScaleFactor;
143 fDeviceScaleX = fontMetrics.iXScaleFactor;
145 // open the font file
146 fFile = fopen( (char *)fontFileName.Ptr(), "rb");
149 status = LE_FONT_FILE_NOT_FOUND_ERROR;
153 // read in the directory
154 SFNTDirectory tempDir;
156 fread(&tempDir, sizeof tempDir, 1, fFile);
158 le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
159 const LETag headTag = LE_HEAD_TABLE_TAG;
160 const LETag hheaTag = LE_HHEA_TABLE_TAG;
161 const HEADTable *headTable = NULL;
162 const HHEATable *hheaTable = NULL;
163 le_uint16 numTables = 0;
165 //coverity[incorrect_multiplication]
166 //coverity[buffer_alloc]
167 // dirSize is The actually sizoe of fDirectory which indeed contains more data thant SFNTDirectory defined.
168 fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
170 if (fDirectory == NULL)
172 status = LE_MEMORY_ALLOCATION_ERROR;
176 fseek(fFile, 0L, SEEK_SET);
177 fread((void *) fDirectory, sizeof(char), dirSize, fFile);
180 // We calculate these numbers 'cause some fonts
181 // have bogus values for them in the directory header.
183 numTables = SWAPW(fDirectory->numTables);
184 fDirPower = 1 << highBit(numTables);
185 fDirExtra = numTables - fDirPower;
187 // read unitsPerEm from 'head' table
188 headTable = (const HEADTable *) readFontTable(headTag);
190 if (headTable == NULL)
192 status = LE_MISSING_FONT_TABLE_ERROR;
196 fUnitsPerEM = SWAPW(headTable->unitsPerEm);
197 deleteTable(headTable);
199 hheaTable = (HHEATable *) readFontTable(hheaTag);
201 if (hheaTable == NULL)
203 status = LE_MISSING_FONT_TABLE_ERROR;
207 fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
208 fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
209 fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
211 fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
213 deleteTable((void *) hheaTable);
215 fCMAPMapper = findUnicodeMapper();
217 if (fCMAPMapper == NULL)
219 status = LE_MISSING_FONT_TABLE_ERROR;
231 SymbianFontInstance::~SymbianFontInstance()
236 deleteTable(fHMTXTable);
238 LE_DELETE_ARRAY(fDirectory);
243 /* read the font directly. This is used if rasterizers do not support
244 the trueTypeExtensionInterface */
246 SymbianFontInstance::SymbianFontInstance(CBitmapFont *aBitmapFont,
248 : fFile(NULL), fUnitsPerEM(0), fAscent(0), fDescent(0), fLeading(0),
249 fDirectory(NULL), fCMAPMapper(NULL), fHMTXTable(0), fNumGlyphs(0),
250 fNumLongHorMetrics(0), iFont(aBitmapFont)
253 // get the OpenFont details
254 if (!aBitmapFont->IsOpenFont())
256 // the font supplied was not a Openfont so ..
257 status = LE_ILLEGAL_ARGUMENT_ERROR;
261 COpenFont* font = aBitmapFont->OpenFont();
263 // get the extended interface
265 font->ExtendedInterface(KUidOpenFontShapingExtension, ext);
266 iExtensionInterface = reinterpret_cast<MOpenFontShapingExtension*>(ext);
268 // do not use the true type interface
269 iTrueTypeExtensionInterface = 0;
271 if (!iExtensionInterface )
273 // this rasterizer does not support the required interface
274 // so do not bother to shape
275 status = LE_ILLEGAL_ARGUMENT_ERROR;
279 // get the font file name from the COpenFontFile in the COpenFont
280 TBuf8<KMaxFileName> fontFileName;
281 fontFileName.Copy(font->File()->FileName());
282 fontFileName.ZeroTerminate();
284 /* get the font metrics via the rasterizer */
285 MOpenFontShapingExtension::TExtensionFontMetrics fontMetrics;
286 iExtensionInterface->GetExtensionFontMetrics(fontMetrics);
288 /* The number of font design units per em. */
289 fUnitsPerEM = fontMetrics.iUnitsPerEm;
291 /* The size of the font's em square in pixels. */
292 fXPixelsPerEm = fontMetrics.iXPixelsPerEm;
293 fYPixelsPerEm = fontMetrics.iYPixelsPerEm;
295 /* Scaling factors, pixels per font unit. */
296 fDeviceScaleY = fontMetrics.iYScaleFactor;
297 fDeviceScaleX = fontMetrics.iXScaleFactor;
299 // open the font file
300 fFile = fopen( (char *)fontFileName.Ptr(), "rb");
303 status = LE_FONT_FILE_NOT_FOUND_ERROR;
307 // read in the directory
308 SFNTDirectory tempDir;
310 fread(&tempDir, sizeof tempDir, 1, fFile);
312 le_int32 dirSize = sizeof tempDir + ((SWAPW(tempDir.numTables) - ANY_NUMBER) * sizeof(DirectoryEntry));
313 const LETag headTag = LE_HEAD_TABLE_TAG;
314 const LETag hheaTag = LE_HHEA_TABLE_TAG;
315 const HEADTable *headTable = NULL;
316 const HHEATable *hheaTable = NULL;
317 le_uint16 numTables = 0;
319 fDirectory = (const SFNTDirectory *) LE_NEW_ARRAY(char, dirSize);
321 if (fDirectory == NULL)
323 status = LE_MEMORY_ALLOCATION_ERROR;
327 fseek(fFile, 0L, SEEK_SET);
328 fread((void *) fDirectory, sizeof(char), dirSize, fFile);
331 // We calculate these numbers 'cause some fonts
332 // have bogus values for them in the directory header.
334 numTables = SWAPW(fDirectory->numTables);
335 fDirPower = 1 << highBit(numTables);
336 fDirExtra = numTables - fDirPower;
338 // read unitsPerEm from 'head' table
339 headTable = (const HEADTable *) readFontTable(headTag);
341 if (headTable == NULL)
343 status = LE_MISSING_FONT_TABLE_ERROR;
347 fUnitsPerEM = SWAPW(headTable->unitsPerEm);
348 deleteTable(headTable);
350 hheaTable = (HHEATable *) readFontTable(hheaTag);
352 if (hheaTable == NULL)
354 status = LE_MISSING_FONT_TABLE_ERROR;
358 fAscent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->ascent));
359 fDescent = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->descent));
360 fLeading = (le_int32) yUnitsToPoints((float) SWAPW(hheaTable->lineGap));
362 fNumLongHorMetrics = SWAPW(hheaTable->numOfLongHorMetrics);
364 deleteTable((void *) hheaTable);
366 fCMAPMapper = findUnicodeMapper();
368 if (fCMAPMapper == NULL)
370 status = LE_MISSING_FONT_TABLE_ERROR;
382 SymbianFontInstance::~SymbianFontInstance()
388 deleteTable(fHMTXTable);
392 LE_DELETE_ARRAY(fDirectory);
399 void SymbianFontInstance::deleteTable(const void *table) const
401 LE_DELETE_ARRAY(table);
404 const DirectoryEntry *SymbianFontInstance::findTable(LETag tag) const
406 if (fDirectory != NULL)
409 le_uint16 probe = fDirPower;
411 if (SWAPL(fDirectory->tableDirectory[fDirExtra].tag) <= tag)
416 while (probe > (1 << 0))
420 if (SWAPL(fDirectory->tableDirectory[table + probe].tag) <= tag)
426 if (SWAPL(fDirectory->tableDirectory[table].tag) == tag)
428 return &fDirectory->tableDirectory[table];
435 const void *SymbianFontInstance::readTable(LETag aTag, le_uint32 *aLength) const
439 /* If the current rasteriser supports the TrueTypeExtensionInterface
440 use it to access the true Type tables */
441 if (iTrueTypeExtensionInterface)
445 TAny * trueTypeTable = iTrueTypeExtensionInterface->
446 GetTrueTypeTable(error, aTag, &length);
457 // allocate some memory for the table & copy table into it
458 table = LE_NEW_ARRAY(char, length);
461 // copy the table from the rasteriser
462 Mem::Copy(table, (char *) trueTypeTable, length);
465 iTrueTypeExtensionInterface->ReleaseTrueTypeTable(trueTypeTable);
469 // old method, read the table directly
470 const DirectoryEntry *entry = findTable(aTag);
479 TInt length = SWAPL(entry->length);
483 table = LE_NEW_ARRAY(char, length);
487 fseek(fFile, SWAPL(entry->offset), SEEK_SET);
488 fread(table, sizeof(char), length, fFile);
495 const void *SymbianFontInstance::getFontTable(LETag tableTag) const
497 if (iTrueTypeExtensionInterface)
500 return iTrueTypeExtensionInterface->GetTrueTypeTable(error, tableTag, 0);
502 return FontTableCache::find(tableTag);
505 const void *SymbianFontInstance::readFontTable(LETag tableTag) const
507 return readTable(tableTag, 0);
510 CMAPMapper *SymbianFontInstance::findUnicodeMapper()
512 LETag cmapTag = LE_CMAP_TABLE_TAG;
513 const CMAPTable *cmap = (CMAPTable *) readFontTable(cmapTag);
515 return cmap ? CMAPMapper::createUnicodeMapper(cmap) : NULL;
518 void SymbianFontInstance::getGlyphAdvance(
519 LEGlyphID aGlyph, LEPoint &aAdvance) const
521 TInt glyph = LE_GET_GLYPH(aGlyph) | 0x80000000;
522 TOpenFontCharMetrics metrics;
523 const TUint8* bitmap = 0;
525 // If an FFFF glyph code is received, avoid trying to rasterize it as there
526 // is no character data associated with FFFF.
527 // This will avoid the overhead of trying to rasterize it.
528 if (glyph == 0x8000FFFF)
535 if (!iFont->GetCharacterData(iSessionHandle, glyph, metrics, bitmap))
537 // Glyph not yet rasterized; rasterize it ourselves
538 iFont->Rasterize(iSessionHandle, glyph, 0);
539 if (!iFont->GetCharacterData(iSessionHandle, glyph, metrics, bitmap))
546 aAdvance.fX = metrics.HorizAdvance();
551 le_bool SymbianFontInstance::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const
555 if (!iExtensionInterface->GlyphPointInHintedPixels(
556 glyph, pointNumber, x, y ))
563 void SymbianFontInstance::transformFunits(float xFunits, float yFunits, LEPoint &pixels) const
565 pixels.fX = xFunits / fUnitsPerEM * fXPixelsPerEm;
566 pixels.fY = yFunits / fUnitsPerEM * fYPixelsPerEm;
569 float SymbianFontInstance::xUnitsToPoints(float xUnits) const
571 // Seems like this function should have been called xUnitsToPixels?!
572 return xUnits / fUnitsPerEM * fXPixelsPerEm;
575 float SymbianFontInstance::yUnitsToPoints(float yUnits) const
577 // Seems like this function should have been called yUnitsToPixels?!
578 return yUnits / fUnitsPerEM * fYPixelsPerEm;
581 float SymbianFontInstance::getXPixelsPerEm() const
583 return fXPixelsPerEm;
586 float SymbianFontInstance::getYPixelsPerEm() const
588 return fYPixelsPerEm;
591 float SymbianFontInstance::getScaleFactorX() const
593 return fDeviceScaleX;
596 float SymbianFontInstance::getScaleFactorY() const
598 return fDeviceScaleY;