os/textandloc/fontservices/fontstore/src/FNTBODY.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include <s32file.h>
sl@0
    20
#include <fntstore.h>
sl@0
    21
#include "FNTBODY.H"
sl@0
    22
#include <graphics/openfontconstants.h>
sl@0
    23
sl@0
    24
#include "OstTraceDefinitions.h"
sl@0
    25
#ifdef OST_TRACE_COMPILER_IN_USE
sl@0
    26
#include "FNTBODYTraces.h"
sl@0
    27
#endif
sl@0
    28
sl@0
    29
sl@0
    30
CFontStoreFile::CFontStoreFile()
sl@0
    31
 :	iCollectionUid(KNullUid),
sl@0
    32
	iUsageCount(1),
sl@0
    33
	iFileStore(NULL),
sl@0
    34
	iFileAddress(0),
sl@0
    35
	iDataStreamId(KNullStreamId)
sl@0
    36
	{
sl@0
    37
	}
sl@0
    38
sl@0
    39
void CFontStoreFile::ConstructL(const TParse& aParse,RFs& aFs)
sl@0
    40
	{
sl@0
    41
	TInt drive;
sl@0
    42
	User::LeaveIfError(RFs::CharToDrive(aParse.Drive()[0], drive));
sl@0
    43
	TDriveInfo driveinfo;
sl@0
    44
	User::LeaveIfError(aFs.Drive(driveinfo, drive));
sl@0
    45
	RFile file;
sl@0
    46
sl@0
    47
	// store the filename
sl@0
    48
	iFullName = aParse.FullName().AllocL();
sl@0
    49
	User::LeaveIfError(file.Open(aFs, *iFullName, EFileStream | EFileRead | EFileShareReadersOnly));
sl@0
    50
sl@0
    51
	// check to see if the fonts are stored on ROM.  Note that NAND != rom so font files in NAND devices
sl@0
    52
	// must be handled as if they were in RAM.  A NULL pointer returned by IsFileInRom means its RAM
sl@0
    53
sl@0
    54
	if (aFs.IsFileInRom(*iFullName)!=NULL)
sl@0
    55
		{
sl@0
    56
		// fonts are stored on a XIP (execute in place) device
sl@0
    57
		TInt ret = file.Seek(ESeekAddress, iFileAddress);
sl@0
    58
sl@0
    59
		if (ret != KErrNone)
sl@0
    60
			{
sl@0
    61
			file.Close();
sl@0
    62
			User::Leave(ret);
sl@0
    63
			}
sl@0
    64
		}
sl@0
    65
sl@0
    66
	// convert RFile into a CDirectFileStore
sl@0
    67
	CDirectFileStore* fileStore = CDirectFileStore::FromLC(file);
sl@0
    68
sl@0
    69
	if (fileStore->Type()[1] != TUid::Uid(KFontStoreFileUidVal))
sl@0
    70
		User::Leave(KErrNotSupported);
sl@0
    71
	TStreamId headerid = fileStore->Root();
sl@0
    72
	RStoreReadStream stream;
sl@0
    73
	stream.OpenLC(*fileStore, headerid);
sl@0
    74
	TInt fnttranversion = stream.ReadInt32L();
sl@0
    75
	// This works for version 42 (with new metrics) and for earlier versions 
sl@0
    76
	// which will synthesize the required metrics. It may have to be changed 
sl@0
    77
	// if the version number is incremented again.
sl@0
    78
	if (fnttranversion < (KFnttranVersion - 1)  && fnttranversion != KFnttran7650Version) 
sl@0
    79
		User::Leave(KErrNotSupported);
sl@0
    80
	iFontVersion = fnttranversion;
sl@0
    81
	stream >> iCollectionUid;
sl@0
    82
	iKPixelAspectRatio = stream.ReadInt32L();
sl@0
    83
	stream >> iDataStreamId;
sl@0
    84
	CleanupStack::PopAndDestroy(&stream);	// close root stream
sl@0
    85
	// ensure font data stream can be opened
sl@0
    86
	stream.OpenLC(*fileStore, iDataStreamId);
sl@0
    87
	CleanupStack::PopAndDestroy(&stream);	// close font stream
sl@0
    88
	// transfer ownership of fileStore
sl@0
    89
	CleanupStack::Pop(fileStore);
sl@0
    90
	iFileStore = fileStore;
sl@0
    91
	}
sl@0
    92
sl@0
    93
