os/graphics/fbs/fontandbitmapserver/sfbs/FBSTOP.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <hal.h>
sl@0
    17
#include <gdi.h>
sl@0
    18
#include <fntstore.h>
sl@0
    19
#include <bitmap.h>
sl@0
    20
#include <ecom/ecom.h>
sl@0
    21
#include <graphics/bitmapuid.h>
sl@0
    22
#include "SERVER.H"
sl@0
    23
#include "BackGroundCompression.h"
sl@0
    24
#include "BitwiseBitmap.inl"
sl@0
    25
#include "bitmapconst.h"
sl@0
    26
#include <graphics/openfontconstants.h>
sl@0
    27
#include <graphics/openfontrasterizer.h>
sl@0
    28
#include <graphics/gdi/glyphsample.h>
sl@0
    29
#include "glyphatlas.h"
sl@0
    30
#include "FbsMessage.H"
sl@0
    31
sl@0
    32
// Local utility functions
sl@0
    33
void ListImplementationsWithRetry(TUid& aInterfaceUid, RImplInfoPtrArray &aImplementationArray, TBool aRomOnly);
sl@0
    34
sl@0
    35
sl@0
    36
CFbTop::CFbTop():
sl@0
    37
	iDefaultLanguageForMetrics(ELangNone)
sl@0
    38
	{
sl@0
    39
	}
sl@0
    40
sl@0
    41
CFbTop::~CFbTop()
sl@0
    42
	{
sl@0
    43
	if (iConIx)
sl@0
    44
		{
sl@0
    45
		iConIx->Remove(iBitmapCon);
sl@0
    46
		iConIx->Remove(iFontCon);
sl@0
    47
		}
sl@0
    48
	// there are no bitmap objects left, so the background compression queue must be empty
sl@0
    49
	delete iBackgroundCompression;
sl@0
    50
	delete iMBMCache;
sl@0
    51
	delete iFontStore;
sl@0
    52
	iFilesys.Close();
sl@0
    53
	iHeap->Check();
sl@0
    54
	__RHEAP_MARKEND(iHeap);
sl@0
    55
	delete iPile;
sl@0
    56
	iHeap->Close();
sl@0
    57
	iChunk.Close();
sl@0
    58
	iLargeBitmapChunk.Close();
sl@0
    59
	delete iConIx;
sl@0
    60
#ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
sl@0
    61
	iDebugMutex.Close();
sl@0
    62
#endif
sl@0
    63
	iFontNameAlias.ResetAndDestroy();
sl@0
    64
	iBitmapObjectIndex.Reset();
sl@0
    65
	delete iGlyphAtlas;
sl@0
    66
	REComSession::FinalClose();
sl@0
    67
	}
sl@0
    68
sl@0
    69
CFbTop* CFbTop::NewL()
sl@0
    70
	{
sl@0
    71
	CFbTop* pT=new(ELeave) CFbTop;
sl@0
    72
	CleanupStack::PushL(pT);
sl@0
    73
	pT->ConstructL();
sl@0
    74
	CleanupStack::Pop();
sl@0
    75
	return(pT);
sl@0
    76
	}
sl@0
    77
sl@0
    78
