fontservices/fontstore/tfs/FNTBODY_OLD.CPP
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 02:02:46 +0200
changeset 0 1fb32624e06b
permissions -rw-r--r--
Revision: 201003 Kit: 201005

/*
* Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: 
*
*/


#include <s32file.h>
#include "FNTSTORE.H"
#include "FNTBODY_OLD.H"
#include <graphics/openfontconstants.h>

TBitmapCodeSectionOld::TBitmapCodeSectionOld(RHeap* aHeap)
 :	TCodeSection(),
	iHeap(aHeap),
	iOffsetsId(),
	iCharacterOffsetsListOffset(0),
	iBitmapId(),
	iBitmapOffset(0)
	{
	}

void TBitmapCodeSectionOld::InternalizeL(RReadStream &aStream)
	{
	iStart = aStream.ReadUint16L();
	iEnd = aStream.ReadUint16L();
	aStream >> iOffsetsId;
	aStream >> iBitmapId; 
	}

void TBitmapCodeSectionOld::RestoreComponentsL(const CStreamStore& aStreamStore)
	{
	if (iCharacterOffsetsListOffset == 0)
		{
		RStoreReadStream stream;
		stream.OpenLC(aStreamStore, iOffsetsId);
		InternalizeOffsetsL(stream);
		CleanupStack::PopAndDestroy();
		}
	if (iBitmapOffset == 0)
		{
		RStoreReadStream stream;
		stream.OpenLC(aStreamStore, iBitmapId);
		InternalizeBitmapL(stream);
		CleanupStack::PopAndDestroy();
		}
	}

void TBitmapCodeSectionOld::FixUpComponents(TInt aFileAddress)
	{
	TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*) (aFileAddress + sizeof(TInt) + iOffsetsId.Value());
	iCharacterOffsetsListOffset = TInt(characterOffsetsList);
	iOffsetsId = KNullStreamId;
	TUint8* bitmap = (TUint8*) (aFileAddress + sizeof(TInt) + iBitmapId.Value());
	iBitmapOffset = TInt(bitmap);
	}

void TBitmapCodeSectionOld::DeleteComponents()
	{
	if (iCharacterOffsetsListOffset)
		{
		iHeap->Free(CharacterOffsetsList());
		iCharacterOffsetsListOffset = 0;
		}
	if (iBitmapOffset)
		{
		iHeap->Free(Bitmap());
		iBitmapOffset = 0;
		}
	}

void TBitmapCodeSectionOld::operator delete(TAny *aThis)
	{
	if (((TBitmapCodeSectionOld *)aThis)->iHeap)
		{
		((TBitmapCodeSectionOld *)aThis)->iHeap->Free(aThis);
		}
	}

void TBitmapCodeSectionOld::InternalizeOffsetsL(RReadStream &aStream)
	{
	TInt size = aStream.ReadInt32L();
	TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*)iHeap->AllocL(sizeof(TBitmapFontCharacterOffset) * size);
	iCharacterOffsetsListOffset = TInt(characterOffsetsList) - TInt(this);
	TBitmapFontCharacterOffset* pEnd = characterOffsetsList + size;
	for (TBitmapFontCharacterOffset* p = characterOffsetsList; p < pEnd; p++)
		{
		p->InternalizeL(aStream);
		}
	}

void TBitmapCodeSectionOld::InternalizeBitmapL(RReadStream &aStream)
	{
	TInt size = aStream.ReadInt32L();
	TUint8* bitmap = (TUint8*)iHeap->AllocL(size);
	iBitmapOffset = TInt(bitmap) - TInt(this);
	aStream.ReadL(bitmap, size);
	}

TBitmapFontCharacterOffset* TBitmapCodeSectionOld::CharacterOffsetsList() const
	{
	if (iOffsetsId == KNullStreamId)
		{
		return (TBitmapFontCharacterOffset*)iCharacterOffsetsListOffset;
		}
	TInt charOffsList = TInt(this) + iCharacterOffsetsListOffset;
	return (TBitmapFontCharacterOffset*)charOffsList;
	}

