Update contrib.
2 * Copyright (c) 1996-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.
22 #include <graphics/openfontconstants.h>
24 #include "OstTraceDefinitions.h"
25 #ifdef OST_TRACE_COMPILER_IN_USE
26 #include "FNTBODYTraces.h"
30 CFontStoreFile::CFontStoreFile()
31 : iCollectionUid(KNullUid),
35 iDataStreamId(KNullStreamId)
39 void CFontStoreFile::ConstructL(const TParse& aParse,RFs& aFs)
42 User::LeaveIfError(RFs::CharToDrive(aParse.Drive()[0], drive));
44 User::LeaveIfError(aFs.Drive(driveinfo, drive));
48 iFullName = aParse.FullName().AllocL();
49 User::LeaveIfError(file.Open(aFs, *iFullName, EFileStream | EFileRead | EFileShareReadersOnly));
51 // check to see if the fonts are stored on ROM. Note that NAND != rom so font files in NAND devices
52 // must be handled as if they were in RAM. A NULL pointer returned by IsFileInRom means its RAM
54 if (aFs.IsFileInRom(*iFullName)!=NULL)
56 // fonts are stored on a XIP (execute in place) device
57 TInt ret = file.Seek(ESeekAddress, iFileAddress);
66 // convert RFile into a CDirectFileStore
67 CDirectFileStore* fileStore = CDirectFileStore::FromLC(file);
69 if (fileStore->Type()[1] != TUid::Uid(KFontStoreFileUidVal))
70 User::Leave(KErrNotSupported);
71 TStreamId headerid = fileStore->Root();
72 RStoreReadStream stream;
73 stream.OpenLC(*fileStore, headerid);
74 TInt fnttranversion = stream.ReadInt32L();
75 // This works for version 42 (with new metrics) and for earlier versions
76 // which will synthesize the required metrics. It may have to be changed
77 // if the version number is incremented again.
78 if (fnttranversion < (KFnttranVersion - 1) && fnttranversion != KFnttran7650Version)
79 User::Leave(KErrNotSupported);
80 iFontVersion = fnttranversion;
81 stream >> iCollectionUid;
82 iKPixelAspectRatio = stream.ReadInt32L();
83 stream >> iDataStreamId;
84 CleanupStack::PopAndDestroy(&stream); // close root stream
85 // ensure font data stream can be opened
86 stream.OpenLC(*fileStore, iDataStreamId);
87 CleanupStack::PopAndDestroy(&stream); // close font stream
88 // transfer ownership of fileStore
89 CleanupStack::Pop(fileStore);
90 iFileStore = fileStore;
93 CFontStoreFile* CFontStoreFile::NewL(const TParse& aParse, RFs& aFs)
95 CFontStoreFile* fontstorefile = new(ELeave) CFontStoreFile;
96 CleanupStack::PushL(fontstorefile);
97 fontstorefile->ConstructL(aParse, aFs);
102 CFontStoreFile::~CFontStoreFile()
110 TBitmapCodeSection::TBitmapCodeSection()
117 //This method is called from CFontBitmap::InternalizeL.
118 //We have to read stream IDs from the stream, not offsets.
119 //Obviously the method is called once per life time of
120 //CFontBitmap instance.
121 void TBitmapCodeSection::InternalizeL(RReadStream &aStream)
123 iStart = aStream.ReadUint16L();
124 iEnd = aStream.ReadUint16L();
125 aStream >> iCharacterData.iOffsetsId;
126 aStream >> iBitmapData.iBitmapId;
129 //This method is called from CFontBitmap::RestoreComponentsL -
130 //if the CFontBitmap instance is in RAM and CFontBitmap::iComponentsRestored is EFalse.
131 //We use here stream IDs, not offsets.
132 //If the memory allocation for the offsets doesn't fail - aAllocMemCounter is incremented
133 //After calling of TBitmapCodeSection::InternalizeOffsetsL character metrics streamID is no more valid -
134 //we have valid character metrics offset into RAM memory.
135 void TBitmapCodeSection::InternalizeOffsetsL(const CStreamStore& aStreamStore, RHeap* aHeap, TInt& aAllocMemCounter)
137 RStoreReadStream stream;
138 stream.OpenLC(aStreamStore, iCharacterData.iOffsetsId);
140 TInt size = stream.ReadInt32L();
141 TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*)aHeap->AllocL(sizeof(TBitmapFontCharacterOffset) * size);
143 iCharacterData.iCharacterOffsetsListOffset = TInt(characterOffsetsList) - TInt(this);
144 TBitmapFontCharacterOffset* pEnd = characterOffsetsList + size;
145 for (TBitmapFontCharacterOffset* p = characterOffsetsList; p < pEnd; p++)
147 p->InternalizeL(stream);
150 CleanupStack::PopAndDestroy();
153 //This method is called from CFontBitmap::RestoreComponentsL -
154 //if the CFontBitmap instance is in RAM and CFontBitmap::iComponentsRestored is EFalse.
155 //We use here stream IDs, not offsets.
156 //If the memory allocation for the bitmap doesn't fail - aAllocMemCounter is incremented
157 //After calling of TBitmapCodeSection::InternalizeBitmapL bitmap streamID is no more valid -
158 //we have valid bitmap offset into RAM memory.
159 void TBitmapCodeSection::InternalizeBitmapL(const CStreamStore& aStreamStore, RHeap* aHeap, TInt& aAllocMemCounter)
161 RStoreReadStream stream;
162 stream.OpenLC(aStreamStore, iBitmapData.iBitmapId);
164 TInt size = stream.ReadInt32L();
165 TUint8* bitmap = (TUint8*)aHeap->AllocL(size);
167 iBitmapData.iBitmapOffset = TInt(bitmap) - TInt(this);
168 stream.ReadL(bitmap, size);
170 CleanupStack::PopAndDestroy();
173 //This method is called from CFontBitmap::InternalizeL if the
174 //CFontBitmap instance is in ROM.
175 //We use here stream IDs to calculate offsets.
176 //After calling of TBitmapCodeSection::FixUpComponents streamIDs are no more valid -
177 //we have valid offsets into ROM memory.
178 //Obviously the method is called once per life time of
179 //CFontBitmap instance.
180 void TBitmapCodeSection::FixUpComponents(TInt aFileAddress)
182 TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*) (aFileAddress + sizeof(TInt) + iCharacterData.iOffsetsId);
183 iCharacterData.iCharacterOffsetsListOffset = TInt(characterOffsetsList);
184 TUint8* bitmap = (TUint8*) (aFileAddress + sizeof(TInt) + iBitmapData.iBitmapId);
185 iBitmapData.iBitmapOffset = TInt(bitmap);
188 //This method is caled from CFontBitmap::DeleteComponents(),
189 //only if the CFontBitmap instance is in RAM.
190 void TBitmapCodeSection::DeleteOffsets(RHeap* aHeap)
192 TBitmapFontCharacterOffset* charactersOffsetsList = CharacterOffsetsList(ETrue);
193 if(TUint32(this) != TUint32(charactersOffsetsList))
195 aHeap->Free(charactersOffsetsList);
199 //This method is caled from CFontBitmap::DeleteComponents(),
200 //only if the CFontBitmap instance is in RAM.
201 void TBitmapCodeSection::DeleteBitmap(RHeap* aHeap)
203 TUint8* bitmap = Bitmap(ETrue);
204 if(TUint32(this) != TUint32(bitmap))
210 TBitmapFontCharacterOffset* TBitmapCodeSection::CharacterOffsetsList(TBool aIsInRAM) const
212 return reinterpret_cast <TBitmapFontCharacterOffset*>
213 (iCharacterData.iCharacterOffsetsListOffset + (aIsInRAM ? TInt(this) : 0));
216 TUint8* TBitmapCodeSection::Bitmap(TBool aIsInRAM) const
218 return reinterpret_cast <TUint8*>
219 (iBitmapData.iBitmapOffset + (aIsInRAM ? TInt(this) : 0));
222 TCharacterMetricsTable::TCharacterMetricsTable(RHeap* aHeap)
224 iMetricsStartId(KNullStreamId),
225 iCharacterMetricsStartPtr(0),
227 iMetricsOnHeap(EFalse)
230 void TCharacterMetricsTable::InternalizeL(RReadStream& aStream)
232 iMetricsStartId = aStream.ReadInt32L();
233 iNumberOfMetrics = aStream.ReadInt32L();
236 void TCharacterMetricsTable::InternalizeMetricsL(RReadStream& aStream)
238 aStream.ReadInt32L(); // size
239 TBitmapFontCharacterMetrics* charactermetricslist = static_cast<TBitmapFontCharacterMetrics*>(iHeap->AllocL(sizeof(TBitmapFontCharacterMetrics) * iNumberOfMetrics));
240 iMetricsOnHeap = ETrue;
241 // Offset from this to location on the heap ('cos the file is not in ROM)
242 iCharacterMetricsStartPtr = reinterpret_cast<TInt>(charactermetricslist) - reinterpret_cast<TInt>(this);
243 TBitmapFontCharacterMetrics* pEnd = charactermetricslist + iNumberOfMetrics;
244 for (TBitmapFontCharacterMetrics* p = charactermetricslist; p < pEnd; p++)
246 p->InternalizeL(aStream);
250 void TCharacterMetricsTable::RestoreL(const CStreamStore& aStreamStore)
252 if (iCharacterMetricsStartPtr == 0)
253 { // We haven't already read it in from RAM file
254 RStoreReadStream stream;
255 stream.OpenLC(aStreamStore, iMetricsStartId);
256 InternalizeMetricsL(stream);
257 CleanupStack::PopAndDestroy();
261 void TCharacterMetricsTable::FixUp(TInt aFileAddress)
263 TBitmapFontCharacterMetrics* charactermetricslist = reinterpret_cast<TBitmapFontCharacterMetrics*>(aFileAddress + sizeof(TInt) + iMetricsStartId.Value());
264 iCharacterMetricsStartPtr = TInt(charactermetricslist); // Ptr to location in a ROM file
265 iMetricsStartId = KNullStreamId;
266 iMetricsOnHeap = EFalse;
269 void TCharacterMetricsTable::Delete()
270 { // This routine is only called if the font file is in RAM, not ROM, and therefore the metrics have been stashed on the heap
271 if (iMetricsOnHeap && iCharacterMetricsStartPtr)
273 iHeap->Free(reinterpret_cast<TAny*>(MetricsFromOffset(0)));
274 iCharacterMetricsStartPtr = 0;
275 iMetricsOnHeap = EFalse;
279 const TBitmapFontCharacterMetrics* TCharacterMetricsTable::Metric(TInt aIndex) const
281 if ((aIndex < 0) || (aIndex > iNumberOfMetrics))
283 OstTraceExt2( TRACE_FATAL, TCHARACTERMETRICSTABLE_METRIC, "TCharacterMetricsTable::Metric, aIndex=%d, iNumberOfMetrics=%d, Panic(EFntMetricsIndexOutOfBounds)", aIndex, iNumberOfMetrics);
284 __ASSERT_DEBUG(0, Panic(EFntMetricsIndexOutOfBounds));
286 // Sometimes the start ptr is to a metrics heap item and sometimes it points into a ROM file
289 // Start ptr is to metrics heap item
290 return MetricsFromOffset(aIndex);
294 // Start ptr is to a file in ROM
295 return reinterpret_cast<const TBitmapFontCharacterMetrics*> (iCharacterMetricsStartPtr + (aIndex * sizeof(TBitmapFontCharacterMetrics)));
299 TInt TCharacterMetricsTable::NumberOfMetrics() const
301 return iNumberOfMetrics;
304 TBitmapFontCharacterMetrics* TCharacterMetricsTable::MetricsFromOffset(TInt aIndex) const
306 __ASSERT_DEBUG(iMetricsOnHeap,Panic(EFntMetricsNotOnHeap));
307 return reinterpret_cast<TBitmapFontCharacterMetrics*>(reinterpret_cast<TInt>(this) + iCharacterMetricsStartPtr+ (aIndex * sizeof(TBitmapFontCharacterMetrics)));
310 CFontBitmap::CFontBitmap(RHeap* aHeap, CFontStoreFile* aFontStoreFile)
312 iFontStoreFileOffset(0),
317 iIsInRAM(!aFontStoreFile->iFileAddress),
319 iCellHeightInPixels(0),
321 iMaxCharWidthInPixels(0),
322 iMaxNormalCharWidthInPixels(0),
325 iCodeSectionListOffset(0),
326 iCharacterMetricsTable(aHeap),
327 iComponentsRestored(EFalse),
328 iAllocMemCounter_Offsets(0),
329 iAllocMemCounter_Bitmaps(0),
330 iFontCapitalAscent(0),
332 iFontStandardDescent(0),
336 iFontStoreFileOffset = TInt(aFontStoreFile) - TInt(this);
339 void CFontBitmap::InternalizeL(RReadStream &aStream, TInt aFontVersion)
342 iPosture = aStream.ReadInt8L();
343 iStrokeWeight = aStream.ReadInt8L();
344 iIsProportional = aStream.ReadInt8L();
345 iCellHeightInPixels = aStream.ReadInt8L();
346 iAscentInPixels = aStream.ReadInt8L();
347 iMaxCharWidthInPixels = aStream.ReadInt8L();
348 iMaxNormalCharWidthInPixels = aStream.ReadInt8L();
349 if ( aFontVersion >= KFnttranVersion )
350 { // read the new metrics in
351 iFontCapitalAscent = aStream.ReadInt8L();
352 iFontMaxAscent = aStream.ReadInt8L();
353 iFontStandardDescent = aStream.ReadInt8L();
354 iFontMaxDescent = aStream.ReadInt8L();
355 iFontLineGap = aStream.ReadInt8L();
357 else // synthesize the extra metrics (data compatibility with third party bitmap fonts for old phones)
359 iFontMaxAscent = iFontCapitalAscent = iAscentInPixels;
360 iFontMaxDescent = iFontStandardDescent = iCellHeightInPixels - iAscentInPixels;
361 iFontLineGap = ( ( iCellHeightInPixels * 12 ) + 5) / 10; // 1.2 times design height
363 iBitmapEncoding = aStream.ReadInt32L();
364 iCharacterMetricsTable.InternalizeL(aStream);
365 const TBool fixup = FontStoreFile()->iFileAddress;
368 iCharacterMetricsTable.FixUp(FontStoreFile()->iFileAddress);
370 iNumCodeSections = aStream.ReadInt32L();
371 TBitmapCodeSection* codesectionlist = (TBitmapCodeSection*)User::LeaveIfNull(iHeap->AllocL(iNumCodeSections * sizeof(TBitmapCodeSection)));
372 iCodeSectionListOffset = TInt(codesectionlist) - TInt(this);
373 for (TInt i = 0; i < iNumCodeSections; i++)
375 new(codesectionlist + i) TBitmapCodeSection;
376 codesectionlist[i].InternalizeL(aStream);
378 codesectionlist[i].FixUpComponents(FontStoreFile()->iFileAddress);
382 void CFontBitmap::UseL()
384 // Note object is created with a Usage Count of 1.
385 // So incrementing to 2 normally indicates the first external reference.
387 if (iUsageCount == 2)
389 RestoreComponentsL();
393 void CFontBitmap::Release()
397 { // object and all its users have closed
403 Get the metrics for a given character.
404 Return aBytes as null if the character aCode doesn't exist in the font.
406 TBitmapFontCharacterMetrics CFontBitmap::CharacterMetrics(TInt aCode, const TUint8*& aBytes) const
408 const TBitmapCodeSection* matchSection = NULL;
409 const TBitmapCodeSection* const lastSection = CodeSectionList() + iNumCodeSections - 1;
411 TBitmapFontCharacterOffset offset;
414 TBitmapFontCharacterMetrics metrics;
415 const TBitmapCodeSection* startSearchBand = CodeSectionList();
416 TInt numCodeSectionsRemaining = iNumCodeSections;
417 while (numCodeSectionsRemaining >= 1)
419 TInt halfNumCodeSectionsRemaining = numCodeSectionsRemaining/2;
420 const TBitmapCodeSection* centralSearchBand = startSearchBand+halfNumCodeSectionsRemaining;
421 if ((aCode >= centralSearchBand->iStart) && (aCode <= centralSearchBand->iEnd))
423 matchSection = centralSearchBand;
426 else if ((aCode < centralSearchBand->iStart) || (centralSearchBand == lastSection))
427 numCodeSectionsRemaining = halfNumCodeSectionsRemaining;
430 startSearchBand = centralSearchBand + 1;
431 numCodeSectionsRemaining -= halfNumCodeSectionsRemaining + 1;
437 offset =* ((matchSection->CharacterOffsetsList(iIsInRAM)) + (aCode-matchSection->iStart));
439 // Fill characters within code section.
440 // Recursive call ensures that a valid metric is always returned.
441 if (offset.iBitmapOffset == KFillCharacterOffset)
443 return CharacterMetrics(KReplacementCharacter, aBytes);
446 aBytes = matchSection->Bitmap(iIsInRAM) + offset.iBitmapOffset;
448 // retrieve metric index from encoded 1 or 2 bytes
450 TUint8 byte1 = (TUint8)*aBytes;
451 const TInt switchMask = 0x1;
452 const TBool oneByteIndex =! (byte1 & switchMask);
453 byte1 = TUint8(byte1 >> 1);
461 const TUint8 byte2 = (TUint8)(*(aBytes + 1));
462 index = byte1 + (byte2 * 128);
465 // Copy metric from table
466 metrics =* iCharacterMetricsTable.Metric(index);
471 void CFontBitmap::operator delete(TAny *aThis)
473 if (((CFontBitmap *)aThis)->iHeap)
475 ((CFontBitmap *)aThis)->iHeap->Free(aThis);
479 void CFontBitmap::SetPosture(TFontPosture aPosture)
481 iPosture = (TInt8)aPosture;
484 TFontPosture CFontBitmap::Posture() const
486 return (TFontPosture)iPosture; // iPosture is always smaller than TFontPosture
489 void CFontBitmap::SetStrokeWeight(TFontStrokeWeight aStrokeWeight)
491 iStrokeWeight = (TInt8)aStrokeWeight;
494 TFontStrokeWeight CFontBitmap::StrokeWeight() const
496 return (TFontStrokeWeight)iStrokeWeight;
499 void CFontBitmap::SetIsProportional(TBool aIsProportional)
501 iIsProportional = (TInt8)aIsProportional;
504 TBool CFontBitmap::IsProportional() const
506 return iIsProportional;
509 CFontStoreFile* CFontBitmap::FontStoreFile() const
511 TInt fsf = TInt(this) + iFontStoreFileOffset;
512 return (CFontStoreFile*)fsf;
515 CFontBitmap::~CFontBitmap()
518 TBitmapCodeSection* codeSectionList = CodeSectionList();
519 if(TUint32(this) != TUint32(codeSectionList))
521 iHeap->Free(codeSectionList);
523 iCodeSectionListOffset = 0;
526 //We have to count how many offsets and bitmaps are allocated successfully because if
527 //some of codesection's Internalize..L fails we have to deallocate the right amount of
529 void CFontBitmap::RestoreComponentsL()
533 if(!iComponentsRestored)
535 iAllocMemCounter_Offsets = 0;
536 iAllocMemCounter_Bitmaps = 0;
537 CStreamStore& store =* FontStoreFile()->iFileStore;
538 for (TInt i = 0; i < iNumCodeSections; i++)
540 CodeSectionList()[i].InternalizeOffsetsL(store, iHeap, iAllocMemCounter_Offsets);
541 CodeSectionList()[i].InternalizeBitmapL(store, iHeap, iAllocMemCounter_Bitmaps);
543 iCharacterMetricsTable.RestoreL(store);
545 iComponentsRestored = ETrue;
549 void CFontBitmap::DeleteComponents()
554 for (i = 0; i < iAllocMemCounter_Offsets; i++)
556 CodeSectionList()[i].DeleteOffsets(iHeap);
558 for (i = 0; i < iAllocMemCounter_Bitmaps; i++)
560 CodeSectionList()[i].DeleteBitmap(iHeap);
562 iCharacterMetricsTable.Delete();
564 iAllocMemCounter_Offsets = 0;
565 iAllocMemCounter_Bitmaps = 0;
566 iComponentsRestored = EFalse;
569 TBitmapCodeSection* CFontBitmap::CodeSectionList() const
571 TInt bcs = TInt(this) + iCodeSectionListOffset;
572 return (TBitmapCodeSection*)bcs;
575 TTypefaceFontBitmap::TTypefaceFontBitmap()
583 TTypefaceFontBitmap::TTypefaceFontBitmap(TTypeface* aTypeface,CFontBitmap* aFontBitmap)
584 : iTypeface(aTypeface),
585 iFontBitmap(aFontBitmap),
591 TInt TTypefaceFontBitmap::HeightInPixels() const
593 return iFontBitmap->iCellHeightInPixels * iHeightFactor;