Update contrib.
2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
22 @internalComponent Internal Symbian test code
29 #include <graphics/shapeimpl.h>
30 #include "ShaperCache.H"
31 #include "openfontsprivate.h"
33 #include "T_SHAPERCACHE.H"
36 _LIT(KFontDummy,"z:\\PlatTest\\Graphics\\TestData\\dummy_fonts\\dummy");
37 _LIT(KFontDummy_b,"z:\\PlatTest\\Graphics\\TestData\\dummy_fonts\\dummy_b");
38 _LIT(KFontDummy_i,"z:\\PlatTest\\Graphics\\TestData\\dummy_fonts\\dummy_i");
39 _LIT(KFontDummy_bi,"z:\\PlatTest\\Graphics\\TestData\\dummy_fonts\\dummy_bi");
41 const TUint32 KDevanagariScriptCode = 0x64657661;
42 _LIT16(KTextToShape, "\x0915\x094D\x0937\x0924\x094D\x0930\x093F\x092F");
43 const TInt KResultNumberOfGlyphs = 4;
45 CTShaperCache::~CTShaperCache()
48 iHeap->__DbgMarkEnd(0);
54 CTShaperCache::CTShaperCache(CTestStep* aStep):
57 INFO_PRINTF1(_L("FontStore T_ShaperCache test\n"));
60 void CTShaperCache::ConstructL()
63 iHeap = UserHeap::ChunkHeap(NULL,0x10000,0x100000);
65 User::Leave(KErrGeneral);
66 iHeap->__DbgMarkStart();
67 iFontStore = CFontStore::NewL(iHeap);
69 // Install the dummy rasterizer.
70 COpenFontRasterizer* r = CDummyRasterizer::NewL();
71 CleanupStack::PushL(r);
72 iFontStore->InstallRasterizerL(r);
75 // Install the dummy shaper
76 CShaperFactory* shaperFactory = CDummyShaperFactory::NewL();
77 CleanupStack::PushL(shaperFactory);
78 iFontStore->InstallShaperFactoryL(shaperFactory);
84 GRAPHICS-FNTSTORE-0043
87 Tests creating and deleting a new shaper cache entry.
90 1. Allocated a TShapeHeader object on the heap/
91 2. Creates a CShaper object on the stack.
92 3. Allocates an entry for the TShapeHeader object in the cache.
93 4. Frees memory taken up by the entry to the cache.
94 5. The heap is checked for memory leaks.
96 @SYMTestExpectedResults
97 No memory leaks should exist.
99 void CTShaperCache::Test1L()
101 INFO_PRINTF1(_L("ShaperCache Test1"));
104 TShapeHeader* shapeHeader=new TShapeHeader();
105 shapeHeader->iGlyphCount=10;
106 shapeHeader->iCharacterCount=20;
108 _LIT(KDummyText,"dummy");
109 CShaper::TInput input;
112 input.iText=&(KDummyText());
114 //create/delete test a new shaper cache entry
115 COpenFontShaperCacheEntry* shapeEntry=COpenFontShaperCacheEntry::New(&User::Heap(),input,shapeHeader);
116 COpenFontShaperCacheEntry::Delete(&User::Heap(),shapeEntry);
125 GRAPHICS-FNTSTORE-0044
128 Tests ncrementation and decrementation of the reference
129 count for a particular session handle.
132 1. Creates a TShapeHeader object on the heap.
133 2. Set som values to the object.
134 3. Creates a CShaper object on the stack.
135 4. Creates a new shaper cache entry.
136 5. Associates a session with this entry.
137 6. Increments the reference count for a particular session (A) handle.
138 7. Increments the reference count for another session (B).
139 8. Decrements an instance from session (A).
140 9. Adds another session to the list (C).
141 10. Decrements the ref count for a particular session handle (C).
142 11. Tests decrement on non-existent session.
143 12. Frees memory taken up by the entry to the cache.
144 13. The heap is checked for memory leaks.
146 @SYMTestExpectedResults
147 The decrementation of the non-existent session should return KErrNotFound.
149 void CTShaperCache::Test2L()
151 INFO_PRINTF1(_L("ShaperCache Test2"));
154 TShapeHeader* shapeHeader=new TShapeHeader();
155 shapeHeader->iGlyphCount=10;
156 shapeHeader->iCharacterCount=20;
158 _LIT(KDummyText,"dummy");
159 CShaper::TInput input;
162 input.iText=&(KDummyText());
164 //create a new shaper cache entry
165 COpenFontShaperCacheEntry* shapeEntry=COpenFontShaperCacheEntry::New(&User::Heap(),input,shapeHeader);
167 //now associate a session with this entry
168 TInt dummySession=12;
169 TEST(shapeEntry->IncRefCount(dummySession)==KErrNone);
170 TEST(shapeEntry->iHandleRefCount==1);
171 TEST(shapeEntry->iHandleRefList!=NULL);
172 TEST(shapeEntry->iHandleRefList->iSessionHandle==dummySession);
173 TEST(shapeEntry->iHandleRefList->iRefCount==1);
174 //increment for another session, the THandleCount::iRef for this session should be 2
175 TEST(shapeEntry->IncRefCount(dummySession)==KErrNone);
176 TEST(shapeEntry->iHandleRefCount==1);
177 TEST(shapeEntry->iHandleRefList->iRefCount==2);
179 //another entry for different session
180 TInt dummySession2=13;
181 TEST(shapeEntry->IncRefCount(dummySession2)==KErrNone);
182 TEST(shapeEntry->iHandleRefCount==2);
183 TEST(shapeEntry->iHandleRefList->iSessionHandle==dummySession);
184 TEST(shapeEntry->iHandleRefList->iRefCount==2);
185 TEST(shapeEntry->iHandleRefList->iNext->iSessionHandle==dummySession2);
186 TEST(shapeEntry->iHandleRefList->iNext->iRefCount==1);
188 //now decrement an instance from this session(DELETE FIRST ENTRY)
189 TEST(shapeEntry->DecRefCount(dummySession)==KErrNone);
190 TEST(shapeEntry->iHandleRefCount==2);
191 TEST(shapeEntry->iHandleRefList->iNext->iRefCount==1);
192 TEST(shapeEntry->DecRefCount(dummySession)==KErrNone);
193 TEST(shapeEntry->iHandleRefCount==1);
194 TEST(shapeEntry->iHandleRefList->iRefCount==1);
195 TEST(shapeEntry->iHandleRefList->iSessionHandle=dummySession2);
197 //now add another session to this list
198 TInt dummySession3=14;
199 TEST(shapeEntry->IncRefCount(dummySession3)==KErrNone);
200 TEST(shapeEntry->iHandleRefCount==2);
201 //test delete this last entry in the list(DELETE LAST ENTRY)
202 TEST(shapeEntry->DecRefCount(dummySession3)==KErrNone);
203 TEST(shapeEntry->iHandleRefCount==1);
204 TEST(shapeEntry->iHandleRefList->iRefCount==1);
205 TEST(shapeEntry->iHandleRefList->iSessionHandle==dummySession2);
208 //test Dec on non-existent session
209 TEST(shapeEntry->DecRefCount(100)==KErrNotFound);
211 COpenFontShaperCacheEntry::Delete(&User::Heap(),shapeEntry);
219 GRAPHICS-FNTSTORE-0045
222 Tests the shaper cache APIs.
225 1. Creates a dummy TShapeHeader object that will be cached and reused through the test.
226 2. Gets some memory to pass back the results. It needs to be big enough for a TShapeHeader
227 object plus 10 bytes for every glyph returned.
228 3. Finds or creates four font file objects to support a font file.
229 4. Gets the number of supported typefaces.
231 6. Gets a COpenFont object.
232 7. For COpenFonts it attempts to put this into the shaper cache and test if it was successful.
233 8. Calls DeleteShape to decrement the reference count.
234 9. Changes the shaped data slightly to make it into a new shaped data and insert into the
235 cache as a new entry.
236 10. Tests if the LRU cache is working by seeing if the first entry in the cache is the newest one.
237 11. Calls DeleteShape to decrement the reference count
238 12. Calls the GetShapedData API and tests the returned TShapeHeader. Also checks if the returned
239 cache entry is at the top of the cache.
240 13. Searches the cache for the first entry using the GetShapedData API.
241 14. Calls DeleteShape to decrement the reference count.
242 15. Brings the end value back to its original value.
243 16. Fills the cache and then tests replacement policy by attempting to add a new entry.
244 17. Prepares a raw input data structure.
245 18. Keeps inserting pseudo-new shaped entries into the cache to fill it up.
246 19. Changes the cached entries slightly to distinguish between each entry.
247 20. Tries to add a new entry and checks that the entry replaced was the last entry in the cache.
248 21. Calculates the memory needed for the new entry.
249 22. Calculates the memory that will be freed to accommodate the new entry and the
250 position of the last entry in the cache once deletion is done.
251 23. Finds the glyphcount of the expected new last entry in the cache.
252 24. Does the insertion and tests.
253 25. Calls DeleteShape to decrement the reference count.
254 26. Calculates the memory occupied by the last entry in the cache. This is the memory that will
255 be released when the last entry is deleted.
256 27. Tests with multiple open fonts with caches. Creates the new font.
257 28. Does the testing only if the font is a COpenFont.
258 29. Attempts to put a new entry into the second shaper cache and test if it was successful.
259 30. Creates a pseudo-new shape header to put into the cache of this new open font.
260 31. Inserst an entry into the cache.
261 32. Tests cache memory freeing policy, i.e. delete from all other caches except the current one.
262 33. Finds out how much memory needs freeing, i.e. how much was just added.
263 34. Tries to free memory from the original open font cache. The result should be that
264 memory should be freed from openFont2 cache, and not openFont cache.
266 a) if the memory used by openFont2 cache has reduced, i.e. back to original memory.
267 b) if the last entry from openFont2 cache has been deleted.
268 c) last entry from openFont cache is intact.
269 36. Cleans up font2, font1 and removes all fonts.
271 @SYMTestExpectedResults
272 All tests shall pass.
275 void CTShaperCache::TestShaperCacheAPIsL()
277 INFO_PRINTF1(_L("The following results are for shaper cache API tests\n"));
279 // Create a dummy TShapeHeader object that will be cached, and reused all through this test
280 TShapeHeader* shape = 0;
282 // get some memory to pass back the results,
283 // This needs to be big enough for a TShapeHeader
284 // plus 10 bytes for every glyph returned (-1 for the 1 byte allocated in TShapeHeader for iBuffer)
285 shape = reinterpret_cast<TShapeHeader*>( iHeap->AllocL(sizeof(TShapeHeader) + (KResultNumberOfGlyphs * 10) + 3) );
287 // get the results into the shaper structure 'shape'
288 shape->iGlyphCount = KResultNumberOfGlyphs;
289 shape->iCharacterCount = 8;
290 shape->iReserved0 = 0;
291 shape->iReserved1 = 0;
293 // iBuffer contains 10 bytes for every glyph
294 // the glyph code (4 bytes), position X(2 bytes) Y(2 bytes) and indices(2 bytes)
295 // first is glyph count * 4 byte glyph codes
296 TUint32* glyphOut = reinterpret_cast<TUint32*>(shape->iBuffer);
297 TInt16* posOut = reinterpret_cast<TInt16*>(shape->iBuffer +
298 (4 * KResultNumberOfGlyphs));
299 TInt16* indicesOut = reinterpret_cast<TInt16*>(shape->iBuffer +
300 (8 * KResultNumberOfGlyphs) + 4);
302 *glyphOut++ = (TUint32)1461;
303 *posOut++ = (TInt16)0;
304 *posOut++ = (TInt16)0;
305 *indicesOut++ = (TInt16)0;
307 *glyphOut++ = (TUint32)1778;
308 *posOut++ = (TInt16)12;
309 *posOut++ = (TInt16)0;
310 *indicesOut++ = (TInt16)7;
312 *glyphOut++ = (TUint32)1550;
313 *posOut++ = (TInt16)16;
314 *posOut++ = (TInt16)0;
315 *indicesOut++ = (TInt16)3;
317 *glyphOut++ = (TUint32)1362;
318 *posOut++ = (TInt16)28;
319 *posOut++ = (TInt16)0;
320 *indicesOut++ = (TInt16)7;
322 // There is an extra pair of positions: this is the total advance
323 posOut[0] = (TInt16)28;
324 posOut[1] = (TInt16)0;
326 TFontShapeFunctionParameters* params;
327 params = reinterpret_cast<TFontShapeFunctionParameters*>( iHeap->AllocL(sizeof(TFontShapeFunctionParameters)));
329 params->iLanguage = 0;
330 params->iScript = KDevanagariScriptCode;
332 //TBufC16<9> text(KTextToShape);
333 params->iText = &KTextToShape();
336 TUid id1 = iFontStore->AddFileL(KFontDummy);
337 TUid id2 = iFontStore->AddFileL(KFontDummy_b);
338 TUid id3 = iFontStore->AddFileL(KFontDummy_i);
339 TUid id4 = iFontStore->AddFileL(KFontDummy_bi);
341 INFO_PRINTF1(_L("SHAPER CACHE API TESTS SET 1: Testing cache with a single COpentFont cache"));
343 TInt typefaces = iFontStore->NumTypefaces();
347 TTypefaceSupport support;
348 iFontStore->TypefaceSupport(support,typeface);
350 fs.iTypeface = support.iTypeface;
352 INFO_PRINTF3(_L("Typeface is %d and height is %d"), typeface, height);
355 fs.iHeight = iFontStore->FontHeightInTwips(typeface,height);
356 // get a COpenFont object
357 iFontStore->GetNearestFontToDesignHeightInPixels(font, fs);
358 CleanupStack::PushL(font);
361 // Do the testing only if the font is a COpenFont
362 COpenFont* openFont = NULL;
363 CShaper::TInput input;
364 if (((CBitmapFont*)font)->IsOpenFont())
367 openFont = ((CBitmapFont*)font)->OpenFont();
369 /***************************First Test***************************
370 Attempt to put this into the shaper cache and then delete it. Test if it was successful
372 TShapeHeader* cached_header = openFont->InsertShapedDataIntoCache(0,params, shape);
374 INFO_PRINTF1(_L("SHAPER CACHE API TEST 1: Simple cache insertion test"));
375 TEST(cached_header != NULL && openFont->GetGlyphCache()->iNumberOfShaperCacheEntries == 2);
377 /* Call DeleteShape to decrement the reference count */
378 ((CBitmapFont*)font)->DeleteShape(0, cached_header);
380 // Now delete this data
381 openFont->FreeShaperCacheMemory(openFont->GetGlyphCache()->iShapingInfoCacheMemory);
382 TEST(openFont->GetGlyphCache()->iNumberOfShaperCacheEntries == 1);
383 // Put the shaped data back into the cache to continue with testing
384 cached_header = openFont->InsertShapedDataIntoCache(0,params, shape);
385 TEST(cached_header != NULL && openFont->GetGlyphCache()->iNumberOfShaperCacheEntries == 2);
386 ((CBitmapFont*)font)->DeleteShape(0, cached_header);
388 /**************************Second Test**************************
389 Now change the shaped data slightly to make it into a new shaped data and insert into the
392 shape->iGlyphCount++;
394 TShapeHeader* cached_header2 = openFont->InsertShapedDataIntoCache(0,params, shape);
396 /* Now test if the LRU cache is working by seeing if the first entry in the cache is the newest one */
397 COpenFontGlyphCache* glyphCache = openFont->GetGlyphCache();
399 INFO_PRINTF1(_L("SHAPER CACHE API TEST 2: Test the LRU (Least Recently Used) cache structure"));
400 TEST(glyphCache->iShaperCacheSentinel->iNext->iShapeHeader->iGlyphCount == KResultNumberOfGlyphs + 1);
402 /* Call DeleteShape to decrement the reference count */
403 ((CBitmapFont*)font)->DeleteShape(0, cached_header2);
406 /**************************Third Test**************************
407 Call the GetShapedData API and test the returned TShapeHeader, and also check if the returned
408 cache entry is now at the top of the cache
411 /* Now search the cache for the first entry using the GetShapedData API */
413 TInt expectedGlyphCount = glyphCache->iShaperCacheSentinel->iPrevious->iShapeHeader->iGlyphCount;
414 TShapeHeader* searchedCachedHeader = openFont->GetShapedData(0,params);
416 INFO_PRINTF1(_L("SHAPER CACHE API TEST 3: GetShapedData API test"));
417 TEST(searchedCachedHeader->iGlyphCount == expectedGlyphCount &&
418 searchedCachedHeader->iGlyphCount ==glyphCache->iShaperCacheSentinel->iNext->iShapeHeader->iGlyphCount);
420 /* Call DeleteShape to decrement the reference count */
421 ((CBitmapFont*)font)->DeleteShape(0, searchedCachedHeader);
423 /* Bring the end value back to its original value */
427 /**************************Fourth Test**************************
428 Fill the cache and then test replacement policy by attempting to add a new entry
431 /* First prepare a raw input data structure */
433 input.iText = &KTextToShape();
435 input.iEnd = params->iEnd;
436 input.iScript= KDevanagariScriptCode;
438 input.iMaximumAdvance = KMaxTInt;
440 input.iSessionHandle = 0;
441 input.iReserved1 = 0;
443 TShapeHeader* chached_header3 = 0;
444 openFont->FreeShaperCacheMemory(KMaxShaperSesssionCacheMemory);
445 openFont->File()->GetFontStore()->SetShaperCacheMemUsage(0);
446 RArray<TInt> cacheMemUsage;
447 /* Keep inserting pseudo-new shaped entries into the cache to fill it up */
448 while(openFont->File()->GetFontStore()->GetShaperCacheMemUsage() < KMaxShaperSesssionCacheMemory)
450 memoryUsed = openFont->File()->GetFontStore()->GetShaperCacheMemUsage();
451 // Change the cached entries slightly to distinguish between each entry
452 shape->iGlyphCount++;
454 chached_header3 = glyphCache->Insert(0,iHeap, input, shape, addedBytes);
455 if (chached_header3 != NULL)
456 openFont->File()->GetFontStore()->SetShaperCacheMemUsage(memoryUsed + addedBytes);
457 ((CBitmapFont*)font)->DeleteShape(0, chached_header3);
458 cacheMemUsage.AppendL(openFont->File()->GetFontStore()->GetShaperCacheMemUsage() - memoryUsed);
459 chached_header3 = NULL;
462 /* Now try to add a new entry, and check that the entry replaced was the last entry in the cache */
463 TInt last_entry_glyph_count = glyphCache->iShaperCacheSentinel->iPrevious->iShapeHeader->iGlyphCount;
464 shape->iGlyphCount++;
466 params->iEnd = input.iEnd;
468 /* Calculate the memory needed for the new entry */
471 TInt heapSizeBefAloc = 0;
472 iHeap->AllocSize(heapSizeBefAloc);
473 COpenFontShaperCacheEntry *tempEntry = COpenFontShaperCacheEntry::New(iHeap, input, shape);
474 TInt heapSizeAftAloc = 0;
475 iHeap->AllocSize(heapSizeAftAloc);
476 TInt bytes_needed = heapSizeAftAloc - heapSizeBefAloc;
477 COpenFontShaperCacheEntry::Delete(iHeap, tempEntry);
479 TInt bytesToDelete = 0;
481 COpenFontShaperCacheEntry* previous = glyphCache->iShaperCacheSentinel->iPrevious;
482 /* Calculate the memory that will be freed to accommodate the new entry,
483 and the position of the last entry in the cache once deletion is done */
485 while (bytesToDelete <= bytes_needed)
488 bytesToDelete += cacheMemUsage[index++];
489 previous = previous->iPrevious;
491 cacheMemUsage.Close();
492 /* Find the glyphcount of the expected new last entry in the cache */
493 expectedGlyphCount = previous->iShapeHeader->iGlyphCount;
495 /* Finally, do the insertion, and test */
496 TShapeHeader* cached_header4 = openFont->InsertShapedDataIntoCache(0, params, shape);
498 INFO_PRINTF1(_L("SHAPER CACHE API TEST 4: LRU cache replacement policy test"));
499 TEST(glyphCache->iShaperCacheSentinel->iPrevious->iShapeHeader->iGlyphCount == expectedGlyphCount);
501 /* Call DeleteShape to decrement the reference cout */
502 ((CBitmapFont*)font)->DeleteShape(0, cached_header4);
505 /**************************Fifth Test**************************
506 Simply test the FreeShaperCacheMemory API
509 /* Calculate the memory of occupied by the last entry in the cache. This is the memory that will
510 be released when the last entry is deleted
512 last_entry_glyph_count = glyphCache->iShaperCacheSentinel->iPrevious->iShapeHeader->iGlyphCount;
513 TInt bufferSize = (sizeof(TUint32) + sizeof(TInt16) + sizeof(TInt16) * 2)
514 * last_entry_glyph_count + sizeof(TInt16) * 2;
516 bytes_needed = bufferSize + sizeof(COpenFontShaperCacheEntry) +
517 sizeof(TShapeHeader) + sizeof(TUint16)*input.iText->Length();
519 memoryUsed = openFont->File()->GetFontStore()->GetShaperCacheMemUsage();
520 expectedGlyphCount = glyphCache->iShaperCacheSentinel->iPrevious->iPrevious->iShapeHeader->iGlyphCount;
521 TInt memoryReleased = openFont->FreeShaperCacheMemory(bytes_needed);
523 INFO_PRINTF1(_L("SHAPER CACHE API TEST 5: FreeShaperCacheMemory API test\n"));
524 TEST(openFont->File()->GetFontStore()->GetShaperCacheMemUsage() == memoryUsed - memoryReleased &&
525 glyphCache->iShaperCacheSentinel->iPrevious->iShapeHeader->iGlyphCount == expectedGlyphCount);
530 INFO_PRINTF1(_L("SHAPER CACHE API TESTS SET 2: Testing cache with a two COpentFont caches"));
531 /* Now test with multiple open fonts with caches */
532 /* Create the new font */
534 iFontStore->TypefaceSupport(support,typeface);
535 fs.iTypeface = support.iTypeface;
537 INFO_PRINTF3(_L("Typeface is %d and height is %d"), typeface, height);
540 fs.iHeight = iFontStore->FontHeightInTwips(typeface,height);
541 iFontStore->GetNearestFontToDesignHeightInPixels(font2, fs);
542 CleanupStack::PushL(font2);
544 COpenFont* openFont2;
545 /* Do the testing only if the font is a COpenFont */
546 if (((CBitmapFont*)font2)->IsOpenFont())
549 openFont2 = ((CBitmapFont*)font2)->OpenFont();
551 /***************************Sixth Test***************************
552 Attempt to put a new entry into the second shaper cache and test if it was successful
555 /* Create a pseudo-new shape header to put into the cache of this new open font */
556 shape->iGlyphCount++;
559 /* Insert an entry into the cache */
560 TShapeHeader* cached_header5 = openFont2->InsertShapedDataIntoCache(0, params, shape);
561 ((CBitmapFont*)font2)->DeleteShape(0, cached_header5);
563 INFO_PRINTF1(_L("SHAPER CACHE API TEST 6: Second cache insertion test"));
564 TEST(cached_header5 != NULL && openFont2->GetGlyphCache()->iNumberOfShaperCacheEntries == 2);
566 /***************************Seventh, Eighth and Ninth Tests***************************
567 Test cache memory freeing policy, i.e. delete from all other caches except the current one
570 /* First find out how much memory needs freeing, i.e. how much was just added */
571 TInt bufferSize = (sizeof(TUint32) + sizeof(TInt16) + sizeof(TInt16) * 2)
572 * shape->iGlyphCount + sizeof(TInt16) * 2;
574 TInt bytes_needed = bufferSize + sizeof(COpenFontShaperCacheEntry) +
575 sizeof(TShapeHeader) + sizeof(TUint16)*input.iText->Length();
578 /* Now try to free memory from the original open font cache. The result should be that
579 memory should be freed from openFont2 cache, and not openFont cache
581 TInt memoryUsed = openFont2->GetGlyphCache()->iShapingInfoCacheMemory;
582 TInt expectedGlyphCount = openFont->GetGlyphCache()->iShaperCacheSentinel->iPrevious->iShapeHeader->iGlyphCount;
583 TInt deletedMemory = openFont->FreeShaperCacheMemory(bytes_needed);
586 a) if the memory used by openFont2 cache has reduced, i.e. back to original memory
587 b) if the last entry from openFont2 cache has been deleted
588 c) last entry from openFont cache is intact
590 INFO_PRINTF1(_L("SHAPER CACHE API TEST 7: Test if memory is freed from second COpenFont"));
591 TEST(memoryUsed - openFont2->GetGlyphCache()->iShapingInfoCacheMemory == deletedMemory &&
592 openFont2->GetGlyphCache()->iShapingInfoCacheMemory == 0);
594 INFO_PRINTF1(_L("SHAPER CACHE API TEST 8: Test if last entry of second COpenFont is deleted"));
595 TEST(openFont2->GetGlyphCache()->iNumberOfShaperCacheEntries == 1);
597 INFO_PRINTF1(_L("SHAPER CACHE API TEST 9: Test if the last entry of the first COpenFont is intact"));
598 TEST(openFont->GetGlyphCache()->iShaperCacheSentinel->iPrevious->iShapeHeader->iGlyphCount == expectedGlyphCount);
600 /***********************************Tenth Tests*****************************************
601 Test cache memory consistency and that there are no leakages when deleting memory from the cache
604 /* Continue adding entries to second open font cache until the memory used by the first one
605 goes down to zero, at which point the number of cache entries should be 1, and memory from
606 the current open font should start getting released and eventually reach 0 when the number
607 of cached entries reaches 1.
609 TShapeHeader* cached_header6 = NULL;
610 /* Keep inserting pseudo-new shaped entries into the cache to fill it up */
611 while(openFont->GetGlyphCache()->iNumberOfShaperCacheEntries > 1)
613 memoryUsed = openFont2->File()->GetFontStore()->GetShaperCacheMemUsage();
614 // Change the cached entries slightly to distinguish between each entry
615 shape->iGlyphCount++;
617 cached_header6 = openFont2->InsertShapedDataIntoCache(0, params, shape);
618 ((CBitmapFont*)font2)->DeleteShape(0, cached_header6);
619 cached_header6 = NULL;
622 INFO_PRINTF1(_L("SHAPER CACHE API TEST 10: Test consistency of cache memory"));
623 TEST(openFont->GetGlyphCache()->iShapingInfoCacheMemory == 0);
627 @SYMTestCaseID GRAPHICS-SYSLIB-FNTSTORE-UT-4001
628 @SYMTestCaseDesc Test that when trying to delete a shape not in the cache it
629 does not loop infinitely trying to find it.
630 @SYMTestPriority Medium
631 @SYMTestActions Pass a null shape header to the DeleteShape function.
632 @SYMTestExpectedResults The function call should return instead of looping infinitely.
635 ((CTShaperCacheStep*)iStep)->RecordTestResultL();
636 ((CTShaperCacheStep*)iStep)->SetTestStepID(_L("GRAPHICS-SYSLIB-FNTSTORE-UT-4001"));
637 INFO_PRINTF1(_L("SHAPER CACHE API TEST 11: Test that shape not found does not loop infinitely."));
638 TShapeHeader* null_header = NULL;
639 // Timeout set in TEF script to catch infinite loop.
640 ((CBitmapFont*)font2)->DeleteShape(0, null_header);
642 ((CTShaperCacheStep*)iStep)->CloseTMSGraphicsStep();
647 CleanupStack::Pop(font2);
648 iFontStore->ReleaseFont(font2);
651 CleanupStack::Pop(font);
652 iFontStore->ReleaseFont(font);
655 iFontStore->RemoveFile(id1);
656 iFontStore->RemoveFile(id2);
657 iFontStore->RemoveFile(id3);
658 iFontStore->RemoveFile(id4);
661 void CTShaperCache::RunTestCaseL(TInt aCurTestCase)
663 ((CTShaperCacheStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
667 ((CTShaperCacheStep*)iStep)->SetTestStepID(_L("GRAPHICS-FNTSTORE-0043"));
668 INFO_PRINTF1(_L("#################### T_SHAPERCACHE test case 1 ########################\n"));
670 TEST(err == KErrNone);
673 ((CTShaperCacheStep*)iStep)->SetTestStepID(_L("GRAPHICS-FNTSTORE-0044"));
674 INFO_PRINTF1(_L("#################### T_SHAPERCACHE test case 2 ########################\n"));
676 TEST(err == KErrNone);
679 ((CTShaperCacheStep*)iStep)->SetTestStepID(_L("GRAPHICS-FNTSTORE-0045"));
680 INFO_PRINTF1(_L("#################### T_SHAPERCACHE test case 3 ########################"));
681 TRAP(err,TestShaperCacheAPIsL());
682 TEST(err == KErrNone);
685 ((CTShaperCacheStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
686 ((CTShaperCacheStep*)iStep)->CloseTMSGraphicsStep();
690 ((CTShaperCacheStep*)iStep)->RecordTestResultL();
695 __CONSTRUCT_STEP__(ShaperCache)