TUint8* TBitmapCodeSectionOld::Bitmap() const
	{
	if (iOffsetsId == KNullStreamId)
		{
		return (TUint8*)iBitmapOffset;
		}
	TInt bitmap = TInt(this)+iBitmapOffset;
	return (TUint8*)bitmap;
	}

CFontBitmapOld::CFontBitmapOld(RHeap* aHeap, CFontStoreFile* aFontStoreFile)
 :	iHeap(aHeap),
	iFontStoreFileOffset(0),
	iUid(KNullUid),
	iPosture(0),
	iStrokeWeight(0),
	iIsProportional(0),
	iIsInRAM(!aFontStoreFile->iFileAddress),
	iUsageCount(1),
	iCellHeightInPixels(0),
	iAscentInPixels(0),
	iMaxCharWidthInPixels(0),
	iMaxNormalCharWidthInPixels(0),
	iBitmapEncoding(0),
	iNumCodeSections(0),
	iCodeSectionListOffset(0),
	iCharacterMetricsTable(aHeap)
	{
	iFontStoreFileOffset = TInt(aFontStoreFile) - TInt(this);
	}

void CFontBitmapOld::InternalizeL(RReadStream &aStream)
	{
	aStream >> iUid;
	iPosture = aStream.ReadInt8L();
	iStrokeWeight = aStream.ReadInt8L();
	iIsProportional = aStream.ReadInt8L();
	iCellHeightInPixels = aStream.ReadInt8L();
	iAscentInPixels = aStream.ReadInt8L();
	iMaxCharWidthInPixels = aStream.ReadInt8L();
	iMaxNormalCharWidthInPixels = aStream.ReadInt8L();
	iBitmapEncoding = aStream.ReadInt32L();
	iCharacterMetricsTable.InternalizeL(aStream);
	const TBool fixup = FontStoreFile()->iFileAddress;
	if (fixup)
		{
		iCharacterMetricsTable.FixUp(FontStoreFile()->iFileAddress);
		}
	iNumCodeSections = aStream.ReadInt32L();
	TBitmapCodeSectionOld* codesectionlist = (TBitmapCodeSectionOld*)User::LeaveIfNull(iHeap->AllocL(iNumCodeSections * sizeof(TBitmapCodeSectionOld)));
	iCodeSectionListOffset = TInt(codesectionlist) - TInt(this);
	for (TInt i = 0; i < iNumCodeSections; i++)
		{
		new(codesectionlist + i) TBitmapCodeSectionOld(iHeap);
		codesectionlist[i].InternalizeL(aStream);
		if (fixup)
			codesectionlist[i].FixUpComponents(FontStoreFile()->iFileAddress);
		}
	}

void CFontBitmapOld::UseL()
	{
	iUsageCount++;
	if (iUsageCount == 2)
		RestoreComponentsL();
	}

void CFontBitmapOld::Release()
	{
	iUsageCount--;
	if (!iUsageCount)
		{
		delete this;
		}
	}

