os/textandloc/textrendering/textformatting/test/src/TGraphicsContext.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     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".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include "TGraphicsContext.h"
    20 #include <e32std.h>
    21 
    22 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    23 #include <graphics/gdi/gdiconsts.h>
    24 #include <graphics/gdi/gdistructs.h>
    25 #endif
    26 
    27 _LIT(KTestFontName, "Non Functional Test Font");
    28 
    29 
    30 // Utility functions to show contents of test data using test.Printf
    31 
    32 extern void PrintTestData (const TDesC& aTitle , const TDesC16& aDataBuffer);
    33 
    34 extern void PrintTestData(const TDesC& aTitle, const TText16* aDataBuffer, const TInt aSize);
    35 
    36 //
    37 //
    38 // CLineArray
    39 //
    40 //
    41 CLineArray::CLineArray() : iArrayIsEnabled(ETrue), iArray(0)
    42 	{
    43 	iPrev = iNext = this;
    44 	}
    45 
    46 void CLineArray::Null()
    47 	{
    48 	if (iNext == this && iArray)
    49 		{
    50 		iArray->Close();
    51 		delete iArray;
    52 		}
    53 	iArray = 0;
    54 	iPrev->iNext = iNext;
    55 	iNext->iPrev = iPrev;
    56 	iNext = iPrev = this;
    57 	}
    58 
    59 CLineArray::~CLineArray()
    60 	{
    61 	Null();
    62 	}
    63 
    64 void CLineArray::ConstructL(TInt aGranularity)
    65 	{
    66 	CLineArray::Null();
    67 	iArray = new (ELeave) RArray<TTestGCDisplayLine>(aGranularity);
    68 	}
    69 
    70 void CLineArray::Copy(const CLineArray& aOther)
    71 	{
    72 	CLineArray::Null();
    73 	iNext = &aOther;
    74 	iPrev = aOther.iPrev;
    75 	iPrev->iNext = this;
    76 	aOther.iPrev = this;
    77 	iArray = aOther.iArray;
    78 	iArrayIsEnabled = aOther.iArrayIsEnabled;
    79 	}
    80 
    81 void CLineArray::ResetLineArray()
    82 	{
    83 	iArray->Reset();
    84 	}
    85 
    86 const TTestGCDisplayLine& CLineArray::Line(TInt aIndex)
    87 	{
    88 	return (*iArray)[aIndex];
    89 	}
    90 
    91 const TTestGCDisplayLine* CLineArray::Find(const TDesC& aText)
    92 	{
    93 	TInt count = LinesPresent();
    94 	for (TInt i = 0; i != count; ++i)
    95 		{		
    96 		const TTestGCDisplayLine& line = Line(i);
    97 		if (line.iLineData.Find(aText) != KErrNotFound)
    98 			return &line;
    99 		}
   100 	return 0;
   101 	}
   102 
   103 void CLineArray::AddLineL(TTestGCDisplayLine& aLine)
   104 	{
   105 	if (iArrayIsEnabled)
   106 		User::LeaveIfError(iArray->Append(aLine));
   107 	}
   108 
   109 TInt CLineArray::LinesPresent()
   110 	{
   111 	return iArray->Count();
   112 	}
   113 
   114 //
   115 //
   116 // CTestGraphicsDevice
   117 //
   118 //
   119 CTestGraphicsDevice* CTestGraphicsDevice::NewL(TSize aSizeInPixels, RWsSession* aWsSession)
   120 	{
   121 	CTestGraphicsDevice* r = aWsSession?
   122 		new (ELeave) CTestGraphicsDevice(aSizeInPixels, aWsSession)
   123 		: new (ELeave) CTestGraphicsDevice(aSizeInPixels);
   124 	r->iLineArray.ConstructL(4);
   125 	if (aWsSession && KErrNone != r->Construct())
   126 		{
   127 		delete r;
   128 		return 0;
   129 		}
   130 	return r;
   131 	}
   132 
   133 CTestGraphicsDevice::CTestGraphicsDevice(TSize aSizeInPixels, RWsSession* aWsSession)
   134 	: CWsScreenDevice(*aWsSession)
   135 	{
   136 	Set(aSizeInPixels);
   137 	}
   138 
   139 CTestGraphicsDevice::CTestGraphicsDevice(TSize aSizeInPixels)
   140 	{
   141 	Set(aSizeInPixels);
   142 	}
   143 
   144 void CTestGraphicsDevice::Set(TSize aSizeInPixels)
   145 	{
   146 	iSize = aSizeInPixels;
   147 	iHorizontalTwipsToPixels = 40;
   148 	iVerticalTwipsToPixels = 40;
   149 	iPalette.SetEntry(0, KRgbBlack);
   150 	iPalette.SetEntry(1, KRgbWhite);
   151 	iPalette.SetEntry(2, KRgbMagenta);
   152 	iPalette.SetEntry(3, KRgbCyan);
   153 	}
   154 
   155 void CTestGraphicsDevice::SetHorizontalTwipsToPixels(TInt aTwipsToPixels)
   156 	{
   157 	iHorizontalTwipsToPixels = aTwipsToPixels;
   158 	}
   159 
   160 void CTestGraphicsDevice::SetVerticalTwipsToPixels(TInt aTwipsToPixels)
   161 	{
   162 	iVerticalTwipsToPixels = aTwipsToPixels;
   163 	}
   164 
   165 TDisplayMode CTestGraphicsDevice::DisplayMode() const
   166 	{
   167 	return EColor16M;
   168 	}
   169 
   170 TSize CTestGraphicsDevice::SizeInPixels() const
   171 	{
   172 	return iSize;
   173 	}
   174 
   175 TSize CTestGraphicsDevice::SizeInTwips() const
   176 	{
   177 	return TSize(iSize.iWidth * iHorizontalTwipsToPixels,
   178 		iSize.iHeight * iVerticalTwipsToPixels);
   179 	}
   180 
   181 TInt CTestGraphicsDevice::CreateContext(CWindowGc*& aGC)
   182 	{
   183 	CTestGraphicsContext* r = new CTestGraphicsContext(this);
   184 	if (!r)
   185 		return KErrNoMemory;
   186 	// only contruct if it is a fully-fledged Window Server thing
   187 	if (iBuffer)
   188 		r->Construct();
   189 	aGC = r;
   190 	return KErrNone;
   191 	}
   192 
   193 TInt CTestGraphicsDevice::CreateContext(CGraphicsContext*& aGC)
   194 	{
   195 	CWindowGc* p;
   196 	TInt r = CreateContext(p);
   197 	aGC = p;
   198 	return r;
   199 	}
   200 
   201 TInt CTestGraphicsDevice::NumTypefaces() const
   202 	{
   203 	return 1;
   204 	}
   205 
   206 void CTestGraphicsDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport, TInt aTypefaceIndex) const
   207 	{
   208 	// The only font we have at the moment is 10 pixels * 12 pixels for every character
   209 	__ASSERT_ALWAYS(aTypefaceIndex == 0,
   210 		CTestGraphicsContext::Panic(CTestGraphicsContext::ETypefaceIndexOutOfRange));
   211 	aTypefaceSupport.iIsScalable = EFalse;
   212 	aTypefaceSupport.iMaxHeightInTwips = iVerticalTwipsToPixels * 12;
   213 	aTypefaceSupport.iMinHeightInTwips = iVerticalTwipsToPixels * 10;
   214 	aTypefaceSupport.iNumHeights = 1;
   215 	aTypefaceSupport.iTypeface.iName = KTestFontName;
   216 	aTypefaceSupport.iTypeface.SetIsProportional(ETrue); // a bit of a lie
   217 	aTypefaceSupport.iTypeface.SetIsSerif(EFalse);
   218 	aTypefaceSupport.iTypeface.SetIsSymbol(EFalse);
   219 	}
   220 
   221 TInt CTestGraphicsDevice::FontHeightInTwips(TInt aTypefaceIndex, TInt aHeightIndex) const
   222 	{
   223 	// The only font we have at the moment is 10 pixels * 12 pixels for every character
   224 	__ASSERT_ALWAYS(aTypefaceIndex == 0,
   225 		CTestGraphicsContext::Panic(CTestGraphicsContext::ETypefaceIndexOutOfRange));
   226 	return iVerticalTwipsToPixels * FontHeightInPixels(aTypefaceIndex, aHeightIndex);
   227 	}
   228 
   229 void CTestGraphicsDevice::PaletteAttributes(TBool& aModifiable, TInt& aNumEntries) const
   230 	{
   231 	aModifiable = ETrue;
   232 	aNumEntries = 4;
   233 	}
   234 
   235 void CTestGraphicsDevice::SetPalette(CPalette* aPalette)
   236 	{
   237 	for (TInt i = 0; i != CTestPalette::KNumEntries; ++i)
   238 		{
   239 		TRgb col = aPalette->GetEntry(i);
   240 		iPalette.SetEntry(i, col);
   241 		}
   242 	}
   243 
   244 TInt CTestGraphicsDevice::GetPalette(CPalette*& aPalette) const
   245 	{
   246 	aPalette = const_cast<CTestPalette*>(&iPalette);
   247 	return KErrNone;
   248 	}
   249 
   250 void CTestGraphicsDevice::GetPixel(TRgb& aColor, const TPoint&) const
   251 	{
   252 	aColor = KRgbWhite;
   253 	}
   254 
   255 void CTestGraphicsDevice::GetScanLine(TDes8&, const TPoint&, TInt, TDisplayMode) const
   256 	{
   257 	__ASSERT_DEBUG(0, CTestGraphicsContext::Panic(CTestGraphicsContext::EUnimplemented));
   258 	}
   259 
   260 TInt CTestGraphicsDevice::AddFile(const TDesC&, TInt&)
   261 	{
   262 	return KErrNotSupported;
   263 	}
   264 
   265 void CTestGraphicsDevice::RemoveFile(TInt)
   266 	{
   267 	}
   268 
   269 TInt CTestGraphicsDevice::GetNearestFontInPixels(CFont*& aFont, const TFontSpec&)
   270 	{
   271 	CTestFont* font = new CTestFont();
   272 	if (!font)
   273 		return KErrNoMemory;
   274 	aFont = font;
   275 	return KErrNone;
   276 	}
   277 
   278 TInt CTestGraphicsDevice::FontHeightInPixels(TInt, TInt) const
   279 	{
   280 	return 12;
   281 	}
   282 
   283 TInt CTestGraphicsDevice::HorizontalTwipsToPixels(TInt aTwips) const
   284 	{
   285 	return aTwips / iHorizontalTwipsToPixels;
   286 	}
   287 
   288 TInt CTestGraphicsDevice::VerticalTwipsToPixels(TInt aTwips) const
   289 	{
   290 	return aTwips / iVerticalTwipsToPixels;
   291 	}
   292 
   293 TInt CTestGraphicsDevice::HorizontalPixelsToTwips(TInt aPixels) const
   294 	{
   295 	return aPixels * iHorizontalTwipsToPixels;
   296 	}
   297 
   298 TInt CTestGraphicsDevice::VerticalPixelsToTwips(TInt aPixels) const
   299 	{
   300 	return aPixels * iVerticalTwipsToPixels;
   301 	}
   302 
   303 TInt CTestGraphicsDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
   304 	{
   305 	TFontSpec fontSpec = aFontSpec;
   306 	fontSpec.iHeight = VerticalTwipsToPixels(fontSpec.iHeight);
   307 	return GetNearestFontInPixels(aFont, fontSpec);
   308 	}
   309 
   310 void CTestGraphicsDevice::ReleaseFont(CFont* aFont)
   311 	{
   312 	__ASSERT_ALWAYS(aFont->TypeUid() == TUid::Uid(12345),
   313 		CTestGraphicsContext::Panic(CTestGraphicsContext::EUnknownFont));
   314 	delete static_cast<CTestFont*>(aFont);
   315 	}
   316 
   317 void CTestGraphicsDevice::AddRectToDrawnArea(const TRect& aRect, TBool aCondition)
   318 	{
   319 	// check if the drawing is on testing area
   320 	if (!(iTestingArea.IsEmpty()) &&  	// if testing area has been set
   321 		!iHasDrawnOnTestingArea)		// and nothing hasn't been drawn on it so far
   322 		iHasDrawnOnTestingArea = iTestingArea.Intersects(aRect);
   323 	
   324 	if (iDrawnArea.IsEmpty())
   325 		iDrawnArea = aRect;
   326 	else
   327 		iDrawnArea.BoundingRect(aRect);
   328 	// only one condition at the moment
   329 	if (aCondition)
   330 		{
   331 		if (iAreaDrawnWithCondition.IsEmpty())
   332 			iAreaDrawnWithCondition = aRect;
   333 		else
   334 			iAreaDrawnWithCondition.BoundingRect(aRect);
   335 		}
   336 	}
   337 
   338 void CTestGraphicsDevice::SetTestingArea(TRect& aTestingArea)
   339 	{
   340 	iTestingArea = aTestingArea;
   341 	}
   342 
   343 void CTestGraphicsDevice::AddTestingArea(TRect& moreTestingArea)
   344 	{
   345 	if (iTestingArea.IsEmpty())
   346 		iTestingArea = moreTestingArea;
   347 	else
   348 		iTestingArea.BoundingRect(moreTestingArea);
   349 	}
   350 
   351 //
   352 //
   353 // CTestGraphicsContext
   354 //
   355 //
   356 void CTestGraphicsContext::Panic(TInt aReason)
   357 	{
   358 	User::Panic(_L("CTestGC"), aReason);
   359 	}
   360 
   361 CTestGraphicsContext::CTestGraphicsContext(CTestGraphicsDevice* aGd)
   362 	: CWindowGc(aGd), iGd(aGd), iDrawMode(EDrawModePEN), iPenSize(1,1)
   363 	{
   364 	iLineArray.Copy(aGd->LineArray());
   365 	}
   366 
   367 TInt CTestGraphicsContext::Construct()
   368 	{
   369 	return CWindowGc::Construct();
   370 	}
   371 
   372 void CTestGraphicsContext::AddRectToDrawnArea(const TRect& aRect)
   373 	{
   374 	TRect drawnRect = aRect;
   375 	drawnRect.Grow(iPenSize);
   376 	iGd->AddRectToDrawnArea(drawnRect,
   377 		iDrawMode == EDrawModeXOR || iDrawMode == EDrawModeNOTSCREEN);
   378 	}
   379 
   380 void CTestGraphicsContext::AddPointToDrawnArea(const TPoint& aPoint)
   381 	{
   382 	AddRectToDrawnArea(TRect(aPoint, iPenSize));
   383 	}
   384 
   385 CGraphicsDevice* CTestGraphicsContext::Device() const
   386 	{
   387 	return iGd;
   388 	}
   389 
   390 void CTestGraphicsContext::SetOrigin(const TPoint& aPos)
   391 	{
   392 	iOrigin = aPos;
   393 	}
   394 
   395 void CTestGraphicsContext::SetDrawMode(TDrawMode aDrawingMode)
   396 	{
   397 	iDrawMode = aDrawingMode;
   398 	}
   399 
   400 void CTestGraphicsContext::SetClippingRect(const TRect& /*aRect*/)
   401 	{
   402 	}
   403 
   404 void CTestGraphicsContext::CancelClippingRect()
   405 	{
   406 	}
   407 
   408 TInt CTestGraphicsContext::SetClippingRegion(const TRegion& /*aRegion*/)
   409 	{
   410 	return KErrNone;
   411 	}
   412 
   413 void CTestGraphicsContext::CancelClippingRegion()
   414 	{
   415 	}
   416 
   417 void CTestGraphicsContext::Reset()
   418 	{
   419 	iDrawMode = EDrawModePEN;
   420 	iFont = 0;
   421 	iPenSize.iWidth = 1;
   422 	iPenSize.iHeight = 1;
   423 	}
   424 
   425 void CTestGraphicsContext::UseFont(const CFont* aFont)
   426 	{
   427 	iFont = aFont;
   428 	}
   429 
   430 void CTestGraphicsContext::DiscardFont()
   431 	{
   432 	iFont = 0;
   433 	}
   434 
   435 void CTestGraphicsContext::SetUnderlineStyle(TFontUnderline /*UnderlineStyle*/)
   436 	{
   437 	}
   438 
   439 void CTestGraphicsContext::SetStrikethroughStyle(TFontStrikethrough /*aStrikethroughStyle*/)
   440 	{
   441 	}
   442 
   443 void CTestGraphicsContext::SetWordJustification(TInt /*aExcessWidth*/,TInt /*aNumGaps*/)
   444 	{
   445 	}
   446 
   447 void CTestGraphicsContext::SetCharJustification(TInt /*aExcessWidth*/,TInt /*aNumChars*/)
   448 	{
   449 	}
   450 
   451 void CTestGraphicsContext::SetPenColor(const TRgb& aColor)
   452 	{
   453 	CPalette* palette;
   454 	iGd->GetPalette(palette);
   455 	iPenColorIndex = palette->NearestIndex(aColor);
   456 	}
   457 
   458 void CTestGraphicsContext::SetPenStyle(TPenStyle /*aPenStyle*/)
   459 	{
   460 	}
   461 
   462 void CTestGraphicsContext::SetPenSize(const TSize& aSize)
   463 	{
   464 	iPenSize = aSize;
   465 	}
   466 
   467 void CTestGraphicsContext::SetBrushColor(const TRgb& /*aColor*/)
   468 	{
   469 	}
   470 
   471 void CTestGraphicsContext::SetBrushStyle(TBrushStyle /*aBrushStyle*/)
   472 	{
   473 	}
   474 
   475 void CTestGraphicsContext::SetBrushOrigin(const TPoint& /*aOrigin*/)
   476 	{
   477 	}
   478 
   479 void CTestGraphicsContext::UseBrushPattern(const CFbsBitmap* /*aBitmap*/)
   480 	{
   481 	}
   482 
   483 void CTestGraphicsContext::DiscardBrushPattern()
   484 	{
   485 	}
   486 
   487 void CTestGraphicsContext::MoveTo(const TPoint& aPoint)
   488 	{
   489 	iCurrentPos = iOrigin + aPoint;
   490 	}
   491 
   492 void CTestGraphicsContext::MoveBy(const TPoint& aVector)
   493 	{
   494 	iCurrentPos += aVector;
   495 	}
   496 
   497 void CTestGraphicsContext::Plot(const TPoint& aPoint)
   498 	{
   499 	iCurrentPos = iOrigin + aPoint;
   500 	AddPointToDrawnArea(iCurrentPos);
   501 	}
   502 
   503 void CTestGraphicsContext::DrawArc(const TRect& aRect,const TPoint& /*aStart*/,const TPoint& aEnd)
   504 	{
   505 	TRect r = aRect;
   506 	r.Move(iOrigin);
   507 	AddRectToDrawnArea(r);
   508 	iCurrentPos = iOrigin + aEnd;
   509 	}
   510 
   511 void CTestGraphicsContext::DrawLine(const TPoint& aPoint1,const TPoint& aPoint2)
   512 	{
   513 	AddPointToDrawnArea(iOrigin + aPoint1);
   514 	iCurrentPos = iOrigin + aPoint2;
   515 	AddPointToDrawnArea(iCurrentPos);
   516 	}
   517 
   518 void CTestGraphicsContext::DrawLineTo(const TPoint& aPoint)
   519 	{
   520 	AddPointToDrawnArea(iCurrentPos);
   521 	iCurrentPos = iOrigin + aPoint;
   522 	AddPointToDrawnArea(iCurrentPos);
   523 	}
   524 
   525 void CTestGraphicsContext::DrawLineBy(const TPoint& aVector)
   526 	{
   527 	AddPointToDrawnArea(iCurrentPos);
   528 	iCurrentPos += aVector;
   529 	AddPointToDrawnArea(iCurrentPos);
   530 	}
   531 
   532 void CTestGraphicsContext::DrawPolyLine(const CArrayFix<TPoint>* aPointList)
   533 	{
   534 	TInt num = aPointList->Count();
   535 	while (num--)
   536 		{
   537 		iCurrentPos = iOrigin + (*aPointList)[num - 1];
   538 		AddPointToDrawnArea(iCurrentPos);
   539 		}
   540 	}
   541 
   542 void CTestGraphicsContext::DrawPolyLine(const TPoint* aPointList,TInt aNumPoints)
   543 	{
   544 	while (aNumPoints--)
   545 		{
   546 		iCurrentPos = iOrigin + aPointList[aNumPoints - 1];
   547 		AddPointToDrawnArea(iCurrentPos);
   548 		}
   549 	}
   550 
   551 void CTestGraphicsContext::DrawPie(const TRect& aRect,
   552 	const TPoint& /*aStart*/, const TPoint& aEnd)
   553 	{
   554 	TRect r = aRect;
   555 	r.Move(iOrigin);
   556 	AddRectToDrawnArea(r);
   557 	iCurrentPos = iOrigin + aEnd;
   558 	}
   559 
   560 void CTestGraphicsContext::DrawEllipse(const TRect& aRect)
   561 	{
   562 	TRect r = aRect;
   563 	r.Move(iOrigin);
   564 	AddRectToDrawnArea(r);
   565 	}
   566 
   567 void CTestGraphicsContext::DrawRect(const TRect& aRect)
   568 	{
   569 	TRect r = aRect;
   570 	r.Move(iOrigin);
   571 	AddRectToDrawnArea(r);
   572 	}
   573 
   574 void CTestGraphicsContext::DrawRoundRect(const TRect& aRect,const TSize& aCornerSize)
   575 	{
   576 	TRect r = aRect;
   577 	r.Move(iOrigin);
   578 	r.Grow(aCornerSize);
   579 	AddRectToDrawnArea(r);
   580 	}
   581 
   582 TInt CTestGraphicsContext::DrawPolygon(const CArrayFix<TPoint>* aPointList,TFillRule /*aFillRule*/)
   583 	{
   584 	TInt num = aPointList->Count();
   585 	while (num--)
   586 		{
   587 		iCurrentPos = iOrigin + (*aPointList)[num - 1];
   588 		AddPointToDrawnArea(iCurrentPos);
   589 		}
   590 	return KErrNone;
   591 	}
   592 
   593 TInt CTestGraphicsContext::DrawPolygon(const TPoint* aPointList,TInt aNumPoints,TFillRule /*aFillRule*/)
   594 	{
   595 	while (aNumPoints--)
   596 		{
   597 		iCurrentPos = iOrigin + aPointList[aNumPoints - 1];
   598 		AddPointToDrawnArea(iCurrentPos);
   599 		}
   600 	return KErrNone;
   601 	}
   602 
   603 void CTestGraphicsContext::DrawBitmap(const TPoint& /*aTopLeft*/,const CFbsBitmap* /*aSource*/)
   604 	{
   605 	}
   606 
   607 void CTestGraphicsContext::DrawBitmap(const TRect& /*aDestRect*/,const CFbsBitmap* /*aSource*/)
   608 	{
   609 	}
   610 
   611 void CTestGraphicsContext::DrawBitmap(const TRect& /*aDestRect*/,const CFbsBitmap* /*aSource*/,const TRect& /*aSourceRect*/)
   612 	{
   613 	}
   614 
   615 void CTestGraphicsContext::DrawText(const TDesC& aText, const TPoint& aPosition)
   616 	{
   617 #ifdef PRINT_DRAWTEXT_LINES
   618 
   619 	_LIT(KDrawTextTitle, "Text being drawn");
   620 		PrintTestData(KDrawTextTitle, aText);
   621 
   622 #endif /* PRINT_DRAWTEXT_LINES */
   623 	
   624 	TTestGCDisplayLine thisLine;
   625 	thisLine.Set(aPosition, aText);
   626 	iLineArray.AddLineL(thisLine);
   627 	}
   628 
   629 void CTestGraphicsContext::DrawText(const TDesC& aText,const TRect& aBox,TInt aBaselineOffset,
   630 	TTextAlign /*aAlignment*/, TInt aLeftMargin)
   631 	{
   632 	TPoint pos(aBox.iBr.iX + aLeftMargin, aBox.iTl.iY + aBaselineOffset);
   633 	pos += iOrigin;
   634 	DrawText(aText, pos);
   635 	}
   636 	
   637 void CTestGraphicsContext::DrawText(const TDesC& aText,TTextParameters* aParam, const TPoint& aPosition)
   638 	{
   639 #ifdef PRINT_DRAWTEXT_LINES
   640 
   641 	_LIT(KDrawTextTitle, "Text being drawn");
   642 		PrintTestData(KDrawTextTitle, aText);
   643 
   644 #endif /* PRINT_DRAWTEXT_LINES */
   645 
   646 	//Avoid crash by ASSERT in BitGdi DrawText function
   647 	__ASSERT_ALWAYS(aParam->iStart < aParam->iEnd,
   648 		CTestGraphicsContext::Panic(CTestGraphicsContext::EErrorParameter));
   649 	
   650 	TTestGCDisplayLine thisLine;
   651 	TPtrC actualText = aText.Mid(aParam->iStart,aParam->iEnd - aParam->iStart + 1);
   652 	thisLine.Set(aPosition, actualText);
   653 	iLineArray.AddLineL(thisLine);
   654 	}
   655 
   656 void CTestGraphicsContext::DrawText(const TDesC& aText,TTextParameters* aParam,const TRect& aBox,TInt aBaselineOffset,
   657 	TTextAlign /*aAlignment*/, TInt aLeftMargin)
   658 	{
   659 	TPoint pos(aBox.iBr.iX + aLeftMargin, aBox.iTl.iY + aBaselineOffset);
   660 	pos += iOrigin;
   661 	DrawText(aText,aParam, pos);
   662 	}
   663 
   664 TInt CTestGraphicsContext::APIExtension(TUid aUid, TAny*& aOutput, TAny* aInput)
   665 	{
   666 	if (aUid == KDrawTextInContextUid)
   667 		{
   668 		TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
   669 		DrawText(contextParam->iText, &contextParam->iParam, contextParam->iPosition);
   670 		return KErrNone;
   671 		}
   672 	else if (aUid == KDrawBoxTextInContextUid)
   673 		{
   674 		TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
   675 		DrawText(contextParam->iText,&contextParam->iParam,contextParam->iBox,contextParam->iBaselineOffset,contextParam->iAlign,contextParam->iMargin);
   676 		return KErrNone;
   677 		}
   678 	// Future cases may be placed here later
   679 	else
   680 		return CWindowGc::APIExtension(aUid, aOutput, aInput);
   681 	}
   682 
   683 
   684 void CTestGraphicsContext::Clear()
   685 	{
   686 	}
   687 
   688 void CTestGraphicsContext::Clear(const TRect& /*aRect*/)
   689 	{
   690 	}
   691 
   692 void CTestGraphicsContext::CopyRect(const TPoint& /*aOffset*/, const TRect& /*aRect*/)
   693 	{
   694 	}
   695 
   696 void CTestGraphicsContext::BitBlt(const TPoint& /*aPoint*/, const CFbsBitmap* /*aBitmap*/)
   697 	{
   698 	}
   699 
   700 void CTestGraphicsContext::BitBlt(const TPoint& /*aPoint*/, const CFbsBitmap* /*aBitmap*/,
   701 	const TRect& /*aRect*/)
   702 	{
   703 	}
   704 
   705 void CTestGraphicsContext::BitBltMasked(const TPoint& /*aPoint*/, const CFbsBitmap* /*aBitmap*/,
   706 	const TRect& /*aSourceRect*/, const CFbsBitmap* /*aMaskBitmap*/, TBool /*aInvertMask*/)
   707 	{
   708 	}
   709 
   710 void CTestGraphicsContext::SetFaded(TBool)
   711 	{
   712 	}
   713 
   714 void CTestGraphicsContext::SetFadingParameters(TUint8,TUint8)
   715 	{
   716 	}
   717 
   718 //
   719 //
   720 // CTestFont
   721 //
   722 //
   723 inline TBool IsSurrogate(TText a) { return 0xD800 == (a & 0xF800); }
   724 inline TBool IsHighSurrogate(TText a) { return 0xD800 == (a & 0xFC00); }
   725 inline TBool IsLowSurrogate(TText a) { return 0xDC00 == (a & 0xFC00); }
   726 inline TChar PairSurrogates(TText aHigh, TText aLow)
   727 	{
   728 	return ((aHigh - 0xd7f7) << 10) + aLow;
   729 	}
   730 
   731 TUid CTestFont::DoTypeUid() const
   732 	{
   733 	return TUid::Uid(12345);
   734 	}
   735 
   736 TInt CTestFont::DoHeightInPixels() const
   737 	{
   738 	return 12;
   739 	}
   740 
   741 TInt CTestFont::DoAscentInPixels() const
   742 	{
   743 	return 10;
   744 	}
   745 
   746 struct TSpecialSizes
   747 	{
   748 	TInt iCharacter;
   749 	TInt iWidth;
   750 	};
   751 
   752 static const TSpecialSizes KSpecialSizes[] =
   753 	{
   754 	{ CTestFont::KThreePerEmSpace, 3 },
   755 	{ CTestFont::KThinSpace, 2 },
   756 	{ CTestFont::KHairSpace, 1 },
   757 	{ CTestFont::KZeroWidthSpace, 0 },
   758 	{ CTestFont::KZeroWidthNoBreakSpace, 0 },
   759 	};
   760 
   761 TInt CTestFont::DoCharWidthInPixels(TChar aChar) const
   762 	{
   763 	TInt cn = aChar;
   764 	// non-characters 0x??FFFE and 0x??FFFF
   765 	if ((cn & 0xFFFE) == 0xFFFE)
   766 		return 0;
   767 
   768 	// Find character in the special sizes table
   769 	TInt first = 0;
   770 	TInt last = sizeof(KSpecialSizes)/sizeof(KSpecialSizes[0]);
   771 	while (first != last)
   772 		{
   773 		TInt c = static_cast<TInt>(aChar);
   774 		TInt mid = (first + last) >> 1;
   775 		if (c < KSpecialSizes[mid].iCharacter)
   776 			last = mid;
   777 		else if (KSpecialSizes[mid].iCharacter < c)
   778 			first = mid + 1;
   779 		else
   780 			return KSpecialSizes[mid].iWidth;
   781 		}
   782 
   783 	return 10;
   784 	}
   785 
   786 TInt CTestFont::DoTextCount(const TDesC& aText, TInt aWidthInPixels,
   787 	TInt& aExcessWidthInPixels) const
   788 	{
   789 	const TText* p = &aText[0];
   790 	const TText* pEnd = p + aText.Length();
   791 	TInt total = 0;
   792 	TInt prevSurrogate = 0;
   793 	TInt charactersThatFit = 0;
   794 	while (p != pEnd)
   795 		{
   796 		TChar c = *p;
   797 		if (IsSurrogate(*p))
   798 			{
   799 			c = 0xFFFF;
   800 			if (IsHighSurrogate(*p))
   801 				prevSurrogate = *p;
   802 			else if (prevSurrogate != 0)
   803 				{
   804 				c = PairSurrogates(static_cast<TText>(prevSurrogate), *p);
   805 				prevSurrogate = 0;
   806 				}
   807 			}
   808 		else
   809 			prevSurrogate = 0;
   810 		total += CharWidthInPixels(c);
   811 		if (total <= aWidthInPixels)
   812 			++charactersThatFit;
   813 		++p;
   814 		}
   815 	aExcessWidthInPixels = total - aWidthInPixels;
   816 	return charactersThatFit;
   817 	}
   818 
   819 TInt CTestFont::DoTextWidthInPixels(const TDesC& aText) const
   820 	{
   821 	TInt excess;
   822 	TextCount(aText, 0, excess);
   823 	return excess;
   824 	}
   825 
   826 TInt CTestFont::DoBaselineOffsetInPixels() const
   827 	{
   828 	return 10;
   829 	}
   830 
   831 TInt CTestFont::DoTextCount(const TDesC& aText,TInt aWidthInPixels) const
   832 	{
   833 	TInt excess;
   834 	return TextCount(aText, aWidthInPixels, excess);
   835 	}
   836 
   837 TInt CTestFont::DoMaxCharWidthInPixels() const
   838 	{
   839 	return 10;
   840 	}
   841 
   842 TInt CTestFont::DoMaxNormalCharWidthInPixels() const
   843 	{
   844 	return 10;
   845 	}
   846 
   847 TFontSpec CTestFont::DoFontSpecInTwips() const
   848 	{
   849 	return TFontSpec(KTestFontName, 12);
   850 	}
   851  
   852 CFont::TCharacterDataAvailability 
   853 CTestFont::DoGetCharacterData(TUint aCode, TOpenFontCharMetrics& aMetrics,
   854 	const TUint8*& aBitmap, TSize& aBitmapSize) const
   855 	{
   856 	TInt width;
   857 	switch (aCode)
   858 		{
   859 	case 0x001B:
   860 		// ESC character should cause this fault; no character data available.
   861 		return CFont::ENoCharacterData;
   862 	case 'W':
   863 		// We want 'W' to have side-bearings
   864 		CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
   865 		width = aMetrics.Width();
   866 		aMetrics.SetHorizBearingX(-1);
   867 		aMetrics.SetWidth(width + 2);
   868 		return CFont::ECharacterWidthOnly ;
   869 	case '/':
   870 		// We want / to have a left side-bearing
   871 		CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
   872 		width = aMetrics.Width();
   873 		aMetrics.SetHorizBearingX(-1);
   874 		aMetrics.SetWidth(width + 1);
   875 		return CFont::ECharacterWidthOnly ;
   876 	case 'D':
   877 		// We want 'D' to have a left side-bearing only
   878 		CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
   879 		aMetrics.SetHorizBearingX(-1);
   880 		return CFont::ECharacterWidthOnly ;
   881 	case KTav:
   882 		// We want Hebrew Tav to have a +ve left side-bearing
   883 		CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
   884 		aMetrics.SetHorizBearingX(1);
   885 		return CFont::ECharacterWidthOnly ;
   886 	case KFullWidthSolidus:
   887 		// We want fw/ to have a right side-bearing
   888 		CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
   889 		width = aMetrics.Width();
   890 		aMetrics.SetWidth(width + 1);
   891 		return CFont::ECharacterWidthOnly ;
   892 	case KArabicWaw:
   893 		// Arabic Waw-- has massive left side-bearing
   894 		CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
   895 		width = aMetrics.Width();
   896 		aMetrics.SetHorizBearingX(-5);
   897 		aMetrics.SetWidth(width + 5);
   898 		return CFont::ECharacterWidthOnly ;
   899 	default:
   900 		return CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
   901 		}
   902 	}
   903