--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/textformatting/test/src/TGraphicsContext.cpp Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,903 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "TGraphicsContext.h"
+#include <e32std.h>
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <graphics/gdi/gdiconsts.h>
+#include <graphics/gdi/gdistructs.h>
+#endif
+
+_LIT(KTestFontName, "Non Functional Test Font");
+
+
+// Utility functions to show contents of test data using test.Printf
+
+extern void PrintTestData (const TDesC& aTitle , const TDesC16& aDataBuffer);
+
+extern void PrintTestData(const TDesC& aTitle, const TText16* aDataBuffer, const TInt aSize);
+
+//
+//
+// CLineArray
+//
+//
+CLineArray::CLineArray() : iArrayIsEnabled(ETrue), iArray(0)
+ {
+ iPrev = iNext = this;
+ }
+
+void CLineArray::Null()
+ {
+ if (iNext == this && iArray)
+ {
+ iArray->Close();
+ delete iArray;
+ }
+ iArray = 0;
+ iPrev->iNext = iNext;
+ iNext->iPrev = iPrev;
+ iNext = iPrev = this;
+ }
+
+CLineArray::~CLineArray()
+ {
+ Null();
+ }
+
+void CLineArray::ConstructL(TInt aGranularity)
+ {
+ CLineArray::Null();
+ iArray = new (ELeave) RArray<TTestGCDisplayLine>(aGranularity);
+ }
+
+void CLineArray::Copy(const CLineArray& aOther)
+ {
+ CLineArray::Null();
+ iNext = &aOther;
+ iPrev = aOther.iPrev;
+ iPrev->iNext = this;
+ aOther.iPrev = this;
+ iArray = aOther.iArray;
+ iArrayIsEnabled = aOther.iArrayIsEnabled;
+ }
+
+void CLineArray::ResetLineArray()
+ {
+ iArray->Reset();
+ }
+
+const TTestGCDisplayLine& CLineArray::Line(TInt aIndex)
+ {
+ return (*iArray)[aIndex];
+ }
+
+const TTestGCDisplayLine* CLineArray::Find(const TDesC& aText)
+ {
+ TInt count = LinesPresent();
+ for (TInt i = 0; i != count; ++i)
+ {
+ const TTestGCDisplayLine& line = Line(i);
+ if (line.iLineData.Find(aText) != KErrNotFound)
+ return &line;
+ }
+ return 0;
+ }
+
+void CLineArray::AddLineL(TTestGCDisplayLine& aLine)
+ {
+ if (iArrayIsEnabled)
+ User::LeaveIfError(iArray->Append(aLine));
+ }
+
+TInt CLineArray::LinesPresent()
+ {
+ return iArray->Count();
+ }
+
+//
+//
+// CTestGraphicsDevice
+//
+//
+CTestGraphicsDevice* CTestGraphicsDevice::NewL(TSize aSizeInPixels, RWsSession* aWsSession)
+ {
+ CTestGraphicsDevice* r = aWsSession?
+ new (ELeave) CTestGraphicsDevice(aSizeInPixels, aWsSession)
+ : new (ELeave) CTestGraphicsDevice(aSizeInPixels);
+ r->iLineArray.ConstructL(4);
+ if (aWsSession && KErrNone != r->Construct())
+ {
+ delete r;
+ return 0;
+ }
+ return r;
+ }
+
+CTestGraphicsDevice::CTestGraphicsDevice(TSize aSizeInPixels, RWsSession* aWsSession)
+ : CWsScreenDevice(*aWsSession)
+ {
+ Set(aSizeInPixels);
+ }
+
+CTestGraphicsDevice::CTestGraphicsDevice(TSize aSizeInPixels)
+ {
+ Set(aSizeInPixels);
+ }
+
+void CTestGraphicsDevice::Set(TSize aSizeInPixels)
+ {
+ iSize = aSizeInPixels;
+ iHorizontalTwipsToPixels = 40;
+ iVerticalTwipsToPixels = 40;
+ iPalette.SetEntry(0, KRgbBlack);
+ iPalette.SetEntry(1, KRgbWhite);
+ iPalette.SetEntry(2, KRgbMagenta);
+ iPalette.SetEntry(3, KRgbCyan);
+ }
+
+void CTestGraphicsDevice::SetHorizontalTwipsToPixels(TInt aTwipsToPixels)
+ {
+ iHorizontalTwipsToPixels = aTwipsToPixels;
+ }
+
+void CTestGraphicsDevice::SetVerticalTwipsToPixels(TInt aTwipsToPixels)
+ {
+ iVerticalTwipsToPixels = aTwipsToPixels;
+ }
+
+TDisplayMode CTestGraphicsDevice::DisplayMode() const
+ {
+ return EColor16M;
+ }
+
+TSize CTestGraphicsDevice::SizeInPixels() const
+ {
+ return iSize;
+ }
+
+TSize CTestGraphicsDevice::SizeInTwips() const
+ {
+ return TSize(iSize.iWidth * iHorizontalTwipsToPixels,
+ iSize.iHeight * iVerticalTwipsToPixels);
+ }
+
+TInt CTestGraphicsDevice::CreateContext(CWindowGc*& aGC)
+ {
+ CTestGraphicsContext* r = new CTestGraphicsContext(this);
+ if (!r)
+ return KErrNoMemory;
+ // only contruct if it is a fully-fledged Window Server thing
+ if (iBuffer)
+ r->Construct();
+ aGC = r;
+ return KErrNone;
+ }
+
+TInt CTestGraphicsDevice::CreateContext(CGraphicsContext*& aGC)
+ {
+ CWindowGc* p;
+ TInt r = CreateContext(p);
+ aGC = p;
+ return r;
+ }
+
+TInt CTestGraphicsDevice::NumTypefaces() const
+ {
+ return 1;
+ }
+
+void CTestGraphicsDevice::TypefaceSupport(TTypefaceSupport& aTypefaceSupport, TInt aTypefaceIndex) const
+ {
+ // The only font we have at the moment is 10 pixels * 12 pixels for every character
+ __ASSERT_ALWAYS(aTypefaceIndex == 0,
+ CTestGraphicsContext::Panic(CTestGraphicsContext::ETypefaceIndexOutOfRange));
+ aTypefaceSupport.iIsScalable = EFalse;
+ aTypefaceSupport.iMaxHeightInTwips = iVerticalTwipsToPixels * 12;
+ aTypefaceSupport.iMinHeightInTwips = iVerticalTwipsToPixels * 10;
+ aTypefaceSupport.iNumHeights = 1;
+ aTypefaceSupport.iTypeface.iName = KTestFontName;
+ aTypefaceSupport.iTypeface.SetIsProportional(ETrue); // a bit of a lie
+ aTypefaceSupport.iTypeface.SetIsSerif(EFalse);
+ aTypefaceSupport.iTypeface.SetIsSymbol(EFalse);
+ }
+
+TInt CTestGraphicsDevice::FontHeightInTwips(TInt aTypefaceIndex, TInt aHeightIndex) const
+ {
+ // The only font we have at the moment is 10 pixels * 12 pixels for every character
+ __ASSERT_ALWAYS(aTypefaceIndex == 0,
+ CTestGraphicsContext::Panic(CTestGraphicsContext::ETypefaceIndexOutOfRange));
+ return iVerticalTwipsToPixels * FontHeightInPixels(aTypefaceIndex, aHeightIndex);
+ }
+
+void CTestGraphicsDevice::PaletteAttributes(TBool& aModifiable, TInt& aNumEntries) const
+ {
+ aModifiable = ETrue;
+ aNumEntries = 4;
+ }
+
+void CTestGraphicsDevice::SetPalette(CPalette* aPalette)
+ {
+ for (TInt i = 0; i != CTestPalette::KNumEntries; ++i)
+ {
+ TRgb col = aPalette->GetEntry(i);
+ iPalette.SetEntry(i, col);
+ }
+ }
+
+TInt CTestGraphicsDevice::GetPalette(CPalette*& aPalette) const
+ {
+ aPalette = const_cast<CTestPalette*>(&iPalette);
+ return KErrNone;
+ }
+
+void CTestGraphicsDevice::GetPixel(TRgb& aColor, const TPoint&) const
+ {
+ aColor = KRgbWhite;
+ }
+
+void CTestGraphicsDevice::GetScanLine(TDes8&, const TPoint&, TInt, TDisplayMode) const
+ {
+ __ASSERT_DEBUG(0, CTestGraphicsContext::Panic(CTestGraphicsContext::EUnimplemented));
+ }
+
+TInt CTestGraphicsDevice::AddFile(const TDesC&, TInt&)
+ {
+ return KErrNotSupported;
+ }
+
+void CTestGraphicsDevice::RemoveFile(TInt)
+ {
+ }
+
+TInt CTestGraphicsDevice::GetNearestFontInPixels(CFont*& aFont, const TFontSpec&)
+ {
+ CTestFont* font = new CTestFont();
+ if (!font)
+ return KErrNoMemory;
+ aFont = font;
+ return KErrNone;
+ }
+
+TInt CTestGraphicsDevice::FontHeightInPixels(TInt, TInt) const
+ {
+ return 12;
+ }
+
+TInt CTestGraphicsDevice::HorizontalTwipsToPixels(TInt aTwips) const
+ {
+ return aTwips / iHorizontalTwipsToPixels;
+ }
+
+TInt CTestGraphicsDevice::VerticalTwipsToPixels(TInt aTwips) const
+ {
+ return aTwips / iVerticalTwipsToPixels;
+ }
+
+TInt CTestGraphicsDevice::HorizontalPixelsToTwips(TInt aPixels) const
+ {
+ return aPixels * iHorizontalTwipsToPixels;
+ }
+
+TInt CTestGraphicsDevice::VerticalPixelsToTwips(TInt aPixels) const
+ {
+ return aPixels * iVerticalTwipsToPixels;
+ }
+
+TInt CTestGraphicsDevice::GetNearestFontInTwips(CFont*& aFont, const TFontSpec& aFontSpec)
+ {
+ TFontSpec fontSpec = aFontSpec;
+ fontSpec.iHeight = VerticalTwipsToPixels(fontSpec.iHeight);
+ return GetNearestFontInPixels(aFont, fontSpec);
+ }
+
+void CTestGraphicsDevice::ReleaseFont(CFont* aFont)
+ {
+ __ASSERT_ALWAYS(aFont->TypeUid() == TUid::Uid(12345),
+ CTestGraphicsContext::Panic(CTestGraphicsContext::EUnknownFont));
+ delete static_cast<CTestFont*>(aFont);
+ }
+
+void CTestGraphicsDevice::AddRectToDrawnArea(const TRect& aRect, TBool aCondition)
+ {
+ // check if the drawing is on testing area
+ if (!(iTestingArea.IsEmpty()) && // if testing area has been set
+ !iHasDrawnOnTestingArea) // and nothing hasn't been drawn on it so far
+ iHasDrawnOnTestingArea = iTestingArea.Intersects(aRect);
+
+ if (iDrawnArea.IsEmpty())
+ iDrawnArea = aRect;
+ else
+ iDrawnArea.BoundingRect(aRect);
+ // only one condition at the moment
+ if (aCondition)
+ {
+ if (iAreaDrawnWithCondition.IsEmpty())
+ iAreaDrawnWithCondition = aRect;
+ else
+ iAreaDrawnWithCondition.BoundingRect(aRect);
+ }
+ }
+
+void CTestGraphicsDevice::SetTestingArea(TRect& aTestingArea)
+ {
+ iTestingArea = aTestingArea;
+ }
+
+void CTestGraphicsDevice::AddTestingArea(TRect& moreTestingArea)
+ {
+ if (iTestingArea.IsEmpty())
+ iTestingArea = moreTestingArea;
+ else
+ iTestingArea.BoundingRect(moreTestingArea);
+ }
+
+//
+//
+// CTestGraphicsContext
+//
+//
+void CTestGraphicsContext::Panic(TInt aReason)
+ {
+ User::Panic(_L("CTestGC"), aReason);
+ }
+
+CTestGraphicsContext::CTestGraphicsContext(CTestGraphicsDevice* aGd)
+ : CWindowGc(aGd), iGd(aGd), iDrawMode(EDrawModePEN), iPenSize(1,1)
+ {
+ iLineArray.Copy(aGd->LineArray());
+ }
+
+TInt CTestGraphicsContext::Construct()
+ {
+ return CWindowGc::Construct();
+ }
+
+void CTestGraphicsContext::AddRectToDrawnArea(const TRect& aRect)
+ {
+ TRect drawnRect = aRect;
+ drawnRect.Grow(iPenSize);
+ iGd->AddRectToDrawnArea(drawnRect,
+ iDrawMode == EDrawModeXOR || iDrawMode == EDrawModeNOTSCREEN);
+ }
+
+void CTestGraphicsContext::AddPointToDrawnArea(const TPoint& aPoint)
+ {
+ AddRectToDrawnArea(TRect(aPoint, iPenSize));
+ }
+
+CGraphicsDevice* CTestGraphicsContext::Device() const
+ {
+ return iGd;
+ }
+
+void CTestGraphicsContext::SetOrigin(const TPoint& aPos)
+ {
+ iOrigin = aPos;
+ }
+
+void CTestGraphicsContext::SetDrawMode(TDrawMode aDrawingMode)
+ {
+ iDrawMode = aDrawingMode;
+ }
+
+void CTestGraphicsContext::SetClippingRect(const TRect& /*aRect*/)
+ {
+ }
+
+void CTestGraphicsContext::CancelClippingRect()
+ {
+ }
+
+TInt CTestGraphicsContext::SetClippingRegion(const TRegion& /*aRegion*/)
+ {
+ return KErrNone;
+ }
+
+void CTestGraphicsContext::CancelClippingRegion()
+ {
+ }
+
+void CTestGraphicsContext::Reset()
+ {
+ iDrawMode = EDrawModePEN;
+ iFont = 0;
+ iPenSize.iWidth = 1;
+ iPenSize.iHeight = 1;
+ }
+
+void CTestGraphicsContext::UseFont(const CFont* aFont)
+ {
+ iFont = aFont;
+ }
+
+void CTestGraphicsContext::DiscardFont()
+ {
+ iFont = 0;
+ }
+
+void CTestGraphicsContext::SetUnderlineStyle(TFontUnderline /*UnderlineStyle*/)
+ {
+ }
+
+void CTestGraphicsContext::SetStrikethroughStyle(TFontStrikethrough /*aStrikethroughStyle*/)
+ {
+ }
+
+void CTestGraphicsContext::SetWordJustification(TInt /*aExcessWidth*/,TInt /*aNumGaps*/)
+ {
+ }
+
+void CTestGraphicsContext::SetCharJustification(TInt /*aExcessWidth*/,TInt /*aNumChars*/)
+ {
+ }
+
+void CTestGraphicsContext::SetPenColor(const TRgb& aColor)
+ {
+ CPalette* palette;
+ iGd->GetPalette(palette);
+ iPenColorIndex = palette->NearestIndex(aColor);
+ }
+
+void CTestGraphicsContext::SetPenStyle(TPenStyle /*aPenStyle*/)
+ {
+ }
+
+void CTestGraphicsContext::SetPenSize(const TSize& aSize)
+ {
+ iPenSize = aSize;
+ }
+
+void CTestGraphicsContext::SetBrushColor(const TRgb& /*aColor*/)
+ {
+ }
+
+void CTestGraphicsContext::SetBrushStyle(TBrushStyle /*aBrushStyle*/)
+ {
+ }
+
+void CTestGraphicsContext::SetBrushOrigin(const TPoint& /*aOrigin*/)
+ {
+ }
+
+void CTestGraphicsContext::UseBrushPattern(const CFbsBitmap* /*aBitmap*/)
+ {
+ }
+
+void CTestGraphicsContext::DiscardBrushPattern()
+ {
+ }
+
+void CTestGraphicsContext::MoveTo(const TPoint& aPoint)
+ {
+ iCurrentPos = iOrigin + aPoint;
+ }
+
+void CTestGraphicsContext::MoveBy(const TPoint& aVector)
+ {
+ iCurrentPos += aVector;
+ }
+
+void CTestGraphicsContext::Plot(const TPoint& aPoint)
+ {
+ iCurrentPos = iOrigin + aPoint;
+ AddPointToDrawnArea(iCurrentPos);
+ }
+
+void CTestGraphicsContext::DrawArc(const TRect& aRect,const TPoint& /*aStart*/,const TPoint& aEnd)
+ {
+ TRect r = aRect;
+ r.Move(iOrigin);
+ AddRectToDrawnArea(r);
+ iCurrentPos = iOrigin + aEnd;
+ }
+
+void CTestGraphicsContext::DrawLine(const TPoint& aPoint1,const TPoint& aPoint2)
+ {
+ AddPointToDrawnArea(iOrigin + aPoint1);
+ iCurrentPos = iOrigin + aPoint2;
+ AddPointToDrawnArea(iCurrentPos);
+ }
+
+void CTestGraphicsContext::DrawLineTo(const TPoint& aPoint)
+ {
+ AddPointToDrawnArea(iCurrentPos);
+ iCurrentPos = iOrigin + aPoint;
+ AddPointToDrawnArea(iCurrentPos);
+ }
+
+void CTestGraphicsContext::DrawLineBy(const TPoint& aVector)
+ {
+ AddPointToDrawnArea(iCurrentPos);
+ iCurrentPos += aVector;
+ AddPointToDrawnArea(iCurrentPos);
+ }
+
+void CTestGraphicsContext::DrawPolyLine(const CArrayFix<TPoint>* aPointList)
+ {
+ TInt num = aPointList->Count();
+ while (num--)
+ {
+ iCurrentPos = iOrigin + (*aPointList)[num - 1];
+ AddPointToDrawnArea(iCurrentPos);
+ }
+ }
+
+void CTestGraphicsContext::DrawPolyLine(const TPoint* aPointList,TInt aNumPoints)
+ {
+ while (aNumPoints--)
+ {
+ iCurrentPos = iOrigin + aPointList[aNumPoints - 1];
+ AddPointToDrawnArea(iCurrentPos);
+ }
+ }
+
+void CTestGraphicsContext::DrawPie(const TRect& aRect,
+ const TPoint& /*aStart*/, const TPoint& aEnd)
+ {
+ TRect r = aRect;
+ r.Move(iOrigin);
+ AddRectToDrawnArea(r);
+ iCurrentPos = iOrigin + aEnd;
+ }
+
+void CTestGraphicsContext::DrawEllipse(const TRect& aRect)
+ {
+ TRect r = aRect;
+ r.Move(iOrigin);
+ AddRectToDrawnArea(r);
+ }
+
+void CTestGraphicsContext::DrawRect(const TRect& aRect)
+ {
+ TRect r = aRect;
+ r.Move(iOrigin);
+ AddRectToDrawnArea(r);
+ }
+
+void CTestGraphicsContext::DrawRoundRect(const TRect& aRect,const TSize& aCornerSize)
+ {
+ TRect r = aRect;
+ r.Move(iOrigin);
+ r.Grow(aCornerSize);
+ AddRectToDrawnArea(r);
+ }
+
+TInt CTestGraphicsContext::DrawPolygon(const CArrayFix<TPoint>* aPointList,TFillRule /*aFillRule*/)
+ {
+ TInt num = aPointList->Count();
+ while (num--)
+ {
+ iCurrentPos = iOrigin + (*aPointList)[num - 1];
+ AddPointToDrawnArea(iCurrentPos);
+ }
+ return KErrNone;
+ }
+
+TInt CTestGraphicsContext::DrawPolygon(const TPoint* aPointList,TInt aNumPoints,TFillRule /*aFillRule*/)
+ {
+ while (aNumPoints--)
+ {
+ iCurrentPos = iOrigin + aPointList[aNumPoints - 1];
+ AddPointToDrawnArea(iCurrentPos);
+ }
+ return KErrNone;
+ }
+
+void CTestGraphicsContext::DrawBitmap(const TPoint& /*aTopLeft*/,const CFbsBitmap* /*aSource*/)
+ {
+ }
+
+void CTestGraphicsContext::DrawBitmap(const TRect& /*aDestRect*/,const CFbsBitmap* /*aSource*/)
+ {
+ }
+
+void CTestGraphicsContext::DrawBitmap(const TRect& /*aDestRect*/,const CFbsBitmap* /*aSource*/,const TRect& /*aSourceRect*/)
+ {
+ }
+
+void CTestGraphicsContext::DrawText(const TDesC& aText, const TPoint& aPosition)
+ {
+#ifdef PRINT_DRAWTEXT_LINES
+
+ _LIT(KDrawTextTitle, "Text being drawn");
+ PrintTestData(KDrawTextTitle, aText);
+
+#endif /* PRINT_DRAWTEXT_LINES */
+
+ TTestGCDisplayLine thisLine;
+ thisLine.Set(aPosition, aText);
+ iLineArray.AddLineL(thisLine);
+ }
+
+void CTestGraphicsContext::DrawText(const TDesC& aText,const TRect& aBox,TInt aBaselineOffset,
+ TTextAlign /*aAlignment*/, TInt aLeftMargin)
+ {
+ TPoint pos(aBox.iBr.iX + aLeftMargin, aBox.iTl.iY + aBaselineOffset);
+ pos += iOrigin;
+ DrawText(aText, pos);
+ }
+
+void CTestGraphicsContext::DrawText(const TDesC& aText,TTextParameters* aParam, const TPoint& aPosition)
+ {
+#ifdef PRINT_DRAWTEXT_LINES
+
+ _LIT(KDrawTextTitle, "Text being drawn");
+ PrintTestData(KDrawTextTitle, aText);
+
+#endif /* PRINT_DRAWTEXT_LINES */
+
+ //Avoid crash by ASSERT in BitGdi DrawText function
+ __ASSERT_ALWAYS(aParam->iStart < aParam->iEnd,
+ CTestGraphicsContext::Panic(CTestGraphicsContext::EErrorParameter));
+
+ TTestGCDisplayLine thisLine;
+ TPtrC actualText = aText.Mid(aParam->iStart,aParam->iEnd - aParam->iStart + 1);
+ thisLine.Set(aPosition, actualText);
+ iLineArray.AddLineL(thisLine);
+ }
+
+void CTestGraphicsContext::DrawText(const TDesC& aText,TTextParameters* aParam,const TRect& aBox,TInt aBaselineOffset,
+ TTextAlign /*aAlignment*/, TInt aLeftMargin)
+ {
+ TPoint pos(aBox.iBr.iX + aLeftMargin, aBox.iTl.iY + aBaselineOffset);
+ pos += iOrigin;
+ DrawText(aText,aParam, pos);
+ }
+
+TInt CTestGraphicsContext::APIExtension(TUid aUid, TAny*& aOutput, TAny* aInput)
+ {
+ if (aUid == KDrawTextInContextUid)
+ {
+ TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
+ DrawText(contextParam->iText, &contextParam->iParam, contextParam->iPosition);
+ return KErrNone;
+ }
+ else if (aUid == KDrawBoxTextInContextUid)
+ {
+ TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput;
+ DrawText(contextParam->iText,&contextParam->iParam,contextParam->iBox,contextParam->iBaselineOffset,contextParam->iAlign,contextParam->iMargin);
+ return KErrNone;
+ }
+ // Future cases may be placed here later
+ else
+ return CWindowGc::APIExtension(aUid, aOutput, aInput);
+ }
+
+
+void CTestGraphicsContext::Clear()
+ {
+ }
+
+void CTestGraphicsContext::Clear(const TRect& /*aRect*/)
+ {
+ }
+
+void CTestGraphicsContext::CopyRect(const TPoint& /*aOffset*/, const TRect& /*aRect*/)
+ {
+ }
+
+void CTestGraphicsContext::BitBlt(const TPoint& /*aPoint*/, const CFbsBitmap* /*aBitmap*/)
+ {
+ }
+
+void CTestGraphicsContext::BitBlt(const TPoint& /*aPoint*/, const CFbsBitmap* /*aBitmap*/,
+ const TRect& /*aRect*/)
+ {
+ }
+
+void CTestGraphicsContext::BitBltMasked(const TPoint& /*aPoint*/, const CFbsBitmap* /*aBitmap*/,
+ const TRect& /*aSourceRect*/, const CFbsBitmap* /*aMaskBitmap*/, TBool /*aInvertMask*/)
+ {
+ }
+
+void CTestGraphicsContext::SetFaded(TBool)
+ {
+ }
+
+void CTestGraphicsContext::SetFadingParameters(TUint8,TUint8)
+ {
+ }
+
+//
+//
+// CTestFont
+//
+//
+inline TBool IsSurrogate(TText a) { return 0xD800 == (a & 0xF800); }
+inline TBool IsHighSurrogate(TText a) { return 0xD800 == (a & 0xFC00); }
+inline TBool IsLowSurrogate(TText a) { return 0xDC00 == (a & 0xFC00); }
+inline TChar PairSurrogates(TText aHigh, TText aLow)
+ {
+ return ((aHigh - 0xd7f7) << 10) + aLow;
+ }
+
+TUid CTestFont::DoTypeUid() const
+ {
+ return TUid::Uid(12345);
+ }
+
+TInt CTestFont::DoHeightInPixels() const
+ {
+ return 12;
+ }
+
+TInt CTestFont::DoAscentInPixels() const
+ {
+ return 10;
+ }
+
+struct TSpecialSizes
+ {
+ TInt iCharacter;
+ TInt iWidth;
+ };
+
+static const TSpecialSizes KSpecialSizes[] =
+ {
+ { CTestFont::KThreePerEmSpace, 3 },
+ { CTestFont::KThinSpace, 2 },
+ { CTestFont::KHairSpace, 1 },
+ { CTestFont::KZeroWidthSpace, 0 },
+ { CTestFont::KZeroWidthNoBreakSpace, 0 },
+ };
+
+TInt CTestFont::DoCharWidthInPixels(TChar aChar) const
+ {
+ TInt cn = aChar;
+ // non-characters 0x??FFFE and 0x??FFFF
+ if ((cn & 0xFFFE) == 0xFFFE)
+ return 0;
+
+ // Find character in the special sizes table
+ TInt first = 0;
+ TInt last = sizeof(KSpecialSizes)/sizeof(KSpecialSizes[0]);
+ while (first != last)
+ {
+ TInt c = static_cast<TInt>(aChar);
+ TInt mid = (first + last) >> 1;
+ if (c < KSpecialSizes[mid].iCharacter)
+ last = mid;
+ else if (KSpecialSizes[mid].iCharacter < c)
+ first = mid + 1;
+ else
+ return KSpecialSizes[mid].iWidth;
+ }
+
+ return 10;
+ }
+
+TInt CTestFont::DoTextCount(const TDesC& aText, TInt aWidthInPixels,
+ TInt& aExcessWidthInPixels) const
+ {
+ const TText* p = &aText[0];
+ const TText* pEnd = p + aText.Length();
+ TInt total = 0;
+ TInt prevSurrogate = 0;
+ TInt charactersThatFit = 0;
+ while (p != pEnd)
+ {
+ TChar c = *p;
+ if (IsSurrogate(*p))
+ {
+ c = 0xFFFF;
+ if (IsHighSurrogate(*p))
+ prevSurrogate = *p;
+ else if (prevSurrogate != 0)
+ {
+ c = PairSurrogates(static_cast<TText>(prevSurrogate), *p);
+ prevSurrogate = 0;
+ }
+ }
+ else
+ prevSurrogate = 0;
+ total += CharWidthInPixels(c);
+ if (total <= aWidthInPixels)
+ ++charactersThatFit;
+ ++p;
+ }
+ aExcessWidthInPixels = total - aWidthInPixels;
+ return charactersThatFit;
+ }
+
+TInt CTestFont::DoTextWidthInPixels(const TDesC& aText) const
+ {
+ TInt excess;
+ TextCount(aText, 0, excess);
+ return excess;
+ }
+
+TInt CTestFont::DoBaselineOffsetInPixels() const
+ {
+ return 10;
+ }
+
+TInt CTestFont::DoTextCount(const TDesC& aText,TInt aWidthInPixels) const
+ {
+ TInt excess;
+ return TextCount(aText, aWidthInPixels, excess);
+ }
+
+TInt CTestFont::DoMaxCharWidthInPixels() const
+ {
+ return 10;
+ }
+
+TInt CTestFont::DoMaxNormalCharWidthInPixels() const
+ {
+ return 10;
+ }
+
+TFontSpec CTestFont::DoFontSpecInTwips() const
+ {
+ return TFontSpec(KTestFontName, 12);
+ }
+
+CFont::TCharacterDataAvailability
+CTestFont::DoGetCharacterData(TUint aCode, TOpenFontCharMetrics& aMetrics,
+ const TUint8*& aBitmap, TSize& aBitmapSize) const
+ {
+ TInt width;
+ switch (aCode)
+ {
+ case 0x001B:
+ // ESC character should cause this fault; no character data available.
+ return CFont::ENoCharacterData;
+ case 'W':
+ // We want 'W' to have side-bearings
+ CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
+ width = aMetrics.Width();
+ aMetrics.SetHorizBearingX(-1);
+ aMetrics.SetWidth(width + 2);
+ return CFont::ECharacterWidthOnly ;
+ case '/':
+ // We want / to have a left side-bearing
+ CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
+ width = aMetrics.Width();
+ aMetrics.SetHorizBearingX(-1);
+ aMetrics.SetWidth(width + 1);
+ return CFont::ECharacterWidthOnly ;
+ case 'D':
+ // We want 'D' to have a left side-bearing only
+ CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
+ aMetrics.SetHorizBearingX(-1);
+ return CFont::ECharacterWidthOnly ;
+ case KTav:
+ // We want Hebrew Tav to have a +ve left side-bearing
+ CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
+ aMetrics.SetHorizBearingX(1);
+ return CFont::ECharacterWidthOnly ;
+ case KFullWidthSolidus:
+ // We want fw/ to have a right side-bearing
+ CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
+ width = aMetrics.Width();
+ aMetrics.SetWidth(width + 1);
+ return CFont::ECharacterWidthOnly ;
+ case KArabicWaw:
+ // Arabic Waw-- has massive left side-bearing
+ CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
+ width = aMetrics.Width();
+ aMetrics.SetHorizBearingX(-5);
+ aMetrics.SetWidth(width + 5);
+ return CFont::ECharacterWidthOnly ;
+ default:
+ return CFont::DoGetCharacterData(aCode, aMetrics, aBitmap, aBitmapSize);
+ }
+ }
+