CFontStoreFile* CFontStoreFile::NewL(const TParse& aParse, RFs& aFs)
sl@0
    94
	{
sl@0
    95
	CFontStoreFile* fontstorefile = new(ELeave) CFontStoreFile;
sl@0
    96
	CleanupStack::PushL(fontstorefile);
sl@0
    97
	fontstorefile->ConstructL(aParse, aFs);
sl@0
    98
	CleanupStack::Pop();
sl@0
    99
	return fontstorefile;
sl@0
   100
	}
sl@0
   101
sl@0
   102
CFontStoreFile::~CFontStoreFile()
sl@0
   103
	{
sl@0
   104
	delete iFullName;
sl@0
   105
	iFullName = NULL;
sl@0
   106
	delete iFileStore;
sl@0
   107
	iFileStore = NULL;
sl@0
   108
	}
sl@0
   109
sl@0
   110
TBitmapCodeSection::TBitmapCodeSection()
sl@0
   111
 :	TCodeSection(),
sl@0
   112
	iCharacterData(),
sl@0
   113
	iBitmapData()
sl@0
   114
	{
sl@0
   115
	}
sl@0
   116
sl@0
   117
//This method is called  from CFontBitmap::InternalizeL.
sl@0
   118
//We have to read stream IDs from the stream, not offsets.
sl@0
   119
//Obviously the method is called once per life time of 
sl@0
   120
//CFontBitmap instance.
sl@0
   121
void TBitmapCodeSection::InternalizeL(RReadStream &aStream)
sl@0
   122
	{
sl@0
   123
	iStart = aStream.ReadUint16L();
sl@0
   124
	iEnd = aStream.ReadUint16L();
sl@0
   125
	aStream >> iCharacterData.iOffsetsId;
sl@0
   126
	aStream >> iBitmapData.iBitmapId; 
sl@0
   127
	}
sl@0
   128
sl@0
   129
//This method is called  from CFontBitmap::RestoreComponentsL - 
sl@0
   130
//if the CFontBitmap instance is in RAM and CFontBitmap::iComponentsRestored is EFalse.
sl@0
   131
//We use here stream IDs, not offsets.
sl@0
   132
//If the memory allocation for the offsets doesn't fail - aAllocMemCounter is incremented
sl@0
   133
//After calling of TBitmapCodeSection::InternalizeOffsetsL character metrics streamID is no more valid - 
sl@0
   134
//we have valid character metrics offset into RAM memory.
sl@0
   135
void TBitmapCodeSection::InternalizeOffsetsL(const CStreamStore& aStreamStore, RHeap* aHeap, TInt& aAllocMemCounter)
sl@0
   136
	{
sl@0
   137
	RStoreReadStream stream;
sl@0
   138
	stream.OpenLC(aStreamStore, iCharacterData.iOffsetsId);
sl@0
   139
sl@0
   140
	TInt size = stream.ReadInt32L();
sl@0
   141
	TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*)aHeap->AllocL(sizeof(TBitmapFontCharacterOffset) * size);
sl@0
   142
	aAllocMemCounter++;
sl@0
   143
	iCharacterData.iCharacterOffsetsListOffset = TInt(characterOffsetsList) - TInt(this);
sl@0
   144
	TBitmapFontCharacterOffset* pEnd = characterOffsetsList + size;
sl@0
   145
	for (TBitmapFontCharacterOffset* p = characterOffsetsList; p < pEnd; p++)
sl@0
   146
		{
sl@0
   147
		p->InternalizeL(stream);
sl@0
   148
		}
sl@0
   149
sl@0
   150
	CleanupStack::PopAndDestroy();
sl@0
   151
	}
sl@0
   152
sl@0
   153
//This method is called  from CFontBitmap::RestoreComponentsL - 
sl@0
   154
//if the CFontBitmap instance is in RAM and CFontBitmap::iComponentsRestored is EFalse.
sl@0
   155
//We use here stream IDs, not offsets.
sl@0
   156
//If the memory allocation for the bitmap doesn't fail - aAllocMemCounter is incremented
sl@0
   157
//After calling of TBitmapCodeSection::InternalizeBitmapL bitmap streamID is no more valid - 
sl@0
   158
//we have valid bitmap offset into RAM memory.
sl@0
   159