void CFbTop::ConstructL()
sl@0
    79
	{
sl@0
    80
	TInt maxmem = 0;
sl@0
    81
	HAL::Get(HALData::EMemoryRAM, maxmem);
sl@0
    82
	ASSERT(maxmem > 0);
sl@0
    83
	TInt maxHeapSize = Min(maxmem, KFbServSharedHeapMaxSize);
sl@0
    84
	
sl@0
    85
	TChunkHeapCreateInfo sharedHeapCreateInfo(KFBSERVInitialHeapSize, maxHeapSize);
sl@0
    86
	sharedHeapCreateInfo.SetCreateChunk(&KFBSERVSharedChunkName);
sl@0
    87
	sharedHeapCreateInfo.SetSingleThread(EFalse);
sl@0
    88
	sharedHeapCreateInfo.SetAlignment(0);
sl@0
    89
	sharedHeapCreateInfo.SetGrowBy(KMinHeapGrowBy * KFBSERVHeapGrowByMultiplier);
sl@0
    90
sl@0
    91
	if(KFbServWritableDataPagingMode == EFbsWdpPageBitmapDataAndSharedHeapChunksOnly)
sl@0
    92
		{
sl@0
    93
		//Request that the shared heap chunk is paged.
sl@0
    94
		sharedHeapCreateInfo.SetPaging(TChunkHeapCreateInfo::EPaged);
sl@0
    95
		}
sl@0
    96
	else
sl@0
    97
		{
sl@0
    98
		//Use the creating process's paging attributes.
sl@0
    99
		sharedHeapCreateInfo.SetPaging(TChunkHeapCreateInfo::EUnspecified);
sl@0
   100
		}
sl@0
   101
sl@0
   102
	iHeap = UserHeap::ChunkHeap(sharedHeapCreateInfo);
sl@0
   103
	
sl@0
   104
	User::LeaveIfError(iChunk.OpenGlobal(KFBSERVSharedChunkName,ETrue));
sl@0
   105
	TInt virtualSize = CChunkPile::VirtualSize();
sl@0
   106
	
sl@0
   107
	TChunkCreateInfo createInfo;
sl@0
   108
	createInfo.SetDisconnected(0, 0, virtualSize);
sl@0
   109
	createInfo.SetGlobal(KFBSERVLargeChunkName);
sl@0
   110
	createInfo.SetOwner(EOwnerProcess);
sl@0
   111
	createInfo.SetClearByte(0xff); // clear to white on creation
sl@0
   112
sl@0
   113
	if(KFbServWritableDataPagingMode == EFbsWdpPageBitmapDataChunkOnly || 
sl@0
   114
		KFbServWritableDataPagingMode == EFbsWdpPageBitmapDataAndSharedHeapChunksOnly)
sl@0
   115
		{
sl@0
   116
		//Request that large bitmap chunk is paged.
sl@0
   117
		createInfo.SetPaging(TChunkCreateInfo::EPaged);
sl@0
   118
		}
sl@0
   119
	else
sl@0
   120
		{
sl@0
   121
		//Use the creating process's paging attributes.
sl@0
   122
		createInfo.SetPaging(TChunkCreateInfo::EUnspecified);
sl@0
   123
		}
sl@0
   124
sl@0
   125
	User::LeaveIfError(iLargeBitmapChunk.Create(createInfo));
sl@0
   126
	__RHEAP_MARK(iHeap);
sl@0
   127
	iConIx=CObjectConIx::NewL();
sl@0
   128
	iBitmapCon=iConIx->CreateL();
sl@0
   129
	iFontCon=iConIx->CreateL();
sl@0
   130
	User::LeaveIfError(iFilesys.Connect());
sl@0
   131
#ifdef SYMBIAN_DEBUG_FBS_LOCKHEAP
sl@0
   132
	User::LeaveIfError(iDebugMutex.CreateGlobal(KFBSERVDebugMutexName));
sl@0
   133
#endif
sl@0
   134
	iPile = CChunkPile::NewL(iLargeBitmapChunk);
sl@0
   135
	iFontStore=CFontStore::NewL(iHeap);
sl@0
   136
	//Constructing a cache to store the stream ids of the bitmaps from a mbm file.
sl@0
   137
	//The cache here will store maximum 30 bitmaps before  & maximum 30 after the 
sl@0
   138
	//current loaded bitmap.These values are chosen as to optimize the boottime performance
sl@0
   139
	//as we notice during the boottime logs,sequential loading of bitmaps never exceed 30 bitmaps.
sl@0
   140
	// The cache will also store maximum 5 mbm files. This number must be as low as possible
sl@0
   141
	// while trying to minimize flushing of the cache due to mbm file switching.
sl@0
   142
	iMBMCache=new (ELeave) CFbTopStreamIdCache(30,30,5);
sl@0
   143
sl@0
   144
	LoadOpenFontLibraries();
sl@0
   145
	iFontStore->LoadFontsAtStartupL();
sl@0
   146
	LoadShaperFactories();
sl@0
   147
	TRAP_IGNORE(iGlyphAtlas = CGlyphAtlas::NewL(KFbServGlyphAtlasCacheLimit);)
sl@0
   148
#ifdef _DEBUG
sl@0
   149
	if (!iGlyphAtlas)
sl@0
   150
	    {
sl@0
   151
        RDebug::Printf("FBSERV failed to initialize Glyph Atlas");
sl@0
   152
	    }
sl@0
   153
#endif
sl@0
   154
sl@0
   155
	// start a new thread for background compression after all the other objects have been created
sl@0
   156
	iBackgroundCompression = CFbsBackgroundCompression::NewL(*this);
sl@0
   157
	}
sl@0
   158
sl@0
   159
sl@0
   160
sl@0
   161
sl@0
   162
/*
sl@0
   163
Load all ECOM implemented rasterizer DLLs.
sl@0
   164
*/
sl@0
   165
sl@0
   166
void CFbTop::LoadOpenFontLibraries()
sl@0
   167
	{
sl@0
   168
	RImplInfoPtrArray implementationArray;
sl@0
   169
	TUid uid = {KUidOpenFontRasterizerPlunginInterface};
sl@0
   170
sl@0
   171
	// get implementation list
sl@0
   172
	ListImplementationsWithRetry(uid, implementationArray, EFalse);
sl@0
   173
sl@0
   174
	const TInt availCount = implementationArray.Count();
sl@0
   175
	for (TInt count=0; count < availCount; ++count)
sl@0
   176
		{
sl@0
   177
		const CImplementationInformation* info = implementationArray[count];
sl@0
   178
		// Create & install a rasterizer
sl@0
   179
		// ignore Leaves, as any necessary cleanup will have already been done through the cleanup stack
sl@0
   180
		TRAP_IGNORE(SafeInstallOfRasterizerL(info->ImplementationUid()));
sl@0
   181
		}
sl@0
   182
	
sl@0
   183
	// free memory
sl@0
   184
	implementationArray.ResetAndDestroy();
sl@0
   185
	}
sl@0
   186
sl@0
   187
sl@0
   188
/*
sl@0
   189
Load all ECOM implemented shaper factory DLLs.
sl@0
   190
*/	
sl@0
   191
