os/graphics/graphicsdeviceinterface/directgdi/test/tglyphimagecache.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-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 // This test is designed to run in environment with monotype font support.
    15 // To set up environment launch ityperast.cmd  from epoc32\winscw\, and 
    16 // then follow instruction on the screen.
    17 // 
    18 //
    19 
    20 #include "tglyphimagecache.h"
    21 #include <graphics/directgdiengine.h>
    22 #include <e32base.h>
    23 #include <VG/openvg.h>
    24 
    25 // The size of the target in pixels to use for these tests
    26 const TSize KGlyphCacheWindowSize(400, 400);
    27 
    28 enum TFontParam
    29 	{
    30 	ENormal, 
    31 	EUnderline = 0x1, 
    32 	EStrikeThrough = 0x2,
    33 	EBold = 0x4,
    34 	EUnderlineBold = 0x5, 
    35 	EItalic = 0x8,
    36 	EItalicStrikeThrough = 0xa,
    37 	};
    38 
    39 class TFontType
    40 	{
    41 public:
    42 	TInt iFontSize;
    43 	TFontParam iFontParam;
    44 	}; 
    45 
    46 LOCAL_C void CleanCache(TAny* aPtr)
    47 	{
    48 	MFontGlyphImageStorage* glyphImageStorage = reinterpret_cast<MFontGlyphImageStorage*> (aPtr);
    49 	glyphImageStorage->CleanGlyphImageCache();
    50 	}
    51 
    52 CTGlyphImageCache::CTGlyphImageCache()
    53 	{
    54 	SetTestStepName(KTGlyphImageCacheStep);
    55 	}
    56 
    57 CTGlyphImageCache::~CTGlyphImageCache()
    58 	{
    59 	}
    60 
    61 /**
    62 @SYMTestCaseID
    63 	GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0001
    64 
    65 @SYMPREQ 
    66 	PREQ39
    67 
    68 @SYMREQ
    69 	REQ9195
    70 	REQ9201 
    71 	REQ9202 
    72 	REQ9222 
    73 	REQ9223 
    74 	REQ9236 
    75 	REQ9237
    76 
    77 @SYMTestCaseDesc
    78 	Test requests Glyph Image elements from storage according their Glyph Key.
    79 
    80 @SYMTestStatus
    81 	Implemented
    82 
    83 @SYMTestPriority
    84 	High
    85 
    86 @SYMTestActions
    87 	Create Font Image Storage. In the cycle request aGlyph Image entry for a particular Glyph 
    88 	code and a font ID. 
    89 	Delete Glyph Storage.
    90 	
    91 @SYMTestExpectedResults
    92 	GlyphImage function must succeed; foreground, shadow and outlined images (if applicable) must be created
    93 */
    94 void CTGlyphImageCache::TestRetrieveEntryL(MFontGlyphImageStorage* aGlyphStorage, TGlyphBitmapType aGlyphType)
    95 	{
    96 	if(!aGlyphStorage)
    97 		return;	
    98 	_LIT(KTestName, "GlyphCache_RetrieveEntry"); 
    99 	if(!iRunningOomTests)
   100 		{
   101 		INFO_PRINTF1(KTestName);
   102 		}
   103 
   104 	TSize size(20, 30);
   105 	TInt bufferLength = size.iWidth * size.iHeight;
   106 	TUint8* buffer = (TUint8*)User::AllocL(bufferLength);
   107 	CleanupStack::PushL(buffer);
   108 	if(aGlyphType == EMonochromeGlyphBitmap)
   109 		{//to make decoding mechanizm work properly we need to fill the buffer
   110 		Mem::Fill(buffer, bufferLength, 0x1);
   111 		}
   112 	
   113 	TInt fontListId[] = 
   114 		{
   115 		1, 5, 3, 5
   116 		};
   117 	TInt numFont = sizeof(fontListId) / sizeof(fontListId[0]);
   118 	TUint charCodeList[] =
   119 		{
   120 		1, 2, 3, 2, 3,
   121 		};
   122 	TInt numGlyphCode = sizeof(charCodeList) / sizeof(charCodeList[0]);
   123 
   124 	for(TInt jj = 0; jj < numFont; jj++)
   125 		{
   126 		TInt fontId = fontListId[jj];
   127 		for(TInt ii = 0; ii < numGlyphCode; ii++)
   128 			{
   129 			TChar glyphCode = TChar(charCodeList[ii]);
   130 			VGImage foregroundImg = VG_INVALID_HANDLE;
   131 			VGImage shadowImg = VG_INVALID_HANDLE;
   132 			VGImage outlineImg = VG_INVALID_HANDLE;
   133 			TBool res = aGlyphStorage->GlyphImage(fontId, glyphCode, aGlyphType, buffer, size, &foregroundImg, &shadowImg, &outlineImg);
   134 			TESTNOERROR(res);
   135 			if(res != KErrNone)
   136 				{
   137 				User::Leave(res); 
   138 				}
   139 			else
   140 				{
   141 				TEST(foregroundImg);
   142 				if(aGlyphType == EFourColourBlendGlyphBitmap)
   143 					{
   144 					TEST(shadowImg);
   145 					TEST(outlineImg);
   146 					}
   147 				}	
   148 			}
   149 		}
   150 	CleanupStack::PopAndDestroy(buffer);
   151 	}
   152 
   153 /**
   154 @SYMTestCaseID
   155 	GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0002
   156 
   157 @SYMPREQ 
   158 	PREQ39
   159 
   160 @SYMREQ
   161 	REQ9195
   162 	REQ9201 
   163 	REQ9202 
   164 	REQ9222 
   165 	REQ9223 
   166 	REQ9236 
   167 	REQ9237
   168 
   169 @SYMTestCaseDesc
   170 	Drawing monochrome, anti-aliased and four colour fonts with different styles  
   171 
   172 @SYMTestStatus
   173 	Implemented
   174 
   175 @SYMTestPriority
   176 	High
   177 
   178 @SYMTestActions
   179 	Text is output with different effects (strikethrough, underline) and orientation 
   180 	(horizontal, vertical up, vertical down) and at different sizes and positions.
   181 	Clip region is also specified.
   182 
   183 @SYMTestExpectedResults
   184 	Test and reference images must match
   185 */
   186 void CTGlyphImageCache::TestDrawGlyphL(MFontGlyphImageStorage* aGlyphStorage, TGlyphBitmapType aGlyphBitmapType, DrawTextDirection aDirection, DrawTextAdjustment aDrawAdjustment, TBool aClipText)
   187 	{	
   188 	_LIT(KTestNameTemplate, "DrawGlyph%S_Dir%d_Clip%d_Adjust%d"); 
   189 	TBuf<128> testName;
   190 	_LIT(KTextOutput, "Hello world! Hello world! Hello world! Hello world! Hello world! Hello world!");
   191 	
   192 	switch(aGlyphBitmapType)
   193 		{
   194 	case EMonochromeGlyphBitmap:
   195 		_LIT(KMonochromeName, "Monochrome");
   196 		testName.Format(KTestNameTemplate, &KMonochromeName, aDirection, aClipText, aDrawAdjustment);
   197 		break;
   198 	case EAntiAliasedGlyphBitmap:
   199 		_LIT(KAntiAliasedName, "AntiAliased");
   200 		testName.Format(KTestNameTemplate, &KAntiAliasedName, aDirection, aClipText, aDrawAdjustment);
   201 		break;
   202 	case EFourColourBlendGlyphBitmap:
   203 		_LIT(KFourColourName, "FourColour");
   204 		testName.Format(KTestNameTemplate, &KFourColourName, aDirection, aClipText, aDrawAdjustment);
   205 		break;
   206 	default: 
   207 		User::Leave(KErrNotSupported);
   208 		break;	
   209 		}
   210 	
   211 	if(!iRunningOomTests)
   212 		{
   213 		INFO_PRINTF1(testName);
   214 		}
   215 	
   216 	ResetGc();
   217 	_LIT(KTestFontTypefaceName,"DejaVu Sans Condensed");
   218 	const TFontType fontType[] =
   219 		{
   220 		18, EStrikeThrough, 48, EUnderline, 16, EItalic, 78, EItalicStrikeThrough,
   221 
   222 		18, EStrikeThrough, 48, EUnderlineBold, 16, ENormal, 78, EStrikeThrough, 78, EBold, 
   223 		};
   224 	
   225 	TPoint pt(5, 5);
   226 	TInt *coord = & (pt.iY);
   227 
   228 	TSize size = iGdiTarget->SizeInPixels();
   229 	TRect rect = size;
   230 	rect.Shrink(20, 5);
   231 	RRegion region(rect);
   232 	TRect rect1;
   233 	if(aDirection == EDrawTextHorizontal)
   234 		{
   235 		rect1 = TRect(size.iWidth / 2 - 40, 40, size.iWidth / 2 + 40, size.iHeight - 40);
   236 		}
   237 	else
   238 		{
   239 		rect1 = TRect(20, size.iHeight / 2 - 40, size.iWidth - 20, size.iHeight / 2 + 40);
   240 		}	
   241 	region.SubRect(rect1);
   242 		
   243 	if(aDirection == EDrawTextVerticalUp || aDirection == EDrawTextVerticalDown)
   244 		{
   245 		if(aDirection == EDrawTextVerticalUp)
   246 			{
   247 			pt.iY = size.iHeight - 5;
   248 			}
   249 		coord = &(pt.iX);
   250 		}
   251 	
   252 	TInt arraySize = sizeof(fontType) / sizeof(fontType[0]);
   253 	
   254 	for(TInt ii = 0; ii < arraySize; ii++)
   255 		{
   256 		CFont *font = NULL;
   257 		TFontSpec fspec(KTestFontTypefaceName, fontType[ii].iFontSize);
   258 		fspec.iFontStyle.SetBitmapType(aGlyphBitmapType);
   259 		
   260 		iGc->Reset();
   261 
   262 		if(aClipText)
   263 			{
   264 			iGc->SetClippingRegion(region);
   265 			}
   266 
   267 		if(aGlyphBitmapType == EFourColourBlendGlyphBitmap)
   268 			{
   269 			fspec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
   270 			fspec.iFontStyle.SetEffects(FontEffect::EOutline, ETrue);
   271 			fspec.iFontStyle.SetEffects(FontEffect::EDropShadow, ETrue);
   272 			TRgb shadowColor = TRgb(0, 0, 255);
   273 			iGc->SetTextShadowColor(shadowColor);
   274 			TEST(shadowColor == iGc->TextShadowColor());
   275 			iGc->SetBrushColor(TRgb(255, 0, 0));
   276 			TEST(TRgb(255, 0, 0) == iGc->BrushColor());
   277 			}
   278 		else
   279 			{
   280 			iGc->SetBrushStyle(DirectGdi::ENullBrush);
   281 			iGc->SetPenStyle(DirectGdi::ESolidPen);
   282 			}	
   283 		iGc->SetPenColor(TRgb(0, 255, 0));
   284 		if(fontType[ii].iFontParam & EItalic)
   285 			{
   286 			fspec.iFontStyle.SetPosture(EPostureItalic);
   287 			}
   288 		if(fontType[ii].iFontParam & EBold)
   289 			{
   290 			fspec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
   291 			}
   292 			
   293 		User::LeaveIfError(iFontStore->GetNearestFontToDesignHeightInPixels((CFont*&) font, fspec));
   294 		if(iUseDirectGdi)
   295 			{
   296 			if(ii == 2)
   297 				{
   298 				iGc->SetFontNoDuplicate(font);
   299 				(reinterpret_cast <CTestDirectGdiContext*> (iGc))->NoJustifyAutoUpdate();
   300 				}
   301 			else
   302 				{
   303 				iGc->SetFont(font);
   304 				iGc->SetFontNoDuplicate(font);//shoudn't have any impact
   305 				(reinterpret_cast <CTestDirectGdiContext*> (iGc))->SetJustifyAutoUpdate();
   306 				}	
   307 			}
   308 		else
   309 			{
   310 			iGc->SetFont(font);
   311 			iGc->SetFontNoDuplicate(font);//shoudn't have any impact
   312 			}	
   313 		TEST(iGc->HasFont());
   314 		
   315 		TFontSpec fontSpec = font->FontSpecInTwips();
   316 		TGlyphBitmapType glyphBitmapType = fontSpec.iFontStyle.BitmapType();
   317 
   318 		TEST(glyphBitmapType == aGlyphBitmapType);	
   319 		if(fontType[ii].iFontParam & EUnderline)
   320 			{
   321 			iGc->SetUnderlineStyle(DirectGdi::EUnderlineOn);
   322 			}
   323 		else if(fontType[ii].iFontParam & EStrikeThrough)
   324 			{
   325 			iGc->SetStrikethroughStyle(DirectGdi::EStrikethroughOn);
   326 			}
   327 		
   328 		if(EDrawTextVerticalDown != aDirection)
   329 			{
   330 			*coord += font->HeightInPixels() + 5;
   331 			}
   332 		
   333 		if(aGlyphStorage && (ii == 0) && (arraySize > 1))
   334 			{
   335 			aGlyphStorage->CleanGlyphImageCache();
   336 			aGlyphStorage->EnforceOOMFailure(ETrue);
   337 			}
   338 		DrawText(KTextOutput, pt, aDirection, aDrawAdjustment, ii == 1);
   339 		if(aGlyphStorage)
   340 			{
   341 			aGlyphStorage->EnforceOOMFailure(EFalse);
   342 			}
   343 		
   344 		if(EDrawTextVerticalDown == aDirection)
   345 			{
   346 			*coord += font->HeightInPixels() + 5;
   347 			}
   348 
   349 		if(fontType[ii].iFontParam == ENormal)
   350 			{
   351 			iGc->SetUnderlineStyle(DirectGdi::EUnderlineOff);
   352 			iGc->SetStrikethroughStyle(DirectGdi::EStrikethroughOff);
   353 			}
   354 		iGc->ResetFont();
   355 		iFontStore->ReleaseFont(font);
   356 	
   357 		TEST(!iGc->HasFont());
   358 		}
   359 	region.Close();
   360 	if(aClipText)
   361 		{
   362 		iGc->ResetClippingRegion();
   363 		}
   364 
   365 	// Write the output to file.
   366 	//
   367 	TESTNOERROR(WriteTargetOutput(iTestParams, testName));
   368 	}
   369 
   370 /**
   371 @SYMTestCaseID
   372 	GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0003
   373 
   374 @SYMPREQ 
   375 	PREQ39
   376 
   377 @SYMREQ
   378 	REQ9195
   379 	REQ9201 
   380 	REQ9202 
   381 	REQ9222 
   382 	REQ9223 
   383 	REQ9236 
   384 	REQ9237
   385 
   386 @SYMTestCaseDesc
   387 	Filling up the glyph image cache
   388 
   389 @SYMTestStatus
   390 	Implemented
   391 
   392 @SYMTestPriority
   393 	High
   394 
   395 @SYMTestActions
   396 	1.	Fill glyph image storage with the same font but different glyphs until it exceeds its limit and resets the cache.
   397 	Repeat this operation for other glyph types
   398 
   399 	2.	Fill glyph image storage with different font and different glyph codes
   400 
   401 @SYMTestExpectedResults
   402 	Check that Glyph cache storage increments cache size correctly and deletes the least 
   403 	usable tree.
   404 */
   405 void CTGlyphImageCache::FillUpCacheL(MFontGlyphImageStorage* aGlyphStorage)
   406 	{
   407 	if(!aGlyphStorage)
   408 		return;
   409 	
   410 	aGlyphStorage->CleanGlyphImageCache();
   411 	TBuf<128> testName;
   412 	_LIT(KTestName, "GlyphCache_FillUpCache"); 
   413 	if(!iRunningOomTests)
   414 		{
   415 		INFO_PRINTF1(KTestName);
   416 		}
   417 	
   418 	const TSize size(12, 16);
   419 	TUint8* buffer = (TUint8*)User::AllocL(size.iWidth * size.iHeight);
   420 	CleanupStack::PushL(buffer);
   421 	TInt fontId = 10;
   422 	TGlyphBitmapType glyphTypeList[] = 
   423 		{
   424 		EMonochromeGlyphBitmap,
   425 		EAntiAliasedGlyphBitmap,
   426 		EFourColourBlendGlyphBitmap,
   427 		};
   428 	const TInt numGlyphType = sizeof(glyphTypeList) / sizeof(glyphTypeList[0]);
   429 	TESTL(aGlyphStorage->GlyphCacheSize() == 0);
   430 	
   431 	TInt glyphSizeInByte = 0;
   432 	TInt expectedSize = 0;
   433 	TUint32 glyphCode = 1;
   434 	
   435 	VGImage foregroundImg = VG_INVALID_HANDLE;
   436 	VGImage shadowImg = VG_INVALID_HANDLE;
   437 	VGImage outlineImg = VG_INVALID_HANDLE;
   438 	for(TInt ii = 0; ii < numGlyphType; ii++)
   439 		{
   440 		TGlyphBitmapType glyphType = glyphTypeList[ii];
   441 		//calculate the actual size of the glyph
   442 		glyphSizeInByte = GlyphImageSizeInByte(glyphType, size);
   443 
   444 		TUint maxGlyphSize = aGlyphStorage->MaxGlyphCacheSize() + glyphSizeInByte;
   445 		do 
   446 			{
   447 			TEST(expectedSize == aGlyphStorage->GlyphCacheSize());
   448 			TBool res = aGlyphStorage->GlyphImage(fontId, TChar(glyphCode), (TGlyphBitmapType)glyphType, buffer, size, &foregroundImg, &shadowImg, &outlineImg);
   449 			TESTNOERRORL(res);
   450 			glyphCode++;
   451 			expectedSize+= glyphSizeInByte; 
   452 			foregroundImg = VG_INVALID_HANDLE;
   453 			shadowImg = VG_INVALID_HANDLE;
   454 			outlineImg = VG_INVALID_HANDLE;
   455 			}while(expectedSize <= maxGlyphSize);
   456 		glyphCode = 1;	
   457 		expectedSize = 0;
   458 		TEST(glyphSizeInByte == aGlyphStorage->GlyphCacheSize());
   459 		aGlyphStorage->CleanGlyphImageCache();
   460 		}
   461 		
   462 	//now try to filling cache with different fonts and check that last usable font wont be removed
   463 	TUint maxGlyphSize = aGlyphStorage->MaxGlyphCacheSize();
   464 	glyphSizeInByte = GlyphImageSizeInByte(EMonochromeGlyphBitmap, size);
   465 	do 
   466 		{
   467 		TEST(expectedSize == aGlyphStorage->GlyphCacheSize());
   468 		TBool res = aGlyphStorage->GlyphImage(fontId, TChar(glyphCode), EMonochromeGlyphBitmap, buffer, size, &foregroundImg, &shadowImg, &outlineImg);
   469 		TESTNOERRORL(res);
   470 		glyphCode++;
   471 		expectedSize+= glyphSizeInByte; 
   472 		foregroundImg = VG_INVALID_HANDLE;
   473 		shadowImg = VG_INVALID_HANDLE;
   474 		outlineImg = VG_INVALID_HANDLE;
   475 		}while(expectedSize <= maxGlyphSize);
   476 
   477 	fontId += 10;
   478 	glyphCode = 1;
   479 
   480 	TBool res = aGlyphStorage->GlyphImage(fontId, TChar(glyphCode), EMonochromeGlyphBitmap, buffer, size, &foregroundImg, &shadowImg, &outlineImg);
   481 	TEST(glyphSizeInByte == aGlyphStorage->GlyphCacheSize());
   482 	TESTNOERROR(res);
   483 	
   484 	RArray<TUint32> listFontId;
   485 	aGlyphStorage->FontIdInOrder(listFontId);
   486 	TESTL(listFontId.Count() == 1);
   487 	TEST(listFontId[0] == fontId);
   488 	listFontId.Reset();
   489 	
   490 	CleanupStack::PopAndDestroy(buffer);
   491 	}
   492 
   493 /**
   494 @SYMTestCaseID
   495 	GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0004
   496 
   497 @SYMPREQ 
   498 	PREQ39
   499 
   500 @SYMREQ
   501 	REQ9195
   502 	REQ9201 
   503 	REQ9202 
   504 	REQ9222 
   505 	REQ9223 
   506 	REQ9236 
   507 	REQ9237
   508 
   509 @SYMTestCaseDesc
   510 	Tests filling the glyph image cache with different glyph images
   511 
   512 @SYMTestStatus
   513 	Implemented
   514 
   515 @SYMTestPriority
   516 	High
   517 
   518 @SYMTestActions
   519 	Specify glyphs which correspond to different fonts, glyph codes.
   520 	Request related VGImages.
   521 	Test the cache size is correct after each operation.
   522 	Get the driver's MDirectGdiDriverCacheSize interface.
   523 	Attempt to set the maximum size of the glyph cache to a size smaller than
   524 	the existing cache size.
   525 	Attempt to set the maximum size of the glyph cache to a size the same as
   526 	the existing cache size.
   527 	
   528 
   529 @SYMTestExpectedResults
   530 	Obtained glyph code and cache size must be correct each time.
   531 	Setting the maximum glyph cache size to a smaller size than the existing cache
   532 	size should fail with error KErrArgument.
   533 	Setting the maximum glyph cache size to a size the same as the existing cache
   534 	size should pass.
   535 */
   536 void CTGlyphImageCache::FillCacheL(MFontGlyphImageStorage* aGlyphStorage)
   537 	{
   538 	ASSERT(aGlyphStorage);		
   539 	
   540 	aGlyphStorage->CleanGlyphImageCache();
   541 	TBuf<128> testName;
   542 	_LIT(KTestName, "GlyphCache_FillCache"); 
   543 	if(!iRunningOomTests)
   544 		{
   545 		INFO_PRINTF1(KTestName);
   546 		}
   547 	
   548 	const TSize smallFontSize = TSize(12, 16);
   549 	const TSize smallFont1Size = TSize(10, 14);
   550 	const TSize bigFontSize = TSize(18, 24);
   551 	const TSize bigFont1Size = TSize(20, 26);
   552 	const TInt smallFontId = 10;
   553 	const TInt bigFontId = 20;
   554 	const TInt smallFont1Id = 30;
   555 	const TInt bigFont1Id = 40;
   556 	VGImage foregroundImg = VG_INVALID_HANDLE;
   557 	VGImage shadowImg = VG_INVALID_HANDLE;
   558 	VGImage outlineImg = VG_INVALID_HANDLE;
   559 	
   560 	TUint8* buffer = (TUint8*)User::AllocL(bigFontSize.iWidth * bigFontSize.iHeight);
   561 	CleanupStack::PushL(buffer);
   562 	TESTL(aGlyphStorage->GlyphCacheSize() == 0);
   563 	
   564 	TInt expectedCacheSize = 0;
   565 	TChar glyphCode = TChar(1);
   566 	TGlyphBitmapType glyphType = EMonochromeGlyphBitmap;
   567 	TBool res = aGlyphStorage->GlyphImage(smallFontId, glyphCode, glyphType, buffer, smallFontSize, &foregroundImg, &shadowImg, &outlineImg);
   568 	TESTNOERRORL(res);
   569 	expectedCacheSize = GlyphImageSizeInByte(glyphType, smallFontSize);
   570 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize());
   571 
   572 	//try to retrieve the same glyph
   573 	res = aGlyphStorage->GlyphImage(smallFontId, glyphCode, glyphType, buffer, smallFontSize, &foregroundImg, &shadowImg, &outlineImg);
   574 	TESTNOERRORL(res);
   575 	//the size should be the same
   576 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize()); 
   577 		
   578 	//now retrieving the same glyphCode but for the different font
   579 	res = aGlyphStorage->GlyphImage(bigFontId, glyphCode, glyphType, buffer, bigFontSize, &foregroundImg, &shadowImg, &outlineImg);
   580 	TESTNOERRORL(res);
   581 	expectedCacheSize += GlyphImageSizeInByte(glyphType, bigFontSize);
   582 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize()); 
   583 
   584 	//last font but different glyphCode
   585 	glyphCode = TChar(2);
   586 	res = aGlyphStorage->GlyphImage(bigFontId, glyphCode, glyphType, buffer, bigFontSize, &foregroundImg, &shadowImg, &outlineImg);
   587 	TESTNOERRORL(res);
   588 	expectedCacheSize += GlyphImageSizeInByte(glyphType, bigFontSize);
   589 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize()); 
   590 
   591 	//small font and last glyphCode
   592 	res = aGlyphStorage->GlyphImage(smallFontId, glyphCode, glyphType, buffer, smallFontSize, &foregroundImg, &shadowImg, &outlineImg);
   593 	TESTNOERRORL(res);
   594 	expectedCacheSize += GlyphImageSizeInByte(glyphType, smallFontSize);
   595 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize()); 
   596 
   597 	//now change the type
   598 	glyphType = EAntiAliasedGlyphBitmap;
   599 	res = aGlyphStorage->GlyphImage(smallFont1Id, glyphCode, glyphType, buffer, smallFont1Size, &foregroundImg, &shadowImg, &outlineImg);
   600 	TESTNOERRORL(res);
   601 	expectedCacheSize += GlyphImageSizeInByte(glyphType, smallFont1Size);
   602 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize()); 
   603 	//try again
   604 	res = aGlyphStorage->GlyphImage(smallFont1Id, glyphCode, glyphType, buffer, smallFont1Size, &foregroundImg, &shadowImg, &outlineImg);
   605 	TESTNOERRORL(res);
   606 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize()); 
   607 
   608 	//now change the type again
   609 	glyphType = EFourColourBlendGlyphBitmap;
   610 	res = aGlyphStorage->GlyphImage(bigFont1Id, glyphCode, glyphType, buffer, bigFont1Size, &foregroundImg, &shadowImg, &outlineImg);
   611 	TESTNOERRORL(res);
   612 	expectedCacheSize += GlyphImageSizeInByte(glyphType, bigFont1Size);
   613 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize()); 
   614 
   615 	//using initial value.
   616 	glyphType = EMonochromeGlyphBitmap;
   617 	glyphCode = TChar(1);
   618 	res = aGlyphStorage->GlyphImage(smallFontId, glyphCode, glyphType, buffer, smallFontSize, &foregroundImg, &shadowImg, &outlineImg);
   619 	TESTNOERRORL(res);
   620 	TEST(expectedCacheSize == aGlyphStorage->GlyphCacheSize());
   621 	
   622 	//get the driver's MDirectGdiDriverCacheSize extension interface and attempt
   623 	//to set the maximum cache size to be smaller than the existing cache size
   624 	CDirectGdiDriver* driver = CDirectGdiDriver::Static();
   625 	TESTL(driver != NULL);
   626 	MDirectGdiDriverCacheSize* driverCacheSize = NULL;
   627 	res = driver->GetInterface(TUid::Uid(KDirectGdiDriverCacheSizeUid), (TAny*&)driverCacheSize);
   628 	TESTNOERRORL(res);
   629 	//save the original cache size
   630 	TInt originalCacheSize = driverCacheSize->MaxGlyphCacheSize();
   631 	//setting the cache size to a size smaller than the existing cache should fail
   632 	res = driverCacheSize->SetMaxGlyphCacheSize(aGlyphStorage->GlyphCacheSize()-1);
   633 	TEST(res == KErrArgument);	
   634 	//setting the cache size to the same size as the existing cache should pass
   635 	res = driverCacheSize->SetMaxGlyphCacheSize(aGlyphStorage->GlyphCacheSize());
   636 	TESTNOERROR(res);
   637 	TEST(aGlyphStorage->GlyphCacheSize() == driverCacheSize->MaxGlyphCacheSize());
   638 	//reset the original driver cache size
   639 	res = driverCacheSize->SetMaxGlyphCacheSize(originalCacheSize);
   640 	TESTNOERROR(res);
   641 	
   642 	CleanupStack::PopAndDestroy(buffer);
   643 	}
   644 
   645 /**
   646 @SYMTestCaseID
   647 	GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0005
   648 
   649 @SYMPREQ 
   650 	PREQ39
   651 
   652 @SYMREQ
   653 	REQ9195
   654 	REQ9201 
   655 	REQ9202 
   656 	REQ9222 
   657 	REQ9223 
   658 	REQ9236 
   659 	REQ9237
   660 
   661 @SYMTestCaseDesc
   662 	Tests the ordering font IDs in the glyph image cache.
   663 
   664 @SYMTestStatus
   665 	Implemented
   666 
   667 @SYMTestPriority
   668 	High
   669 
   670 @SYMTestActions
   671 	Request glyph images for different fonts.
   672 
   673 @SYMTestExpectedResults
   674 	List of glyph cache trees must be arranged in order from most used to least used.
   675 */
   676 void CTGlyphImageCache::FontListIdOrderL(MFontGlyphImageStorage* aGlyphStorage)
   677 	{
   678 	if(!aGlyphStorage)
   679 		return;
   680 	
   681 	aGlyphStorage->CleanGlyphImageCache();
   682 	TBuf<128> testName;
   683 	_LIT(KTestName, "GlyphCache_FontListIdOrder"); 
   684 	if(!iRunningOomTests)
   685 		{
   686 		INFO_PRINTF1(KTestName);
   687 		}
   688 	
   689 	const TSize fontSize = TSize(12, 16);
   690 	TUint8* buffer = (TUint8*)User::AllocL(fontSize.iWidth * fontSize.iHeight);
   691 	CleanupStack::PushL(buffer);
   692 
   693 	TChar glyphCode = TChar(10);
   694 	TInt fontId = 10;
   695 	VGImage foregroundImg = VG_INVALID_HANDLE;
   696 	VGImage shadowImg = VG_INVALID_HANDLE;
   697 	VGImage outlineImg = VG_INVALID_HANDLE;
   698 	
   699 	TGlyphBitmapType glyphType = EMonochromeGlyphBitmap;
   700 	TInt res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   701 	TESTNOERRORL(res);
   702 
   703 	fontId = 20;
   704 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   705 	TESTNOERRORL(res);
   706 
   707 	fontId = 30;
   708 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   709 	TESTNOERRORL(res);
   710 
   711 	RArray<TUint32> fontListId;
   712 	res = aGlyphStorage->FontIdInOrder(fontListId);
   713 	if(res != KErrNone)
   714 		{
   715 		fontListId.Reset();
   716 		User::Leave(res);
   717 		}
   718 	
   719 	TESTL(fontListId.Count() == 3);
   720 	TEST(fontListId[0] == 30);
   721 	TEST(fontListId[1] == 20);
   722 	TEST(fontListId[2] == 10);
   723 	fontListId.Reset();
   724 
   725 	//call entries again to reorder font id list
   726 	fontId = 30;
   727 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   728 	TESTNOERRORL(res);
   729 	
   730 	fontId = 20;
   731 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   732 	TESTNOERRORL(res);
   733 
   734 	fontId = 40;
   735 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   736 	TESTNOERRORL(res);
   737 
   738 	fontId = 10;
   739 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   740 	TESTNOERRORL(res);
   741 
   742 	fontId = 50;
   743 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   744 	TESTNOERRORL(res);
   745 
   746 	res = aGlyphStorage->FontIdInOrder(fontListId);
   747 	if(res != KErrNone)
   748 		{
   749 		fontListId.Reset();
   750 		User::Leave(res);
   751 		}
   752 
   753 	TESTL(fontListId.Count() == 5);
   754 	TEST(fontListId[0] == 50);
   755 	TEST(fontListId[1] == 10);
   756 	TEST(fontListId[2] == 40);
   757 	TEST(fontListId[3] == 20);
   758 	TEST(fontListId[4] == 30);
   759 	fontListId.Reset();
   760 
   761 	CleanupStack::PopAndDestroy(buffer);
   762 	}
   763 
   764 /**
   765 @SYMTestCaseID
   766 	GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0006
   767 
   768 @SYMPREQ 
   769 	PREQ39
   770 
   771 @SYMREQ
   772 	REQ9195
   773 	REQ9222 
   774 	REQ9223 
   775 	REQ9236 
   776 	REQ9237
   777 
   778 @SYMTestCaseDesc
   779 	Test the operation of the glyph image cache when sent wrong parameters.
   780 
   781 @SYMTestStatus
   782 	Implemented
   783 
   784 @SYMTestPriority
   785 	High
   786 
   787 @SYMTestActions
   788 	Test requesting of glyph images with invalid paramaters - test an invalid glyph type
   789 	and test requesting a glyph image with zero height and one with zero width.
   790 
   791 @SYMTestExpectedResults
   792 	The function must identify wrong arguments and return the expected error.
   793 */
   794 void CTGlyphImageCache::WrongParameterL(MFontGlyphImageStorage* aGlyphStorage)
   795 	{
   796 	_LIT(KTestName, "GlyphCache_WrongParameters"); 
   797 	if(!iRunningOomTests)
   798 		{
   799 		INFO_PRINTF1(KTestName);
   800 		}
   801 	
   802 	aGlyphStorage->CleanGlyphImageCache();
   803 
   804 	TChar glyphCode = TChar(10);
   805 	TInt fontId = 10;
   806 	VGImage foregroundImg = VG_INVALID_HANDLE;
   807 	VGImage shadowImg = VG_INVALID_HANDLE;
   808 	VGImage outlineImg = VG_INVALID_HANDLE;
   809 	TSize fontSize = TSize(10, 12);
   810 	TUint8* buffer = (TUint8*)User::AllocL(fontSize.iWidth * fontSize.iHeight);
   811 	CleanupStack::PushL(buffer);
   812 
   813 	TGlyphBitmapType glyphType = EDefaultGlyphBitmap; // unsupported
   814 	
   815 	TInt res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, fontSize, &foregroundImg, &shadowImg, &outlineImg);
   816 	TEST(res == KErrNotSupported);
   817 	TEST(foregroundImg == VG_INVALID_HANDLE);
   818 	TEST(shadowImg == VG_INVALID_HANDLE);
   819 	TEST(outlineImg == VG_INVALID_HANDLE);
   820 	
   821 	glyphType = EMonochromeGlyphBitmap; // supported
   822 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, TSize(12, 0), &foregroundImg, &shadowImg, &outlineImg);
   823 	TEST(res == KErrArgument);
   824 	res = aGlyphStorage->GlyphImage(fontId, glyphCode, glyphType, buffer, TSize(0, 12), &foregroundImg, &shadowImg, &outlineImg);
   825 	TEST(res == KErrArgument);
   826 	TEST(foregroundImg == VG_INVALID_HANDLE);
   827 	TEST(shadowImg == VG_INVALID_HANDLE);
   828 	TEST(outlineImg == VG_INVALID_HANDLE);
   829 
   830 	CleanupStack::PopAndDestroy(buffer);
   831 	}
   832 
   833 TInt CTGlyphImageCache::GlyphImageSizeInByte(TGlyphBitmapType aGlyphType, const TSize& aSize) const
   834 	{
   835 	TInt glyphSizeInByte = 0;	
   836 		//calculate the actual size of the glyph
   837 	switch(aGlyphType)
   838 		{
   839 	case EMonochromeGlyphBitmap:
   840 		glyphSizeInByte = (((aSize.iWidth + 31) / 32) << 2) * aSize.iHeight;
   841 		break;
   842 	case EAntiAliasedGlyphBitmap:
   843 		glyphSizeInByte = aSize.iWidth * aSize.iHeight;
   844 		break;
   845 	case EFourColourBlendGlyphBitmap:
   846 		glyphSizeInByte = aSize.iWidth * aSize.iHeight;
   847 		//we have to allocate memory for shadow and outline bitmap as well
   848 		glyphSizeInByte *= 3;
   849 		break;
   850 	default :
   851 		break;
   852 		}
   853 	return glyphSizeInByte;
   854 	}
   855 /**
   856 Draws the text on the screen according its direction and alignment.
   857 */	
   858 void CTGlyphImageCache::DrawText(const TDesC& aText, const TPoint& aPt, DrawTextDirection aDirection, DrawTextAdjustment aDrawAdjustment, TBool aUpdateJustification)
   859 	{
   860 	const TSize size = iGdiTarget->SizeInPixels();
   861 	TRect rect = size;
   862 	
   863 	if(aDirection == EDrawTextHorizontal)
   864 		{
   865 		switch(aDrawAdjustment)
   866 			{
   867 		case EDrawFromPoint:
   868 			iGc->DrawText(aText, NULL, aPt);
   869 			break;
   870 		case EDrawInBox:
   871 			iGc->SetOrigin(aPt);
   872 			rect = TRect(-aPt, size);
   873 			iGc->DrawText(aText, NULL, rect);
   874 			break;
   875 		case EDrawRightAlignment:
   876 			rect.iTl = aPt;
   877 			rect.iBr.iX -= 30;
   878 			iGc->DrawText(aText, NULL, rect, 0, DirectGdi::ERight);
   879 			break;
   880 			}
   881 		}
   882 	else if ((aDirection == EDrawTextVerticalDown) || (aDirection == EDrawTextVerticalUp))
   883 		{
   884 		TBool up = (aDirection==EDrawTextVerticalUp);
   885 		switch(aDrawAdjustment)
   886 			{
   887 		case EDrawFromPoint:
   888 			iGc->DrawTextVertical(aText, NULL, aPt, up);
   889 			break;
   890 		case EDrawInBox:
   891 			iGc->SetOrigin(aPt);
   892 			rect = TRect(-aPt, size);
   893 			if(aUpdateJustification)
   894 				{
   895 				iGc->SetCharJustification(80, aText.Length());
   896 				iGc->UpdateJustificationVertical(aText, NULL, up);
   897 				}
   898 
   899 			iGc->DrawTextVertical(aText, NULL, rect, up);
   900 			iGc->SetOrigin(TPoint());
   901 			break;
   902 		case EDrawRightAlignment:
   903 			rect.iTl = aPt;
   904 			rect.iBr.iY -= 30;
   905 			iGc->DrawTextVertical(aText, NULL, rect, 0, DirectGdi::ERight);
   906 			break;
   907 			}
   908 		}
   909 	}
   910 
   911 /**
   912 Overrides of base class virtual
   913 @leave Gets system wide error code
   914 @return - TVerdict code
   915 */
   916 TVerdict CTGlyphImageCache::doTestStepPreambleL()
   917 	{			
   918 	CTDirectGdiStepBase::doTestStepPreambleL();
   919 	return TestStepResult();
   920 	}
   921 	
   922 /** 
   923 Overrides of base class pure virtual
   924 Our implementation only gets called if the base class doTestStepPreambleL() did
   925 not leave. That being the case, the current test result value will be EPass.
   926 @leave Gets system wide error code
   927 @return TVerdict code
   928 */	
   929 TVerdict CTGlyphImageCache::doTestStepL()
   930 	{		
   931 	// Test for each pixel format
   932 	TInt maxPixelFormat =  iTargetPixelFormatArray.Count() - 1;
   933 	for(TInt targetPixelFormatIndex = maxPixelFormat; targetPixelFormatIndex >= 0 ; targetPixelFormatIndex--)
   934 		{
   935 		iTestParams.iTargetPixelFormat = iTargetPixelFormatArray[targetPixelFormatIndex];
   936 		SetTargetL(iTestParams.iTargetPixelFormat, EOneContextOneTarget, KGlyphCacheWindowSize);
   937 
   938 		if(maxPixelFormat == targetPixelFormatIndex)
   939 			{
   940 			iMonotypeFont = DetectMonotypeFontL();
   941 			
   942 			if(!iMonotypeFont)
   943 				{
   944 				WARN_PRINTF1(_L("!! Due to running the test in environment without monotype fonts, some test cases will not \
   945 be executed! To set up environment with monotype font support, launch ityperast.cmd \
   946 from epoc32\\winscw\\c\\, and then follow the instruction on the screen!!"));
   947 				}
   948 			else
   949 				{
   950 				INFO_PRINTF1(_L("Monotype fonts have been detected"));
   951 				}	
   952 			}
   953 		
   954 		RunTestsL();
   955 		if(targetPixelFormatIndex == 0)
   956 			{
   957 			RunOomTestsL();
   958 			}
   959 		}
   960 	CloseTMSGraphicsStep();
   961 	return TestStepResult();
   962 	}
   963 
   964 /**
   965 Overrides of base class pure virtual function
   966 Lists the tests to be run
   967 */
   968 void CTGlyphImageCache::RunTestsL()
   969 	{
   970 	MFontGlyphImageStorage* glyphStorage = NULL;
   971 	TBool testImageCache = (iUseDirectGdi && !iUseSwDirectGdi);
   972 	if(testImageCache)
   973 		{
   974 		TInt err = iGc->GetInterface(TUid::Uid(KDirectGdiGetGlyphStorageUid), (TAny*&) glyphStorage);
   975 		if(err != KErrNone)
   976 			{
   977 			ERR_PRINTF2(_L("Error while retrieving Glyph Storage Interface, err = %d"), err);
   978 			TESTNOERRORL(err);
   979 			}
   980 		User::LeaveIfNull(glyphStorage);
   981 		CleanupStack::PushL(TCleanupItem(CleanCache, glyphStorage));
   982 		glyphStorage->CleanGlyphImageCache();
   983 		}
   984 
   985 	if(testImageCache)
   986 		{
   987 		SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0001"));
   988 		TestRetrieveEntryL(glyphStorage, EAntiAliasedGlyphBitmap);
   989 		RecordTestResultL();
   990 		glyphStorage->CleanGlyphImageCache();
   991 		SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0001"));
   992 		TestRetrieveEntryL(glyphStorage, EFourColourBlendGlyphBitmap);
   993 		RecordTestResultL();
   994 		glyphStorage->CleanGlyphImageCache();
   995 		SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0001"));
   996 		TestRetrieveEntryL(glyphStorage, EMonochromeGlyphBitmap);
   997 		RecordTestResultL();
   998 		SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0006"));
   999 		WrongParameterL(glyphStorage);
  1000 		RecordTestResultL();
  1001 		SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0005"));
  1002 		FontListIdOrderL(glyphStorage);
  1003 		RecordTestResultL();
  1004 		glyphStorage->CleanGlyphImageCache();
  1005 		}
  1006 
  1007 	if(!iRunningOomTests)//fonts are cached in the array, where memory won't be freed even if the font is released
  1008 		{
  1009 		if(testImageCache)
  1010 			{
  1011 			SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0004"));
  1012 			FillCacheL(glyphStorage);
  1013 			RecordTestResultL();
  1014 			SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0003"));
  1015 			FillUpCacheL(glyphStorage);
  1016 			RecordTestResultL();
  1017 			glyphStorage->CleanGlyphImageCache();
  1018 			}
  1019 		for(TInt ii = EDrawTextHorizontal; ii < EDrawTextLast; ii++)
  1020 			{
  1021 			for(TInt kk = EDrawFromPoint; kk <= EDrawInBox; kk++)
  1022 				{
  1023 				DrawTextDirection direction = (DrawTextDirection) ii;
  1024 				DrawTextAdjustment adjustment = (DrawTextAdjustment) kk;
  1025 		
  1026 				SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0002"));
  1027 				TestDrawGlyphL(glyphStorage, EMonochromeGlyphBitmap, direction, adjustment, EFalse);
  1028 				RecordTestResultL();
  1029 				SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0002"));
  1030 				TestDrawGlyphL(glyphStorage, EMonochromeGlyphBitmap, direction, adjustment, ETrue);
  1031 				RecordTestResultL();
  1032 				SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0002"));
  1033 				TestDrawGlyphL(glyphStorage, EAntiAliasedGlyphBitmap, direction, adjustment, EFalse);
  1034 				RecordTestResultL();
  1035 				SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0002"));
  1036 				TestDrawGlyphL(glyphStorage, EAntiAliasedGlyphBitmap, direction, adjustment, ETrue);
  1037 				RecordTestResultL();
  1038 				
  1039 				if(iMonotypeFont)
  1040 					{
  1041 					SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0002"));
  1042 					TestDrawGlyphL(glyphStorage, EFourColourBlendGlyphBitmap, direction, adjustment, EFalse);
  1043 					RecordTestResultL();
  1044 					SetTestStepID(_L("GRAPHICS-DIRECTGDI-GLYPHIMAGECACHE-0002"));
  1045 					TestDrawGlyphL(glyphStorage, EFourColourBlendGlyphBitmap, direction, adjustment, ETrue);
  1046 					RecordTestResultL();
  1047 					}
  1048 				}
  1049 			}
  1050 		}
  1051 
  1052 	//next set of tests should start from clean cache to garantee consistent results
  1053 	if(testImageCache)
  1054 		{
  1055 		glyphStorage->CleanGlyphImageCache();
  1056 		CleanupStack::Pop(glyphStorage);
  1057 		}
  1058 	}
  1059 
  1060 /**
  1061 See if monotype font is installed on the platform we are running on. Monotype font is required
  1062 to run the glyph tests that use the glyph bitmap type EFourColourBlendGlyphBitmap to draw
  1063 outlined and shadowed fonts.
  1064 @return ETrue if monotype is installed, EFalse if it is not installed.
  1065  */
  1066 TBool CTGlyphImageCache::DetectMonotypeFontL()
  1067 	{
  1068 	CFont *font = NULL;
  1069 	_LIT(KTestFontTypefaceName,"DejaVu Sans Condensed");
  1070 	TFontSpec fspec(KTestFontTypefaceName, 12);
  1071 	fspec.iFontStyle.SetBitmapType(EFourColourBlendGlyphBitmap);
  1072 
  1073 	fspec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap);
  1074 	fspec.iFontStyle.SetEffects(FontEffect::EOutline, ETrue);
  1075 	fspec.iFontStyle.SetEffects(FontEffect::EDropShadow, ETrue);
  1076 
  1077 	User::LeaveIfError(iFontStore->GetNearestFontToDesignHeightInPixels((CFont*&) font, fspec));
  1078 
  1079 	TFontSpec fontSpec = font->FontSpecInTwips();
  1080 	TGlyphBitmapType glyphBitmapType = fontSpec.iFontStyle.BitmapType();
  1081 	iFontStore->ReleaseFont(font);
  1082 
  1083 	return (EFourColourBlendGlyphBitmap==glyphBitmapType);
  1084 	}