void TBitmapCodeSection::InternalizeBitmapL(const CStreamStore& aStreamStore, RHeap* aHeap, TInt& aAllocMemCounter)
sl@0
   160
	{
sl@0
   161
	RStoreReadStream stream;
sl@0
   162
	stream.OpenLC(aStreamStore, iBitmapData.iBitmapId);
sl@0
   163
sl@0
   164
	TInt size = stream.ReadInt32L();
sl@0
   165
	TUint8* bitmap = (TUint8*)aHeap->AllocL(size);
sl@0
   166
	aAllocMemCounter++;
sl@0
   167
	iBitmapData.iBitmapOffset = TInt(bitmap) - TInt(this);
sl@0
   168
	stream.ReadL(bitmap, size);
sl@0
   169
sl@0
   170
	CleanupStack::PopAndDestroy();
sl@0
   171
	}
sl@0
   172
sl@0
   173
//This method is called from CFontBitmap::InternalizeL if the
sl@0
   174
//CFontBitmap instance is in ROM.
sl@0
   175
//We use here stream IDs to calculate offsets.
sl@0
   176
//After calling of TBitmapCodeSection::FixUpComponents streamIDs are no more valid - 
sl@0
   177
//we have valid offsets into ROM memory.
sl@0
   178
//Obviously the method is called once per life time of 
sl@0
   179
//CFontBitmap instance.
sl@0
   180
void TBitmapCodeSection::FixUpComponents(TInt aFileAddress)
sl@0
   181
	{
sl@0
   182
	TBitmapFontCharacterOffset* characterOffsetsList = (TBitmapFontCharacterOffset*) (aFileAddress + sizeof(TInt) + iCharacterData.iOffsetsId);
sl@0
   183
	iCharacterData.iCharacterOffsetsListOffset = TInt(characterOffsetsList);
sl@0
   184
	TUint8* bitmap = (TUint8*) (aFileAddress + sizeof(TInt) + iBitmapData.iBitmapId);
sl@0
   185
	iBitmapData.iBitmapOffset = TInt(bitmap);
sl@0
   186
	}
sl@0
   187
sl@0
   188
//This method is caled from CFontBitmap::DeleteComponents(),
sl@0
   189
//only if the CFontBitmap instance is in RAM.
sl@0
   190
void TBitmapCodeSection::DeleteOffsets(RHeap* aHeap)
sl@0
   191
	{
sl@0
   192
	TBitmapFontCharacterOffset*  charactersOffsetsList = CharacterOffsetsList(ETrue);
sl@0
   193
	if(TUint32(this) != TUint32(charactersOffsetsList))
sl@0
   194
		{
sl@0
   195
		aHeap->Free(charactersOffsetsList);
sl@0
   196
		}
sl@0
   197
	}
sl@0
   198
sl@0
   199
//This method is caled from CFontBitmap::DeleteComponents(),
sl@0
   200
//only if the CFontBitmap instance is in RAM.
sl@0
   201
void TBitmapCodeSection::DeleteBitmap(RHeap* aHeap)
sl@0
   202
	{
sl@0
   203
	TUint8* bitmap = Bitmap(ETrue);
sl@0
   204
	if(TUint32(this) != TUint32(bitmap))
sl@0
   205
		{
sl@0
   206
		aHeap->Free(bitmap);
sl@0
   207
		}
sl@0
   208
	}
sl@0
   209
sl@0
   210
TBitmapFontCharacterOffset* TBitmapCodeSection::CharacterOffsetsList(TBool aIsInRAM) const
sl@0
   211
	{
sl@0
   212
	return reinterpret_cast <TBitmapFontCharacterOffset*> 
sl@0
   213
		(iCharacterData.iCharacterOffsetsListOffset + (aIsInRAM ? TInt(this) : 0));
sl@0
   214
	}
sl@0
   215
sl@0
   216
TUint8* TBitmapCodeSection::Bitmap(TBool aIsInRAM) const
sl@0
   217
	{
sl@0
   218
	return reinterpret_cast <TUint8*> 
sl@0
   219
		(iBitmapData.iBitmapOffset + (aIsInRAM ? TInt(this) : 0));
sl@0
   220
	}
sl@0
   221
sl@0
   222
TCharacterMetricsTable::TCharacterMetricsTable(RHeap* aHeap)
sl@0
   223
 :	iHeap(aHeap),
sl@0
   224
	iMetricsStartId(KNullStreamId),
sl@0
   225
	iCharacterMetricsStartPtr(0),
sl@0
   226
	iNumberOfMetrics(0),