void CFbTop::LoadShaperFactories()
sl@0
   192
	{
sl@0
   193
	RImplInfoPtrArray implementationArray;
sl@0
   194
	TUid uid = {KUidShaperFactoryPlunginInterface};
sl@0
   195
sl@0
   196
	// get implementation list
sl@0
   197
	ListImplementationsWithRetry(uid, implementationArray, ETrue);
sl@0
   198
sl@0
   199
	const TInt availCount = implementationArray.Count();
sl@0
   200
	for (TInt count=0;count<availCount;++count)
sl@0
   201
		{
sl@0
   202
		const CImplementationInformation* info = implementationArray[count];
sl@0
   203
		// Create & install a shaper factory
sl@0
   204
		// ignore Leaves, as any necessary cleanup will have already been done through the cleanup stack
sl@0
   205
		TRAP_IGNORE(SafeInstallOfShaperFactoryL(info->ImplementationUid()));
sl@0
   206
		}
sl@0
   207
sl@0
   208
	// free memory
sl@0
   209
	implementationArray.ResetAndDestroy();
sl@0
   210
	}
sl@0
   211
sl@0
   212
sl@0
   213
void ListImplementationsWithRetry(TUid& aInterfaceUid, RImplInfoPtrArray &aImplementationArray, TBool aRomOnly)
sl@0
   214
	{
sl@0
   215
	// Making sure that no race situation arises between FBserv and Ecom
sl@0
   216
	// If ECom is not ready, give it another chance and try again. if it still doesn't work 
sl@0
   217
	// after the third try, then it just carries on quietly and fails... 
sl@0
   218
	for (TInt ecomnotready =0; ecomnotready <3; ecomnotready++)
sl@0
   219
		{
sl@0
   220
		TInt ecomError = KErrNone;
sl@0
   221
		if (aRomOnly)
sl@0
   222
			{
sl@0
   223
			TEComResolverParams resParams;
sl@0
   224
			TRAP(ecomError, REComSession::ListImplementationsL(aInterfaceUid, resParams, KRomOnlyResolverUid, aImplementationArray));
sl@0
   225
			}
sl@0
   226
		else
sl@0
   227
			{ // default resolver
sl@0
   228
			TRAP(ecomError, REComSession::ListImplementationsL(aInterfaceUid, aImplementationArray));
sl@0
   229
			}
sl@0
   230
sl@0
   231
		if (!ecomError)
sl@0
   232
			{
sl@0
   233
			return;
sl@0
   234
			}
sl@0
   235
		else
sl@0
   236
			{
sl@0
   237
			User::After(0);
sl@0
   238
			}
sl@0
   239
		}
sl@0
   240
	}
sl@0
   241
sl@0
   242
// utility methods to transfer ownership, or destroy object on failure
sl@0
   243
void CFbTop::SafeInstallOfRasterizerL(TUid aInterfaceImplUid)
sl@0
   244
	{
sl@0
   245
	COpenFontRasterizer* rasterizer = COpenFontRasterizer::NewL(aInterfaceImplUid);
sl@0
   246
	CleanupStack::PushL(rasterizer);
sl@0
   247
	// Install it in the font store.
sl@0
   248
	iFontStore->InstallRasterizerL(rasterizer);
sl@0
   249
	CleanupStack::Pop(rasterizer);
sl@0
   250
	}
sl@0
   251
sl@0
   252
sl@0
   253
void CFbTop::SafeInstallOfShaperFactoryL(TUid aInterfaceImplUid)
sl@0
   254
	{
sl@0
   255
	CShaperFactory* shaperFactory = CShaperFactory::NewL(aInterfaceImplUid);
sl@0
   256
	CleanupStack::PushL(shaperFactory);
sl@0
   257
	// Install it in the font store.
sl@0
   258
	iFontStore->InstallShaperFactoryL(shaperFactory);
sl@0
   259
	CleanupStack::Pop(shaperFactory);
sl@0
   260
	}
sl@0
   261
sl@0
   262
/**
sl@0
   263
Gets the nearest matching font for a given font specification. If the named font cannot be found 
sl@0
   264
font aliases are checked. 
sl@0
   265
sl@0
   266
@param aFontObjPtr On success this contains the font object that is the closest match.
sl@0
   267
@param aMessage The font request message.
sl@0
   268
@param aFontSpec The font spec to match.
sl@0
   269
@param aMaxHeight The maximum height of the font to match.
sl@0
   270
@return KErrNone if successful, KErrNotFound if the font is not found, or one of the other System Error codes.
sl@0
   271
 */
sl@0
   272
TInt CFbTop::GetNearestFont(
sl@0
   273
	CFontObject*&		aFontObjPtr,
sl@0
   274
	TFbsMessage			aMessage,
sl@0
   275
	const TFontSpec&	aFontSpec,
sl@0
   276
	TInt				aMaxHeight)
