fbs/fontandbitmapserver/tfbs/tglyphatlas.cpp
author hgs
Fri, 24 Sep 2010 16:14:28 +0300
changeset 187 9f66f99ee56f
permissions -rw-r--r--
201026
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
187
hgs
parents:
diff changeset
     1
// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     2
// All rights reserved.
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     7
//
hgs
parents:
diff changeset
     8
// Initial Contributors:
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    10
//
hgs
parents:
diff changeset
    11
// Contributors:
hgs
parents:
diff changeset
    12
//
hgs
parents:
diff changeset
    13
// Description:
hgs
parents:
diff changeset
    14
//
hgs
parents:
diff changeset
    15
hgs
parents:
diff changeset
    16
/**
hgs
parents:
diff changeset
    17
 @file
hgs
parents:
diff changeset
    18
 @internalComponent - Internal Symbian test code
hgs
parents:
diff changeset
    19
*/
hgs
parents:
diff changeset
    20
hgs
parents:
diff changeset
    21
#include "tglyphatlas.h"
hgs
parents:
diff changeset
    22
#include "TFBS.H"
hgs
parents:
diff changeset
    23
#include "glyphatlastestwrapper.h"
hgs
parents:
diff changeset
    24
hgs
parents:
diff changeset
    25
_LIT(KTypefaceName, "DejaVu Sans Condensed");
hgs
parents:
diff changeset
    26
_LIT(KMonoTypefaceName, "DejaVu Sans Mono");
hgs
parents:
diff changeset
    27
const TInt KNumGlyphCodesLatin = 96;
hgs
parents:
diff changeset
    28
hgs
parents:
diff changeset
    29
hgs
parents:
diff changeset
    30
CTGlyphAtlas::CTGlyphAtlas(CTestStep* aStep):
hgs
parents:
diff changeset
    31
	CTGraphicsBase(aStep),
hgs
parents:
diff changeset
    32
	iFbs(NULL),
hgs
parents:
diff changeset
    33
	iTs(NULL),
hgs
parents:
diff changeset
    34
	iGlyphCodesLatin(NULL),
hgs
parents:
diff changeset
    35
	iFont(NULL)
hgs
parents:
diff changeset
    36
	{
hgs
parents:
diff changeset
    37
	}
hgs
parents:
diff changeset
    38
hgs
parents:
diff changeset
    39
void CTGlyphAtlas::ConstructL()
hgs
parents:
diff changeset
    40
	{
hgs
parents:
diff changeset
    41
	iFbs = RFbsSession::GetSession();
hgs
parents:
diff changeset
    42
	iTs = (CFbsTypefaceStore*)CFbsTypefaceStore::NewL(NULL);
hgs
parents:
diff changeset
    43
	User::LeaveIfError(iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont, TFontSpec(KTypefaceName, 15)));
hgs
parents:
diff changeset
    44
	User::LeaveIfError(iTs->GetNearestFontToDesignHeightInPixels((CFont*&)iFont2, TFontSpec(KMonoTypefaceName, 8)));
hgs
parents:
diff changeset
    45
	
hgs
parents:
diff changeset
    46
	iGlyphCodesLatin = new(ELeave) TUint[KNumGlyphCodesLatin];
hgs
parents:
diff changeset
    47
	for (TInt ii = 0; ii < KNumGlyphCodesLatin; ++ii)
hgs
parents:
diff changeset
    48
		{
hgs
parents:
diff changeset
    49
		iGlyphCodesLatin[ii] = ii+32; // ASCII characters from 0020 to 007F
hgs
parents:
diff changeset
    50
		}
hgs
parents:
diff changeset
    51
hgs
parents:
diff changeset
    52
	INFO_PRINTF1(_L("FBSERV Glyph Atlas Testing"));
hgs
parents:
diff changeset
    53
	}
hgs
parents:
diff changeset
    54
hgs
parents:
diff changeset
    55