sl@0
   227
	iMetricsOnHeap(EFalse)
sl@0
   228
	{}
sl@0
   229
sl@0
   230
void TCharacterMetricsTable::InternalizeL(RReadStream& aStream)
sl@0
   231
	{
sl@0
   232
	iMetricsStartId = aStream.ReadInt32L();
sl@0
   233
	iNumberOfMetrics = aStream.ReadInt32L();
sl@0
   234
	}
sl@0
   235
sl@0
   236
void TCharacterMetricsTable::InternalizeMetricsL(RReadStream& aStream)
sl@0
   237
	{
sl@0
   238
	aStream.ReadInt32L(); // size
sl@0
   239
	TBitmapFontCharacterMetrics* charactermetricslist = static_cast<TBitmapFontCharacterMetrics*>(iHeap->AllocL(sizeof(TBitmapFontCharacterMetrics) * iNumberOfMetrics));
sl@0
   240
	iMetricsOnHeap = ETrue;
sl@0
   241
	// Offset from this to location on the heap ('cos the file is not in ROM)
sl@0
   242
	iCharacterMetricsStartPtr = reinterpret_cast<TInt>(charactermetricslist) - reinterpret_cast<TInt>(this);
sl@0
   243
	TBitmapFontCharacterMetrics* pEnd = charactermetricslist + iNumberOfMetrics;
sl@0
   244
	for (TBitmapFontCharacterMetrics* p = charactermetricslist; p < pEnd; p++)
sl@0
   245
		{
sl@0
   246
		p->InternalizeL(aStream);
sl@0
   247
		}
sl@0
   248
	}
sl@0
   249
sl@0
   250
void TCharacterMetricsTable::RestoreL(const CStreamStore& aStreamStore)
sl@0
   251
	{
sl@0
   252
	if (iCharacterMetricsStartPtr == 0)
sl@0
   253
		{	// We haven't already read it in from RAM file
sl@0
   254
		RStoreReadStream stream;
sl@0
   255
		stream.OpenLC(aStreamStore, iMetricsStartId);
sl@0
   256
		InternalizeMetricsL(stream);
sl@0
   257
		CleanupStack::PopAndDestroy();
sl@0
   258
		}
sl@0
   259
	}
sl@0
   260
sl@0
   261
void TCharacterMetricsTable::FixUp(TInt aFileAddress)
sl@0
   262
	{
sl@0
   263
	TBitmapFontCharacterMetrics* charactermetricslist = reinterpret_cast<TBitmapFontCharacterMetrics*>(aFileAddress + sizeof(TInt) + iMetricsStartId.Value());
sl@0
   264
	iCharacterMetricsStartPtr = TInt(charactermetricslist);	// Ptr to location in a ROM file
sl@0
   265
	iMetricsStartId = KNullStreamId;
sl@0
   266
	iMetricsOnHeap = EFalse;
sl@0
   267
	}
sl@0
   268
sl@0
   269
void TCharacterMetricsTable::Delete()
sl@0
   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
sl@0
   271
    if (iMetricsOnHeap && iCharacterMetricsStartPtr)
sl@0
   272
        {
sl@0
   273
        iHeap->Free(reinterpret_cast<TAny*>(MetricsFromOffset(0)));
sl@0
   274
        iCharacterMetricsStartPtr = 0;
sl@0
   275
        iMetricsOnHeap = EFalse;
sl@0
   276
        }
sl@0
   277
	}
sl@0
   278
sl@0
   279
const TBitmapFontCharacterMetrics* TCharacterMetricsTable::Metric(TInt aIndex) const
sl@0
   280
	{
sl@0
   281
	if ((aIndex < 0) || (aIndex > iNumberOfMetrics))
sl@0
   282
	    {
sl@0
   283
	    OstTraceExt2( TRACE_FATAL, TCHARACTERMETRICSTABLE_METRIC, "TCharacterMetricsTable::Metric, aIndex=%d, iNumberOfMetrics=%d, Panic(EFntMetricsIndexOutOfBounds)", aIndex, iNumberOfMetrics);
sl@0
   284
	    __ASSERT_DEBUG(0, Panic(EFntMetricsIndexOutOfBounds));
sl@0
   285
	    }
sl@0
   286
    // Sometimes the start ptr is to a metrics heap item and sometimes it points into a ROM file
sl@0
   287
    if (iMetricsOnHeap)
sl@0
   288
        {
sl@0
   289
        // Start ptr is to metrics heap item
sl@0
   290
        return MetricsFromOffset(aIndex);
sl@0
   291
        }
sl@0
   292
    else
sl@0
   293
        {
sl@0
   294
        // Start ptr is to a file in ROM
sl@0
   295
        return reinterpret_cast<const TBitmapFontCharacterMetrics*> (iCharacterMetricsStartPtr + (aIndex * sizeof(TBitmapFontCharacterMetrics)));
sl@0
   296
        }
sl@0
   297
	}