sl@0
   277
	{
sl@0
   278
#ifdef _DEBUG
sl@0
   279
	User::Heap().Check();
sl@0
   280
	iHeap->Check();
sl@0
   281
#endif
sl@0
   282
	aFontObjPtr = NULL;
sl@0
   283
sl@0
   284
	TFontSpec fontSpec(aFontSpec);
sl@0
   285
sl@0
   286
	// Check if the font typeface is empty and if so use the system default font if it is set
sl@0
   287
	if (fontSpec.iTypeface.iName.Length() == 0 && iSystemDefaultFontTypefaceName.Length() != 0)
sl@0
   288
		{
sl@0
   289
		fontSpec.iTypeface.iName = iSystemDefaultFontTypefaceName;
sl@0
   290
		}
sl@0
   291
sl@0
   292
	if (GlyphSample::EScriptDefault == fontSpec.ScriptTypeForMetrics())
sl@0
   293
		{
sl@0
   294
		fontSpec.SetScriptTypeForMetrics(iDefaultLanguageForMetrics);
sl@0
   295
		}
sl@0
   296
sl@0
   297
	// Find the requested font
sl@0
   298
	TBool familyNameExistsInTypefaceStore = iFontStore->HaveTypefaceFamilyName(fontSpec.iTypeface.iName);
sl@0
   299
	
sl@0
   300
	// If the font is not found try finding an alias font
sl@0
   301
	if (!familyNameExistsInTypefaceStore) 
sl@0
   302
		{
sl@0
   303
		TInt aliasIndex = FindFontNameAlias(fontSpec.iTypeface.iName);
sl@0
   304
		//KErrNotFound is the only error which can be returned
sl@0
   305
		if (aliasIndex != KErrNotFound)
sl@0
   306
			{
sl@0
   307
			fontSpec.iTypeface.iName = *iFontNameAlias[aliasIndex + 1];
sl@0
   308
			}
sl@0
   309
		}
sl@0
   310
sl@0
   311
	CFont* font = NULL;
sl@0
   312
	TInt ret = GetNearestNonAliasedFont(font, aMessage, fontSpec, aMaxHeight);
sl@0
   313
sl@0
   314
	if (ret != KErrNone)
sl@0
   315
		{
sl@0
   316
		return ret;
sl@0
   317
		}
sl@0
   318
	
sl@0
   319
	return GetFontObjectFromFont(aFontObjPtr, font);
sl@0
   320
	}
sl@0
   321
	
sl@0
   322
/**
sl@0
   323
Gets the nearest matching loaded font for a given font specification.
sl@0
   324
sl@0
   325
@param aFont On success this contains the font object that is the closest match.
sl@0
   326
@param aMessage The font request message.
sl@0
   327
@param aFontSpec The font spec to match.
sl@0
   328
@param aMaxHeight The maximum height of the font to match.
sl@0
   329
@return KErrNone if successful, KErrNotFound if the font is not found, or one of the other System Error codes.
sl@0
   330
*/
sl@0
   331
TInt CFbTop::GetNearestNonAliasedFont(CFont*& aFont, TFbsMessage aMessage, const TFontSpec&	aFontSpec, TInt	aMaxHeight)
sl@0
   332
	{
sl@0
   333
	TInt ret = KErrNotSupported;
sl@0
   334
	switch (aMessage)
sl@0
   335
		{
sl@0
   336
		case EFbsMessGetNearestFontToDesignHeightInTwips:
sl@0
   337
			{
sl@0
   338
			ret = iFontStore->GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
sl@0
   339
			break;
sl@0
   340
			}
sl@0
   341
		case EFbsMessGetNearestFontToDesignHeightInPixels:
sl@0
   342
			{
sl@0
   343
			ret = iFontStore->GetNearestFontToDesignHeightInPixels(aFont, aFontSpec);
sl@0
   344
			break;
sl@0
   345
			}
sl@0
   346
		case EFbsMessGetNearestFontToMaxHeightInTwips:
sl@0
   347
			{
sl@0
   348
			ret = iFontStore->GetNearestFontToMaxHeightInTwips(aFont, aFontSpec, aMaxHeight);
sl@0
   349
			break;
sl@0
   350
			}
sl@0
   351
		case EFbsMessGetNearestFontToMaxHeightInPixels:
sl@0
   352
			{
sl@0
   353
			ret = iFontStore->GetNearestFontToMaxHeightInPixels(aFont, aFontSpec, aMaxHeight);
sl@0
   354
			break;
sl@0
   355
			}
sl@0
   356
		}
sl@0
   357
	return ret;
sl@0
   358
	}
sl@0
   359
sl@0
   360
TInt CFbTop::GetFontObjectFromFont(CFontObject*& aFontObjPtr, CFont* aFont)
sl@0
   361
	{
sl@0
   362
	// First, check if a CFontObject exists for this CFont.
sl@0
   363
	// If so, increment its reference count and return it.
sl@0
   364
	for (TInt ii = iFontCon->Count() - 1; ii >= 0; --ii)
sl@0
   365
		{
sl@0
   366
		CFontObject* fontObjPtr = reinterpret_cast<CFontObject*>((*iFontCon)[ii]);
sl@0
   367
		if (fontObjPtr->iAddressPointer == reinterpret_cast<CBitmapFont*>(aFont))
sl@0
   368
			{
sl@0
   369
			aFontObjPtr = fontObjPtr;
sl@0
   370
			// The CFontObject instance keeps the reference count of the CBitmapFont, 
sl@0
   371
			// not the font store. There is only one CFontObject instance
sl@0
   372
			// per CBitmapFont, so to keep the reference count at 1 in the fontstore
sl@0
   373
			// call ReleaseFont(). 
sl@0
   374
			iFontStore->ReleaseFont(aFont);
sl@0
   375
			return fontObjPtr->Open();
sl@0
   376
			}
sl@0
   377
		}
sl@0
   378
	
sl@0
   379
	// Existing FontObject not found, so create new one.
sl@0
   380
	CFontObject* fontObjPtr = new CFontObject(iFontStore, iGlyphAtlas);
sl@0
   381
	if (!fontObjPtr)
sl@0
   382
		{
sl@0
   383
		iFontStore->ReleaseFont(aFont);
sl@0
   384
		return KErrNoMemory;
sl@0
   385
		}
sl@0
   386
	
sl@0
   387
	fontObjPtr->iAddressPointer = reinterpret_cast<CBitmapFont*>(aFont);
sl@0
   388
	fontObjPtr->iHeightInTwips = ((aFont->HeightInPixels() * iFontStore->iKPixelHeightInTwips) + 667) / 1000;
sl@0
   389
	TRAPD(ret, iFontCon->AddL(fontObjPtr));
sl@0
   390
	if (ret != KErrNone)
sl@0
   391
		{
sl@0
   392
		fontObjPtr->Close();
sl@0
   393
		}
sl@0
   394
	else
sl@0
   395
		{ // transfer ownership
sl@0
   396
		aFontObjPtr = fontObjPtr;
sl@0
   397
		}
sl@0
   398
	return ret;
sl@0
   399
	}