/*
Get the metrics for a given character.
Return aBytes as null if the character aCode doesn't exist in the font.
*/
TBitmapFontCharacterMetrics CFontBitmapOld::CharacterMetrics(TInt aCode, const TUint8*& aBytes) const
	{
 	const TBitmapCodeSectionOld* matchSection = NULL;
	const TBitmapCodeSectionOld* const lastSection = CodeSectionList() + iNumCodeSections - 1;

	TBitmapFontCharacterOffset offset;
	aBytes = NULL;

	TBitmapFontCharacterMetrics metrics;
	const TBitmapCodeSectionOld* startSearchBand = CodeSectionList();
	TInt numCodeSectionsRemaining = iNumCodeSections;
	while (numCodeSectionsRemaining >= 1)
		{
		TInt halfNumCodeSectionsRemaining = numCodeSectionsRemaining/2;
		const TBitmapCodeSectionOld* centralSearchBand = startSearchBand+halfNumCodeSectionsRemaining;
		if ((aCode >= centralSearchBand->iStart) && (aCode <= centralSearchBand->iEnd))
			{
			matchSection = centralSearchBand;
			break;
			}
		else if ((aCode < centralSearchBand->iStart) || (centralSearchBand == lastSection))
			numCodeSectionsRemaining = halfNumCodeSectionsRemaining;
		else
			{
			startSearchBand = centralSearchBand + 1;
			numCodeSectionsRemaining -= halfNumCodeSectionsRemaining + 1;
			}
		}

	if (matchSection)
		{
		offset =* ((matchSection->CharacterOffsetsList()) + (aCode-matchSection->iStart));

		// Fill characters within code section.
		// Recursive call ensures that a valid metric is always returned.
		if (offset.iBitmapOffset == KFillCharacterOffset)
			{
			return CharacterMetrics(KReplacementCharacter, aBytes);
			}
		
		aBytes = matchSection->Bitmap() + offset.iBitmapOffset;
		
		// retrieve metric index from encoded 1 or 2 bytes
		TInt index = 0;
		TUint8 byte1 = (TUint8)*aBytes;
		const TInt switchMask = 0x1;
		const TBool oneByteIndex =! (byte1 & switchMask);
		byte1 = TUint8(byte1 >> 1);
		if (oneByteIndex)
			{
			index = byte1;
			aBytes += 1;
			}
		else
			{
			const TUint8 byte2 = (TUint8)(*(aBytes + 1));
			index = byte1 + (byte2 * 128);
			aBytes += 2;
			}
		// Copy metric from table
		metrics =* iCharacterMetricsTable.Metric(index);
		}
	return metrics;
	}

void CFontBitmapOld::operator delete(TAny *aThis)
	{
	if (((CFontBitmapOld *)aThis)->iHeap)
		{
		((CFontBitmapOld *)aThis)->iHeap->Free(aThis);
		}
	}

void CFontBitmapOld::SetPosture(TFontPosture aPosture)
	{
	iPosture = (TInt8)aPosture;
	}

TFontPosture CFontBitmapOld::Posture()
	{
	return (TFontPosture)iPosture;	 // iPosture is always smaller than TFontPosture
	}

void CFontBitmapOld::SetStrokeWeight(TFontStrokeWeight aStrokeWeight)
	{
	iStrokeWeight = (TInt8)aStrokeWeight;
	}

TFontStrokeWeight CFontBitmapOld::StrokeWeight()
	{
	return (TFontStrokeWeight)iStrokeWeight;
	}

void CFontBitmapOld::SetIsProportional(TBool aIsProportional)
	{
	iIsProportional = (TInt8)aIsProportional;
	}

TBool CFontBitmapOld::IsProportional()
	{
	return iIsProportional;
	}

CFontStoreFile* CFontBitmapOld::FontStoreFile() const
	{
	TInt fsf = TInt(this) + iFontStoreFileOffset;
	return (CFontStoreFile*)fsf;
	}

CFontBitmapOld::~CFontBitmapOld()
	{
	DeleteComponents();
	iHeap->Free(CodeSectionList());
	iCodeSectionListOffset = 0;
	}

void CFontBitmapOld::RestoreComponentsL()
	{
	if (iIsInRAM)
		{
		CStreamStore& store =* FontStoreFile()->iFileStore;
		for (TInt i = 0; i < iNumCodeSections; i++)
			{
			CodeSectionList()[i].RestoreComponentsL(store);
			}
		iCharacterMetricsTable.RestoreL(store);
		}
	}

void CFontBitmapOld::DeleteComponents()
	{
	if (iIsInRAM)
		{
		for (TInt i = 0; i < iNumCodeSections; i++)
			{
			CodeSectionList()[i].DeleteComponents();
			}
		iCharacterMetricsTable.Delete();
		}
	}

TBitmapCodeSectionOld* CFontBitmapOld::CodeSectionList() const
	{
	TInt bcs = TInt(this) + iCodeSectionListOffset;
	return (TBitmapCodeSectionOld*)bcs;
	}