sl@0: /*
sl@0: * Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: * All rights reserved.
sl@0: * This component and the accompanying materials are made available
sl@0: * under the terms of "Eclipse Public License v1.0"
sl@0: * which accompanies this distribution, and is available
sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: *
sl@0: * Initial Contributors:
sl@0: * Nokia Corporation - initial contribution.
sl@0: *
sl@0: * Contributors:
sl@0: *
sl@0: * Description: 
sl@0: *
sl@0: */
sl@0: 
sl@0: 
sl@0: #include <s32file.h>
sl@0: #include <fntstore.h>
sl@0: #include "FNTBODY.H"
sl@0: #include <graphics/openfontconstants.h>
sl@0: 
sl@0: #include "OstTraceDefinitions.h"
sl@0: #ifdef OST_TRACE_COMPILER_IN_USE
sl@0: #include "FNTBODYTraces.h"
sl@0: #endif
sl@0: 
sl@0: 
sl@0: CFontStoreFile::CFontStoreFile()
sl@0:  :	iCollectionUid(KNullUid),
sl@0: 	iUsageCount(1),
sl@0: 	iFileStore(NULL),
sl@0: 	iFileAddress(0),
sl@0: 	iDataStreamId(KNullStreamId)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: void CFontStoreFile::ConstructL(const TParse& aParse,RFs& aFs)
sl@0: 	{
sl@0: 	TInt drive;
sl@0: 	User::LeaveIfError(RFs::CharToDrive(aParse.Drive()[0], drive));
sl@0: 	TDriveInfo driveinfo;
sl@0: 	User::LeaveIfError(aFs.Drive(driveinfo, drive));
sl@0: 	RFile file;
sl@0: 
sl@0: 	// store the filename
sl@0: 	iFullName = aParse.FullName().AllocL();
sl@0: 	User::LeaveIfError(file.Open(aFs, *iFullName, EFileStream | EFileRead | EFileShareReadersOnly));
sl@0: 
sl@0: 	// check to see if the fonts are stored on ROM.  Note that NAND != rom so font files in NAND devices
sl@0: 	// must be handled as if they were in RAM.  A NULL pointer returned by IsFileInRom means its RAM
sl@0: 
sl@0: 	if (aFs.IsFileInRom(*iFullName)!=NULL)
sl@0: 		{
sl@0: 		// fonts are stored on a XIP (execute in place) device
sl@0: 		TInt ret = file.Seek(ESeekAddress, iFileAddress);
sl@0: 
sl@0: 		if (ret != KErrNone)
sl@0: 			{
sl@0: 			file.Close();
sl@0: 			User::Leave(ret);
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	// convert RFile into a CDirectFileStore
sl@0: 	CDirectFileStore* fileStore = CDirectFileStore::FromLC(file);
sl@0: 
sl@0: 	if (fileStore->Type()[1] != TUid::Uid(KFontStoreFileUidVal))
sl@0: 		User::Leave(KErrNotSupported);
sl@0: 	TStreamId headerid = fileStore->Root();
sl@0: 	RStoreReadStream stream;
sl@0: 	stream.OpenLC(*fileStore, headerid);
sl@0: 	TInt fnttranversion = stream.ReadInt32L();
sl@0: 	// This works for version 42 (with new metrics) and for earlier versions 
sl@0: 	// which will synthesize the required metrics. It may have to be changed 
sl@0: 	// if the version number is incremented again.
sl@0: 	if (fnttranversion < (KFnttranVersion - 1)  && fnttranversion != KFnttran7650Version) 
sl@0: 		User::Leave(KErrNotSupported);
sl@0: 	iFontVersion = fnttranversion;
sl@0: 	stream >> iCollectionUid;
sl@0: 	iKPixelAspectRatio = stream.ReadInt32L();
sl@0: 	stream >> iDataStreamId;
sl@0: 	CleanupStack::PopAndDestroy(&stream);	// close root stream
sl@0: 	// ensure font data stream can be opened
sl@0: 	stream.OpenLC(*fileStore, iDataStreamId);
sl@0: 	CleanupStack::PopAndDestroy(&stream);	// close font stream
sl@0: 	// transfer ownership of fileStore
sl@0: 	CleanupStack::Pop(fileStore);
sl@0: 	iFileStore = fileStore;
sl@0: 	}
sl@0: 
sl@0: CFontStoreFile* CFontStoreFile::NewL(const TParse& aParse, RFs& aFs)
sl@0: 	{
sl@0: 	CFontStoreFile* fontstorefile = new(ELeave) CFontStoreFile;
sl@0: 	CleanupStack::PushL(fontstorefile);
sl@0: 	fontstorefile->ConstructL(aParse, aFs);
sl@0: 	CleanupStack::Pop();
sl@0: 	return fontstorefile;
sl@0: 	}
sl@0: 
sl@0: CFontStoreFile::~CFontStoreFile()
sl@0: 	{
sl@0: 	delete iFullName;
sl@0: 	iFullName = NULL;
sl@0: 	delete iFileStore;
sl@0: 	iFileStore = NULL;
sl@0: 	}
sl@0: 
sl@0: TBitmapCodeSection::TBitmapCodeSection()
sl@0:  :	TCodeSection(),
sl@0: 	iCharacterData(),
sl@0: 	iBitmapData()
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: //This method is called  from CFontBitmap::InternalizeL.
sl@0: //We have to read stream IDs from the stream, not offsets.
sl@0: //Obviously the method is called once per life time of 
sl@0: //CFontBitmap instance.
sl@0: void TBitmapCodeSection::InternalizeL(RReadStream &aStream)
sl@0: 	{
sl@0: 	iStart = aStream.ReadUint16L();
sl@0: 	iEnd = aStream.ReadUint16L();
sl@0: 	aStream >> iCharacterData.iOffsetsId;
sl@0: 	aStream >> iBitmapData.iBitmapId; 
sl@0: 	}
sl@0: 
sl@0: //This method is called  from CFontBitmap::RestoreComponentsL - 
sl@0: //if the CFontBitmap instance is in RAM and CFontBitmap::iComponentsRestored is EFalse.
sl@0: //We use here stream IDs, not offsets.
sl@0: //If the memory allocation for the offsets doesn't fail - aAllocMemCounter is incremented
sl@0: //After calling of TBitmapCodeSection::InternalizeOffsetsL character metrics streamID is no more valid - 
sl@0: //we have valid character metrics offset into RAM memory.
sl@0: void TBitmapCodeSection::InternalizeOffsetsL(const CStreamStore& aStreamStore, RHeap* aHeap, TInt& aAllocMemCounter)
sl@0: 	{
sl@0: 	RStoreReadStream stream;
sl@0: 	stream.OpenLC(aStreamStore, iCharacterData.iOffsetsId);
sl@0: 
sl@0: 	TInt size = stream.ReadInt32L();
sl@0: 	TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*)aHeap->AllocL(sizeof(TBitmapFontCharacterOffset) * size);
sl@0: 	aAllocMemCounter++;
sl@0: 	iCharacterData.iCharacterOffsetsListOffset = TInt(characterOffsetsList) - TInt(this);
sl@0: 	TBitmapFontCharacterOffset* pEnd = characterOffsetsList + size;
sl@0: 	for (TBitmapFontCharacterOffset* p = characterOffsetsList; p < pEnd; p++)
sl@0: 		{
sl@0: 		p->InternalizeL(stream);
sl@0: 		}
sl@0: 
sl@0: 	CleanupStack::PopAndDestroy();
sl@0: 	}
sl@0: 
sl@0: //This method is called  from CFontBitmap::RestoreComponentsL - 
sl@0: //if the CFontBitmap instance is in RAM and CFontBitmap::iComponentsRestored is EFalse.
sl@0: //We use here stream IDs, not offsets.
sl@0: //If the memory allocation for the bitmap doesn't fail - aAllocMemCounter is incremented
sl@0: //After calling of TBitmapCodeSection::InternalizeBitmapL bitmap streamID is no more valid - 
sl@0: //we have valid bitmap offset into RAM memory.
sl@0: void TBitmapCodeSection::InternalizeBitmapL(const CStreamStore& aStreamStore, RHeap* aHeap, TInt& aAllocMemCounter)
sl@0: 	{
sl@0: 	RStoreReadStream stream;
sl@0: 	stream.OpenLC(aStreamStore, iBitmapData.iBitmapId);
sl@0: 
sl@0: 	TInt size = stream.ReadInt32L();
sl@0: 	TUint8* bitmap = (TUint8*)aHeap->AllocL(size);
sl@0: 	aAllocMemCounter++;
sl@0: 	iBitmapData.iBitmapOffset = TInt(bitmap) - TInt(this);
sl@0: 	stream.ReadL(bitmap, size);
sl@0: 
sl@0: 	CleanupStack::PopAndDestroy();
sl@0: 	}
sl@0: 
sl@0: //This method is called from CFontBitmap::InternalizeL if the
sl@0: //CFontBitmap instance is in ROM.
sl@0: //We use here stream IDs to calculate offsets.
sl@0: //After calling of TBitmapCodeSection::FixUpComponents streamIDs are no more valid - 
sl@0: //we have valid offsets into ROM memory.
sl@0: //Obviously the method is called once per life time of 
sl@0: //CFontBitmap instance.
sl@0: void TBitmapCodeSection::FixUpComponents(TInt aFileAddress)
sl@0: 	{
sl@0: 	TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*) (aFileAddress + sizeof(TInt) + iCharacterData.iOffsetsId);
sl@0: 	iCharacterData.iCharacterOffsetsListOffset = TInt(characterOffsetsList);
sl@0: 	TUint8* bitmap = (TUint8*) (aFileAddress + sizeof(TInt) + iBitmapData.iBitmapId);
sl@0: 	iBitmapData.iBitmapOffset = TInt(bitmap);
sl@0: 	}
sl@0: 
sl@0: //This method is caled from CFontBitmap::DeleteComponents(),
sl@0: //only if the CFontBitmap instance is in RAM.
sl@0: void TBitmapCodeSection::DeleteOffsets(RHeap* aHeap)
sl@0: 	{
sl@0: 	TBitmapFontCharacterOffset*  charactersOffsetsList = CharacterOffsetsList(ETrue);
sl@0: 	if(TUint32(this) != TUint32(charactersOffsetsList))
sl@0: 		{
sl@0: 		aHeap->Free(charactersOffsetsList);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: //This method is caled from CFontBitmap::DeleteComponents(),
sl@0: //only if the CFontBitmap instance is in RAM.
sl@0: void TBitmapCodeSection::DeleteBitmap(RHeap* aHeap)
sl@0: 	{
sl@0: 	TUint8* bitmap = Bitmap(ETrue);
sl@0: 	if(TUint32(this) != TUint32(bitmap))
sl@0: 		{
sl@0: 		aHeap->Free(bitmap);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: TBitmapFontCharacterOffset* TBitmapCodeSection::CharacterOffsetsList(TBool aIsInRAM) const
sl@0: 	{
sl@0: 	return reinterpret_cast <TBitmapFontCharacterOffset*> 
sl@0: 		(iCharacterData.iCharacterOffsetsListOffset + (aIsInRAM ? TInt(this) : 0));
sl@0: 	}
sl@0: 
sl@0: TUint8* TBitmapCodeSection::Bitmap(TBool aIsInRAM) const
sl@0: 	{
sl@0: 	return reinterpret_cast <TUint8*> 
sl@0: 		(iBitmapData.iBitmapOffset + (aIsInRAM ? TInt(this) : 0));
sl@0: 	}
sl@0: 
sl@0: TCharacterMetricsTable::TCharacterMetricsTable(RHeap* aHeap)
sl@0:  :	iHeap(aHeap),
sl@0: 	iMetricsStartId(KNullStreamId),
sl@0: 	iCharacterMetricsStartPtr(0),
sl@0: 	iNumberOfMetrics(0),
sl@0: 	iMetricsOnHeap(EFalse)
sl@0: 	{}
sl@0: 
sl@0: void TCharacterMetricsTable::InternalizeL(RReadStream& aStream)
sl@0: 	{
sl@0: 	iMetricsStartId = aStream.ReadInt32L();
sl@0: 	iNumberOfMetrics = aStream.ReadInt32L();
sl@0: 	}
sl@0: 
sl@0: void TCharacterMetricsTable::InternalizeMetricsL(RReadStream& aStream)
sl@0: 	{
sl@0: 	aStream.ReadInt32L(); // size
sl@0: 	TBitmapFontCharacterMetrics* charactermetricslist = static_cast<TBitmapFontCharacterMetrics*>(iHeap->AllocL(sizeof(TBitmapFontCharacterMetrics) * iNumberOfMetrics));
sl@0: 	iMetricsOnHeap = ETrue;
sl@0: 	// Offset from this to location on the heap ('cos the file is not in ROM)
sl@0: 	iCharacterMetricsStartPtr = reinterpret_cast<TInt>(charactermetricslist) - reinterpret_cast<TInt>(this);
sl@0: 	TBitmapFontCharacterMetrics* pEnd = charactermetricslist + iNumberOfMetrics;
sl@0: 	for (TBitmapFontCharacterMetrics* p = charactermetricslist; p < pEnd; p++)
sl@0: 		{
sl@0: 		p->InternalizeL(aStream);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: void TCharacterMetricsTable::RestoreL(const CStreamStore& aStreamStore)
sl@0: 	{
sl@0: 	if (iCharacterMetricsStartPtr == 0)
sl@0: 		{	// We haven't already read it in from RAM file
sl@0: 		RStoreReadStream stream;
sl@0: 		stream.OpenLC(aStreamStore, iMetricsStartId);
sl@0: 		InternalizeMetricsL(stream);
sl@0: 		CleanupStack::PopAndDestroy();
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: void TCharacterMetricsTable::FixUp(TInt aFileAddress)
sl@0: 	{
sl@0: 	TBitmapFontCharacterMetrics* charactermetricslist = reinterpret_cast<TBitmapFontCharacterMetrics*>(aFileAddress + sizeof(TInt) + iMetricsStartId.Value());
sl@0: 	iCharacterMetricsStartPtr = TInt(charactermetricslist);	// Ptr to location in a ROM file
sl@0: 	iMetricsStartId = KNullStreamId;
sl@0: 	iMetricsOnHeap = EFalse;
sl@0: 	}
sl@0: 
sl@0: void TCharacterMetricsTable::Delete()
sl@0: 	{	// This routine is only called if the font file is in RAM, not ROM, and therefore the metrics have been stashed on the heap
sl@0:     if (iMetricsOnHeap && iCharacterMetricsStartPtr)
sl@0:         {
sl@0:         iHeap->Free(reinterpret_cast<TAny*>(MetricsFromOffset(0)));
sl@0:         iCharacterMetricsStartPtr = 0;
sl@0:         iMetricsOnHeap = EFalse;
sl@0:         }
sl@0: 	}
sl@0: 
sl@0: const TBitmapFontCharacterMetrics* TCharacterMetricsTable::Metric(TInt aIndex) const
sl@0: 	{
sl@0: 	if ((aIndex < 0) || (aIndex > iNumberOfMetrics))
sl@0: 	    {
sl@0: 	    OstTraceExt2( TRACE_FATAL, TCHARACTERMETRICSTABLE_METRIC, "TCharacterMetricsTable::Metric, aIndex=%d, iNumberOfMetrics=%d, Panic(EFntMetricsIndexOutOfBounds)", aIndex, iNumberOfMetrics);
sl@0: 	    __ASSERT_DEBUG(0, Panic(EFntMetricsIndexOutOfBounds));
sl@0: 	    }
sl@0:     // Sometimes the start ptr is to a metrics heap item and sometimes it points into a ROM file
sl@0:     if (iMetricsOnHeap)
sl@0:         {
sl@0:         // Start ptr is to metrics heap item
sl@0:         return MetricsFromOffset(aIndex);
sl@0:         }
sl@0:     else
sl@0:         {
sl@0:         // Start ptr is to a file in ROM
sl@0:         return reinterpret_cast<const TBitmapFontCharacterMetrics*> (iCharacterMetricsStartPtr + (aIndex * sizeof(TBitmapFontCharacterMetrics)));
sl@0:         }
sl@0: 	}
sl@0: 
sl@0: TInt TCharacterMetricsTable::NumberOfMetrics() const
sl@0: 	{
sl@0: 	return iNumberOfMetrics;
sl@0: 	}
sl@0: 
sl@0: TBitmapFontCharacterMetrics* TCharacterMetricsTable::MetricsFromOffset(TInt aIndex) const
sl@0:     {
sl@0:     __ASSERT_DEBUG(iMetricsOnHeap,Panic(EFntMetricsNotOnHeap));
sl@0:     return reinterpret_cast<TBitmapFontCharacterMetrics*>(reinterpret_cast<TInt>(this) + iCharacterMetricsStartPtr+ (aIndex * sizeof(TBitmapFontCharacterMetrics)));
sl@0:     }
sl@0: 
sl@0: CFontBitmap::CFontBitmap(RHeap* aHeap, CFontStoreFile* aFontStoreFile)
sl@0:  :	iHeap(aHeap),
sl@0: 	iFontStoreFileOffset(0),
sl@0: 	iUid(KNullUid),
sl@0: 	iPosture(0),
sl@0: 	iStrokeWeight(0),
sl@0: 	iIsProportional(0),
sl@0: 	iIsInRAM(!aFontStoreFile->iFileAddress),
sl@0: 	iUsageCount(1),
sl@0: 	iCellHeightInPixels(0),
sl@0: 	iAscentInPixels(0),
sl@0: 	iMaxCharWidthInPixels(0),
sl@0: 	iMaxNormalCharWidthInPixels(0),
sl@0: 	iBitmapEncoding(0),
sl@0: 	iNumCodeSections(0),
sl@0: 	iCodeSectionListOffset(0),
sl@0: 	iCharacterMetricsTable(aHeap),
sl@0: 	iComponentsRestored(EFalse),
sl@0: 	iAllocMemCounter_Offsets(0),
sl@0: 	iAllocMemCounter_Bitmaps(0),
sl@0: 	iFontCapitalAscent(0),
sl@0: 	iFontMaxAscent(0),
sl@0: 	iFontStandardDescent(0),
sl@0: 	iFontMaxDescent(0),
sl@0: 	iFontLineGap(0)
sl@0: 	{
sl@0: 	iFontStoreFileOffset = TInt(aFontStoreFile) - TInt(this);
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::InternalizeL(RReadStream &aStream, TInt aFontVersion)
sl@0: 	{
sl@0: 	aStream >> iUid;
sl@0: 	iPosture = aStream.ReadInt8L();
sl@0: 	iStrokeWeight = aStream.ReadInt8L();
sl@0: 	iIsProportional = aStream.ReadInt8L();
sl@0: 	iCellHeightInPixels = aStream.ReadInt8L();
sl@0: 	iAscentInPixels = aStream.ReadInt8L();
sl@0: 	iMaxCharWidthInPixels = aStream.ReadInt8L();
sl@0: 	iMaxNormalCharWidthInPixels = aStream.ReadInt8L();
sl@0: 	if ( aFontVersion  >= KFnttranVersion )
sl@0: 		{ // read the new metrics in
sl@0: 		iFontCapitalAscent = aStream.ReadInt8L();
sl@0: 		iFontMaxAscent = aStream.ReadInt8L();
sl@0: 		iFontStandardDescent = aStream.ReadInt8L();
sl@0: 		iFontMaxDescent = aStream.ReadInt8L();
sl@0: 		iFontLineGap = aStream.ReadInt8L();
sl@0: 		}
sl@0: 	else // synthesize the extra metrics (data compatibility with third party bitmap fonts for old phones)
sl@0: 		{
sl@0: 		iFontMaxAscent = iFontCapitalAscent = iAscentInPixels;
sl@0: 		iFontMaxDescent = iFontStandardDescent = iCellHeightInPixels - iAscentInPixels;
sl@0: 		iFontLineGap = ( ( iCellHeightInPixels * 12 ) + 5) / 10;  // 1.2 times design height
sl@0: 		}	
sl@0: 	iBitmapEncoding = aStream.ReadInt32L();
sl@0: 	iCharacterMetricsTable.InternalizeL(aStream);
sl@0: 	const TBool fixup = FontStoreFile()->iFileAddress;
sl@0: 	if (fixup)
sl@0: 		{
sl@0: 		iCharacterMetricsTable.FixUp(FontStoreFile()->iFileAddress);
sl@0: 		}
sl@0: 	iNumCodeSections = aStream.ReadInt32L();
sl@0: 	TBitmapCodeSection* codesectionlist = (TBitmapCodeSection*)User::LeaveIfNull(iHeap->AllocL(iNumCodeSections * sizeof(TBitmapCodeSection)));
sl@0: 	iCodeSectionListOffset = TInt(codesectionlist) - TInt(this);
sl@0: 	for (TInt i = 0; i < iNumCodeSections; i++)
sl@0: 		{
sl@0: 		new(codesectionlist + i) TBitmapCodeSection;
sl@0: 		codesectionlist[i].InternalizeL(aStream);
sl@0: 		if (fixup)
sl@0: 			codesectionlist[i].FixUpComponents(FontStoreFile()->iFileAddress);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::UseL()
sl@0: 	{
sl@0: 	// Note object is created with a Usage Count of 1.
sl@0: 	// So incrementing to 2 normally indicates the first external reference.
sl@0: 	iUsageCount++;
sl@0: 	if (iUsageCount == 2)
sl@0: 		{
sl@0: 		RestoreComponentsL();
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::Release()
sl@0: 	{
sl@0: 	iUsageCount--;
sl@0: 	if (!iUsageCount)
sl@0: 		{ // object and all its users have closed
sl@0: 		delete this;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: /*
sl@0: Get the metrics for a given character.
sl@0: Return aBytes as null if the character aCode doesn't exist in the font.
sl@0: */
sl@0: TBitmapFontCharacterMetrics CFontBitmap::CharacterMetrics(TInt aCode, const TUint8*& aBytes) const
sl@0: 	{
sl@0:  	const TBitmapCodeSection* matchSection = NULL;
sl@0: 	const TBitmapCodeSection* const lastSection = CodeSectionList() + iNumCodeSections - 1;
sl@0: 
sl@0: 	TBitmapFontCharacterOffset offset;
sl@0: 	aBytes = NULL;
sl@0: 
sl@0: 	TBitmapFontCharacterMetrics metrics;
sl@0: 	const TBitmapCodeSection* startSearchBand = CodeSectionList();
sl@0: 	TInt numCodeSectionsRemaining = iNumCodeSections;
sl@0: 	while (numCodeSectionsRemaining >= 1)
sl@0: 		{
sl@0: 		TInt halfNumCodeSectionsRemaining = numCodeSectionsRemaining/2;
sl@0: 		const TBitmapCodeSection* centralSearchBand = startSearchBand+halfNumCodeSectionsRemaining;
sl@0: 		if ((aCode >= centralSearchBand->iStart) && (aCode <= centralSearchBand->iEnd))
sl@0: 			{
sl@0: 			matchSection = centralSearchBand;
sl@0: 			break;
sl@0: 			}
sl@0: 		else if ((aCode < centralSearchBand->iStart) || (centralSearchBand == lastSection))
sl@0: 			numCodeSectionsRemaining = halfNumCodeSectionsRemaining;
sl@0: 		else
sl@0: 			{
sl@0: 			startSearchBand = centralSearchBand + 1;
sl@0: 			numCodeSectionsRemaining -= halfNumCodeSectionsRemaining + 1;
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	if (matchSection)
sl@0: 		{
sl@0: 		offset =* ((matchSection->CharacterOffsetsList(iIsInRAM)) + (aCode-matchSection->iStart));
sl@0: 
sl@0: 		// Fill characters within code section.
sl@0: 		// Recursive call ensures that a valid metric is always returned.
sl@0: 		if (offset.iBitmapOffset == KFillCharacterOffset)
sl@0: 			{
sl@0: 			return CharacterMetrics(KReplacementCharacter, aBytes);
sl@0: 			}
sl@0: 		
sl@0: 		aBytes = matchSection->Bitmap(iIsInRAM) + offset.iBitmapOffset;
sl@0: 		
sl@0: 		// retrieve metric index from encoded 1 or 2 bytes
sl@0: 		TInt index = 0;
sl@0: 		TUint8 byte1 = (TUint8)*aBytes;
sl@0: 		const TInt switchMask = 0x1;
sl@0: 		const TBool oneByteIndex =! (byte1 & switchMask);
sl@0: 		byte1 = TUint8(byte1 >> 1);
sl@0: 		if (oneByteIndex)
sl@0: 			{
sl@0: 			index = byte1;
sl@0: 			aBytes += 1;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			const TUint8 byte2 = (TUint8)(*(aBytes + 1));
sl@0: 			index = byte1 + (byte2 * 128);
sl@0: 			aBytes += 2;
sl@0: 			}
sl@0: 		// Copy metric from table
sl@0: 		metrics =* iCharacterMetricsTable.Metric(index);
sl@0: 		}
sl@0: 	return metrics;
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::operator delete(TAny *aThis)
sl@0: 	{
sl@0: 	if (((CFontBitmap *)aThis)->iHeap)
sl@0: 		{
sl@0: 		((CFontBitmap *)aThis)->iHeap->Free(aThis);
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::SetPosture(TFontPosture aPosture)
sl@0: 	{
sl@0: 	iPosture = (TInt8)aPosture;
sl@0: 	}
sl@0: 
sl@0: TFontPosture CFontBitmap::Posture() const
sl@0: 	{
sl@0: 	return (TFontPosture)iPosture;	 // iPosture is always smaller than TFontPosture
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::SetStrokeWeight(TFontStrokeWeight aStrokeWeight)
sl@0: 	{
sl@0: 	iStrokeWeight = (TInt8)aStrokeWeight;
sl@0: 	}
sl@0: 
sl@0: TFontStrokeWeight CFontBitmap::StrokeWeight() const
sl@0: 	{
sl@0: 	return (TFontStrokeWeight)iStrokeWeight;
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::SetIsProportional(TBool aIsProportional)
sl@0: 	{
sl@0: 	iIsProportional = (TInt8)aIsProportional;
sl@0: 	}
sl@0: 
sl@0: TBool CFontBitmap::IsProportional() const
sl@0: 	{
sl@0: 	return iIsProportional;
sl@0: 	}
sl@0: 
sl@0: CFontStoreFile* CFontBitmap::FontStoreFile() const
sl@0: 	{
sl@0: 	TInt fsf = TInt(this) + iFontStoreFileOffset;
sl@0: 	return (CFontStoreFile*)fsf;
sl@0: 	}
sl@0: 
sl@0: CFontBitmap::~CFontBitmap()
sl@0: 	{
sl@0: 	DeleteComponents();
sl@0: 	TBitmapCodeSection* codeSectionList = CodeSectionList();
sl@0: 	if(TUint32(this) != TUint32(codeSectionList))
sl@0: 		{
sl@0: 		iHeap->Free(codeSectionList);
sl@0: 		}
sl@0: 	iCodeSectionListOffset = 0;
sl@0: 	}
sl@0: 
sl@0: //We have to count how many offsets and bitmaps are allocated successfully because if
sl@0: //some of codesection's Internalize..L fails we have to deallocate the right amount of 
sl@0: //data.
sl@0: void CFontBitmap::RestoreComponentsL()
sl@0: 	{
sl@0: 	if (iIsInRAM)
sl@0: 		{
sl@0: 		if(!iComponentsRestored)
sl@0: 			{
sl@0: 			iAllocMemCounter_Offsets = 0;
sl@0: 			iAllocMemCounter_Bitmaps = 0;
sl@0: 			CStreamStore& store =* FontStoreFile()->iFileStore;
sl@0: 			for (TInt i = 0; i < iNumCodeSections; i++)
sl@0: 				{
sl@0: 				CodeSectionList()[i].InternalizeOffsetsL(store, iHeap, iAllocMemCounter_Offsets);
sl@0: 				CodeSectionList()[i].InternalizeBitmapL(store, iHeap, iAllocMemCounter_Bitmaps);
sl@0: 				}
sl@0: 			iCharacterMetricsTable.RestoreL(store);
sl@0: 			}
sl@0: 		iComponentsRestored = ETrue;
sl@0: 		}
sl@0: 	}
sl@0: 
sl@0: void CFontBitmap::DeleteComponents()
sl@0: 	{
sl@0: 	if (iIsInRAM)
sl@0: 		{
sl@0: 		TInt i;
sl@0: 		for (i = 0; i < iAllocMemCounter_Offsets; i++)
sl@0: 			{
sl@0: 			CodeSectionList()[i].DeleteOffsets(iHeap);
sl@0: 			}
sl@0: 		for (i = 0; i < iAllocMemCounter_Bitmaps; i++)
sl@0: 			{
sl@0: 			CodeSectionList()[i].DeleteBitmap(iHeap);
sl@0: 			}
sl@0: 		iCharacterMetricsTable.Delete();
sl@0: 		}
sl@0: 	iAllocMemCounter_Offsets = 0;
sl@0: 	iAllocMemCounter_Bitmaps = 0;
sl@0: 	iComponentsRestored = EFalse;
sl@0: 	}
sl@0: 
sl@0: TBitmapCodeSection* CFontBitmap::CodeSectionList() const
sl@0: 	{
sl@0: 	TInt bcs = TInt(this) + iCodeSectionListOffset;
sl@0: 	return (TBitmapCodeSection*)bcs;
sl@0: 	}
sl@0: 
sl@0: TTypefaceFontBitmap::TTypefaceFontBitmap()
sl@0:  :	iTypeface(NULL),
sl@0: 	iFontBitmap(NULL),
sl@0: 	iHeightFactor(1),
sl@0: 	iWidthFactor(1)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: TTypefaceFontBitmap::TTypefaceFontBitmap(TTypeface* aTypeface,CFontBitmap* aFontBitmap)
sl@0:  :	iTypeface(aTypeface),
sl@0: 	iFontBitmap(aFontBitmap),
sl@0: 	iHeightFactor(1),
sl@0: 	iWidthFactor(1)
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: TInt TTypefaceFontBitmap::HeightInPixels() const
sl@0: 	{
sl@0: 	return iFontBitmap->iCellHeightInPixels * iHeightFactor;
sl@0: 	}