sl@0
   400
sl@0
   401
sl@0
   402
/** Create a Bitmap Font, from a UID and Algorithmic drawing Style see CFontStore::GetFontById()
sl@0
   403
@internalComponent
sl@0
   404
*/
sl@0
   405
TInt CFbTop::GetFontById(CFontObject*& aFontObjPtr,TUid aUid,const TAlgStyle& aAlgStyle)
sl@0
   406
	{
sl@0
   407
#ifdef _DEBUG
sl@0
   408
	User::Heap().Check();
sl@0
   409
	iHeap->Check();
sl@0
   410
#endif
sl@0
   411
	aFontObjPtr=NULL;
sl@0
   412
	CBitmapFont* font=NULL;
sl@0
   413
	TInt ret=iFontStore->GetFontById((CFont*&)font,aUid,(TAlgStyle&)aAlgStyle);
sl@0
   414
	if (ret != KErrNone)
sl@0
   415
		{
sl@0
   416
		return ret;
sl@0
   417
		}
sl@0
   418
	return GetFontObjectFromFont(aFontObjPtr, font);
sl@0
   419
	}
sl@0
   420
sl@0
   421
sl@0
   422
/** Create a bitmap with the given size, display mode and UID.
sl@0
   423
sl@0
   424
@param aSize Size of the bitmap in pixels.
sl@0
   425
@param aDispMode Display mode of the bitmap.
sl@0
   426
@param aUid The UID to use for bitmap creation. This can be:
sl@0
   427
	- KUidCFbsBitmapCreation for standard bitmaps.
sl@0
   428
	- The application UID for hardware bitmaps.
sl@0
   429
	- The data type UID for extended bitmaps.
sl@0
   430
@param aReplacement If ETrue the bitmap is being created as a replacement
sl@0
   431
	for a bitmap being made dirty by a resize or compress operation.
sl@0
   432
@param aDataSize If different from zero, it indicates that the bitmap to create
sl@0
   433
	is an extended bitmap and specifies the size in bytes of the bitmap.
sl@0
   434
	If equal to zero, it indicates that the bitmap to create is a standard
sl@0
   435
	bitmap or a hardware bitmap, depending on the value of aUid, and the size
sl@0
   436
	in bytes is calculated from the size in pixels and the display mode.
sl@0
   437
@internalComponent
sl@0
   438
*/
sl@0
   439
CBitmapObject* CFbTop::CreateBitmapL(const TSize& aSize, TDisplayMode aDispMode, TUid aUid, TBool aReplacement, TInt aDataSize)
sl@0
   440
	{
sl@0
   441
#ifdef _DEBUG
sl@0
   442
	User::Heap().Check();
sl@0
   443
	iHeap->Check();
sl@0
   444
#endif
sl@0
   445
	CBitwiseBitmap* bmp=(CBitwiseBitmap*)iHeap->AllocL(sizeof(CBitwiseBitmap) + sizeof(CBitwiseBitmap::TExtra));
sl@0
   446
	new(bmp) CBitwiseBitmap(iHeap,iPile);
sl@0
   447
	CleanupDeletePushL(bmp);  // CBitwiseBitmap is not derived from CBase!
sl@0
   448
sl@0
   449
	if (aDataSize == 0)
sl@0
   450
		User::LeaveIfError(bmp->Construct(aSize, aDispMode, aUid));
sl@0
   451
	else
sl@0
   452
		User::LeaveIfError(bmp->ConstructExtended(aSize, aDispMode, aUid, aDataSize));
sl@0
   453
	// bmp popped out of the clean-up stack by NewL
sl@0
   454
	CBitmapObject* bmpObj = CBitmapObject::NewL(*this, bmp, aReplacement);
sl@0
   455
	if (!aReplacement)
sl@0
   456
		{
sl@0
   457
		bmp->Extra()->iSerialNumber = iNextAvailableSerialNumber++;
sl@0
   458
		}
sl@0
   459
sl@0
   460
	return bmpObj;
sl@0
   461
	}
sl@0
   462
sl@0
   463