sl@0
   298
sl@0
   299
TInt TCharacterMetricsTable::NumberOfMetrics() const
sl@0
   300
	{
sl@0
   301
	return iNumberOfMetrics;
sl@0
   302
	}
sl@0
   303
sl@0
   304
TBitmapFontCharacterMetrics* TCharacterMetricsTable::MetricsFromOffset(TInt aIndex) const
sl@0
   305
    {
sl@0
   306
    __ASSERT_DEBUG(iMetricsOnHeap,Panic(EFntMetricsNotOnHeap));
sl@0
   307
    return reinterpret_cast<TBitmapFontCharacterMetrics*>(reinterpret_cast<TInt>(this) + iCharacterMetricsStartPtr+ (aIndex * sizeof(TBitmapFontCharacterMetrics)));
sl@0
   308
    }
sl@0
   309
sl@0
   310
CFontBitmap::CFontBitmap(RHeap* aHeap, CFontStoreFile* aFontStoreFile)
sl@0
   311
 :	iHeap(aHeap),
sl@0
   312
	iFontStoreFileOffset(0),
sl@0
   313
	iUid(KNullUid),
sl@0
   314
	iPosture(0),
sl@0
   315
	iStrokeWeight(0),
sl@0
   316
	iIsProportional(0),
sl@0
   317
	iIsInRAM(!aFontStoreFile->iFileAddress),
sl@0
   318
	iUsageCount(1),
sl@0
   319
	iCellHeightInPixels(0),
sl@0
   320
	iAscentInPixels(0),
sl@0
   321
	iMaxCharWidthInPixels(0),
sl@0
   322
	iMaxNormalCharWidthInPixels(0),
sl@0
   323
	iBitmapEncoding(0),
sl@0
   324
	iNumCodeSections(0),
sl@0
   325
	iCodeSectionListOffset(0),
sl@0
   326
	iCharacterMetricsTable(aHeap),
sl@0
   327
	iComponentsRestored(EFalse),
sl@0
   328
	iAllocMemCounter_Offsets(0),
sl@0
   329
	iAllocMemCounter_Bitmaps(0),
sl@0
   330
	iFontCapitalAscent(0),
sl@0
   331
	iFontMaxAscent(0),
sl@0
   332
	iFontStandardDescent(0),
sl@0
   333
	iFontMaxDescent(0),
sl@0
   334
	iFontLineGap(0)
sl@0
   335
	{
sl@0
   336
	iFontStoreFileOffset = TInt(aFontStoreFile) - TInt(this);
sl@0
   337
	}
sl@0
   338
sl@0
   339