CTGlyphAtlas::~CTGlyphAtlas()
hgs
parents:
diff changeset
    56
	{
hgs
parents:
diff changeset
    57
	if (iTs)
hgs
parents:
diff changeset
    58
		{
hgs
parents:
diff changeset
    59
		iTs->ReleaseFont(iFont);
hgs
parents:
diff changeset
    60
		}
hgs
parents:
diff changeset
    61
	delete iTs;
hgs
parents:
diff changeset
    62
	delete[] iGlyphCodesLatin;
hgs
parents:
diff changeset
    63
	}
hgs
parents:
diff changeset
    64
hgs
parents:
diff changeset
    65
void CTGlyphAtlas::RunTestCaseL(TInt aCurTestCase)
hgs
parents:
diff changeset
    66
	{
hgs
parents:
diff changeset
    67
	((CTGlyphAtlasStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
hgs
parents:
diff changeset
    68
	switch(aCurTestCase)
hgs
parents:
diff changeset
    69
		{
hgs
parents:
diff changeset
    70
	case 1:
hgs
parents:
diff changeset
    71
		((CTGlyphAtlasStep*)iStep)->SetTestStepID(_L("GRAPHICS-FBSERV-0663"));
hgs
parents:
diff changeset
    72
		TestFullCache();
hgs
parents:
diff changeset
    73
		break;
hgs
parents:
diff changeset
    74
	case 2:
hgs
parents:
diff changeset
    75
		((CTGlyphAtlasStep*)iStep)->SetTestStepID(_L("GRAPHICS-FBSERV-0664"));
hgs
parents:
diff changeset
    76
		TestFontReleased();
hgs
parents:
diff changeset
    77
		break;
hgs
parents:
diff changeset
    78
	default:
hgs
parents:
diff changeset
    79
		((CTGlyphAtlasStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
hgs
parents:
diff changeset
    80
		((CTGlyphAtlasStep*)iStep)->CloseTMSGraphicsStep();
hgs
parents:
diff changeset
    81
		TestComplete();		
hgs
parents:
diff changeset
    82
		break;
hgs
parents:
diff changeset
    83
		}
hgs
parents:
diff changeset
    84
	((CTGlyphAtlasStep*)iStep)->RecordTestResultL();
hgs
parents:
diff changeset
    85
	}
hgs
parents:
diff changeset
    86
hgs
parents:
diff changeset
    87
/**
hgs
parents:
diff changeset
    88
@SYMTestCaseID		GRAPHICS-FBSERV-0663
hgs
parents:
diff changeset
    89
@SYMTestPriority	High
hgs
parents:
diff changeset
    90
@SYMTestType		UT
hgs
parents:
diff changeset
    91
@SYMTestStatus		Implemented
hgs
parents:
diff changeset
    92
@SYMPREQ			PREQ2678
hgs
parents:
diff changeset
    93
hgs
parents:
diff changeset
    94
@SYMTestCaseDesc
hgs
parents:
diff changeset
    95
	Shows that when the glyph atlas reaches its memory limit, any new added 
hgs
parents:
diff changeset
    96
	glyphs will cause the eviction of the least recently used glyphs.
hgs
parents:
diff changeset
    97
	The new glyph will be added successfully.
hgs
parents:
diff changeset
    98
hgs
parents:
diff changeset
    99
@SYMTestActions
hgs
parents:
diff changeset
   100
	i. Create a glyph atlas with a memory limit of 1000 bytes.
hgs
parents:
diff changeset
   101
	ii. Add glyphs to the atlas such that its memory consumption reaches the limit.
hgs
parents:
diff changeset
   102
	iii. Add one more glyph.
hgs
parents:
diff changeset
   103
	iv. Call CGlyphAtlas::GetGlyph() for the last glyph added.
hgs
parents:
diff changeset
   104
	v. Call CGlyphAtlas::GetGlyph() for the least recently used glyphs to check 
hgs
parents:
diff changeset
   105
		that it has been evicted.
hgs
parents:
diff changeset
   106
	vi. Delete glyph atlas
hgs
parents:
diff changeset
   107
hgs
parents:
diff changeset
   108
@SYMTestExpectedResults
hgs
parents:
diff changeset
   109
	Each glyph is added successfully.
hgs
parents:
diff changeset
   110
	CGlyphAtlas::GetGlyph() returns KErrNone for the last glyph added.
hgs
parents:
diff changeset
   111
	CGlyphAtlas::GetGlyph() returns KErrNotFound for the least recently used glyph.
hgs
parents:
diff changeset
   112
*/
hgs
parents:
diff changeset
   113
void CTGlyphAtlas::TestFullCache()
hgs
parents:
diff changeset
   114
	{
hgs
parents:
diff changeset
   115
	INFO_PRINTF1(_L("Test full cache eviction"));
hgs
parents:
diff changeset
   116
hgs
parents:
diff changeset
   117
	__UHEAP_MARK;
hgs
parents:
diff changeset
   118
	// Fill cache up using expected size of glyph using AddGlyph.
hgs
parents:
diff changeset
   119
	const TInt KMaxAtlasSizeInBytes = 1000;
hgs
parents:
diff changeset
   120
	CGlyphAtlasTestWrapper* atlas = NULL;
hgs
parents:
diff changeset
   121
	TRAPD(ret, atlas = CGlyphAtlasTestWrapper::NewL(KMaxAtlasSizeInBytes));
hgs
parents:
diff changeset
   122
	TESTNOERROR(ret);
hgs
parents:
diff changeset
   123
	if (KErrNone != ret)
hgs
parents:
diff changeset
   124
		{
hgs
parents:
diff changeset
   125
		return;
hgs
parents:
diff changeset
   126
		}
hgs
parents:
diff changeset
   127
	TOpenFontCharMetrics charMetrics;
hgs
parents:
diff changeset
   128
	TGlyphImageInfo imageInfo;
hgs
parents:
diff changeset
   129
	TSize bitmapSize;
hgs
parents:
diff changeset
   130
	const TUint8* bitmapData = NULL;
hgs
parents:
diff changeset
   131
	TInt glyphIndex = 0;
hgs
parents:
diff changeset
   132
	TBool atlasFull = EFalse;
hgs
parents:
diff changeset
   133
	CBitmapFont* bmFont = CTFbsFont::FontAddress(iFont);
hgs
parents:
diff changeset
   134
	// Fill up atlas by adding glyphs.
hgs
parents:
diff changeset
   135
	// Next glyph shold tip the atlas over the memory limit.
hgs
parents:
diff changeset
   136
	// Glyphs are added in ascending glyph code order.
hgs
parents:
diff changeset
   137
	// Leave at least one glyph so that we can guarantee that we can add one more unique glyph.
hgs
parents:
diff changeset
   138
	while (glyphIndex < KNumGlyphCodesLatin-1 && !atlasFull)
hgs
parents:
diff changeset
   139
		{
hgs
parents:
diff changeset
   140
		iFont->GetCharacterData(iGlyphCodesLatin[glyphIndex], charMetrics, bitmapData, bitmapSize);
hgs
parents:
diff changeset
   141
		TInt sizeInBytes = charMetrics.Height() * charMetrics.Width();
hgs
parents:
diff changeset
   142
		if (atlas->SizeInBytes() + sizeInBytes <= KMaxAtlasSizeInBytes)
hgs
parents:
diff changeset
   143
			{
hgs
parents:
diff changeset
   144
			CGlyphAtlas::TAddGlyphArgs args(bitmapData, iGlyphCodesLatin[glyphIndex++], charMetrics);
hgs
parents:
diff changeset
   145
			TESTNOERROR(atlas->AddGlyph(*bmFont, args, imageInfo));
hgs
parents:
diff changeset
   146
			}
hgs
parents:
diff changeset
   147
		else
hgs
parents:
diff changeset
   148
			{
hgs
parents:
diff changeset
   149
			atlasFull = ETrue;
hgs
parents:
diff changeset
   150
			}
hgs
parents:
diff changeset
   151
		}
hgs
parents:
diff changeset
   152
	TEST(atlasFull);
hgs
parents:
diff changeset
   153
hgs
parents:
diff changeset
   154
	// check least recently used page contains the first glyph in glyph codes
hgs
parents:
diff changeset
   155
	TUint leastUsedGlyphCode = iGlyphCodesLatin[0];
hgs
parents:
diff changeset
   156
	TEST(atlas->LruPageContainsGlyph(leastUsedGlyphCode));
hgs
parents:
diff changeset
   157
hgs
parents:
diff changeset
   158
	// To ensure that the test does not pass if a FIFO eviction policy occurs,
hgs
parents:
diff changeset
   159
	// get the least recently used glyph so that it is moved internally.
hgs
parents:
diff changeset
   160
	TESTNOERROR(atlas->GetGlyph(*bmFont, leastUsedGlyphCode, imageInfo));
hgs
parents:
diff changeset
   161
hgs
parents:
diff changeset
   162
	// glyphIndex, bitmapData and charMetrics now current for next glyph which 
hgs
parents:
diff changeset
   163
	// will take the atlas over the cache limit.
hgs
parents:
diff changeset
   164
	CGlyphAtlas::TAddGlyphArgs args(bitmapData, iGlyphCodesLatin[glyphIndex], charMetrics);
hgs
parents:
diff changeset
   165
	TESTNOERROR(atlas->AddGlyph(*bmFont, args, imageInfo));
hgs
parents:
diff changeset
   166
hgs
parents:
diff changeset
   167
	// check that searching for most recently added glyph is successful
hgs
parents:
diff changeset
   168
	TGlyphImageInfo newInfo;
hgs
parents:
diff changeset
   169
	TESTNOERROR(atlas->GetGlyph(*bmFont, iGlyphCodesLatin[glyphIndex], newInfo));
hgs
parents:
diff changeset
   170
hgs
parents:
diff changeset
   171
	// check atlas size is still under the limit
hgs
parents:
diff changeset
   172
	TEST(atlas->SizeInBytes() <= KMaxAtlasSizeInBytes);
hgs
parents:
diff changeset
   173
hgs
parents:
diff changeset
   174
	// check that the pages which were evicted contained the least used glyphs
hgs
parents:
diff changeset
   175
	// i.e. searching for these returns KErrNotFound
hgs
parents:
diff changeset
   176
	TInt err = KErrNotFound;
hgs
parents:
diff changeset
   177
	TInt index = 1;
hgs
parents:
diff changeset
   178
	for (; KErrNotFound == err && index <= glyphIndex; ++index)
hgs
parents:
diff changeset
   179
		{
hgs
parents:
diff changeset
   180
		err = atlas->GetGlyph(*bmFont, iGlyphCodesLatin[index], newInfo);
hgs
parents:
diff changeset
   181
		}
hgs
parents:
diff changeset
   182
	TESTNOERROR(err);
hgs
parents:
diff changeset
   183
	// first found glyph should be greater than glyph at index 1
hgs
parents:
diff changeset
   184
	TEST(index-1 > 1);
hgs
parents:
diff changeset
   185
	
hgs
parents:
diff changeset
   186
	// check that the remaining pages contained the least used glyphs
hgs
parents:
diff changeset
   187
	for (; index <= glyphIndex; ++index)
hgs
parents:
diff changeset
   188
		{
hgs
parents:
diff changeset
   189
		TESTNOERROR(atlas->GetGlyph(*bmFont, iGlyphCodesLatin[index], newInfo));
hgs
parents:
diff changeset
   190
		}
hgs
parents:
diff changeset
   191
hgs
parents:
diff changeset
   192
	delete atlas;
hgs
parents:
diff changeset
   193
	__UHEAP_MARKEND;
hgs
parents:
diff changeset
   194
	}
hgs
parents:
diff changeset
   195
hgs
parents:
diff changeset
   196
hgs
parents:
diff changeset
   197
/**
hgs
parents:
diff changeset
   198
@SYMTestCaseID		GRAPHICS-FBSERV-0664
hgs
parents:
diff changeset
   199
@SYMTestPriority	High
hgs
parents:
diff changeset
   200
@SYMTestType		UT
hgs
parents:
diff changeset
   201
@SYMTestStatus		Implemented
hgs
parents:
diff changeset
   202
@SYMPREQ			PREQ2678
hgs
parents:
diff changeset
   203
hgs
parents:
diff changeset
   204
@SYMTestCaseDesc
hgs
parents:
diff changeset
   205
	Shows that CGlyphAtlas::FontReleased() does actually delete all the glyphs 
hgs
parents:
diff changeset
   206
	associated with the released font and leaves glyphs associated with other 
hgs
parents:
diff changeset
   207
	fonts untouched.
hgs
parents:
diff changeset
   208
hgs
parents:
diff changeset
   209
@SYMTestActions
hgs
parents:
diff changeset
   210
	i. Create a glyph atlas with no memory limit.
hgs
parents:
diff changeset
   211
	ii. Add glyphs for two different fonts to the atlas.
hgs
parents:
diff changeset
   212
	iii. Check all glyphs for both fonts were successfully added.
hgs
parents:
diff changeset
   213
	iv. Call CGlyphAtlas::ReleaseFont for one of the fonts.
hgs
parents:
diff changeset
   214
	v. Check that there are no glyphs associated with the released font.
hgs
parents:
diff changeset
   215
	vi. Call CGlyphAtlas::ReleaseFont for the remaining font.
hgs
parents:
diff changeset
   216
	vii Check that there are no glyphs associated with the released font and 
hgs
parents:
diff changeset
   217
		that the atlas is empty.
hgs
parents:
diff changeset
   218
	viii Delete the glyph atlas.
hgs
parents:
diff changeset
   219
	
hgs
parents:
diff changeset
   220
@SYMTestExpectedResults
hgs
parents:
diff changeset
   221
	After each font is released, there are no glyphs associated with that font 
hgs
parents:
diff changeset
   222
	left in the atlas.
hgs
parents:
diff changeset
   223
*/
hgs
parents:
diff changeset
   224
void CTGlyphAtlas::TestFontReleased()
hgs
parents:
diff changeset
   225
	{
hgs
parents:
diff changeset
   226
	INFO_PRINTF1(_L("Test behaviour of CGlyphAtlas::FontReleased()"));
hgs
parents:
diff changeset
   227
hgs
parents:
diff changeset
   228
	__UHEAP_MARK;
hgs
parents:
diff changeset
   229
	CGlyphAtlasTestWrapper* atlas = NULL;
hgs
parents:
diff changeset
   230
	TRAPD(ret, atlas = CGlyphAtlasTestWrapper::NewL(KGlyphAtlasNoCacheLimit));
hgs
parents:
diff changeset
   231
	TESTNOERROR(ret);
hgs
parents:
diff changeset
   232
	if (KErrNone != ret)
hgs
parents:
diff changeset
   233
		{
hgs
parents:
diff changeset
   234
		return;
hgs
parents:
diff changeset
   235
		}
hgs
parents:
diff changeset
   236
	TOpenFontCharMetrics charMetrics;
hgs
parents:
diff changeset
   237
	TGlyphImageInfo imageInfo;
hgs
parents:
diff changeset
   238
	TSize bitmapSize;
hgs
parents:
diff changeset
   239
	const TUint8* bitmapData = NULL;
hgs
parents:
diff changeset
   240
	CBitmapFont* bmFont = CTFbsFont::FontAddress(iFont);
hgs
parents:
diff changeset
   241
	CBitmapFont* bmFont2 = CTFbsFont::FontAddress(iFont2);
hgs
parents:
diff changeset
   242
	for (TInt glyphIndex = 0; glyphIndex < KNumGlyphCodesLatin; ++glyphIndex)
hgs
parents:
diff changeset
   243
		{
hgs
parents:
diff changeset
   244
		iFont->GetCharacterData(iGlyphCodesLatin[glyphIndex], charMetrics, bitmapData, bitmapSize);
hgs
parents:
diff changeset
   245
		CGlyphAtlas::TAddGlyphArgs args(bitmapData, iGlyphCodesLatin[glyphIndex], charMetrics);
hgs
parents:
diff changeset
   246
		TESTNOERROR(atlas->AddGlyph(*bmFont, args, imageInfo));
hgs
parents:
diff changeset
   247
hgs
parents:
diff changeset
   248
		iFont2->GetCharacterData(iGlyphCodesLatin[KNumGlyphCodesLatin-1-glyphIndex], charMetrics, bitmapData, bitmapSize);
hgs
parents:
diff changeset
   249
		CGlyphAtlas::TAddGlyphArgs args2(bitmapData, iGlyphCodesLatin[glyphIndex], charMetrics);
hgs
parents:
diff changeset
   250
		TESTNOERROR(atlas->AddGlyph(*bmFont2, args2, imageInfo));
hgs
parents:
diff changeset
   251
		}
hgs
parents:
diff changeset
   252
	// check there are font entries for these 2 fonts
hgs
parents:
diff changeset
   253
	TEST(2 == atlas->FontCount());
hgs
parents:
diff changeset
   254
hgs
parents:
diff changeset
   255
	// check actual number of glyphs in atlas for each font is as expected
hgs
parents:
diff changeset
   256
	TEST(KNumGlyphCodesLatin == atlas->GlyphCountByFont(bmFont));
hgs
parents:
diff changeset
   257
	TEST(KNumGlyphCodesLatin == atlas->GlyphCountByFont(bmFont2));
hgs
parents:
diff changeset
   258
	TEST(2*KNumGlyphCodesLatin == atlas->GlyphCount());
hgs
parents:
diff changeset
   259
hgs
parents:
diff changeset
   260
	// release one font and check number of glyphs in atlas for each font 
hgs
parents:
diff changeset
   261
	// is as expected
hgs
parents:
diff changeset
   262
	atlas->FontReleased(*bmFont);
hgs
parents:
diff changeset
   263
	TEST(1 == atlas->FontCount());
hgs
parents:
diff changeset
   264
	TEST(0 == atlas->GlyphCountByFont(bmFont));
hgs
parents:
diff changeset
   265
	TEST(KNumGlyphCodesLatin == atlas->GlyphCountByFont(bmFont2));
hgs
parents:
diff changeset
   266
	TEST(KNumGlyphCodesLatin == atlas->GlyphCount());
hgs
parents:
diff changeset
   267
hgs
parents:
diff changeset
   268
	// release one font and check number of glyphs in atlas for each font 
hgs
parents:
diff changeset
   269
	// is as expected
hgs
parents:
diff changeset
   270
	atlas->FontReleased(*bmFont2);
hgs
parents:
diff changeset
   271
	TEST(0 == atlas->FontCount());
hgs
parents:
diff changeset
   272
	TEST(0 == atlas->GlyphCountByFont(bmFont));
hgs
parents:
diff changeset
   273
	TEST(0 == atlas->GlyphCountByFont(bmFont2));
hgs
parents:
diff changeset
   274
	TEST(0 == atlas->GlyphCount());
hgs
parents:
diff changeset
   275
hgs
parents:
diff changeset
   276
	delete atlas;
hgs
parents:
diff changeset
   277
hgs
parents:
diff changeset
   278
	__UHEAP_MARKEND;
hgs
parents:
diff changeset
   279
	}
hgs
parents:
diff changeset
   280
hgs
parents:
diff changeset
   281
hgs
parents:
diff changeset
   282
hgs
parents:
diff changeset
   283
//--------------
hgs
parents:
diff changeset
   284
__CONSTRUCT_STEP__(GlyphAtlas)