CBitmapObject* CFbTop::LoadBitmapL(const TDesC& aFilename, TInt32 aId, TUint aFileOffset, RFile* aFile, TInt aSessionHandle)
sl@0
   464
	{
sl@0
   465
	CBitwiseBitmap* bmp=DoLoadBitmapLC(aFilename, aId, aFileOffset, aFile, aSessionHandle);
sl@0
   466
	// bmp popped out of the clean-up stack by NewL
sl@0
   467
	CBitmapObject* bmpObj = CBitmapObject::NewL(*this, bmp, EFalse);
sl@0
   468
sl@0
   469
	return bmpObj;
sl@0
   470
	}
sl@0
   471
sl@0
   472
_LIT(KZDrive, "z:");
sl@0
   473
sl@0
   474
CBitwiseBitmap* CFbTop::DoLoadBitmapLC(const TDesC& aFilename, TInt32 aId, TUint aFileOffset, RFile* aFile, TInt aSessionHandle)
sl@0
   475
	{
sl@0
   476
#ifdef _DEBUG
sl@0
   477
	User::Heap().Check();
sl@0
   478
	iHeap->Check();
sl@0
   479
#endif
sl@0
   480
	CBitwiseBitmap* bmp=(CBitwiseBitmap*)iHeap->AllocL(sizeof(CBitwiseBitmap) + sizeof(CBitwiseBitmap::TExtra));
sl@0
   481
	new(bmp) CBitwiseBitmap(iHeap,iPile);
sl@0
   482
	bmp->Extra()->iSerialNumber = iNextAvailableSerialNumber++;
sl@0
   483
	CleanupDeletePushL(bmp);  // CBitwiseBitmap is not derived from CBase!
sl@0
   484
sl@0
   485
	if (NULL == aFile)
sl@0
   486
		{
sl@0
   487
		// In this case file should be in z: drive
sl@0
   488
		// so load the bitmap from the mbm cache
sl@0
   489
		TStreamId streamid(0);
sl@0
   490
		streamid=iMBMCache->GetStreamIdL(iFilesys,aFilename,aId,aFileOffset,aSessionHandle);
sl@0
   491
		bmp->ConstructL(iMBMCache->MruFileStore(),streamid);
sl@0
   492
		}
sl@0
   493
	else
sl@0
   494
		{
sl@0
   495
		//only use the cache when it is Rom File which is read only because when using
sl@0
   496
		//the cache the file store is always opened as read access until it is replaced by
sl@0
   497
		//another different file, Trying to write it(RAM file) will cause access violation
sl@0
   498
		//and therefore we have to split the implementation into two parts one for ROM
sl@0
   499
		//and one for RAM
sl@0
   500
		if (aFilename.Left(2).CompareF(KZDrive))
sl@0
   501
			{
sl@0
   502
			// File is not in ROFS
sl@0
   503
			bmp->ConstructL(*aFile,aId,aFileOffset);
sl@0
   504
			}
sl@0
   505
		else
sl@0
   506
			{
sl@0
   507
			// File is in ROFS
sl@0
   508
			TStreamId streamid(0);
sl@0
   509
			streamid=iMBMCache->GetStreamIdL(*aFile,aFilename,aId,aFileOffset,aSessionHandle);
sl@0
   510
sl@0
   511
			bmp->ConstructL(iMBMCache->MruFileStore(),streamid);
sl@0
   512
			}
sl@0
   513
		}
sl@0
   514
	return bmp;
sl@0
   515
	}
sl@0
   516
sl@0
   517
sl@0
   518
/* Similar to LoadBitmap.
sl@0
   519
This function only performs a load the first time it is called for a
sl@0
   520
particular bitmap.  Subsequent calls increment a reference counting object.
sl@0
   521
sl@0
   522
Upon return, aBmpObjPtr points to an object containing a pointer to the loaded bitmap.
sl@0
   523
*/
sl@0
   524
CSharedBitmapObject* CFbTop::ShareBitmapL(TDes& aFilename, TInt32 aId, TUint aFileOffset, RFile* aFile, TInt aSessionHandle)
sl@0
   525
	{
sl@0
   526
	TTime modtime(0);
sl@0
   527
	if (aFilename.Left(2).CompareF(KZDrive))// instead of Compare, CompareF is used to perform folding prior to Compare which is safe with Unicode.
sl@0
   528
		{
sl@0
   529
		// file is not in z: drive so it should not be null.
sl@0
   530
		__ASSERT_DEBUG(aFile != NULL, User::Panic(KFBSERVPanicCategory, KErrBadHandle));
sl@0
   531
		// File is not in ROM so ModTime is needed to identify it
sl@0
   532
		User::LeaveIfError(aFile->Modified(modtime));
sl@0
   533
		}
sl@0
   534
sl@0
   535
	// Creation of the key is performed here so that it can potentially be
sl@0
   536
	// reused in both object lookup and object creation
sl@0
   537
	HBufC* key = CSharedBitmapObject::KeyLC(aFilename, aId, modtime);
sl@0
   538
sl@0
   539
	// Calculation of the hash value is performed here so that it can 
sl@0
   540
	// potentially be reused in both object lookup and object insert.
sl@0
   541
	const TUint hash = iSharedBitmapObjectHashMap.Hash(*key);    
sl@0
   542
sl@0
   543
	CSharedBitmapObject* bmpObj = iSharedBitmapObjectHashMap.Lookup(*key, hash);
sl@0
   544
	
sl@0
   545
	if (bmpObj)
sl@0
   546
		{
sl@0
   547
		// Bitmap already in memory
sl@0
   548
		CleanupStack::PopAndDestroy(key);      // key will not be needed
sl@0
   549
		User::LeaveIfError(bmpObj->Open());    // increase reference count
sl@0
   550
		}
sl@0
   551
	else
sl@0
   552
		{
sl@0
   553
		// Bitmap not in memory
sl@0
   554
		CBitwiseBitmap* bmp = DoLoadBitmapLC(aFilename, aId, aFileOffset, aFile, aSessionHandle);
sl@0
   555
		// bmp and key popped out of the clean-up stack by NewL
sl@0
   556
		bmpObj = CSharedBitmapObject::NewL(*this, bmp, key, hash);
sl@0
   557
		}
sl@0
   558
sl@0
   559
	return bmpObj;
sl@0
   560
	}