void CFontBitmap::InternalizeL(RReadStream &aStream, TInt aFontVersion)
sl@0
   340
	{
sl@0
   341
	aStream >> iUid;
sl@0
   342
	iPosture = aStream.ReadInt8L();
sl@0
   343
	iStrokeWeight = aStream.ReadInt8L();
sl@0
   344
	iIsProportional = aStream.ReadInt8L();
sl@0
   345
	iCellHeightInPixels = aStream.ReadInt8L();
sl@0
   346
	iAscentInPixels = aStream.ReadInt8L();
sl@0
   347
	iMaxCharWidthInPixels = aStream.ReadInt8L();
sl@0
   348
	iMaxNormalCharWidthInPixels = aStream.ReadInt8L();
sl@0
   349
	if ( aFontVersion  >= KFnttranVersion )
sl@0
   350
		{ // read the new metrics in
sl@0
   351
		iFontCapitalAscent = aStream.ReadInt8L();
sl@0
   352
		iFontMaxAscent = aStream.ReadInt8L();
sl@0
   353
		iFontStandardDescent = aStream.ReadInt8L();
sl@0
   354
		iFontMaxDescent = aStream.ReadInt8L();
sl@0
   355
		iFontLineGap = aStream.ReadInt8L();
sl@0
   356
		}
sl@0
   357
	else // synthesize the extra metrics (data compatibility with third party bitmap fonts for old phones)
sl@0
   358
		{
sl@0
   359
		iFontMaxAscent = iFontCapitalAscent = iAscentInPixels;
sl@0
   360
		iFontMaxDescent = iFontStandardDescent = iCellHeightInPixels - iAscentInPixels;
sl@0
   361
		iFontLineGap = ( ( iCellHeightInPixels * 12 ) + 5) / 10;  // 1.2 times design height
sl@0
   362
		}	
sl@0
   363
	iBitmapEncoding = aStream.ReadInt32L();
sl@0
   364
	iCharacterMetricsTable.InternalizeL(aStream);
sl@0
   365
	const TBool fixup = FontStoreFile()->iFileAddress;
sl@0
   366
	if (fixup)
sl@0
   367
		{
sl@0
   368
		iCharacterMetricsTable.FixUp(FontStoreFile()->iFileAddress);
sl@0
   369
		}
sl@0
   370
	iNumCodeSections = aStream.ReadInt32L();
sl@0
   371
	TBitmapCodeSection* codesectionlist = (TBitmapCodeSection*)User::LeaveIfNull(iHeap->AllocL(iNumCodeSections * sizeof(TBitmapCodeSection)));
sl@0
   372
	iCodeSectionListOffset = TInt(codesectionlist) - TInt(this);
sl@0
   373
	for (TInt i = 0; i < iNumCodeSections; i++)
sl@0
   374
		{
sl@0
   375
		new(codesectionlist + i) TBitmapCodeSection;
sl@0
   376
		codesectionlist[i].InternalizeL(aStream);
sl@0
   377
		if (fixup)
sl@0
   378
			codesectionlist[i].FixUpComponents(FontStoreFile()->iFileAddress);
sl@0
   379
		}
sl@0
   380
	}
sl@0
   381
sl@0
   382
void CFontBitmap::UseL()
sl@0
   383
	{
sl@0
   384
	// Note object is created with a Usage Count of 1.
sl@0
   385
	// So incrementing to 2 normally indicates the first external reference.
sl@0
   386
	iUsageCount++;
sl@0
   387
	if (iUsageCount == 2)
sl@0
   388
		{
sl@0
   389
		RestoreComponentsL();
sl@0
   390
		}
sl@0
   391
	}
sl@0
   392
sl@0
   393
void CFontBitmap::Release()
sl@0
   394
	{
sl@0
   395
	iUsageCount--;
sl@0
   396
	if (!iUsageCount)
sl@0
   397
		{ // object and all its users have closed
sl@0
   398
		delete this;
sl@0
   399
		}
sl@0
   400
	}
sl@0
   401
sl@0
   402
/*
sl@0
   403
Get the metrics for a given character.
sl@0
   404
Return aBytes as null if the character aCode doesn't exist in the font.
sl@0
   405
*/
sl@0
   406
