First public contribution.
1 // Copyright (c) 2009-2010 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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
18 @internalComponent - Internal Symbian test code
21 #include "tglyphatlas.h"
23 #include "glyphatlastestwrapper.h"
25 _LIT(KTypefaceName, "DejaVu Sans Condensed");
26 _LIT(KMonoTypefaceName, "DejaVu Sans Mono");
27 const TInt KNumGlyphCodesLatin = 96;
30 CTGlyphAtlas::CTGlyphAtlas(CTestStep* aStep):
31 CTGraphicsBase(aStep),
34 iGlyphCodesLatin(NULL),
39 void CTGlyphAtlas::ConstructL()
41 iFbs = RFbsSession::GetSession();
42 iTs = (CFbsTypefaceStore*)CFbsTypefaceStore::NewL(NULL);
43 User::LeaveIfError(iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont, TFontSpec(KTypefaceName, 15)));
44 User::LeaveIfError(iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont2, TFontSpec(KMonoTypefaceName, 8)));
46 iGlyphCodesLatin = new(ELeave) TUint[KNumGlyphCodesLatin];
47 for (TInt ii = 0; ii < KNumGlyphCodesLatin; ++ii)
49 iGlyphCodesLatin[ii] = ii+32; // ASCII characters from 0020 to 007F
52 INFO_PRINTF1(_L("FBSERV Glyph Atlas Testing"));
55 CTGlyphAtlas::~CTGlyphAtlas()
59 iTs->ReleaseFont(iFont);
62 delete[] iGlyphCodesLatin;
65 void CTGlyphAtlas::RunTestCaseL(TInt aCurTestCase)
67 ((CTGlyphAtlasStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
71 ((CTGlyphAtlasStep*)iStep)->SetTestStepID(_L("GRAPHICS-FBSERV-0663"));
75 ((CTGlyphAtlasStep*)iStep)->SetTestStepID(_L("GRAPHICS-FBSERV-0664"));
79 ((CTGlyphAtlasStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
80 ((CTGlyphAtlasStep*)iStep)->CloseTMSGraphicsStep();
84 ((CTGlyphAtlasStep*)iStep)->RecordTestResultL();
88 @SYMTestCaseID GRAPHICS-FBSERV-0663
91 @SYMTestStatus Implemented
95 Shows that when the glyph atlas reaches its memory limit, any new added
96 glyphs will cause the eviction of the least recently used glyphs.
97 The new glyph will be added successfully.
100 i. Create a glyph atlas with a memory limit of 1000 bytes.
101 ii. Add glyphs to the atlas such that its memory consumption reaches the limit.
102 iii. Add one more glyph.
103 iv. Call CGlyphAtlas::GetGlyph() for the last glyph added.
104 v. Call CGlyphAtlas::GetGlyph() for the least recently used glyphs to check
105 that it has been evicted.
106 vi. Delete glyph atlas
108 @SYMTestExpectedResults
109 Each glyph is added successfully.
110 CGlyphAtlas::GetGlyph() returns KErrNone for the last glyph added.
111 CGlyphAtlas::GetGlyph() returns KErrNotFound for the least recently used glyph.
113 void CTGlyphAtlas::TestFullCache()
115 INFO_PRINTF1(_L("Test full cache eviction"));
118 // Fill cache up using expected size of glyph using AddGlyph.
119 const TInt KMaxAtlasSizeInBytes = 1000;
120 CGlyphAtlasTestWrapper* atlas = NULL;
121 TRAPD(ret, atlas = CGlyphAtlasTestWrapper::NewL(KMaxAtlasSizeInBytes));
127 TOpenFontCharMetrics charMetrics;
128 TGlyphImageInfo imageInfo;
130 const TUint8* bitmapData = NULL;
132 TBool atlasFull = EFalse;
133 CBitmapFont* bmFont = CTFbsFont::FontAddress(iFont);
134 // Fill up atlas by adding glyphs.
135 // Next glyph shold tip the atlas over the memory limit.
136 // Glyphs are added in ascending glyph code order.
137 // Leave at least one glyph so that we can guarantee that we can add one more unique glyph.
138 while (glyphIndex < KNumGlyphCodesLatin-1 && !atlasFull)
140 iFont->GetCharacterData(iGlyphCodesLatin[glyphIndex], charMetrics, bitmapData, bitmapSize);
141 TInt sizeInBytes = charMetrics.Height() * charMetrics.Width();
142 if (atlas->SizeInBytes() + sizeInBytes <= KMaxAtlasSizeInBytes)
144 CGlyphAtlas::TAddGlyphArgs args(bitmapData, iGlyphCodesLatin[glyphIndex++], charMetrics);
145 TESTNOERROR(atlas->AddGlyph(*bmFont, args, imageInfo));
154 // check least recently used page contains the first glyph in glyph codes
155 TUint leastUsedGlyphCode = iGlyphCodesLatin[0];
156 TEST(atlas->LruPageContainsGlyph(leastUsedGlyphCode));
158 // To ensure that the test does not pass if a FIFO eviction policy occurs,
159 // get the least recently used glyph so that it is moved internally.
160 TESTNOERROR(atlas->GetGlyph(*bmFont, leastUsedGlyphCode, imageInfo));
162 // glyphIndex, bitmapData and charMetrics now current for next glyph which
163 // will take the atlas over the cache limit.
164 CGlyphAtlas::TAddGlyphArgs args(bitmapData, iGlyphCodesLatin[glyphIndex], charMetrics);
165 TESTNOERROR(atlas->AddGlyph(*bmFont, args, imageInfo));
167 // check that searching for most recently added glyph is successful
168 TGlyphImageInfo newInfo;
169 TESTNOERROR(atlas->GetGlyph(*bmFont, iGlyphCodesLatin[glyphIndex], newInfo));
171 // check atlas size is still under the limit
172 TEST(atlas->SizeInBytes() <= KMaxAtlasSizeInBytes);
174 // check that the pages which were evicted contained the least used glyphs
175 // i.e. searching for these returns KErrNotFound
176 TInt err = KErrNotFound;
178 for (; KErrNotFound == err && index <= glyphIndex; ++index)
180 err = atlas->GetGlyph(*bmFont, iGlyphCodesLatin[index], newInfo);
183 // first found glyph should be greater than glyph at index 1
186 // check that the remaining pages contained the least used glyphs
187 for (; index <= glyphIndex; ++index)
189 TESTNOERROR(atlas->GetGlyph(*bmFont, iGlyphCodesLatin[index], newInfo));
198 @SYMTestCaseID GRAPHICS-FBSERV-0664
199 @SYMTestPriority High
201 @SYMTestStatus Implemented
205 Shows that CGlyphAtlas::FontReleased() does actually delete all the glyphs
206 associated with the released font and leaves glyphs associated with other
210 i. Create a glyph atlas with no memory limit.
211 ii. Add glyphs for two different fonts to the atlas.
212 iii. Check all glyphs for both fonts were successfully added.
213 iv. Call CGlyphAtlas::ReleaseFont for one of the fonts.
214 v. Check that there are no glyphs associated with the released font.
215 vi. Call CGlyphAtlas::ReleaseFont for the remaining font.
216 vii Check that there are no glyphs associated with the released font and
217 that the atlas is empty.
218 viii Delete the glyph atlas.
220 @SYMTestExpectedResults
221 After each font is released, there are no glyphs associated with that font
224 void CTGlyphAtlas::TestFontReleased()
226 INFO_PRINTF1(_L("Test behaviour of CGlyphAtlas::FontReleased()"));
229 CGlyphAtlasTestWrapper* atlas = NULL;
230 TRAPD(ret, atlas = CGlyphAtlasTestWrapper::NewL(KGlyphAtlasNoCacheLimit));
236 TOpenFontCharMetrics charMetrics;
237 TGlyphImageInfo imageInfo;
239 const TUint8* bitmapData = NULL;
240 CBitmapFont* bmFont = CTFbsFont::FontAddress(iFont);
241 CBitmapFont* bmFont2 = CTFbsFont::FontAddress(iFont2);
242 for (TInt glyphIndex = 0; glyphIndex < KNumGlyphCodesLatin; ++glyphIndex)
244 iFont->GetCharacterData(iGlyphCodesLatin[glyphIndex], charMetrics, bitmapData, bitmapSize);
245 CGlyphAtlas::TAddGlyphArgs args(bitmapData, iGlyphCodesLatin[glyphIndex], charMetrics);
246 TESTNOERROR(atlas->AddGlyph(*bmFont, args, imageInfo));
248 iFont2->GetCharacterData(iGlyphCodesLatin[KNumGlyphCodesLatin-1-glyphIndex], charMetrics, bitmapData, bitmapSize);
249 CGlyphAtlas::TAddGlyphArgs args2(bitmapData, iGlyphCodesLatin[glyphIndex], charMetrics);
250 TESTNOERROR(atlas->AddGlyph(*bmFont2, args2, imageInfo));
252 // check there are font entries for these 2 fonts
253 TEST(2 == atlas->FontCount());
255 // check actual number of glyphs in atlas for each font is as expected
256 TEST(KNumGlyphCodesLatin == atlas->GlyphCountByFont(bmFont));
257 TEST(KNumGlyphCodesLatin == atlas->GlyphCountByFont(bmFont2));
258 TEST(2*KNumGlyphCodesLatin == atlas->GlyphCount());
260 // release one font and check number of glyphs in atlas for each font
262 atlas->FontReleased(*bmFont);
263 TEST(1 == atlas->FontCount());
264 TEST(0 == atlas->GlyphCountByFont(bmFont));
265 TEST(KNumGlyphCodesLatin == atlas->GlyphCountByFont(bmFont2));
266 TEST(KNumGlyphCodesLatin == atlas->GlyphCount());
268 // release one font and check number of glyphs in atlas for each font
270 atlas->FontReleased(*bmFont2);
271 TEST(0 == atlas->FontCount());
272 TEST(0 == atlas->GlyphCountByFont(bmFont));
273 TEST(0 == atlas->GlyphCountByFont(bmFont2));
274 TEST(0 == atlas->GlyphCount());
284 __CONSTRUCT_STEP__(GlyphAtlas)