sl@0
   561
sl@0
   562
TInt CFbTop::GetCleanBitmap(CBitmapObject*& aBmpObjPtr)
sl@0
   563
	{
sl@0
   564
	while (aBmpObjPtr->CleanBitmap() != NULL)
sl@0
   565
		{
sl@0
   566
		aBmpObjPtr = aBmpObjPtr->CleanBitmap();
sl@0
   567
		}
sl@0
   568
	if (aBmpObjPtr->IsInCompressionQueue())
sl@0
   569
		return KErrInUse;
sl@0
   570
	return KErrNone;
sl@0
   571
	}
sl@0
   572
sl@0
   573
CBitmapObject* CFbTop::FindBitmap(TInt aHandle)
sl@0
   574
	{
sl@0
   575
	TInt index = iBitmapObjectIndex.FindInOrder(aHandle, CBitmapObject::Compare);
sl@0
   576
	if (index != KErrNotFound)
sl@0
   577
		return iBitmapObjectIndex[index];
sl@0
   578
	return NULL;
sl@0
   579
	}
sl@0
   580
sl@0
   581
TBool CFbTop::ValidFontHandle(TInt aHandle)
sl@0
   582
	{
sl@0
   583
	TInt limit=iFontCon->Count();
sl@0
   584
	for(TInt count=0;count<limit;count++)
sl@0
   585
		if(aHandle==(TInt)((*iFontCon)[count]))
sl@0
   586
			return(ETrue);
sl@0
   587
	return(EFalse);
sl@0
   588
	}
sl@0
   589
	
sl@0
   590
CFontStore* CFbTop::FontStore() const
sl@0
   591
	{
sl@0
   592
	return(iFontStore);
sl@0
   593
	}
sl@0
   594
sl@0
   595
RHeap* CFbTop::Heap() const
sl@0
   596
	{
sl@0
   597
	return(iHeap);
sl@0
   598
	}
sl@0
   599
sl@0
   600
CChunkPile* CFbTop::Pile() const
sl@0
   601
	{
sl@0
   602
	return(iPile);
sl@0
   603
	}
sl@0
   604
sl@0
   605
TInt CFbTop::HeapBase() const
sl@0
   606
	{
sl@0
   607
	return(TInt(iChunk.Base()));
sl@0
   608
	}
sl@0
   609
sl@0
   610
void CFbTop::SetFontNameAliasL(const RMessage2& aMessage)
sl@0
   611
	{
sl@0
   612
	const TInt aliasNameLength = aMessage.Int1();
sl@0
   613
	if (aliasNameLength <= 0)
sl@0
   614
		return; // No alias name to set
sl@0
   615
	
sl@0
   616
	if(aliasNameLength * sizeof(TText) * 2 >= KMaxTInt)
sl@0
   617
		{
sl@0
   618
		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
sl@0
   619
		return;
sl@0
   620
		}
sl@0
   621
		
sl@0
   622
	HBufC* aliasName = HBufC::NewMaxLC(aliasNameLength);
sl@0
   623
	TPtr aliasNamePtr(aliasName->Des());
sl@0
   624
	aMessage.ReadL(0,aliasNamePtr);
sl@0
   625
sl@0
   626
	const TInt aliasIndex = FindFontNameAlias(*aliasName);
sl@0
   627
sl@0
   628
	const TInt fontNameLength = aMessage.Int3();
sl@0
   629
sl@0
   630
	if (fontNameLength > 0)
sl@0
   631
		{ // Set or change an alias
sl@0
   632
		HBufC* fontName = HBufC::NewMaxLC(fontNameLength);
sl@0
   633
		TPtr fontNamePtr(fontName->Des());
sl@0
   634
		aMessage.ReadL(2,fontNamePtr);
sl@0
   635
sl@0
   636
		if (aliasIndex != KErrNotFound)
sl@0
   637
			{ // Change an existing alias
sl@0
   638
			delete iFontNameAlias[aliasIndex + 1];
sl@0
   639
			iFontNameAlias[aliasIndex + 1] = fontName;
sl@0
   640
sl@0
   641
			CleanupStack::Pop(); // fontName
sl@0
   642
			CleanupStack::PopAndDestroy(); // aliasName
sl@0
   643
			}
sl@0
   644
		else
sl@0
   645
			{ // Set a new alias
sl@0
   646
			User::LeaveIfError(iFontNameAlias.Append(aliasName));
sl@0
   647
			TInt ret = iFontNameAlias.Append(fontName);
sl@0
   648
			if (ret != KErrNone)
sl@0
   649
				{
sl@0
   650
				iFontNameAlias.Remove(iFontNameAlias.Count() - 1);
sl@0
   651
				User::Leave(ret);
sl@0
   652
				}
sl@0
   653
sl@0
   654
			CleanupStack::Pop(); // fontName
sl@0
   655
			CleanupStack::Pop(); // aliasName
sl@0
   656
			}
sl@0
   657
		}
sl@0
   658
	else
sl@0
   659
		{ // No fontName so delete the alias
sl@0
   660
		CleanupStack::PopAndDestroy(); // aliasName
sl@0
   661
		if (aliasIndex != KErrNotFound)
sl@0
   662
			{
sl@0
   663
			delete iFontNameAlias[aliasIndex];
sl@0
   664
			iFontNameAlias.Remove(aliasIndex);
sl@0
   665
			delete iFontNameAlias[aliasIndex];
sl@0
   666
			iFontNameAlias.Remove(aliasIndex);
sl@0
   667
			}
sl@0
   668
		}
sl@0
   669
	}