TBitmapFontCharacterMetrics CFontBitmap::CharacterMetrics(TInt aCode, const TUint8*& aBytes) const
sl@0
   407
	{
sl@0
   408
 	const TBitmapCodeSection* matchSection = NULL;
sl@0
   409
	const TBitmapCodeSection* const lastSection = CodeSectionList() + iNumCodeSections - 1;
sl@0
   410
sl@0
   411
	TBitmapFontCharacterOffset offset;
sl@0
   412
	aBytes = NULL;
sl@0
   413
sl@0
   414
	TBitmapFontCharacterMetrics metrics;
sl@0
   415
	const TBitmapCodeSection* startSearchBand = CodeSectionList();
sl@0
   416
	TInt numCodeSectionsRemaining = iNumCodeSections;
sl@0
   417
	while (numCodeSectionsRemaining >= 1)
sl@0
   418
		{
sl@0
   419
		TInt halfNumCodeSectionsRemaining = numCodeSectionsRemaining/2;
sl@0
   420
		const TBitmapCodeSection* centralSearchBand = startSearchBand+halfNumCodeSectionsRemaining;
sl@0
   421
		if ((aCode >= centralSearchBand->iStart) && (aCode <= centralSearchBand->iEnd))
sl@0
   422
			{
sl@0
   423
			matchSection = centralSearchBand;
sl@0
   424
			break;
sl@0
   425
			}
sl@0
   426
		else if ((aCode < centralSearchBand->iStart) || (centralSearchBand == lastSection))
sl@0
   427
			numCodeSectionsRemaining = halfNumCodeSectionsRemaining;
sl@0
   428
		else
sl@0
   429
			{
sl@0
   430
			startSearchBand = centralSearchBand + 1;
sl@0
   431
			numCodeSectionsRemaining -= halfNumCodeSectionsRemaining + 1;
sl@0
   432
			}
sl@0
   433
		}
sl@0
   434
sl@0
   435
	if (matchSection)
sl@0
   436
		{
sl@0
   437
		offset =* ((matchSection->CharacterOffsetsList(iIsInRAM)) + (aCode-matchSection->iStart));
sl@0
   438
sl@0
   439
		// Fill characters within code section.
sl@0
   440
		// Recursive call ensures that a valid metric is always returned.
sl@0
   441
		if (offset.iBitmapOffset == KFillCharacterOffset)
sl@0
   442
			{
sl@0
   443
			return CharacterMetrics(KReplacementCharacter, aBytes);
sl@0
   444
			}
sl@0
   445
		
sl@0
   446
		aBytes = matchSection->Bitmap(iIsInRAM) + offset.iBitmapOffset;
sl@0
   447
		
sl@0
   448
		// retrieve metric index from encoded 1 or 2 bytes
sl@0
   449
		TInt index = 0;
sl@0
   450
		TUint8 byte1 = (TUint8)*aBytes;
sl@0
   451
		const TInt switchMask = 0x1;
sl@0
   452
		const TBool oneByteIndex =! (byte1 & switchMask);
sl@0
   453
		byte1 = TUint8(byte1 >> 1);
sl@0
   454
		if (oneByteIndex)
sl@0
   455
			{
sl@0
   456
			index = byte1;
sl@0
   457
			aBytes += 1;
sl@0
   458
			}
sl@0
   459
		else
sl@0
   460
			{
sl@0
   461
			const TUint8 byte2 = (TUint8)(*(aBytes + 1));
sl@0
   462
			index = byte1 + (byte2 * 128);
sl@0
   463
			aBytes += 2;
sl@0
   464
			}
sl@0
   465
		// Copy metric from table
sl@0
   466
		metrics =* iCharacterMetricsTable.Metric(index);
sl@0
   467
		}
sl@0
   468
	return metrics;
sl@0
   469
	}
sl@0
   470
sl@0
   471
void CFontBitmap::operator delete(TAny *aThis)
sl@0
   472
	{
sl@0
   473
	if (((CFontBitmap *)aThis)->iHeap)
sl@0
   474
		{
sl@0
   475
		((CFontBitmap *)aThis)->iHeap->Free(aThis);
sl@0
   476
		}
sl@0
   477
	}
sl@0
   478
sl@0
   479
void CFontBitmap::SetPosture(TFontPosture aPosture)
sl@0
   480
	{
sl@0
   481
	iPosture = (TInt8)aPosture;
sl@0
   482
	}
sl@0
   483
sl@0
   484
TFontPosture CFontBitmap::Posture() const
sl@0
   485
	{
sl@0
   486
	return (TFontPosture)iPosture;	 // iPosture is always smaller than TFontPosture
sl@0
   487
	}
sl@0
   488
sl@0
   489
void CFontBitmap::SetStrokeWeight(TFontStrokeWeight aStrokeWeight)
sl@0
   490
	{
sl@0
   491
	iStrokeWeight = (TInt8)aStrokeWeight;
sl@0
   492
	}
sl@0
   493
sl@0
   494
TFontStrokeWeight CFontBitmap::StrokeWeight() const
sl@0
   495
	{
sl@0
   496
	return (TFontStrokeWeight)iStrokeWeight;
sl@0
   497
	}
sl@0
   498
sl@0
   499
void CFontBitmap::SetIsProportional(TBool aIsProportional)
sl@0
   500
	{
sl@0
   501
	iIsProportional = (TInt8)aIsProportional;
sl@0
   502
	}
sl@0
   503
sl@0
   504
TBool CFontBitmap::IsProportional() const
sl@0
   505
	{
sl@0
   506
	return iIsProportional;
sl@0
   507
	}
sl@0
   508
sl@0
   509
CFontStoreFile* CFontBitmap::FontStoreFile() const
sl@0
   510
	{
sl@0
   511
	TInt fsf = TInt(this) + iFontStoreFileOffset;
sl@0
   512
	return (CFontStoreFile*)fsf;
sl@0
   513
	}
