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