sl@0
   670
sl@0
   671
TInt CFbTop::FindFontNameAlias(const TDesC& aAlias)
sl@0
   672
	{
sl@0
   673
	const TInt fontNameAliasCount = iFontNameAlias.Count();
sl@0
   674
sl@0
   675
	for (TInt index = 0; index < fontNameAliasCount; index += 2)
sl@0
   676
		{
sl@0
   677
		if ((*iFontNameAlias[index]).CompareF(aAlias)==0)
sl@0
   678
			{
sl@0
   679
			return index;
sl@0
   680
			}
sl@0
   681
		}
sl@0
   682
sl@0
   683
	return KErrNotFound;
sl@0
   684
	}
sl@0
   685
sl@0
   686
void CFbTop::SetDefaultLanguageForMetrics(const RMessage2& aMessage)
sl@0
   687
	{
sl@0
   688
	iDefaultLanguageForMetrics = static_cast<TLanguage>(aMessage.Int0());
sl@0
   689
	}
sl@0
   690
sl@0
   691
void CFbTop::CloseFileStores(TInt aSessionHandle)
sl@0
   692
	{
sl@0
   693
	iMBMCache->CloseFileStores(aSessionHandle);
sl@0
   694
	}
sl@0
   695
sl@0
   696
void CFbTop::SetSystemDefaultTypefaceName(const TDesC& aFontTypefaceName)
sl@0
   697
	{
sl@0
   698
	iSystemDefaultFontTypefaceName = aFontTypefaceName;
sl@0
   699
	}
sl@0
   700
sl@0
   701
TInt CFbTop::GetAllBitmapHandles(const RMessage2& aMessage) const
sl@0
   702
	{
sl@0
   703
	TPckgBuf<TInt> handleBuffer; // Use this buffer to store the bitmap handles to write to the message buffer
sl@0
   704
	const TInt numBitmaps = iBitmapObjectIndex.Count();
sl@0
   705
	TInt ret = KErrNone;
sl@0
   706
	for (TInt count=0; count<numBitmaps; ++count)
sl@0
   707
		{
sl@0
   708
		handleBuffer() = iBitmapObjectIndex[count]->Handle();
sl@0
   709
		ret = aMessage.Write(0, handleBuffer, KNumBytesPerBitmapHandle * count);
sl@0
   710
		if (ret!=KErrNone)
sl@0
   711
			break;
sl@0
   712
		}	
sl@0
   713
	return ret;
sl@0
   714
	}
sl@0
   715
sl@0
   716
void CFbTop::AddClientHelper(TFbClientHelper& aHelper)
sl@0
   717
	{
sl@0
   718
	iClientHelpers.AddLast(aHelper);
sl@0
   719
	}
sl@0
   720
sl@0
   721
void CFbTop::NotifyDirtyBitmap(CBitmapObject& aBmpObj, CFbClient* aClient)
sl@0
   722
	{
sl@0
   723
	TDblQueIter<TFbClientHelper> iterator(iClientHelpers);
sl@0
   724
	TFbClientHelper* helper;
sl@0
   725
	while ((helper = iterator++) != NULL)
sl@0
   726
		{
sl@0
   727
		if (aClient != &helper->iClient)
sl@0
   728
			helper->iClient.NotifyDirtyBitmap(aBmpObj);
sl@0
   729
		}
sl@0
   730
	}
sl@0
   731
sl@0
   732
TInt CFbTop::BitmapConUniqueID() const
sl@0
   733
	{
sl@0
   734
	return iBitmapCon->UniqueID();
sl@0
   735
	}
sl@0
   736
sl@0
   737
TInt CFbTop::FontConUniqueID() const
sl@0
   738
	{
sl@0
   739
	return iFontCon->UniqueID();
sl@0
   740
	}
sl@0
   741
sl@0
   742
CGlyphAtlas* CFbTop::GlyphAtlas() const
sl@0
   743
	{
sl@0
   744
	return iGlyphAtlas;
sl@0
   745
	}