sl@0
   514
sl@0
   515
CFontBitmap::~CFontBitmap()
sl@0
   516
	{
sl@0
   517
	DeleteComponents();
sl@0
   518
	TBitmapCodeSection* codeSectionList = CodeSectionList();
sl@0
   519
	if(TUint32(this) != TUint32(codeSectionList))
sl@0
   520
		{
sl@0
   521
		iHeap->Free(codeSectionList);
sl@0
   522
		}
sl@0
   523
	iCodeSectionListOffset = 0;
sl@0
   524
	}
sl@0
   525
sl@0
   526
//We have to count how many offsets and bitmaps are allocated successfully because if
sl@0
   527
//some of codesection's Internalize..L fails we have to deallocate the right amount of 
sl@0
   528
//data.
sl@0
   529
void CFontBitmap::RestoreComponentsL()
sl@0
   530
	{
sl@0
   531
	if (iIsInRAM)
sl@0
   532
		{
sl@0
   533
		if(!iComponentsRestored)
sl@0
   534
			{
sl@0
   535
			iAllocMemCounter_Offsets = 0;
sl@0
   536
			iAllocMemCounter_Bitmaps = 0;
sl@0
   537
			CStreamStore& store =* FontStoreFile()->iFileStore;
sl@0
   538
			for (TInt i = 0; i < iNumCodeSections; i++)
sl@0
   539
				{
sl@0
   540
				CodeSectionList()[i].InternalizeOffsetsL(store, iHeap, iAllocMemCounter_Offsets);
sl@0
   541
				CodeSectionList()[i].InternalizeBitmapL(store, iHeap, iAllocMemCounter_Bitmaps);
sl@0
   542
				}
sl@0
   543
			iCharacterMetricsTable.RestoreL(store);
sl@0
   544
			}
sl@0
   545
		iComponentsRestored = ETrue;
sl@0
   546
		}
sl@0
   547
	}
sl@0
   548
sl@0
   549
void CFontBitmap::DeleteComponents()
sl@0
   550
	{
sl@0
   551
	if (iIsInRAM)
sl@0
   552
		{
sl@0
   553
		TInt i;
sl@0
   554
		for (i = 0; i < iAllocMemCounter_Offsets; i++)
sl@0
   555
			{
sl@0
   556
			CodeSectionList()[i].DeleteOffsets(iHeap);
sl@0
   557
			}
sl@0
   558
		for (i = 0; i < iAllocMemCounter_Bitmaps; i++)
sl@0
   559
			{
sl@0
   560
			CodeSectionList()[i].DeleteBitmap(iHeap);
sl@0
   561
			}
sl@0
   562
		iCharacterMetricsTable.Delete();
sl@0
   563
		}
sl@0
   564
	iAllocMemCounter_Offsets = 0;
sl@0
   565
	iAllocMemCounter_Bitmaps = 0;
sl@0
   566
	iComponentsRestored = EFalse;
sl@0
   567
	}
sl@0
   568
sl@0
   569
TBitmapCodeSection* CFontBitmap::CodeSectionList() const
sl@0
   570
	{
sl@0
   571
	TInt bcs = TInt(this) + iCodeSectionListOffset;
sl@0
   572
	return (TBitmapCodeSection*)bcs;
sl@0
   573
	}
sl@0
   574
sl@0
   575
TTypefaceFontBitmap::TTypefaceFontBitmap()
sl@0
   576
 :	iTypeface(NULL),
sl@0
   577
	iFontBitmap(NULL),
sl@0
   578
	iHeightFactor(1),
sl@0
   579
	iWidthFactor(1)
sl@0
   580
	{
sl@0
   581
	}
sl@0
   582
sl@0
   583
TTypefaceFontBitmap::TTypefaceFontBitmap(TTypeface* aTypeface,CFontBitmap* aFontBitmap)
sl@0
   584
 :	iTypeface(aTypeface),
sl@0
   585
	iFontBitmap(aFontBitmap),
sl@0
   586
	iHeightFactor(1),
sl@0
   587
	iWidthFactor(1)
sl@0
   588
	{
sl@0
   589
	}
sl@0
   590
sl@0
   591
TInt TTypefaceFontBitmap::HeightInPixels() const
sl@0
   592
	{
sl@0
   593
	return iFontBitmap->iCellHeightInPixels * iHeightFactor;
sl@0
   594
	}