--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/graphicsdeviceinterface/directgdi/src/directgdicontext.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,3588 @@
+// Copyright (c) 2007-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 "directgdicontext.h"
+#include "directgdipaniccodes.h"
+#include "directgdifont.h"
+#include "directgdidriver.h"
+#include <graphics/directgdidrawablesource.h>
+#include <graphics/directgdiengine.h>
+#include <e32cmn.h>
+#include <s32mem.h>
+#include <shapeinfo.h>
+#include <fbs.h>
+#include <fntstore.h>
+
+using namespace DirectGdi;
+
+/**
+CDirectGdiContext InternalizeL/ExternalizeL - version numbers.
+Add new version numbers here. A reason of adding new version numbers may be adding new
+CDirectGdiContext data members, which may have to be externalized/internalized.
+When that happens:
+1.Put a new enum item (like EDirectGDIContext_Ver01) with a version number, which is greater than
+the last version number, that was used.
+2.Document the new enum item.
+3.Update KDirectGDIContext_VerNo value to be the new enum item value.
+4.Update InternalizeL/ExternalizeL methods after adding the new version number.
+For example: If a new member is added to the class - TInt iSmth, when InternalizeL
+is called to operate on older archive, iSmth member won't be in the archive!
+So, in InternalizeL, there should be a check, something like:
+TUint16 archiveVerNo = 0;
+ aReadStream >> archiveVerNo;
+ if(archiveVerNo < EDirectGDIContext_Ver02) //EDirectGDIContext_Ver02 has been added, when iSmth has been added
+ {
+ //Do nothing - iSmth is not in the archive
+ //Initialize it with some default value
+ iSmth = KDefVal;
+ }
+ else
+ {
+ aReadStream >> iSmth;
+ }
+*/
+enum
+ {
+ EDirectGDIContext_Ver01 = 1 //Base version number, when InternalizeL/ExternalizeL were added
+ };
+
+LOCAL_D const TUint16 KDirectGDIContext_VerNo = EDirectGDIContext_Ver01;
+
+/**
+Static two-phase factory constuctor. Creates an object of this class.
+
+@param aDirectGdiDriver The driver object which provides an abstract factory for creating a concrete drawing engine.
+
+@pre CDirectGdiDriver object has been initialised from the calling thread.
+@post Instances of CDirectGdiContext and MDirectGdiEngine have been created.
+
+@leave Leaves if CDirectGdiDriver has not been initialised from the calling thread, or other errors occur during object construction.
+@return Reference to constructed CDirectGdiContext.
+*/
+EXPORT_C CDirectGdiContext* CDirectGdiContext::NewL(CDirectGdiDriver& aDirectGdiDriver)
+ {
+ CDirectGdiContext* result = new(ELeave) CDirectGdiContext(aDirectGdiDriver);
+ CleanupStack::PushL(result);
+
+ // Cache a reference to the driver locally, so that we do not need to use
+ // the singleton accessor all the time. The singleton accessor utilises TLS
+ // and hence incurs a performance penalty.
+ //
+ result->ConstructL();
+
+ CleanupStack::Pop();
+ return result;
+ }
+
+
+/**
+Installs a rendering engine instance from the supplied driver, records
+a reference to the driver (for use by the destructor), and initialises it.
+
+@pre Invoked by NewL().
+@post Instance of MDirectGdiEngine has been created.
+
+@leave If CDirectGdiDriver::CreateEngine() returns an error code.
+*/
+void CDirectGdiContext::ConstructL()
+ {
+ User::LeaveIfError(iDriver.CreateEngine(iEngine));
+ Reset(); // Initialise context and engine to default values.
+ }
+
+
+/**
+Object constructor. Declared private for better encapsulation. A factory method is
+provided to instantiate this class. This class is not intended for derivation. Binary
+compatibility needs to be maintained.
+
+@param aDirectGdiDriver The driver that coordinates management of DirectGDI resources.
+
+@pre The driver must be initialised.
+@post None.
+*/
+EXPORT_C CDirectGdiContext::CDirectGdiContext(CDirectGdiDriver& aDirectGdiDriver) :
+ iDriver(aDirectGdiDriver)
+ {
+ }
+
+
+/**
+Unbind current target from drawing context and mark drawing engine for deletion.
+
+@pre None.
+@post Rendering engine has had targets unbound and is marked for deletion.
+*/
+EXPORT_C CDirectGdiContext::~CDirectGdiContext()
+ {
+ // If an engine has been bound, destroy it through the driver.
+ if (iEngine)
+ {
+ iDriver.DestroyEngine(iEngine);
+ }
+
+ CleanUpBrushPattern();
+ iClippingRegion.Close();
+ }
+
+
+/**
+Binds a rendering target to this drawing context.
+
+Subsequent rendering operations after calling this method will apply to the new rendering
+target. The clipping region will be reset to none, in other words drawing will be clipped to the
+full area of the new target by default, other context states such as pen or brush colour,
+font, etc. will remain unchanged.
+
+This operation could fail, DirectGDI clients should always check the return value when
+calling this method. The error state is not modified by this function.
+
+@param aTarget DirectGDI rendering target.
+
+@pre Rendering target has been fully constructed.
+@post The drawing context is bound to the new rendering target.
+
+@return KErrNone if successful, KErrNotSupported if target is incompatible with the drawing context,
+ otherwise one of the system-wide error codes.
+*/
+EXPORT_C TInt CDirectGdiContext::Activate(RDirectGdiImageTarget& aTarget)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::Activate");
+ TInt err = iEngine->Activate(aTarget);
+
+ iActivated = EFalse;
+ if (err == KErrNone)
+ {
+ iActivated = ETrue;
+ }
+ return err;
+ }
+
+/**
+Disables AutoUpdateJustification state.
+
+@see CDirectGdiContext::SetJustifyAutoUpdate
+*/
+EXPORT_C void CDirectGdiContext::NoJustifyAutoUpdate()
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::NoJustifyAutoUpdate");
+ iAutoUpdateJustification = EFalse;
+ }
+
+/**
+Enables AutoUpdateJustification state.
+During the text drawing, some text parameters which impact on positioning the text on the screen will be updated and applied
+*/
+EXPORT_C void CDirectGdiContext::SetJustifyAutoUpdate()
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::SetJustifyAutoUpdate");
+ iAutoUpdateJustification = ETrue;
+ }
+
+/**
+Draws the whole of a CFbsBitmap. Calls BitBlt() with a rectangle set to the extents of aBitmap.
+
+No scaling or stretching is involved. The current clipping region and drawing mode apply. The
+source bitmap can reside in system memory or ROM. Bitmaps in system memory may be compressed
+using RLE or Palette compression, and can be in any supported display mode. Please refer to
+CFbsBitmap documentation for more details.
+
+If the client modifies the content of the bitmap after issuing a BitBlt() command, the method
+does not guarantee whether the old bitmap content or the new one will be drawn. Clients must call
+Finish() on the driver before modifying the bitmap content if they want a guaranteed result that
+the previously issued BitBlt() will draw the old bitmap content.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@see void CDirectGdiContext::BitBlt(const TPoint& aPoint, const CFbsBitmap* aBitmap, const TRect& aSourceRect);
+@param aDestPos The position to draw the top left corner of the bitmap.
+@param aSourceBitmap The source bitmap.
+
+@pre The rendering target has been activated.
+@post Request to draw the bitmap content has been accepted. There is no guarantee that the request
+ has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::BitBlt(const TPoint& aDestPos, const CFbsBitmap& aSourceBitmap)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::BitBlt(%d,%d)", aDestPos.iX, aDestPos.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (ValidateBitmap (aSourceBitmap))
+ {
+ iEngine->BitBlt(aDestPos, aSourceBitmap, TRect(aSourceBitmap.SizeInPixels()));
+ }
+ }
+
+
+/**
+Draws a particular rectangle from a CFbsBitmap via bitmap block image transfer.
+The bitmap content is specified by the given source rectangle. The bitmap content is drawn
+into the rendering target starting from the given destination position. To draw the content
+of the entire bitmap, a source rectangle TRect(TPoint(0,0), aBitmap.SizeInPixels()) is used.
+
+The source rectangle is intersected with the source bitmap’s full extent, and the intersection
+will become the effective value of the source rectangle.
+
+No scaling or stretching is involved. The current clipping region and drawing mode apply. The
+source bitmap can reside in system memory or ROM. Bitmaps in system memory may be compressed
+using RLE or Palette compression, and can be in any supported display mode. Please refer to
+CFbsBitmap documentation for more details.
+
+The bitmap is not guaranteed to continue to exist outside the implementation of this method, for example
+DirectGDI clients may delete the bitmap immediately after issuing a BitBlt() command. The adaptation
+must maintain its own copy by duplicating the bitmap if access to the bitmap data is required
+later on, for example outside this method implementation. Duplicating the bitmap will increase its
+reference counter and will prevent the object from being destroyed by Fbserv. The adaptation
+must make sure the bitmap copy is destroyed when it is no longer needed.
+
+If the client modifies the content of the bitmap after issuing BitBlt() command, the method
+does not guarantee whether the old bitmap content or the new one will be drawn. Clients must call
+Finish() on the driver before modifying the bitmap content if they want a guaranteed result that
+the previously issued BitBlt() will draw the old bitmap content.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@param aDestPos The position to draw the top left corner of the bitmap (destination position).
+@param aSourceBitmap The source bitmap.
+@param aSourceRect A rectangle defining the piece of the source to be drawn. No image data
+ is transferred if no intersection exists with the bitmap.
+ NOTE: The top and left hand edges are inclusive, the bottom and
+ right hand edge are exclusive.
+
+@pre The rendering target has been activated.
+@post Request to draw the bitmap content has been accepted. There is no guarantee that the request
+ has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::BitBlt(
+ const TPoint& aDestPos,
+ const CFbsBitmap& aSourceBitmap,
+ const TRect& aSourceRect)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::BitBlt(%d,%d)", aDestPos.iX, aDestPos.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (ValidateBitmap(aSourceBitmap))
+ {
+ TRect sourceRect = IntersectBitmapWithRect(aSourceBitmap, aSourceRect);
+ if (!sourceRect.IsEmpty())
+ {
+ iEngine->BitBlt(aDestPos, aSourceBitmap, sourceRect);
+ }
+ }
+ }
+
+/**
+Validates a specified bitmap image.
+The bitmap is deemed invalid if its associated handle equals KNullHandle or it
+has a width or height of zero.
+
+The following errors are set in iDirectGdiDriver if the associated conditions are met:
+ - KErrBadHandle if the handle associated with the bitmap equals KNullHandle.
+ - KErrArgument is the bitmaps width or height is zero.
+
+@param aBitmap The bitmap to validate.
+
+@return ETrue if the specified bitmap is valid, otherwise EFalse.
+*/
+TBool CDirectGdiContext::ValidateBitmap(const CFbsBitmap& aBitmap)
+ {
+ TInt errorCode = KErrNone;
+ TBool result = ETrue;
+
+ if (aBitmap.Handle() == KNullHandle)
+ {
+ errorCode = KErrBadHandle;
+ }
+ else
+ {
+ // Check that mask and source bitmap have width and height.
+ const TSize bitmapSize = aBitmap.SizeInPixels();
+ if (!bitmapSize.iWidth || !bitmapSize.iHeight)
+ {
+ errorCode = KErrArgument;
+ }
+ }
+
+ if (errorCode != KErrNone)
+ {
+ iDriver.SetError(errorCode);
+ result = EFalse;
+ }
+
+ return result;
+ }
+
+/*
+Returns a TRect that intersects both the CFbsBitmap and the passed-in TRect.
+
+@param aBitmap The bitmap to intersect with.
+@param aRect The TRect object that is overlapping the bitmap.
+@return A TRect that represents the intersection of the two. If the two do not intersect,
+ it will be an empty TRect object.
+*/
+TRect CDirectGdiContext::IntersectBitmapWithRect(const CFbsBitmap& aBitmap, const TRect& aRect) const
+ {
+ TRect result = TRect(aBitmap.SizeInPixels());
+
+ if (aRect == result)
+ return result;
+
+ if (result.Intersects(aRect))
+ {
+ result.Intersection(aRect);
+ return result;
+ }
+
+ return TRect(0,0,0,0);
+ }
+
+/**
+
+Validates the specified source bitmap and mask pair.
+First validates the source and mask bitmaps individually, and then checks for valid
+bitmap pairings. The only pairing not supported is: EGray256 masks and sources with
+an alpha-channel when using EDrawModeWriteAlpha.
+
+@see CDirectGdiContext::ValidateBitmap()
+
+The following errors are set in iDirectGdiDriver if the associated conditions are met:
+ - KErrBadHandle if the handle associated with either bitmap equals KNullHandle.
+ - KErrArgument if either bitmaps width or height is zero.
+ - KErrArgument if the mask format is EGray256 and the source contains an alpha-channel and draw mode is EDrawModeWriteAlpha.
+
+@param aSourceBitmap The source bitmap to validate.
+@param aMaskBitmap The mask to validate.
+
+@return ETrue if the specified bitmaps is valid, otherwise EFalse.
+*/
+TBool CDirectGdiContext::ValidateSourceAndMaskBitmaps(const CFbsBitmap& aSourceBitmap, const CFbsBitmap& aMaskBitmap)
+ {
+ TInt errorCode = KErrNone;
+ TBool result = ETrue;
+
+ if (ValidateBitmap (aSourceBitmap) && ValidateBitmap (aMaskBitmap))
+ {
+ TDisplayMode sourceBitmapDisplayMode = aSourceBitmap.DisplayMode();
+
+ // We do not currently support EGray256 masks and sources with an alpha-channel
+ // with EDrawModeWriteAlpha.
+ if ((iDrawMode == DirectGdi::EDrawModeWriteAlpha) &&
+ (aMaskBitmap.DisplayMode() == EGray256) &&
+ ((sourceBitmapDisplayMode == EColor16MA) || (sourceBitmapDisplayMode == EColor16MAP)))
+ {
+ errorCode = KErrArgument;
+ }
+ }
+ else
+ {
+ result = EFalse;
+ }
+
+ if (errorCode != KErrNone)
+ {
+ iDriver.SetError(errorCode);
+ result = EFalse;
+ }
+
+ return result;
+ }
+
+/**
+Helper method for performing BitBltMasked.
+Note that aInvertMask is ignored if aMaskPos is not at 0,0.
+
+@see CDirectGdiContext::BitBlt(const TPoint& aPoint, const CFbsBitmap& aBitmap, const TRect& aSourceRect);
+@see CDirectGdiContext::BitBltMasked(const TPoint&, const CFbsBitmap&,const TRect&, const CFbsBitmap&, const TPoint&);
+
+@param aDestPos The destination for the top left corner of the transferred bitmap.
+ It is relative to the top left corner of the destination bitmap, which may be the screen.
+@param aSourceBitmap A memory-resident source bitmap.
+@param aSourceRect A rectangle defining the piece of the bitmap to be drawn,
+ with co-ordinates relative to the top left corner of the bitmap.
+@param aMaskBitmap Mask bitmap.
+@param aInvertMask If EFalse, a source pixel that is masked by a black pixel is not transferred to
+ the destination rectangle. If ETrue, then a source pixel that is masked by a
+ white pixel is not transferred to the destination rectangle. If alpha blending
+ is used instead of masking, this flag is ignored and no inversion takes place.
+ Note that this parameter is ignored if aMaskPos does not equal TPoint(0,0).
+@param aMaskPos The point on the mask bitmap to use as the top left corner
+*/
+void CDirectGdiContext::DoBitBltMasked(
+ const TPoint& aDestPos,
+ const CFbsBitmap& aSourceBitmap,
+ const TRect& aSourceRect,
+ const CFbsBitmap& aMaskBitmap,
+ TBool aInvertMask,
+ const TPoint& aMaskPos)
+ {
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (ValidateSourceAndMaskBitmaps(aSourceBitmap, aMaskBitmap))
+ {
+ // If the source rectangle does not intersect aBitmap, do nothing.
+ TRect sourceRect = IntersectBitmapWithRect(aSourceBitmap, aSourceRect);
+ if (!sourceRect.IsEmpty())
+ {
+ if (aMaskPos == TPoint(0, 0))
+ {
+ iEngine->BitBltMasked(aDestPos, aSourceBitmap, sourceRect, aMaskBitmap, aInvertMask);
+ }
+ else
+ {
+ TSize maskSize = aMaskBitmap.SizeInPixels();
+ // Convert negative or large mask offsets into sensible positive ones for tiling.
+ TPoint maskOffset(aMaskPos.iX % maskSize.iWidth, aMaskPos.iY % maskSize.iHeight);
+ if (maskOffset.iX < 0)
+ maskOffset.iX += maskSize.iWidth;
+ if (maskOffset.iY < 0)
+ maskOffset.iY += maskSize.iHeight;
+
+ iEngine->BitBltMasked(aDestPos, aSourceBitmap, sourceRect, aMaskBitmap, maskOffset);
+ }
+ }
+ }
+ }
+
+
+/**
+Performs a masked bitmap block transfer. Source rectangle operates in a similar way to BitBlt().
+
+This function uses either a black and white (binary) mask bitmap, or if the mask's display mode is
+EGray256, alpha blending is used. The result is undefined if the mask pixel value is neither black nor
+white and the mask display mode is other than EGray256.
+
+The mask is aligned with the source bitmap by aligning the first pixel of the mask and source bitmaps within
+the source rectangle. Tiling in both directions applies if the mask size is smaller than the source rectangle.
+Note that the mask is applied before the piece of the bitmap is defined - the mask is tiled relative to the
+top left of the original source bitmap rather than the top left of the bitmap piece. If the mask has zero
+width or height, the error state is set to KErrArgument and no drawing is performed.
+
+The mask bitmap can be used as either a positive or negative mask. Masked pixels are not mapped to the
+destination rectangle.
+
+If the client modifies the contents of the bitmap or the mask after issuing the BitBltMasked() command, the
+method does not guarantee whether the old bitmap or mask contents, or the new ones will be used.
+Clients must call Finish() on the driver before modifying the bitmap or mask contents if they want a
+guaranteed result that the previously issued BitBltMasked() will be using the old bitmap or mask contents.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@see CDirectGdiContext::BitBlt(const TPoint& aPoint, const CFbsBitmap& aBitmap, const TRect& aSourceRect);
+@see CDirectGdiContext::BitBltMasked(const TPoint&, const CFbsBitmap&,const TRect&, const CFbsBitmap&, const TPoint&);
+
+@param aDestPos The destination for the top left corner of the transferred bitmap.
+ It is relative to the top left corner of the destination bitmap, which may be the screen.
+@param aSourceBitmap A memory-resident source bitmap.
+@param aSourceRect A rectangle defining the piece of the bitmap to be drawn,
+ with co-ordinates relative to the top left corner of the bitmap.
+@param aMaskBitmap Mask bitmap.
+@param aInvertMask If EFalse, a source pixel that is masked by a black pixel is not transferred to
+ the destination rectangle. If ETrue, then a source pixel that is masked by a
+ white pixel is not transferred to the destination rectangle. If alpha blending
+ is used instead of masking, this flag is ignored and no inversion takes place.
+
+@pre The rendering target has been activated. aBitmap and aMask hold valid handles.
+@post Request to draw the masked bitmap content has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::BitBltMasked(
+ const TPoint& aDestPos,
+ const CFbsBitmap& aSourceBitmap,
+ const TRect& aSourceRect,
+ const CFbsBitmap& aMaskBitmap,
+ TBool aInvertMask)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::BitBltMasked(%d,%d)", aDestPos.iX, aDestPos.iY);
+ DoBitBltMasked (aDestPos, aSourceBitmap, aSourceRect, aMaskBitmap, aInvertMask, TPoint(0, 0));
+ }
+
+
+/**
+Performs a masked bitmap block transfer. Source rectangle operates in a similar way to BitBlt().
+
+This function uses either a black and white (binary) mask bitmap, or if aMaskBitmap's display mode is
+EGray256, alpha blending is used. The result is undefined if the mask pixel value is neither black nor
+white and the mask display mode is other than EGray256.
+
+The source rectangle is intersected with the source bitmap’s full extent and the intersection
+will become the effective value. The mask bitmap is aligned with the source bitmap by aligning
+its pixel at the position specified in aMaskPt with the first pixel of the source bitmap
+within the source rectangle. The mask bitmap will be tiled if it is smaller than the source
+rectangle. If the mask has zero width or height, the error state is set to KErrArgument and
+no drawing is performed.
+
+If the client modifies the contents of the bitmap or the mask after issuing the BitBltMasked() command, the
+method does not guarantee whether the old bitmap or mask contents, or the new ones will be used.
+Clients must call Finish() on the driver before modifying the bitmap or mask contents if they want a
+guaranteed result that the previously issued BitBltMasked() will be using the old bitmap or mask contents.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@see CDirectGdiContext::BitBlt(const TPoint& aPoint, const CFbsBitmap& aBitmap, const TRect& aSourceRect);
+@see CDirectGdiContext::BitBltMasked(const TPoint&, const CFbsBitmap&,const TRect&, const CFbsBitmap&, TBool);
+
+@param aDestPos The destination for the top left corner of the transferred bitmap.
+ It is relative to the top left corner of the destination bitmap, which may be the screen.
+@param aSourceBitmap A memory-resident source bitmap.
+@param aSourceRect A rectangle defining the piece of the bitmap to be drawn,
+ with co-ordinates relative to the top left corner of the bitmap.
+@param aMaskBitmap Mask bitmap.
+@param aMaskPos The point on the mask bitmap to use as the top left corner
+
+@pre The rendering target has been activated. aBitmap and aMask hold valid handles.
+@post Request to draw the masked bitmap content has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if no context is activated
+*/
+EXPORT_C void CDirectGdiContext::BitBltMasked(
+ const TPoint& aDestPos,
+ const CFbsBitmap& aSourceBitmap,
+ const TRect& aSourceRect,
+ const CFbsBitmap& aMaskBitmap,
+ const TPoint& aMaskPos)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::BitBltMasked(%d,%d)", aDestPos.iX, aDestPos.iY);
+ DoBitBltMasked (aDestPos, aSourceBitmap, aSourceRect, aMaskBitmap, EFalse, aMaskPos);
+ }
+
+
+/**
+Resets the current clipping region to none.
+
+@see CDirectGdiContext::SetClippingRegion(const TRegion&)
+
+@pre The rendering target has been activated.
+@post Clipping region is reset to none. Subsequent rendering operations on current target will be clipped to the
+ full area of the target.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::ResetClippingRegion()
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::ResetClippingRegion");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ iClippingRegion.Clear();
+ iEngine->ResetClippingRegion();
+ }
+
+
+/**
+Clears the entire target area with the current brush colour. The area is filled
+as if ESolidBrush is used. Current clipping region and drawing mode apply.
+
+@see CDirectGdiContext::Clear(const TRect&)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+@see CDirectGdiContext::SetClippingRegion(const TRegion& aRegion)
+
+@pre The rendering target has been activated.
+@post Request to clear given rectangular area (clipped to current clipping region)
+ has been accepted. There is no guarantee that the request has been processed
+ when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::Clear()
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::Clear");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ iEngine->Clear();
+ }
+
+
+/**
+Clears the given rectangular area with current brush colour. The area is filled
+as if ESolidBrush is used. Current clipping region and drawing mode apply.
+
+@see CDirectGdiContext::Clear()
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+@see CDirectGdiContext::SetClippingRegion(const TRegion&)
+
+@param aRect Area to be cleared.
+
+@pre The rendering target has been activated.
+@post Request to clear given rectangular area (clipped to current clipping region) has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::Clear(const TRect& aRect)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::Clear(%d,%d)", aRect.Width(), aRect.Height());
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if(aRect.Width() <= 0 || aRect.Height() <= 0)
+ {
+ return;
+ }
+ iEngine->Clear(aRect);
+ }
+
+
+/**
+Resets the bitmap brush pattern to none. If the current brush style is EPatternedBrush, the brush
+style will be set to ENullBrush.
+
+@see CDirectGdiContext::SetBrushPattern(const CFbsBitmap&)
+
+@pre None.
+@post The bitmap brush pattern is no longer used.
+*/
+EXPORT_C void CDirectGdiContext::ResetBrushPattern()
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::ResetBrushPattern");
+ CleanUpBrushPattern();
+ if (iBrushStyle == DirectGdi::EPatternedBrush)
+ {
+ iBrushStyle = DirectGdi::ENullBrush;
+ iEngine->SetBrushStyle(iBrushStyle);
+ }
+ iEngine->ResetBrushPattern();
+ }
+
+
+/**
+Releases the selected font for this context.
+
+@pre None.
+@post Internal resources previously allocated during SetFont() are released.
+
+@see CDirectGdiContext::SetFont()
+@see CGraphicsContext::DiscardFont()
+*/
+EXPORT_C void CDirectGdiContext::ResetFont()
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::ResetFont");
+ iEngine->ResetFont();
+ iFont.Reset();
+ }
+
+
+/**
+Draws an arc. An arc is a segment of an ellipse which is defined by a given rectangle. The arc is drawn
+anti-clockwise from the arc start point to the arc end point. The arc start point is the intersection
+between vectors from the centre of the ellipse to the given start position and the ellipse.
+Arc end point is defined in the same way.
+
+@param aRect The rectangle which defines where to draw the ellipse.
+@param aStart Position to be used in defining the arc start point.
+@param aEnd Position to be used in defining the arc end point.
+
+@pre The rendering target has been activated.
+@post Request to draw an arc has been accepted. There is no guarantee that the request
+ has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+
+@see CDirectGdiContext::DrawPie(const TRect&, const TPoint&, const TPoint&)
+*/
+EXPORT_C void CDirectGdiContext::DrawArc(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawArc");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if (aRect.IsEmpty() || iPenStyle == DirectGdi::ENullPen || (iPenSize.iWidth == 0) || (iPenSize.iHeight == 0))
+ {
+ return;
+ }
+ iEngine->DrawArc(aRect, aStart, aEnd);
+ }
+
+
+/**
+Draws and fills a pie. A pie is a shape defined by an arc from the ellipse and straight lines
+from the centre of the ellipse to the arc start and end position.
+
+@param aRect The rectangle which defines where to draw the ellipse
+@param aStart Position to be used in defining the arc start point
+@param aEnd Position to be used in defining the arc end point
+
+@pre The rendering target has been activated.
+@post Request to draw a pie has been accepted. There is no guarantee that the request
+ has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 9, if the brush style is EPatternedBrush but no pattern has been set.
+
+@see CDirectGdiContext::DrawArc(const TRect&, const TPoint&, const TPoint&)
+*/
+EXPORT_C void CDirectGdiContext::DrawPie(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawPie");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ GRAPHICS_ASSERT_ALWAYS(iBrushStyle != DirectGdi::EPatternedBrush || iBrushPatternUsed, EDirectGdiPanicBrushPatternNotSet);
+
+ if (aRect.IsEmpty())
+ {
+ return;
+ }
+ iEngine->DrawPie(aRect, aStart, aEnd);
+ }
+
+/**
+Draws the bitmap contents into the destination rectangle. Scaling applies when
+the extents of the source bitmap and the destination rectangle do not match.
+If the source rectangle is not completely contained within the source
+bitmap's extents, no drawing will take place.
+
+If the client modifies the content of the bitmap after issuing a DrawBitmap() command,
+the method does not guarantee that the old bitmap content or the new one
+will be drawn. Clients must call Finish() on the driver before modifying the bitmap
+content if they want a guarantee that the previously issued DrawBitmap() will draw the
+old bitmap content.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@see CDirectGdiContext::DrawBitmap(const TRect&, const CFbsBitmap&, const TRect&)
+
+@param aDestRect Destination rectangle.
+@param aSourceBitmap Source bitmap.
+
+@pre The rendering target has been activated.
+@post Request to draw the bitmap content has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::DrawBitmap(const TRect& aDestRect, const CFbsBitmap& aSourceBitmap)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::DrawBitmap(%d,%d)", aDestRect.iTl.iX, aDestRect.iTl.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if (ValidateBitmap (aSourceBitmap))
+ {
+ DrawBitmap(aDestRect, aSourceBitmap,TRect(TPoint(0, 0), aSourceBitmap.SizeInPixels()));
+ }
+ }
+
+/**
+Draws the bitmap contents into the destination rectangle. Scaling applies when
+the destination and source rectangles do not match. The source bitmap may be
+compressed. The destination rectangle will be clipped with the current clipping
+region. If the source rectangle is not completely contained within the source
+bitmap's extents, no drawing will take place.
+
+If the client modifies the content of the bitmap after issuing a DrawBitmap() command,
+the method does not guarantee that the old bitmap content or the new one
+will be drawn. Clients must call Finish() on the driver before modifying the bitmap
+content if they want a guarantee that the previously issued DrawBitmap() will draw the
+old bitmap content.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@see CDirectGdiContext::DrawBitmap(const TRect&, const CFbsBitmap&)
+
+@param aDestRect Destination rectangle.
+@param aSourceBitmap Source bitmap.
+@param aSourceRect Rectangle specifying the area of the source bitmap to be drawn.
+
+@pre The rendering target has been activated.
+@post Request to draw the bitmap content has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::DrawBitmap(const TRect& aDestRect, const CFbsBitmap& aSourceBitmap, const TRect& aSourceRect)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::DrawBitmap(%d,%d)", aDestRect.iTl.iX, aDestRect.iTl.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (ValidateBitmap(aSourceBitmap))
+ {
+ TSize sourceSize = aSourceBitmap.SizeInPixels();
+ // If source rectangle is not fully contained by the extents of the source bitmap,
+ // or the size of the source bitmap is zero, do nothing.
+ if (aSourceRect.iTl.iX >= 0 &&
+ aSourceRect.iTl.iY >= 0 &&
+ aSourceRect.iBr.iX <= sourceSize.iWidth &&
+ aSourceRect.iBr.iY <= sourceSize.iHeight &&
+ !aDestRect.IsEmpty() && !aSourceRect.IsEmpty())
+ {
+ iEngine->DrawBitmap(aDestRect, aSourceBitmap, aSourceRect);
+ }
+ }
+ }
+
+
+/**
+Draws bitmap content with masking. Scaling applies to both the source bitmap and the mask.
+Both the source and the mask bitmap may be compressed. The destination and source rectangles
+operate in a similar way to DrawBitmap().
+
+This function uses either a black and white (binary) mask bitmap, or if the mask's display mode is
+EGray256, alpha blending is used. The result is undefined if the mask pixel value is neither black nor
+white and the mask display mode is other than EGray256.
+
+The mask is aligned with the source bitmap by aligning their first pixels within the source
+rectangle. If the mask size is greater than or equal to the source bitmap size, it will be
+scaled to fit the destination rectangle in the same way the source bitmap is scaled.
+If the mask has zero width or height, the error state is set to KErrArgument and no drawing is performed.
+
+If the mask is smaller than the source bitmap, it will be tiled to fit the source bitmap size,
+and then scaled to fit the destination rectangle.
+
+If the client modifies the content of the bitmap or mask after issuing a DrawBitmapMasked() command,
+the method does not guarantee whether the old bitmap or mask contents, or the new ones
+will be used. Clients must call Finish() on the driver before modifying the bitmap or mask contents
+if they want a guaranteed result that the previously issued DrawBitmapMasked() will be using the old
+bitmap or mask contents.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@param aDestRect Destination rectangle.
+@param aSourceBitmap Source bitmap.
+@param aSourceRect Rectangle specifying the area of the source bitmap to be drawn.
+@param aMaskBitmap Mask bitmap.
+@param aInvertMask If EFalse, a source pixel that is masked by a black pixel is not transferred to
+ the destination rectangle. If ETrue, then a source pixel that is masked by a
+ white pixel is not transferred to the destination rectangle. If alpha blending
+ is used instead of masking, this flag is ignored and no inversion takes place.
+
+@pre The rendering target has been activated.
+@post Request to draw the bitmap content with masking has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::DrawBitmapMasked(
+ const TRect& aDestRect,
+ const CFbsBitmap& aSourceBitmap,
+ const TRect& aSourceRect,
+ const CFbsBitmap& aMaskBitmap,
+ TBool aInvertMask)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::DrawBitmapMasked(%d,%d)", aDestRect.iTl.iX, aDestRect.iTl.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (ValidateSourceAndMaskBitmaps(aSourceBitmap, aMaskBitmap))
+ {
+ TSize sourceSize = aSourceBitmap.SizeInPixels();
+ // Ensure source rect is fully within bounds of bitmap extents and
+ // dest and source rect are not empty.
+ if (aSourceRect.iTl.iX >= 0 &&
+ aSourceRect.iTl.iY >= 0 &&
+ aSourceRect.iBr.iX <= sourceSize.iWidth &&
+ aSourceRect.iBr.iY <= sourceSize.iHeight &&
+ !aDestRect.IsEmpty() && !aSourceRect.IsEmpty())
+ {
+ iEngine->DrawBitmapMasked(aDestRect, aSourceBitmap, aSourceRect, aMaskBitmap, aInvertMask);
+ }
+ }
+ }
+
+/**
+Draws and fills a rectangle with rounded corners. The corner is constructed as an arc of
+an ellipse. The outline is drawn in the current pen colour, size and style if the pen
+colour is not ENullPen. The area inside the rectangle is filled according to the current
+brush colour and style.
+
+If the corner size has zero width or height, a square-cornered rectangle is drawn. If the corner
+size is greater than half the extents of the rectangle, an ellipse is drawn.
+
+@param aRect The rectangle.
+@param aCornerSize The corner size.
+
+@see CDirectGdiContext::SetPenSize()
+@see CDirectGdiContext::SetPenStyle()
+@see CDirectGdiContext::SetPenColor()
+@see CDirectGdiContext::SetBrushColor()
+@see CDirectGdiContext::SetBrushStyle()
+@see CDirectGdiContext::SetBrushPattern()
+
+@pre The rendering target has been activated.
+@post Request to draw a rectangle with rounded corners has been accepted. There is no guarantee
+ that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 9, if the brush style is EPatternedBrush but no pattern has been set.
+*/
+EXPORT_C void CDirectGdiContext::DrawRoundRect(const TRect& aRect, const TSize& aCornerSize)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawRoundRect");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ GRAPHICS_ASSERT_ALWAYS(iBrushStyle != DirectGdi::EPatternedBrush || iBrushPatternUsed, EDirectGdiPanicBrushPatternNotSet);
+
+ TSize ellsize(aCornerSize);
+ ellsize.iWidth <<= 1;
+ ellsize.iHeight <<= 1;
+
+ if (aRect.Width() > 0 && aRect.Height() > 0)
+ {
+ if (ellsize.iWidth < 3 || ellsize.iHeight < 3)
+ {
+ DrawRect(aRect);
+ return;
+ }
+ if (aRect.Width() < ellsize.iWidth && aRect.Height() < ellsize.iHeight)
+ {
+ DrawEllipse(aRect);
+ return;
+ }
+ iEngine->DrawRoundRect(aRect, aCornerSize);
+ }
+ }
+
+/**
+Draws a polyline using the points in an array. A polyline is a series of concatenated straight
+lines joining a set of points. Current pen settings and drawing mode applies. If @c aPointList
+has one element, a plot is performed.
+
+@param aPointList Array of points specifying points on the polyline.
+
+@pre The rendering target has been activated.
+@post Request to draw a polyline has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+ The internal drawing position is set to the last point in the array.
+
+@panic DGDI 7, if the rendering context has not been activated.
+
+@see CDirectGdiContext::DrawPolyLineNoEndPoint(const TArray<TPoint>&)
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+*/
+EXPORT_C void CDirectGdiContext::DrawPolyLine(const TArray<TPoint>& aPointList)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawPolyLine");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if ((aPointList.Count() < 1) || iPenStyle == DirectGdi::ENullPen || (iPenSize.iWidth == 0) || (iPenSize.iHeight == 0))
+ {
+ return;
+ }
+
+ if (aPointList.Count() == 1)
+ {
+ Plot(aPointList[0]);
+ }
+ else
+ {
+ iEngine->DrawPolyLine(aPointList);
+ }
+ }
+
+
+/**
+Draws a polyline using the points in an array. A polyline is a series of concatenated straight
+lines joining a set of points. Current pen settings and drawing mode applies. If @c aPointList
+has less than two elements, no drawing is performed. If @c aPointList has exactly two elements
+then a DrawLine is performed.
+
+@param aPointList Array of points specifying points on the polyline.
+
+@pre The rendering target has been activated.
+@post Request to draw a polyline has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+ The internal drawing position is set to the last point in the array.
+
+@panic DGDI 7, if the rendering context has not been activated.
+
+@see CDirectGdiContext::DrawPolyLine(const TArray<TPoint>&)
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+*/
+EXPORT_C void CDirectGdiContext::DrawPolyLineNoEndPoint(const TArray<TPoint>& aPointList)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawPolyLineNoEndPoint");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ const TInt points = aPointList.Count();
+
+ if (points == 1)
+ {
+ Plot(aPointList[0]);
+ }
+ else if (points == 2)
+ {
+ DrawLine(aPointList[0], aPointList[1]);
+ }
+ else if (points > 2 && !(iPenStyle == DirectGdi::ENullPen || (iPenSize.iWidth == 0) || (iPenSize.iHeight == 0)))
+ {
+ iEngine->DrawPolyLineNoEndPoint(aPointList);
+ }
+ }
+
+/**
+Draws and fills a polygon defined using an array of points. The first point in the array defines the
+start of the first side of the polygon. The final side of the polygon is drawn using the last point
+from the array, and the line is drawn to the start point of the first side. The outline of the polygon
+is drawn using the current pen settings and the area is filled with the current brush settings.
+
+Self-crossing polygons are filled according to the specified fill rule.
+
+If @c aPointList is empty, no drawing is performed. If it has one element, the result is the same as Plot().
+If it has two elements, the result is the same as DrawLine().
+
+The error state is set to KErrArgument if aFillRule is an invalid fill rule.
+
+@param aPointList Array of points specifying the vertices of the polygon.
+@param aFillRule Polygon filling rule.
+
+@pre The rendering target has been activated.
+@post Request to draw a polygon has been accepted. There is no guarantee that the request has been processed
+ when the method returns. The internal drawing position is set to the last point in the array.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 9, if the brush style is EPatternedBrush but no pattern has been set.
+
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetBrushStyle(DirectGdi::TBrushStyle)
+@see CDirectGdiContext::SetBrushPattern(const CFbsBitmap&)
+@see CDirectGdiContext::SetBrushOrigin(TPoint)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+@see DirectGdi::TFillRule
+*/
+EXPORT_C void CDirectGdiContext::DrawPolygon(const TArray<TPoint>& aPointList, DirectGdi::TFillRule aFillRule)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawPolygon");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ GRAPHICS_ASSERT_ALWAYS(iBrushStyle != DirectGdi::EPatternedBrush || iBrushPatternUsed, EDirectGdiPanicBrushPatternNotSet);
+
+ if (aFillRule != DirectGdi::EAlternate && aFillRule != DirectGdi::EWinding)
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+
+ if (aPointList.Count() == 0)
+ {
+ return;
+ }
+
+ iEngine->DrawPolygon(aPointList, aFillRule);
+ }
+
+
+/**
+Draws and fills an ellipse inside the given rectangle. Current pen and brush settings apply.
+
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetBrushStyle(DirectGdi::TBrushStyle)
+@see CDirectGdiContext::SetBrushPattern(const CFbsBitmap&)
+
+@param aRect The rectangle in which to draw the ellipse.
+
+@pre The rendering target has been activated.
+@post Request to draw an ellipse has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 9, if the brush style is EPatternedBrush but no pattern has been set.
+*/
+EXPORT_C void CDirectGdiContext::DrawEllipse(const TRect& aRect)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawEllipse");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ GRAPHICS_ASSERT_ALWAYS(iBrushStyle != DirectGdi::EPatternedBrush || iBrushPatternUsed, EDirectGdiPanicBrushPatternNotSet);
+
+ if (aRect.IsEmpty())
+ {
+ return;
+ }
+ iEngine->DrawEllipse(aRect);
+ }
+
+
+/**
+Draws a straight line from the start to the end position using current pen size, colour and style.
+
+@param aStart Start position.
+@param aEnd End position.
+
+@pre The rendering target has been activated.
+@post Request to draw a straight line with the current pen colour, size and style has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+ The internal drawing position is set to @c aEnd.
+
+@panic DGDI 7, if the rendering context has not been activated.
+
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+*/
+EXPORT_C void CDirectGdiContext::DrawLine(const TPoint& aStart, const TPoint& aEnd)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawLine");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ // Do not draw if start/end at the same point or pensize is 0
+ if(aStart == aEnd || iPenStyle == DirectGdi::ENullPen || iPenSize.iWidth == 0 || iPenSize.iHeight == 0)
+ {
+ return;
+ }
+
+ iEngine->DrawLine(aStart, aEnd);
+ }
+
+
+/**
+Draws a straight line from the current internal drawing position to a point using the current pen size, colour and style.
+
+@param aPoint The end-point of the line.
+
+@pre Rendering target has been activated.
+@post Request to draw a straight line to a specified point with the current pen colour, size and style has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+ Internal drawing position is set to @c aPoint.
+
+@panic DGDI 7, if the rendering context has not been activated.
+
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+@see CDirectGdiContext::MoveTo(TPoint)
+@see CDirectGdiContext::MoveBy(TPoint)
+*/
+EXPORT_C void CDirectGdiContext::DrawLineTo(const TPoint& aPoint)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawLineTo");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if(iPenStyle == DirectGdi::ENullPen || iPenSize.iWidth == 0 || iPenSize.iHeight == 0)
+ {
+ return;
+ }
+ iEngine->DrawLineTo (aPoint);
+ }
+
+
+/**
+Draws a straight line relative to the current internal drawing position, using a vector.
+The start point of the line is the current internal drawing position. The vector @c aVector
+is added to the internal drawing position to give the end point of the line.
+
+@param aVector The vector to add to the current internal drawing position, giving the end point of the line.
+
+@pre The rendering target has been activated.
+@post The request to draw a straight line using the vector with current pen colour, size and style has been
+ accepted. There is no guarantee that the request has been processed when the method returns.
+ The internal drawing position is set to the end of the line.
+
+@panic DGDI 7, if the rendering context has not been activated.
+
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+@see CDirectGdiContext::MoveTo(TPoint)
+@see CDirectGdiContext::MoveBy(TPoint)
+*/
+EXPORT_C void CDirectGdiContext::DrawLineBy(const TPoint& aVector)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawLineBy");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if(iPenStyle == DirectGdi::ENullPen || iPenSize.iWidth == 0 || iPenSize.iHeight == 0)
+ {
+ return;
+ }
+
+ if (aVector != TPoint(0,0))
+ {
+ iEngine->DrawLineBy(aVector);
+ }
+ }
+
+
+/**
+Draws and fills a rectangle. The outlines are drawn according to the current pen colour, size and style.
+The area inside the rectangle is filled according to the current brush colour and style.
+
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetBrushStyle(DirectGdi::TBrushStyle)
+@see CDirectGdiContext::SetBrushPattern(const CFbsBitmap&)
+
+@param aRect The rectangle.
+
+@pre The rendering target has been activated.
+@post Request to draw a rectangle according to the current pen and brush settings has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 9, if the brush style is EPatternedBrush but no pattern has been set.
+*/
+EXPORT_C void CDirectGdiContext::DrawRect(const TRect& aRect)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawRect");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ GRAPHICS_ASSERT_ALWAYS(iBrushStyle != DirectGdi::EPatternedBrush || iBrushPatternUsed, EDirectGdiPanicBrushPatternNotSet);
+
+ if(aRect.IsEmpty())
+ return;
+
+ iEngine->DrawRect(aRect);
+ }
+
+
+/**
+Draws text at the last print position.
+
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetFont(const CFont*)
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+
+@pre The rendering target has been activated.
+@post Request to draw the text at the last text position using the current font and pen colour has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush
+ style is neither ENullBrush nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawText(const TDesC& aText, const DirectGdi::TTextParameters* aParam)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawText");
+ DrawText(aText, aParam, iLastPrintPosition, DirectGdi::ELeft, CFont::EHorizontal);
+ }
+
+
+/**
+Draws text at the specified text position.
+
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetFont(const CFont*)
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aPosition The position to draw at.
+
+@pre The rendering target has been activated.
+@post Request to draw the text at the specified position using the current font and pen colour has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush
+ style is neither ENullBrush nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawText(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TPoint& aPosition)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawText");
+ DrawText(aText, aParam, aPosition, DirectGdi::ELeft, CFont::EHorizontal);
+ }
+
+
+/**
+Draws text clipped to the specified rectangle.
+
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetFont(const CFont*)
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aClipRect The clipping rectangle.
+
+@pre The rendering target has been activated.
+@post Request to draw the text at the last text position using the current font and pen colour, clipped to the specified rectangle has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and
+ the brush style is neither ENullBrush nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawText(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TRect& aClipRect)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawText");
+ DrawText(aText, aParam, iLastPrintPosition, DirectGdi::ELeft, CFont::EHorizontal, &aClipRect);
+ }
+
+
+/**
+Draws text clipped to the specified filled rectangle using a baseline offset,
+horizontal alignment and a margin.
+
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetBrushColor(TRgb)
+@see CDirectGdiContext::SetFont(const CFont*)
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aClipFillRect The clipping rectangle (this rect will also be filled before text is plotted).
+@param aBaselineOffset An offset in pixels for the baseline from the normal position (bottom of the rectangle minus the descent of the font).
+@param aAlignment Horizontal alignment option relative to the specified rectangle.
+@param aMargin Offset to add to the position as calculated using specified rectangle.
+
+@pre The rendering target has been activated.
+@post Request to draw the text within the filled rectangle using the current font and pen colour, offset and clipped to the specified rectangle has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush
+ style is neither ENullBrush nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawText(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TRect& aClipFillRect, TInt aBaselineOffset, DirectGdi::TTextAlign aAlignment, TInt aMargin)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawText");
+ TPoint p(aClipFillRect.iTl);
+ p.iY += aBaselineOffset;
+ switch (aAlignment)
+ {
+ case DirectGdi::ELeft:
+ {
+ p.iX += aMargin;
+ break;
+ }
+ case DirectGdi::ERight:
+ {
+ p.iX = aClipFillRect.iBr.iX - aMargin;
+ break;
+ }
+ case DirectGdi::ECenter:
+ {
+ p.iX += (aClipFillRect.Width() >> 1) + aMargin;
+ break;
+ }
+ default:
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+ }
+ DrawText(aText, aParam, p, aAlignment, CFont::EHorizontal, &aClipFillRect, &aClipFillRect);
+ }
+
+
+/**
+The private general DrawText routine that implements all the others.
+
+@param aText The text to be drawn.
+@param aParam Parameters used in drawing text.
+@param aPosition The origin of the text.
+@param aAlignment Left, centred or right, around aPosition; not used if drawing vertically.
+@param aDirection Direction: left to right, right to left, or top to bottom.
+@param aClipRect If non-null, used as a clippingrect when the text is drawn.
+@param aFillRect If non-null, filled before the text is drawn.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush
+ style is neither ENullBrush nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+void CDirectGdiContext::DrawText(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TPoint& aPosition, DirectGdi::TTextAlign aAlignment,
+ CFont::TTextDirection aDirection, const TRect* aClipRect, const TRect* aFillRect)
+ {
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ // anything to do?
+ if (aClipRect && aClipRect->IsEmpty())
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+
+ GRAPHICS_ASSERT_ALWAYS(iFont.Handle() != 0, EDirectGdiPanicNoFontSelected);
+ // This next check actually covers both bitmap and open fonts
+ const CBitmapFont* bitmap_font = iFont.Address();
+ GRAPHICS_ASSERT_ALWAYS(bitmap_font != 0, EDirectGdiPanicNoFontSelected);
+
+ // measure the text
+ CFont::TMeasureTextInput measure_text_input;
+ measure_text_input.iCharJustNum = iCharJustNum;
+ measure_text_input.iCharJustExcess = iCharJustExcess;
+ measure_text_input.iWordJustNum = iWordJustNum;
+ measure_text_input.iWordJustExcess = iWordJustExcess;
+ measure_text_input.iFlags |= CFont::TMeasureTextInput::EFVisualOrder;
+ if (aParam)
+ {
+ GRAPHICS_ASSERT_ALWAYS(aParam->iStart < aParam->iEnd ,EDirectGdiPanicBadParameter);
+ measure_text_input.iStartInputChar = aParam->iStart;
+ measure_text_input.iEndInputChar = Min(aText.Length(),aParam->iEnd);
+ }
+ CFont::TMeasureTextOutput measure_text_output;
+ const TInt advance = iFont.MeasureText(aText, &measure_text_input, &measure_text_output);
+ TRect text_bounds = measure_text_output.iBounds;
+
+ //for linked fonts need an adjustment to the underline postion
+ TInt underlineStrikeoutOffset = BaselineCorrection();
+
+ if (iUnderline == DirectGdi::EUnderlineOn)
+ {
+ TInt underline_top = 0;
+ TInt underline_bottom = 0;
+ GetUnderlineMetrics(underline_top, underline_bottom);
+ underline_top+=underlineStrikeoutOffset;
+ underline_bottom+=underlineStrikeoutOffset;
+ text_bounds.iTl.iY = Min(text_bounds.iTl.iY, underline_top);
+ text_bounds.iBr.iY = Max(text_bounds.iBr.iY, underline_bottom);
+ }
+ if (iStrikethrough == DirectGdi::EStrikethroughOn)
+ {
+ TInt strike_top = 0;
+ TInt strike_bottom = 0;
+ GetStrikethroughMetrics(strike_top, strike_bottom);
+ strike_top+=underlineStrikeoutOffset;
+ strike_bottom+=underlineStrikeoutOffset;
+ text_bounds.iTl.iY = Min(text_bounds.iTl.iY, strike_top);
+ text_bounds.iBr.iY = Max(text_bounds.iBr.iY, strike_bottom);
+ }
+ if (iUnderline == DirectGdi::EUnderlineOn || iStrikethrough == DirectGdi::EStrikethroughOn)
+ {
+ if (aDirection == CFont::EHorizontal)
+ {
+ text_bounds.iTl.iX = Min(text_bounds.iTl.iX, 0);
+ text_bounds.iBr.iX = Max(text_bounds.iBr.iX, advance);
+ }
+ else
+ {
+ text_bounds.iTl.iY = Min(text_bounds.iTl.iY, 0);
+ text_bounds.iBr.iY = Max(text_bounds.iBr.iY, advance);
+ }
+ }
+
+ // work out the text origin and new drawing position
+ TPoint text_origin = aPosition;
+ if (aDirection != CFont::EVertical)
+ {
+ const TInt leftSideBearing = Min(text_bounds.iTl.iX, 0);
+ const TInt rightSideBearing = Max(text_bounds.iBr.iX, advance);
+ switch (aAlignment)
+ {
+ // We are forbidding side-bearings to leak over the sides here,
+ // but still keeping the start and end pen positions within bounds.
+ case DirectGdi::ELeft:
+ text_origin.iX -= leftSideBearing;
+ break;
+ case DirectGdi::ERight:
+ text_origin.iX -= rightSideBearing;
+ break;
+ case DirectGdi::ECenter:
+ // Centre is the average of left and right
+ text_origin.iX -= (leftSideBearing + rightSideBearing) >> 1;
+ break;
+ default:
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+ }
+ iLastPrintPosition = text_origin;
+ if (aDirection == CFont::EHorizontal)
+ {
+ iLastPrintPosition.iX += advance;
+ }
+ else
+ {
+ iLastPrintPosition.iY += advance;
+ }
+ text_origin.iY += bitmap_font->iAlgStyle.iBaselineOffsetInPixels;
+ text_bounds.Move(text_origin);
+ text_origin += iOrigin;
+
+ // determine clipping rectangle
+ TRect clipRect = aClipRect ? *aClipRect : text_bounds;
+
+ // fill the box if necessary
+ if (aFillRect && (iBrushStyle != DirectGdi::ENullBrush))
+ {
+ TRect fillBox = *aFillRect;
+ if (fillBox.Intersects(clipRect))
+ {
+ fillBox.Intersection(clipRect);
+ iEngine->SetPenStyle(DirectGdi::ENullPen); // Fill box, don't outline it
+ iEngine->DrawRect(fillBox);
+ iEngine->SetPenStyle(iPenStyle); // Put the pen style back
+ }
+ }
+ if (!aText.Length())
+ {
+ return;
+ }
+
+ clipRect.Move(iOrigin);
+
+ // decide which drawing routine to call
+
+ TOpenFontMetrics metrics;
+ iFont.GetFontMetrics(metrics);
+ const TInt maxwidth = metrics.MaxWidth();
+ // extext will be TRUE, if font is underline/strikethrough/anti-aliased or it has shadow/outline effects ON.
+ // Depending on these properties it will call the proper draw routine.
+ TBool extext = EFalse;
+ TBool normaltext = EFalse;
+ const TBool antiAliased = (bitmap_font->GlyphBitmapType() == EAntiAliasedGlyphBitmap);
+ const TBool outlineAndShadow = (bitmap_font->GlyphBitmapType() == EFourColourBlendGlyphBitmap);
+ if (antiAliased || outlineAndShadow )
+ {
+ if ((outlineAndShadow) && !((iBrushStyle == DirectGdi::ENullBrush) || (iBrushStyle == DirectGdi::ESolidBrush)))
+ {
+ //For future compatibility it is better if brush style of ENullBrush or ESolidBrush is used
+ //when drawing outline and shadow fonts.
+ GRAPHICS_PANIC_ALWAYS(EDirectGdiPanicInvalidBrushStyle);
+ }
+ extext = ETrue;
+ }
+ else if ((iUnderline == DirectGdi::EUnderlineOn) || (iStrikethrough == DirectGdi::EStrikethroughOn) || (iCharJustNum > 0) || (iWordJustNum > 0))
+ extext = ETrue;
+ else
+ normaltext = ETrue;
+
+ const TInt charjustexcess = iCharJustExcess;
+ const TInt charjustnum = iCharJustNum;
+ const TInt wordjustexcess = iWordJustExcess;
+ const TInt wordjustnum = iWordJustNum;
+
+ // Set up the parameter block for character positioning.
+ CFont::TPositionParam param;
+ param.iDirection = static_cast<TInt16>(aDirection);
+ param.iText.Set(aText);
+ TInt endDraw = aText.Length();
+ if (aParam)
+ {
+ param.iPosInText = aParam->iStart;
+ endDraw = Min(aText.Length(),aParam->iEnd);
+ }
+ else
+ {
+ param.iPosInText = 0;
+ }
+ param.iPen = text_origin;
+
+ // Draw the text.
+ if (normaltext)
+ {
+ DoDrawText(param, endDraw, clipRect);
+ }
+ else if (extext)
+ {
+ DoDrawTextEx(param, endDraw, clipRect,underlineStrikeoutOffset);
+ }
+
+ // Reset the justification parameters to their original values.
+ // These will be updated as required later in code.
+ iCharJustExcess = charjustexcess;
+ iCharJustNum = charjustnum;
+ iWordJustExcess = wordjustexcess;
+ iWordJustNum = wordjustnum;
+
+ if (iAutoUpdateJustification)
+ UpdateJustification(aText, aParam);
+ }
+
+/**
+Overridden function which draws monochrome text within the given clip rectangle. No rotation applied.
+@param aParam Defines glyph code, ligature creation and diacritic placement.
+@param aEnd The end position within the text descriptor to draw.
+@param aClipRect If not-empty, used as a clippingrect when the text is drawn.
+*/
+void CDirectGdiContext::DoDrawText(CFont::TPositionParam& aParam, const TInt aEnd, const TRect& aClipRect)
+ {
+ iEngine->BeginDrawGlyph();
+ RShapeInfo shapeInfo;
+ while (aParam.iPosInText < aEnd)
+ {
+ if (iFont.GetCharacterPosition2(aParam, shapeInfo))
+ {
+ const CFont::TPositionParam::TOutput* output = aParam.iOutput;
+ for (TInt i = 0; i < aParam.iOutputGlyphs; ++i, ++output)
+ iEngine->DrawGlyph(output->iBounds.iTl, output->iCode, output->iBitmap, EMonochromeGlyphBitmap, output->iBitmapSize, aClipRect); // All other parameters are default
+ }
+ }
+ iEngine->EndDrawGlyph();
+
+ if (shapeInfo.IsOpen())
+ shapeInfo.Close();
+ }
+
+
+/**
+Overridden function which draws monochrome text within the given clip rectangle.
+The current rotation and font style (strikethrough, underline) are applied.
+
+@param aParam Defines glyph code, ligature creation and diacritic placement.
+@param aEnd The end position within the text descriptor to draw.
+@param aClipRect If not-empty, used as a clipping rect when the text is drawn.
+@param aUnderlineStrikethroughOffset the offset for the underline, passed to save calculating this value again
+*/
+void CDirectGdiContext::DoDrawTextEx(CFont::TPositionParam& aParam, const TInt aEnd, const TRect& aClipRect, const TInt aUnderlineStrikethroughOffset)
+ {
+ TPoint startPen = aParam.iPen;
+ const CBitmapFont* bitmap_font = iFont.Address();
+ TInt underlineTop = 0;
+ TInt underlineBottom = 0;
+ if (iUnderline == DirectGdi::EUnderlineOn)
+ {
+ GetUnderlineMetrics(underlineTop, underlineBottom);
+ underlineTop+=aUnderlineStrikethroughOffset;
+ underlineBottom+=aUnderlineStrikethroughOffset;
+ }
+ TInt strikeTop = 0;
+ TInt strikeBottom = 0;
+ if (iStrikethrough == DirectGdi::EStrikethroughOn)
+ {
+ GetStrikethroughMetrics(strikeTop, strikeBottom);
+ strikeTop+=aUnderlineStrikethroughOffset;
+ strikeBottom+=aUnderlineStrikethroughOffset;
+ }
+
+ iEngine->BeginDrawGlyph();
+ RShapeInfo shapeInfo;
+ while (aParam.iPosInText < aEnd)
+ {
+ if (!iFont.GetCharacterPosition2(aParam, shapeInfo))
+ {
+ continue;
+ }
+
+ TInt adjustment = 0;
+ if ((iCharJustExcess > 0) && (iCharJustNum > 0)) // character clipping/justification
+ {
+ adjustment = CGraphicsContext::JustificationInPixels(iCharJustExcess, iCharJustNum);
+ }
+
+ const CFont::TPositionParam::TOutput* output = aParam.iOutput;
+ for (TInt i = 0; i < aParam.iOutputGlyphs; ++i, ++output)
+ {
+ //get the character metrics for the glyph type
+ TOpenFontCharMetrics characterParams;
+ const TUint8* bitmap;
+ TSize size;
+ //note may now be using a glyph code, and not a character
+ iFont.GetCharacterData(aParam.iOutput[i].iCode,characterParams,bitmap,size);
+ TGlyphBitmapType glyphType = characterParams.GlyphType();
+
+ switch (glyphType)
+ {
+ case EAntiAliasedGlyphBitmap:
+ case EFourColourBlendGlyphBitmap:
+ case EDefaultGlyphBitmap:
+ iEngine->DrawGlyph(output->iBounds.iTl, output->iCode, output->iBitmap, glyphType, output->iBitmapSize, aClipRect);
+ break;
+
+ default:
+ //if the outline or shadow is not specified for the character, then use the font setting for the glyph bitmap type
+ iEngine->DrawGlyph(output->iBounds.iTl, output->iCode, output->iBitmap,
+ bitmap_font->GlyphBitmapType(), output->iBitmapSize, aClipRect);
+ break;
+ }
+ }
+
+ if (adjustment)
+ {
+ aParam.iPen.iX += adjustment;
+ }
+ if ((iWordJustExcess > 0) && (iWordJustNum > 0) && (aParam.iOutput[0].iCode == 0x0020)) // word justification
+ {
+ adjustment = CGraphicsContext::JustificationInPixels(iWordJustExcess, iWordJustNum);
+ aParam.iPen.iX += adjustment;
+ }
+ }
+ iEngine->EndDrawGlyph();
+ if (shapeInfo.IsOpen())
+ shapeInfo.Close();
+
+ if (iUnderline == DirectGdi::EUnderlineOn)
+ {
+ TRect underlineRect(startPen.iX, startPen.iY + underlineTop, aParam.iPen.iX, startPen.iY + underlineBottom);
+ FillRect(underlineRect, iPenColor, aClipRect);
+ }
+
+ if (iStrikethrough == DirectGdi::EStrikethroughOn)
+ {
+ TRect strikethroughRect(startPen.iX, startPen.iY + strikeTop, aParam.iPen.iX, startPen.iY + strikeBottom);
+ FillRect(strikethroughRect, iPenColor, aClipRect);
+ }
+ }
+
+
+/**
+Fills the given rectangle with the specified colour (subject to the clip rect).
+This function is internal and used by the text drawing routines.
+
+@param aRect The rectangle to fill.
+@param aColor The colour to fill it with.
+@param aClipRect The clipping rect.
+*/
+void CDirectGdiContext::FillRect(const TRect& aRect, const TRgb& aColor, const TRect& aClipRect)
+ {
+ TRect fillRect = aRect;
+ if (fillRect.Intersects(aClipRect))
+ {
+ fillRect.Intersection(aClipRect);
+ // Override the current settings temporarily
+ iEngine->SetBrushColor(aColor);
+ iEngine->SetBrushStyle(DirectGdi::ESolidBrush);
+ iEngine->SetPenStyle(DirectGdi::ENullPen); // Fill box, don't outline it
+ fillRect.Move(-iOrigin);
+ iEngine->DrawRect(fillRect);
+ // Put things back
+ iEngine->SetPenStyle(iPenStyle);
+ iEngine->SetBrushStyle(iBrushStyle);
+ iEngine->SetBrushColor(iBrushColor);
+ }
+ }
+
+
+/**
+Draws text at the last print position and then rotates it into a vertical position.
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aUp If ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush
+ style is neither ENullBrush nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawTextVertical(const TDesC& aText, const DirectGdi::TTextParameters* aParam, TBool aUp)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawTextVertical");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ // This next check covers both bitmap and open fonts
+ const CBitmapFont* bitmapFont = iFont.Address();
+ GRAPHICS_ASSERT_ALWAYS(bitmapFont != 0, EDirectGdiPanicNoFontSelected);
+ TRect clipRect2(0, 0, 0, 0);
+ TInt baselineOffset = 0;
+ TInt margin = 0;
+ CalculateClipRect2PlusBaselineOffsetAndMargin(aText, aParam, iLastPrintPosition, aUp, clipRect2, baselineOffset, margin);
+ DrawTextVertical(aText, aParam, NULL, &clipRect2, NULL, baselineOffset, -1, aUp, DirectGdi::ELeft, margin); //-1 signifies that text will not be clipped
+ }
+
+
+/**
+Draws text vertically from the specified position.
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aPosition A point specifying the position of the left end of the text.
+@param aUp If ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush style is neither
+ ENullBrush nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawTextVertical(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TPoint& aPosition, TBool aUp)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawTextVertical");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ // This next check covers both bitmap and open fonts
+ const CBitmapFont* bitmapFont = iFont.Address();
+ GRAPHICS_ASSERT_ALWAYS(bitmapFont != 0, EDirectGdiPanicNoFontSelected);
+ TRect clipRect2(0, 0, 0, 0);
+ TInt baselineOffset = 0;
+ TInt margin = 0;
+ CalculateClipRect2PlusBaselineOffsetAndMargin(aText, aParam, aPosition, aUp, clipRect2, baselineOffset, margin);
+ DrawTextVertical(aText, aParam, NULL, &clipRect2, NULL, baselineOffset, -1, aUp, DirectGdi::ELeft, margin);//-1 signifies that text will not be clipped
+ }
+
+
+/**
+Draws text clipped to the specified rectangle and then rotates it into a vertical position.
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aClipRect The clipping rectangle.
+@param aUp ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush style is neither ENullBrush
+ nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawTextVertical(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TRect& aClipRect, TBool aUp)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawTextVertical");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ // This next check covers both bitmap and open fonts
+ const CBitmapFont* bitmapFont = iFont.Address();
+ GRAPHICS_ASSERT_ALWAYS(bitmapFont != 0, EDirectGdiPanicNoFontSelected);
+ TRect clipRect2(0, 0, 0, 0);
+ TInt baselineOffset = 0;
+ TInt margin = 0;
+ CalculateClipRect2PlusBaselineOffsetAndMargin(aText, aParam, iLastPrintPosition, aUp, clipRect2, baselineOffset, margin);
+ DrawTextVertical(aText, aParam, &aClipRect, &clipRect2, NULL, baselineOffset, -1, aUp, DirectGdi::ELeft, margin);
+ }
+
+
+/**
+Private internal function for calculating several parameters needed by these routines.
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aPosition A point specifying the position of the left end of the text.
+@param aUp ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+@param aClipRect2 On return, contains clipping rectangle.
+@param aBaselineOffset On return, contains baseline offset.
+@param aMargin On return, contains margin.
+*/
+void CDirectGdiContext::CalculateClipRect2PlusBaselineOffsetAndMargin(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TPoint& aPosition, TBool aUp, TRect& aClipRect2, TInt& aBaselineOffset, TInt& aMargin)
+ {
+ TOpenFontMetrics metrics;
+ iFont.GetFontMetrics(metrics);
+ aBaselineOffset = metrics.MaxHeight();
+ TInt height = aBaselineOffset + metrics.MaxDepth();
+ // The next few lines do much the same as TextWidthInPixels but pass
+ // the text in visual order instead of logical order and also take
+ // full account of left and right side bearings on the text
+ CFont::TMeasureTextOutput output;
+ CFont::TMeasureTextInput input;
+ input.iFlags = CFont::TMeasureTextInput::EFVisualOrder;
+ if (aParam)
+ {
+ GRAPHICS_ASSERT_ALWAYS(aParam->iStart < aParam->iEnd ,EDirectGdiPanicBadParameter);
+ input.iStartInputChar = aParam->iStart;
+ input.iEndInputChar = Min(aText.Length(),aParam->iEnd);
+ }
+ TInt advance = iFont.MeasureText(aText, &input, &output);
+ TInt leftBearing = output.iBounds.iTl.iX;
+ TInt rightBearing = advance - output.iBounds.iBr.iX;
+ aMargin = 0;
+ if (aUp)
+ {
+ aClipRect2.iTl.iX = aPosition.iX - aBaselineOffset;
+ aClipRect2.iTl.iY = aPosition.iY - advance;
+ aClipRect2.iBr.iX = aPosition.iX + height - aBaselineOffset + 1;
+ aClipRect2.iBr.iY = aPosition.iY;
+ if (leftBearing < 0)
+ {
+ aClipRect2.iBr.iY -= leftBearing;
+ aMargin = -leftBearing;
+ }
+ if (rightBearing < 0)
+ {
+ aClipRect2.iTl.iY += rightBearing;
+ }
+ }
+ else
+ {
+ aClipRect2.iTl.iX = aPosition.iX + aBaselineOffset- height;
+ aClipRect2.iTl.iY = aPosition.iY;
+ aClipRect2.iBr.iX = aPosition.iX + aBaselineOffset + 1;
+ aClipRect2.iBr.iY = aPosition.iY + advance;
+ if (leftBearing < 0)
+ {
+ aClipRect2.iTl.iY += leftBearing;
+ aMargin = -leftBearing;
+ }
+ if (rightBearing < 0)
+ {
+ aClipRect2.iBr.iY -= rightBearing;
+ }
+ }
+ }
+
+
+/**
+Draws text vertically, clipped to a specified rectangle, using a baseline offset, alignment and margin.
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aClipFillRect The clipping rectangle (this rect will also be filled before text is plotted).
+@param aBaselineOffset Number of pixels to offset the baseline by.
+@param aUp ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+@param aVert Vertical alignment of the text relative to the specified rectangle.
+@param aMargin Offset of the text from the position within the rectangle, using the specified alignment.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush style is neither ENullBrush
+ nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawTextVertical(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TRect& aClipFillRect, TInt aBaselineOffset,
+ TBool aUp, DirectGdi::TTextAlign aVert, TInt aMargin)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawTextVertical");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ // This next check covers both bitmap and open fonts
+ const CBitmapFont* bitmapFont = iFont.Address();
+ GRAPHICS_ASSERT_ALWAYS(bitmapFont != 0, EDirectGdiPanicNoFontSelected);
+ DrawTextVertical(aText, aParam, NULL, &aClipFillRect, &aClipFillRect, aBaselineOffset, -1, aUp, aVert, aMargin);
+ }
+
+
+/**
+Draws text vertically, clipped to a specified rectangle, using a baseline offset, alignment and margin.
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aClipFillRect The clipping rectangle (this rect will also be filled before text is plotted).
+@param aBaselineOffset Number of pixels to offset the baseline by.
+@param aTextWidth Number of pixels to clip the text to.
+@param aUp ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+@param aVert Vertical alignment of the text relative to the specified rectangle.
+@param aMargin Offset of the text from the position within the rectangle, using the specified alignment.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush style is neither ENullBrush
+ nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+*/
+EXPORT_C void CDirectGdiContext::DrawTextVertical(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TRect& aClipFillRect, TInt aBaselineOffset,
+ TInt aTextWidth, TBool aUp, DirectGdi::TTextAlign aVert, TInt aMargin)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawTextVertical");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ // This next check covers both bitmap and open fonts
+ const CBitmapFont* bitmapFont = iFont.Address();
+ GRAPHICS_ASSERT_ALWAYS(bitmapFont != 0, EDirectGdiPanicNoFontSelected);
+ DrawTextVertical(aText, aParam, NULL, &aClipFillRect, &aClipFillRect, aBaselineOffset, aTextWidth, aUp, aVert, aMargin);
+ }
+
+
+/**
+The private general DrawTextVertical() routine that implements all the others.
+Two clipping rectangles received from different routines. The final rectangle will be calculated as intersection
+of first and second clipping rectangle. If aClipRect2 is empty, the error state is set to KErrArgument.
+
+@param aText The text string to be drawn.
+@param aParam Parameters used in drawing text.
+@param aClipRect1 Pointer to first clipping rectangle.
+@param aClipRect2 Pointer to second clipping rectangle.
+@param aFillRect Pointer to rectangle to be filled before text plotting.
+@param aBaselineOffset Number of pixels to offset the baseline by.
+@param aTextWidth Number of pixels to clip the text to. If negative, the text will not be clipped
+@param aUp ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+@param aVert Vertical alignment of the text relative to the specified rectangle.
+@param aMargin Offset of the text from the position within the rectangle, using the specified alignment.
+
+@panic DGDI 10, if the active font is an outline and/or shadow font and the brush style is neither ENullBrush
+ nor ESolidBrush.
+@panic DGDI 11, if a font has not been set prior to calling DrawText().
+@panic DGDI 22, if aClipRect2 is NULL.
+*/
+void CDirectGdiContext::DrawTextVertical(const TDesC& aText, const DirectGdi::TTextParameters* aParam, const TRect* aClipRect1, const TRect* aClipRect2, const TRect* aFillRect,
+ TInt aBaselineOffset, TInt aTextWidth, TBool aUp, DirectGdi::TTextAlign aVert, TInt aMargin)
+ {
+ GRAPHICS_ASSERT_ALWAYS(aClipRect2, EDirectGdiPanicBadParameter);
+
+ TRect clipRect2 = *aClipRect2;
+ clipRect2.Move(iOrigin);
+
+ TRect clipRect(clipRect2);
+ if (aClipRect1 != NULL)
+ {
+ if(aClipRect1->IsEmpty())
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+ TRect clipRect1 = *aClipRect1;
+ clipRect1.Move(iOrigin);
+ clipRect.Intersection(clipRect1);
+ }
+
+ if ((aFillRect != NULL) && (iBrushStyle != ENullBrush))
+ {
+ // fill the box if necessary
+ TRect fillBox = *aFillRect;
+ fillBox.Move(iOrigin);
+ if (fillBox.Intersects(clipRect))
+ {
+ fillBox.Intersection(clipRect);
+ iEngine->SetPenStyle(DirectGdi::ENullPen); // Fill box, don't outline it
+ iEngine->DrawRect(*aFillRect);
+ iEngine->SetPenStyle(iPenStyle); // Put the pen style back
+ }
+ }
+ if (!aText.Length())
+ {
+ return;
+ }
+ if (aClipRect2->IsEmpty())
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+
+ const CBitmapFont* bitmapFont = iFont.Address();
+ GRAPHICS_ASSERT_ALWAYS(bitmapFont != 0, EDirectGdiPanicNoFontSelected);
+
+ CFont::TMeasureTextInput input;
+ //CFont::TMeasureTextOutput
+ if (aParam)
+ {
+ GRAPHICS_ASSERT_ALWAYS(aParam->iStart < aParam->iEnd ,EDirectGdiPanicBadParameter);
+ input.iStartInputChar = aParam->iStart;
+ input.iEndInputChar = Min(aText.Length(),aParam->iEnd);
+ }
+ TInt width = iFont.MeasureText(aText,&input);
+ TOpenFontMetrics metrics;
+ iFont.GetFontMetrics(metrics);
+
+ if (aTextWidth < 0)
+ {
+ aTextWidth = width;
+ }
+ TPoint coords;
+ coords.iX = clipRect2.iTl.iX;
+ TInt directionalMultiplier = aUp ? -1 : 1;
+ coords.iY = aUp ? clipRect2.iBr.iY - 1 : clipRect2.iTl.iY;
+ //
+ // iX calculation, for example: ascent(a)=18 descent(d)=2 size=boxwidth=fontheight(h)=20 baseline=ascent
+ // pre: iX = 0
+ //
+ // hhhhhhhhhhhhhhhhhhhh
+ // 01234567890123456789
+ // aaaaaaaaaaaaaaaaaadd aUp=ETrue
+ // ^
+ // iX = 18 (baseline)
+ //
+ // ddaaaaaaaaaaaaaaaaaa aUp=EFalse
+ // ^
+ // iX = 1 (instead of 2 ie 20-18-1 which is boxwidth-baseline-1)
+ //
+ coords.iX += aUp ? aBaselineOffset : clipRect2.Width() - aBaselineOffset - 1;
+ switch (aVert)
+ {
+ case DirectGdi::ELeft:
+ coords.iY += aMargin * directionalMultiplier;
+ break;
+ case DirectGdi::ECenter:
+ coords.iY += (((clipRect2.iBr.iY - clipRect2.iTl.iY - aTextWidth) >> 1) + aMargin) * directionalMultiplier;
+ break;
+ case DirectGdi::ERight:
+ coords.iY += (clipRect2.iBr.iY - clipRect2.iTl.iY - aTextWidth - aMargin) * directionalMultiplier;
+ break;
+ default:
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+ iLastPrintPosition = coords;
+ coords.iX += bitmapFont->iAlgStyle.iBaselineOffsetInPixels * directionalMultiplier;
+ TInt prewidth = width + iCharJustExcess + iWordJustExcess;
+ iLastPrintPosition.iY -= aUp ? prewidth - 1 : -prewidth;
+ if (clipRect.IsEmpty() || !width)
+ {
+ if (iAutoUpdateJustification)
+ {
+ UpdateJustificationVertical(aText, aParam, aUp);
+ }
+ return;
+ }
+
+ /*
+ Set up the parameter block for character positioning.
+ Draw left to right, because although the text is being drawn vertically,
+ it is done by rotating the baseline 90 degrees and drawing in the ordinary way, not by drawing
+ the characters in their normal orientation but in a vertical column.
+ */
+ CFont::TPositionParam param;
+ param.iText.Set(aText);
+ param.iPen = coords;
+ TInt endDraw = aText.Length();
+ if (aParam)
+ {
+ param.iPosInText = aParam->iStart;
+ endDraw = Min(aText.Length(),aParam->iEnd);
+ }
+ else
+ {
+ param.iPosInText = 0;
+ }
+
+ // Draw the text.
+ DoDrawTextVertical(param, aUp, endDraw, clipRect);
+ if(iAutoUpdateJustification)
+ {
+ UpdateJustificationVertical(aText, aParam, aUp);
+ }
+ }
+
+
+/**
+Draws vertical text within the clipping area
+
+@param aParam Defines glyph code, ligature creation and diacritic placement
+@param aUp ETrue, text is rotated 90 degrees anti-clockwise; EFalse, text is rotated 90 degrees clockwise.
+@param aEnd The end position within the text descriptor to draw.
+@param aClipRect The clipping rectangle.
+
+@pre iFont is a valid CFont.
+
+@panic DGDI 13, if the active font is an outline and/or shadow font and the brush style is neither ENullBrush
+ nor ESolidBrush.
+*/
+void CDirectGdiContext::DoDrawTextVertical(CFont::TPositionParam& aParam, TBool aUp, const TInt aEnd, TRect& aClipRect)
+ {
+ const CBitmapFont* bitmapFont = iFont.Address();
+ if ((bitmapFont->GlyphBitmapType() == EFourColourBlendGlyphBitmap) && !((iBrushStyle == DirectGdi::ENullBrush) || (iBrushStyle == DirectGdi::ESolidBrush)))
+ {
+ //For future compatibility it is better if brush style of ENullBrush or ESolidBrush is used
+ //when drawing outline and shadow fonts.
+ GRAPHICS_PANIC_ALWAYS(EDirectGdiPanicInvalidBrushStyle);
+ }
+
+ TPoint startPen = aParam.iPen;
+ TInt charClipping = aClipRect.iTl.iY;
+ TInt underlineTop = 0;
+ TInt underlineBottom = 0;
+
+ //for linked fonts need an adjustment to the underline postion
+ TInt underlineStrikeoutOffset = BaselineCorrection();
+
+ if (iUnderline == DirectGdi::EUnderlineOn)
+ {
+ GetUnderlineMetrics(underlineTop, underlineBottom);
+ underlineTop+=underlineStrikeoutOffset;
+ underlineBottom+=underlineStrikeoutOffset;
+ }
+ TInt strikeTop = 0;
+ TInt strikeBottom = 0;
+ if (iStrikethrough == DirectGdi::EStrikethroughOn)
+ {
+ GetStrikethroughMetrics(strikeTop, strikeBottom);
+ strikeTop+=underlineStrikeoutOffset;
+ strikeBottom+=underlineStrikeoutOffset;
+ }
+
+ const DirectGdi::TGraphicsRotation rotation = aUp ? DirectGdi::EGraphicsRotation270 : DirectGdi::EGraphicsRotation90;
+ iEngine->BeginDrawGlyph();
+ RShapeInfo shapeInfo;
+ while (aParam.iPosInText < aEnd)
+ {
+ TPoint startPen2 = aParam.iPen;
+ if (!iFont.GetCharacterPosition2(aParam, shapeInfo))
+ {
+ continue;
+ }
+ Rotate(aParam.iPen, startPen2, aUp);
+ TInt adjustment = 0;
+ if(iCharJustExcess && (iCharJustNum > 0)) // character clipping/justification
+ {
+ adjustment = CGraphicsContext::JustificationInPixels(iCharJustExcess, iCharJustNum);
+ if (adjustment < 0)
+ {
+ aClipRect.iTl.iY = aParam.iPen.iY + (aUp ? -adjustment : adjustment);
+ }
+ }
+
+ CFont::TPositionParam::TOutput* output = aParam.iOutput;
+ for (TInt i = 0; i < aParam.iOutputGlyphs; i++, output++)
+ {
+ Rotate(output->iBounds.iTl, startPen2, aUp);
+
+ //get the character metrics for the glyph type
+ TOpenFontCharMetrics characterParams;
+ const TUint8* bitmap;
+ TSize size;
+ //note may now be using a glyph code, and not a character
+ iFont.GetCharacterData(aParam.iOutput[i].iCode,characterParams,bitmap,size);
+ TGlyphBitmapType glyphType = characterParams.GlyphType();
+
+ switch (glyphType)
+ {
+ case EAntiAliasedGlyphBitmap:
+ case EFourColourBlendGlyphBitmap:
+ case EDefaultGlyphBitmap:
+ iEngine->DrawGlyph(output->iBounds.iTl, output->iCode, output->iBitmap, glyphType, output->iBitmapSize, aClipRect, rotation);
+ break;
+
+ default:
+ //if the outline or shadow is not specified for the character, then use the font setting
+ iEngine->DrawGlyph(output->iBounds.iTl, output->iCode, output->iBitmap, bitmapFont->GlyphBitmapType(), output->iBitmapSize, aClipRect, rotation);
+ break;
+ }
+ }
+
+ aClipRect.iTl.iY = charClipping;
+ if (adjustment)
+ {
+ aParam.iPen.iY += aUp ? -adjustment : adjustment;
+ }
+ if ((iWordJustExcess > 0) && (iWordJustNum > 0) && (aParam.iOutput[0].iCode == 0x0020)) // word justification
+ {
+ adjustment = CGraphicsContext::JustificationInPixels(iWordJustExcess, iWordJustNum);
+ aParam.iPen.iY += aUp ? -adjustment : adjustment;
+ }
+ }
+ iEngine->EndDrawGlyph();
+ if (shapeInfo.IsOpen())
+ {
+ shapeInfo.Close();
+ }
+
+ if (iUnderline == DirectGdi::EUnderlineOn)
+ {
+ TRect underlineRect; // underline
+ if (aUp)
+ {
+ underlineRect.SetRect(startPen.iX + underlineTop, aParam.iPen.iY, startPen.iX + underlineBottom, startPen.iY + 1);
+ underlineRect.iTl.iY = underlineRect.iBr.iY - underlineRect.Height();
+ }
+ else
+ {
+ underlineRect.SetRect(startPen.iX - underlineBottom, startPen.iY, startPen.iX - underlineTop, aParam.iPen.iY);
+ underlineRect.iBr.iY = underlineRect.iTl.iY + underlineRect.Height();
+ underlineRect.iTl.iX++; // adjust for rect not including last line
+ underlineRect.iBr.iX++;
+ }
+ FillRect(underlineRect, iPenColor, aClipRect);
+ }
+
+ if (iStrikethrough == DirectGdi::EStrikethroughOn)
+ {
+ TRect strikethroughRect; // strikethrough
+ if (aUp)
+ {
+ strikethroughRect.SetRect(startPen.iX + strikeTop, aParam.iPen.iY, startPen.iX + strikeBottom, startPen.iY + 1);
+ strikethroughRect.iTl.iY = strikethroughRect.iBr.iY - strikethroughRect.Height();
+ }
+ else
+ {
+ strikethroughRect.SetRect(startPen.iX - strikeBottom, startPen.iY, startPen.iX - strikeTop, aParam.iPen.iY);
+ strikethroughRect.iBr.iY = strikethroughRect.iTl.iY + strikethroughRect.Height();
+ strikethroughRect.iTl.iX++;
+ strikethroughRect.iBr.iX++;
+ }
+ FillRect(strikethroughRect, iPenColor, aClipRect);
+ }
+ }
+
+
+/**
+Transform a vector, defined by a point relative to an origin, from left-to-right to up or down.
+
+@param aPoint A point relative to the origin aOrigin.
+@param aOrigin The origin to use when transforming the point aPoint.
+@param aUp If ETrue, then transform the point from left-right to up, otherwise transform from
+left-right to down.
+*/
+void CDirectGdiContext::Rotate(TPoint& aPoint, const TPoint& aOrigin, TBool aUp)
+ {
+ TInt dx = aPoint.iX - aOrigin.iX;
+ TInt dy = aPoint.iY - aOrigin.iY;
+ if (aUp)
+ {
+ aPoint.iX = aOrigin.iX + dy;
+ aPoint.iY = aOrigin.iY - dx;
+ }
+ else
+ {
+ aPoint.iX = aOrigin.iX - dy;
+ aPoint.iY = aOrigin.iY + dx;
+ }
+ }
+
+
+/**
+Can be used to find out the top and bottom of an underline for the active font.
+This allows correct calculation of the area required in which to draw text with underline.
+
+@param aTop The top of the underline position.
+@param aBottom The bottom of the underline position.
+*/
+void CDirectGdiContext::GetUnderlineMetrics(TInt& aTop, TInt& aBottom)
+ {
+ const TInt width = Max((iFont.HeightInPixels() / 10), 1);
+ aTop = 1 + (width >> 1);
+ aBottom = aTop + width;
+ }
+
+
+/**
+Get the top and bottom of a strikethrough line for the current font, relative to the baseline.
+
+@param aTop The top of the strikethrough position.
+@param aBottom The bottom of the strikethrough position.
+*/
+void CDirectGdiContext::GetStrikethroughMetrics(TInt& aTop, TInt& aBottom)
+ {
+ aTop = -(iFont.AscentInPixels() * 5/12) - 1;
+ aBottom = aTop + Max((iFont.HeightInPixels() / 10), 1);
+ }
+
+
+/**
+Moves the internal drawing position relative to the co-ordinate origin, without drawing a line.
+A subsequent call to DrawLineTo() or DrawLineBy() will then use the new internal drawing position
+as the start point for the line drawn.
+
+The operations DrawLine(), DrawLineTo(), DrawLineBy() and DrawPolyline() also change the internal drawing
+position to the last point of the drawn line(s). The internal drawing position is set to the co-ordinate
+origin if no drawing or moving operations have yet taken place.
+
+@see CDirectGdiContext::MoveBy(const TPoint&)
+
+@param aPoint The point to move the internal drawing position to.
+
+@pre The rendering target has been activated.
+@post Request to move the internal drawing position to the specified point has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::MoveTo(const TPoint& aPoint)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::MoveTo(%d,%d)", aPoint.iX, aPoint.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ iEngine->MoveTo(aPoint);
+ }
+
+
+/**
+Moves the internal drawing position by a vector, relative to the current position, without drawing a line.
+A subsequent call to DrawLineTo() or DrawLineBy() will then use the new internal drawing position
+as the start point for the line drawn.
+
+The operations DrawLine(), DrawLineTo(), DrawLineBy() and DrawPolyline() also change the internal drawing
+position to the last point of the drawn line(s). The internal drawing position is set to the co-ordinate
+origin if no drawing or moving operations have yet taken place.
+
+@see CDirectGdiContext::MoveTo(const TPoint&)
+
+@param aVector The vector to move the internal position by.
+
+@pre The rendering target has been activated.
+@post Request to move the internal drawing position by a vector has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::MoveBy(const TPoint& aVector)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::MoveBy(%d,%d)", aVector.iX, aVector.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if (aVector != TPoint(0,0))
+ {
+ iEngine->MoveBy(aVector);
+ }
+ }
+
+
+/**
+Draws a point at given location using current pen colour and size.
+If the pen size is greater than 1x1 pixel, a filled circle/ellipse with current pen
+colour should be drawn with the given position as the centre.
+
+@param aPoint The position to plot.
+
+@pre The rendering target has been activated.
+@post Request to draw a point or filled circle/ellipse has been accepted.
+ There is no guarantee that the request has been processed when the method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+
+@see CDirectGdiContext::SetPenSize(const TSize&)
+@see CDirectGdiContext::SetPenColor(TRgb)
+@see CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode)
+*/
+EXPORT_C void CDirectGdiContext::Plot(const TPoint& aPoint)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::Plot(%d,%d)", aPoint.iX, aPoint.iY);
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ if (iPenStyle == DirectGdi::ENullPen || iPenSize.iWidth == 0 || iPenSize.iHeight == 0)
+ {
+ return;
+ }
+ iEngine->Plot(aPoint);
+ }
+
+
+/**
+Resets drawing state to its default settings. This operation does not unbind the current target.
+@pre None.
+@post The drawing state is reset to default values. Subsequent drawing will use the default settings until they are changed to different values.
+*/
+EXPORT_C void CDirectGdiContext::Reset()
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::Reset");
+ iEngine->Reset();
+
+ // Explicit calls are made to the engine to apply the defaults.
+ // Set() methods should generally not be used as they perform unnecessary checks, and may also
+ // block the call to the engine if the value being set is the same as the constructor's default.
+ // Clipping regions.
+ iClippingRegion.Clear();
+ iEngine->ResetClippingRegion();
+ // Origin.
+ iOrigin.SetXY(0,0);
+ iEngine->SetOrigin(iOrigin);
+ // Font.
+ iEngine->ResetFont();
+ iFont.Reset();
+ // Text.
+ iLastPrintPosition.SetXY(0,0);
+ iAutoUpdateJustification = ETrue;
+ SetCharJustification(0, 0);
+ SetWordJustification(0, 0);
+ SetStrikethroughStyle(DirectGdi::EStrikethroughOff);
+ SetUnderlineStyle(DirectGdi::EUnderlineOff);
+ // Pen colour.
+ iPenColor = KRgbBlack;
+ iEngine->SetPenColor(iPenColor);
+ // Pen size.
+ iPenSize = TSize(1,1);
+ iEngine->SetPenSize(iPenSize);
+ // Pen style.
+ iPenStyle = DirectGdi::ESolidPen;
+ iEngine->SetPenStyle(iPenStyle);
+ // Draw mode.
+ iDrawMode = DirectGdi::EDrawModePEN;
+ iEngine->SetDrawMode(iDrawMode);
+ // Text shadow colour.
+ iTextShadowColor = KRgbGray;
+ iEngine->SetTextShadowColor(iTextShadowColor);
+ // Brush colour.
+ iBrushColor = KRgbWhite;
+ iEngine->SetBrushColor(iBrushColor);
+ // Brush style.
+ iBrushStyle = DirectGdi::ENullBrush;
+ iEngine->SetBrushStyle(iBrushStyle);
+ // Brush pattern.
+ CleanUpBrushPattern();
+ iEngine->ResetBrushPattern();
+ iBrushPatternUsed = EFalse;
+ // Brush origin.
+ iBrushOrigin.SetXY(0,0);
+ iEngine->SetBrushOrigin(iBrushOrigin);
+ // Internal drawing position.
+ iEngine->MoveTo(TPoint(0,0));
+ }
+
+
+/**
+Sets the colour for clearing, filling the area of shapes and the background of text boxes.
+
+The default brush colour is white. However, the default brush style is ENullBrush, so when drawing
+to a target the default appears to be the target's background colour.
+
+@see CDirectGdiContext::Clear()
+@see CDirectGdiContext::Clear(const TRect&)
+@see CDirectGdiContext::DrawRect()
+@see CDirectGdiContext::DrawRoundRect()
+@see CDirectGdiContext::DrawPolygon()
+@see CDirectGdiContext::DrawPie()
+
+@param aColor Brush colour.
+
+@pre None.
+@post The new brush colour will be used on subsequent drawing operations if a brush style making
+ use of the brush colour is used. The new brush colour remains in effect until another SetBrushColor()
+ with a different parameter is called.
+*/
+EXPORT_C void CDirectGdiContext::SetBrushColor(const TRgb& aColor)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetBrushColor(%d)", aColor.Internal());
+ if (aColor != iBrushColor)
+ {
+ iBrushColor = aColor;
+ iEngine->SetBrushColor(iBrushColor);
+ }
+ }
+
+
+/**
+Sets the brush pattern origin which specifies the start of a pattern tile.
+Shapes can be considered as a view port into a continuous pattern tile covering the entire
+area of rendering target. The default origin is TPoint(0,0).
+
+@see CDirectGdiContext::SetBrushPattern()
+
+@param aOrigin An origin point for the brush. The coordinates are relative
+ to the rectangle to fill, i.e. specify TPoint(0,0) to align the pattern flush with
+ the top and left hand sides of the rectangle.
+
+@pre None.
+@post New brush origin will be used when filling an area with a pattern is used on
+ subsequent drawing operations. It remains in effect until another SetBrushOrigin()
+ with a different parameter is called.
+*/
+EXPORT_C void CDirectGdiContext::SetBrushOrigin(const TPoint& aOrigin)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::SetBrushOrigin(%d,%d)", aOrigin.iX, aOrigin.iY);
+ if (aOrigin != iBrushOrigin)
+ {
+ iBrushOrigin = aOrigin;
+ iEngine->SetBrushOrigin(iBrushOrigin);
+ }
+ }
+
+
+/**
+Sets the brush style used when filling the area of shapes and the background of text boxes.
+Use ENullBrush to draw the outline of a fillable shape on its own, without filling.
+
+The error state is set to KErrArgument if aBrushStyle is an invalid brush style.
+
+@see DirectGdi::TBrushStyle
+
+@param aBrushStyle The brush style to set.
+
+@pre If aBrushStyle is EPatternedBrush, a pattern must have been set first using SetBrushPattern().
+@post New brush style will be used for subsequent drawing operations, and remains in effect
+ until another SetBrushStyle() with a different parameter is called.
+@panic DGDI 9, if aBrushStyle is EPatternedBrush but no brush pattern has successfully been set.
+*/
+EXPORT_C void CDirectGdiContext::SetBrushStyle(DirectGdi::TBrushStyle aBrushStyle)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetBrushStyle(%d)", aBrushStyle);
+ if (aBrushStyle < DirectGdi::ENullBrush || aBrushStyle > DirectGdi::EDiamondCrossHatchBrush)
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+
+ if (aBrushStyle != iBrushStyle)
+ {
+ GRAPHICS_ASSERT_ALWAYS(aBrushStyle != DirectGdi::EPatternedBrush || iBrushPatternUsed, EDirectGdiPanicBrushPatternNotSet);
+ iBrushStyle = aBrushStyle;
+ iEngine->SetBrushStyle(iBrushStyle);
+ }
+ }
+
+
+/**
+Sets a clipping region which will be used to clip subsequent rendering operations on the current target.
+This operation is non-additive, any previous clipping region setting is replaced by the new one. A clipping
+region can contain one or more rectangles and is specified in absolute values in the target coordinate system.
+By default (when a target is activated for the first time) no clipping region is set and any drawing
+operations will be clipped automatically to the full area of the rendering target.
+
+In the event of a failure, the error state is set to KErrArgument if the given region is invalid or not
+fully contained within the area of target, otherwise one of the system-wide error codes.
+
+@see CDirectGdiContext::ResetClippingRegion()
+
+@param aRegion The new clipping region.
+
+@pre Region is not empty and is fully contained within the full area of the target.
+@post Subsequent rendering operations will be clipped to the given region if there is no error
+ while performing the operation, otherwise previous clipping region settings will be retained.
+*/
+EXPORT_C void CDirectGdiContext::SetClippingRegion(const TRegion& aRegion)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::SetClippingRegion");
+ if (aRegion.CheckError())
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+ iClippingRegion.Copy(aRegion);
+ if (iClippingRegion.CheckError())
+ {
+ iDriver.SetError(KErrNoMemory);
+ return;
+ }
+ iEngine->SetClippingRegion(iClippingRegion);
+ }
+
+
+/**
+Sets the drawing mode which will affect the way pen and brush colour are used in rendering operations.
+The default drawing mode is EDrawModePEN.
+
+The error state is set to KErrArgument if aDrawMode is an invalid draw mode.
+
+@see DirectGdi::TDrawMode
+
+@param aDrawMode The drawing mode.
+
+@pre None.
+@post The new drawing mode will be applied to subsequent rendering operations, and remains in effect
+ until another SetDrawMode() with a different parameter is called.
+*/
+EXPORT_C void CDirectGdiContext::SetDrawMode(DirectGdi::TDrawMode aDrawMode)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetDrawMode(%d)", aDrawMode);
+ if (aDrawMode != DirectGdi::EDrawModePEN && aDrawMode != DirectGdi::EDrawModeWriteAlpha)
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+
+ if (iDrawMode != aDrawMode)
+ {
+ iDrawMode = aDrawMode;
+ iEngine->SetDrawMode(iDrawMode);
+ }
+ }
+
+
+/**
+Sets the origin of the drawing engine coordinate system. By default this is TPoint(0,0) and
+coincides with the origin of the target coordinate system which is at the top-left corner of
+the full area of target. The X value increases from left to right, and Y value increases from
+top to bottom. Integer values are used to represent the position within the coordinate system.
+
+All drawing operations are done relative to the engine’s origin. However, the clipping region
+is always specified in absolute coordinate values (using the target coordinate system) and is
+not affected by changes to the drawing engine’s coordinate system origin.
+
+@param aPoint The new origin for the drawing engine’s coordinate system.
+
+@pre None.
+@post The origin of the drawing engine’s coordinate system is moved to the given position.
+ All subsequent drawing operations will be done relative to the new origin. The new origin remains
+ in effect until SetOrigin() is called again with a different parameter.
+*/
+EXPORT_C void CDirectGdiContext::SetOrigin(const TPoint& aPoint)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::SetOrigin(%d,%d)", aPoint.iX, aPoint.iY);
+ if (aPoint != iOrigin)
+ {
+ iOrigin = aPoint;
+ iEngine->SetOrigin(iOrigin);
+ }
+ }
+
+
+/**
+Sets the colour that will be used for drawing lines, outlines of filled shapes and text. The
+default pen colour is black. For outline and shadow fonts the alpha value of the pen colour will be
+used for blending the font to the destination.
+
+@see CDirectGdiContext::Plot()
+@see CDirectGdiContext::DrawLine()
+@see CDirectGdiContext::DrawRoundRect()
+@see CDirectGdiContext::DrawRect()
+@see CDirectGdiContext::DrawPolyLine()
+@see CDirectGdiContext::DrawPolyLineNoEndPoint()
+@see CDirectGdiContext::DrawPolygon()
+@see CDirectGdiContext::DrawPie()
+@see CDirectGdiContext::DrawArc()
+@see CDirectGdiContext::DrawText()
+
+@param aColor The pen colour.
+
+@pre None.
+@post The new pen colour will be used for subsequent drawing of lines, outlines of filled shapes and text.
+ The new pen colour remains in effect until another SetPenColor() with a different parameter is called.
+*/
+EXPORT_C void CDirectGdiContext::SetPenColor(const TRgb& aColor)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetPenColor(%d)", aColor.Internal());
+ if (aColor != iPenColor)
+ {
+ iPenColor = aColor;
+ iEngine->SetPenColor(iPenColor);
+ }
+ }
+
+
+/**
+Sets the pen or line drawing style.
+
+The pen style is used to draw lines and outlines of shapes. ENullPen can be used if border or
+outlines are not required (when drawing a filled shape). The default pen style is ESolidPen.
+
+The error state is set to KErrArgument if aPenStyle is an invalid pen style.
+
+@see CDirectGdiContext::Plot()
+@see CDirectGdiContext::DrawLine()
+@see CDirectGdiContext::DrawRoundRect()
+@see CDirectGdiContext::DrawRect()
+@see CDirectGdiContext::DrawPolyLine()
+@see CDirectGdiContext::DrawPolyLineNoEndPoint()
+@see CDirectGdiContext::DrawPolygon()
+@see CDirectGdiContext::DrawPie()
+@see CDirectGdiContext::DrawArc()
+@see DirectGdi::TPenStyle
+
+@param aPenStyle The pen style.
+
+@pre None.
+@post The new pen style will be applied for subsequent drawing lines and outlines of filled shapes.
+ The new pen style remains in effect until another SetPenStyle() with a different parameter is called.
+*/
+EXPORT_C void CDirectGdiContext::SetPenStyle(DirectGdi::TPenStyle aPenStyle)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetPenStyle(%d)", aPenStyle);
+ if (aPenStyle < DirectGdi::ENullPen || aPenStyle > DirectGdi::EDotDotDashPen)
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+
+ if (aPenStyle != iPenStyle)
+ {
+ iPenStyle = aPenStyle;
+ iEngine->SetPenStyle(iPenStyle);
+ }
+ }
+
+
+/**
+Sets the pen size for drawing lines or the outlines of a filled shape. The default pen size is 1.
+Lines with pen size greater than 1 are drawn with rounded ends that extend beyond the end points
+and are always drawn using EDrawModePEN for compatibility reasons.
+
+The error state is set to KErrArgument if the specified width or height is negative.
+
+@see CDirectGdiContext::Plot()
+@see CDirectGdiContext::DrawLine()
+@see CDirectGdiContext::DrawRoundRect()
+@see CDirectGdiContext::DrawRect()
+@see CDirectGdiContext::DrawPolyLine()
+@see CDirectGdiContext::DrawPolyLineNoEndPoint()
+@see CDirectGdiContext::DrawPolygon()
+@see CDirectGdiContext::DrawPie()
+@see CDirectGdiContext::DrawArc()
+
+@param aSize The pen size.
+
+@pre None.
+@post The new pen size is used for subsequent drawing lines and outlines of filled shapes. The new
+ pen size remains in effect until another SetPenSize() with a different parameter is called.
+*/
+EXPORT_C void CDirectGdiContext::SetPenSize(const TSize& aSize)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::SetPenSize(%d,%d)", aSize.iWidth, aSize.iHeight);
+ if ((aSize.iWidth < 0) || (aSize.iHeight < 0))
+ {
+ iDriver.SetError(KErrArgument);
+ return;
+ }
+
+ if (aSize != iPenSize)
+ {
+ iPenSize = aSize;
+ iEngine->SetPenSize(iPenSize);
+ }
+ }
+
+
+/**
+Sets the colour that will be used for drawing the shadow for shadowed text.
+
+@param aColor The shadow colour.
+
+@pre None.
+@post The new colour will be used for subsequent drawing of text which has a type EFourColourBlendGlyphBitmap.
+ The shadow component of the text will be filled with this colour.
+ The new pen colour remains in effect until another SetTextShadowColor() with a different parameter is called.
+*/
+EXPORT_C void CDirectGdiContext::SetTextShadowColor(const TRgb& aColor)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetTextShadowColor(%d)", aColor.Internal());
+ if (aColor != iTextShadowColor)
+ {
+ iTextShadowColor = aColor;
+ iEngine->SetTextShadowColor(aColor);
+ }
+ }
+
+
+/**
+Sets the character justification.
+The function provides a concrete implementation of the pure virtual function CGraphicsContext::SetCharJustification().
+The function behaviour is the same as documented (in detail) in that class.
+
+@param aExcessWidth The excess width (in pixels) to be distributed between the specified number of characters.
+@param aNumChars The number of characters involved.
+
+@see CGraphicsContext::SetCharJustification()
+*/
+EXPORT_C void CDirectGdiContext::SetCharJustification(TInt aExcessWidth, TInt aNumChars)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::SetCharJustification(%d,%d)", aExcessWidth, aNumChars);
+ if (aExcessWidth == 0 || aNumChars <= 0)
+ {
+ iCharJustExcess = 0;
+ iCharJustNum = 0;
+ }
+ else
+ {
+ iCharJustExcess = aExcessWidth;
+ iCharJustNum = aNumChars;
+ }
+ }
+
+
+/**
+Sets the word justification.
+The function provides a concrete implementation of the pure virtual function CGraphicsContext::SetWordJustification().
+The function behaviour is the same as documented (in detail) in that class.
+
+@param aExcessWidth The width (in pixels) to be distributed between the specified number of spaces.
+ It may be positive, in which case the text is stretched, or negative, in which case it is shrunk.
+@param aNumGaps The number of word spaces (characters with the code U+0020) over which the change in width is distributed.
+
+@see CGraphicsContext::SetWordJustification()
+*/
+EXPORT_C void CDirectGdiContext::SetWordJustification(TInt aExcessWidth, TInt aNumGaps)
+ {
+ GRAPHICS_TRACE2("CDirectGdiContext::SetWordJustification(%d,%d)", aExcessWidth, aNumGaps);
+ if (aExcessWidth <= 0 || aNumGaps <= 0)
+ {
+ iWordJustExcess = 0;
+ iWordJustNum = 0;
+ }
+ else
+ {
+ iWordJustExcess = aExcessWidth;
+ iWordJustNum = aNumGaps;
+ }
+ }
+
+
+/**
+Sets the underline style for all subsequently drawn text.
+The function provides a concrete implementation of the pure virtual function CGraphicsContext::SetUnderlineStyle().
+The function behaviour is the same as documented in that class.
+
+@param aUnderlineStyle The underline style to be used.
+
+@see CGraphicsContext::SetUnderlineStyle()
+*/
+EXPORT_C void CDirectGdiContext::SetUnderlineStyle(DirectGdi::TFontUnderline aUnderlineStyle)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetWordJustification(%d)", aUnderlineStyle);
+ iUnderline = aUnderlineStyle;
+ }
+
+
+/**
+Sets the strikethrough style for all subsequently drawn text.
+The function provides a concrete implementation of the pure virtual function CGraphicsContext::SetStrikethroughStyle().
+The function behaviour is the same as documented in that class.
+
+@param aStrikethroughStyle The strikethrough style to be used.
+
+@see CGraphicsContext::SetStrikethroughStyle()
+*/
+EXPORT_C void CDirectGdiContext::SetStrikethroughStyle(DirectGdi::TFontStrikethrough aStrikethroughStyle)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetStrikethroughStyle(%d)", aStrikethroughStyle);
+ iStrikethrough = aStrikethroughStyle;
+ }
+
+
+/**
+Sets the bitmap to be used as the brush pattern when EPatternedBrush is selected.
+The DirectGDI generic layer owns the bitmap and will keep the bitmap until ResetBrushPattern() is called.
+
+The client may modify the content of the bitmap used as the brush pattern. If this is done after
+issuing drawing commands there is no guarantee which bitmap content will be used as brush pattern.
+Clients must call Finish() on the driver before modifying the bitmap content if they want a guaranteed
+result that the previously issued drawing commands will be drawn using the old bitmap brush pattern.
+
+In the event of a failure, the error state is set to KErrCouldNotConnect if no connection to the font
+and bitmap server could be made, KErrBadHandle if the handle of the bitmap is null, KErrUnknown if
+no bitmap could be found with the specified handle number, otherwise one of the system-wide error codes.
+
+@see CDirectGdiContext::SetBrushStyle()
+@see CDirectGdiContext::SetBrushOrigin()
+@see CDirectGdiContext::ResetBrushPattern()
+
+@param aBitmap Bitmap that will be used as the brush pattern.
+
+@pre Bitmap is fully constructed.
+@post Bitmap will be used as the brush pattern for subsequent drawing operations when EPatternedBrush
+ is selected. It remains in effect until ResetBrushPattern() is called.
+*/
+EXPORT_C void CDirectGdiContext::SetBrushPattern(const CFbsBitmap& aBitmap)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetBrushPattern(%d)", aBitmap.Handle());
+ SetBrushPattern(aBitmap.Handle());
+ }
+
+
+/**
+Sets the bitmap to be used as the brush pattern when EPatternedBrush is selected.
+The DirectGDI generic layer owns the bitmap and will keep the bitmap until ResetBrushPattern() is called.
+If the client modifies the content of the bitmap used as the brush pattern after issuing any drawing
+commands that uses that brush pattern, the method does not guarantee whether the old bitmap
+content or the new one will be used as brush pattern. Clients must call Finish() on the driver
+before modifying the bitmap content if they want a guaranteed result that the previously issued
+drawing commands will be drawn using the old bitmap brush pattern.
+
+In the event of a failure, the error state is set to KErrCouldNotConnect if no connection to the font
+and bitmap server could be made, KErrBadHandle if the handle is null, KErrUnknown if no bitmap could
+be found with the specified handle number, otherwise one of the system-wide error codes.
+
+@param aFbsBitmapHandle Bitmap handle that will be used as the brush pattern.
+
+@pre Bitmap belonging to the handle is fully constructed.
+@post Bitmap will be used as the brush pattern for subsequent drawing operations when EPatternedBrush
+ is selected. It remains in effect until ResetBrushPattern() is called.
+@panic DGDI 8, if aFbsBitmapHandle is 0.
+*/
+EXPORT_C void CDirectGdiContext::SetBrushPattern(TInt aFbsBitmapHandle)
+ {
+ GRAPHICS_TRACE1("CDirectGdiContext::SetBrushPattern(%d)", aFbsBitmapHandle);
+ if (aFbsBitmapHandle == KNullHandle)
+ {
+ iDriver.SetError(KErrBadHandle);
+ return;
+ }
+
+ // Check we're not already using the passed brush pattern
+ if (iBrushPattern.Handle() == aFbsBitmapHandle)
+ {
+ return;
+ }
+
+ // Delete any previously saved brush pattern
+ CleanUpBrushPattern();
+
+ TInt result = iBrushPattern.Duplicate(aFbsBitmapHandle);
+ if (result == KErrNone)
+ {
+ result = iEngine->SetBrushPattern(iBrushPattern);
+ }
+
+ if (result == KErrNone)
+ {
+ iBrushPatternUsed = ETrue;
+ }
+ else
+ {
+ iDriver.SetError(result);
+ }
+
+ return;
+ }
+
+
+/**
+Selects the font to be used for text drawing.
+Notes:
+When the font is no longer required, use ResetFont() to free up the memory used.
+If SetFont() is used again without using ResetFont() then the previous font is reset
+automatically. If no font has been selected, and an attempt is made to draw text with
+DrawText(), then a panic occurs.
+
+@see CDirectGdiContext::ResetFont()
+@see CDirectGdiContext::DrawText()
+
+@param aFont The font to be used.
+
+@panic DGDI 12, if aFont has an invalid handle or is not a CFbsFont, or the font cannot be duplicated.
+*/
+EXPORT_C void CDirectGdiContext::SetFont(const CFont* aFont)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::SetFont");
+ // Note: We pass a ptr in, rather than a reference, because otherwise the caller would almost always have to do complex casting
+ GRAPHICS_ASSERT_ALWAYS(aFont->TypeUid() == KCFbsFontUid, EDirectGdiPanicInvalidFont);
+ const CDirectGdiFont* font = reinterpret_cast<const CDirectGdiFont*>(aFont);
+ GRAPHICS_ASSERT_ALWAYS(font->Handle(), EDirectGdiPanicInvalidFont);
+
+ if (iFont.Handle() == font->Handle())
+ {
+ return;
+ }
+ ResetFont();
+ TInt err = iFont.Duplicate(font->Handle());
+ GRAPHICS_ASSERT_ALWAYS(err == KErrNone, EDirectGdiPanicInvalidFont); // This may seem extreme but it is what BitGdi did
+ iEngine->SetFont(iFont.Address()->UniqueFontId());
+ }
+
+
+/**
+Copies the content of a rectangular area on the target to another location.
+The source rect will be intersected with the target’s full extent.
+
+@param aOffset Offset from the top left corner of the rectangle to be copied to the top left corner of the copy.
+@param aRect Area to be copied.
+
+@pre The rendering target has been activated.
+@post Request to copy an area has been accepted. There is no guarantee that the
+ request has been processed when this method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::CopyRect(const TPoint& aOffset, const TRect& aRect)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::CopyRect");
+ if (aRect.IsEmpty() || aOffset == TPoint(0,0))
+ {
+ return;
+ }
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ iEngine->CopyRect(aOffset, aRect);
+ }
+
+/**
+Copies all settings from the specified DirectGDI context.
+
+@param aGc The DirectGDI context whose settings are to be copied.
+*/
+EXPORT_C void CDirectGdiContext::CopySettings(const CDirectGdiContext& aGc)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::CopySettings");
+ SetOrigin(aGc.iOrigin);
+ SetFont(&(aGc.iFont));
+ SetCharJustification(aGc.iCharJustExcess, aGc.iCharJustNum);
+ SetWordJustification(aGc.iWordJustExcess, aGc.iWordJustNum);
+ iLastPrintPosition = aGc.iLastPrintPosition;
+ SetStrikethroughStyle(aGc.iStrikethrough);
+ SetUnderlineStyle(aGc.iUnderline);
+ SetPenColor(aGc.iPenColor);
+ SetPenSize(aGc.iPenSize);
+ SetPenStyle(aGc.iPenStyle);
+ SetDrawMode(aGc.iDrawMode);
+ SetTextShadowColor(aGc.iTextShadowColor);
+ SetBrushColor(aGc.iBrushColor);
+ SetBrushStyle(aGc.iBrushStyle);
+ if(aGc.iBrushPattern.Handle())
+ {
+ SetBrushPattern(aGc.iBrushPattern.Handle());
+ }
+ iBrushPatternUsed = aGc.iBrushPatternUsed;
+ SetBrushOrigin(aGc.iBrushOrigin);
+ }
+
+/**
+Updates the justification settings.
+This function assumes that NoJustifyAutoUpdate() has not been used.
+
+@param aText The text for which justification is to be adjusted.
+@param aParam Parameters used in drawing text.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 13, if NoJustifyAutoUpdate() had been called prior to this.
+*/
+EXPORT_C void CDirectGdiContext::UpdateJustification(const TDesC& aText, const DirectGdi::TTextParameters* aParam)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::UpdateJustification");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ GRAPHICS_ASSERT_ALWAYS(iAutoUpdateJustification, EDirectGdiPanicAutoUpdateJustificationUsed);
+ if (((iCharJustNum < 1) || (iCharJustExcess == 0)) && ((iWordJustNum < 1) || (iWordJustExcess < 1)))
+ {
+ return;
+ }
+
+ TInt length = aText.Length();
+ CFont::TPositionParam param;
+ param.iText.Set(aText); // Set the start of the string
+ if (aParam)
+ {
+ length = aParam->iEnd;
+ param.iPosInText = aParam->iStart;
+ }
+ TInt excess = 0;
+ TInt glyphs = 0;
+ RShapeInfo shapeInfo;
+ for (TInt count = 0; count < length; count++)
+ {
+ if ((iCharJustNum > 0) && (iCharJustExcess != 0))
+ {
+ excess += CGraphicsContext::JustificationInPixels(iCharJustExcess, iCharJustNum);
+ }
+ if ((iWordJustNum > 0) && (iWordJustExcess > 0) && (aText[count] == ' '))
+ {
+ excess += CGraphicsContext::JustificationInPixels(iWordJustExcess, iWordJustNum);
+ }
+ if (iCharJustNum < (glyphs + length - count)) // there's at least 1 combined glyph to come
+ {
+ // otherwise we can skip this slow bit and just increment
+ if (iFont.GetCharacterPosition2(param, shapeInfo))
+ {
+ count = param.iPosInText - 1; // -1 'cos it gets incremented anyway
+ }
+ }
+ glyphs++;
+ }
+ if (shapeInfo.IsOpen())
+ {
+ shapeInfo.Close();
+ }
+ iLastPrintPosition.iX += excess;
+ }
+
+
+/**
+Updates the justification for vertical text.
+This function assumes that NoJustifyAutoUpdate() has not been used.
+
+@param aText The text for which justification is to be adjusted.
+@param aParam Parameters used in drawing text.
+@param aUp ETrue, if text is to be justified upwards; EFalse, if text is to be justified downwards.
+
+@panic DGDI 7, if the rendering context has not been activated.
+@panic DGDI 13, if NoJustifyAutoUpdate() had been called prior to this.
+*/
+EXPORT_C void CDirectGdiContext::UpdateJustificationVertical(const TDesC& aText, const DirectGdi::TTextParameters* aParam, TBool aUp)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::UpdateJustificationVertical");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+ GRAPHICS_ASSERT_ALWAYS(iAutoUpdateJustification, EDirectGdiPanicAutoUpdateJustificationUsed);
+
+ if (((iCharJustNum < 1) || (iCharJustExcess == 0)) && ((iWordJustNum < 1) || (iWordJustExcess < 1)))
+ {
+ return;
+ }
+
+ TInt length = aText.Length();
+ CFont::TPositionParam param;
+ param.iText.Set(aText); // Set the start of the string
+ if (aParam)
+ {
+ length = aParam->iEnd;
+ param.iPosInText = aParam->iStart;
+ }
+ TInt excess = 0;
+ TInt glyphs = 0;
+ RShapeInfo shapeInfo;
+ for (TInt count = 0; count < length; count++)
+ {
+ if ((iCharJustNum > 0) && (iCharJustExcess != 0))
+ {
+ excess += CGraphicsContext::JustificationInPixels(iCharJustExcess, iCharJustNum);
+ }
+ if ((iWordJustNum > 0) && (iWordJustExcess > 0) && (aText[count] == ' '))
+ {
+ excess += CGraphicsContext::JustificationInPixels(iWordJustExcess, iWordJustNum);
+ }
+ if (iCharJustNum < (glyphs + length - count)) // there's at least 1 combined glyph to come
+ {
+ // otherwise we can skip this slow bit and just increment
+ if (iFont.GetCharacterPosition2(param, shapeInfo))
+ {
+ count = param.iPosInText - 1; // -1 because it gets incremented anyway
+ }
+ }
+ glyphs++;
+ }
+ if (shapeInfo.IsOpen())
+ {
+ shapeInfo.Close();
+ }
+
+ if (aUp)
+ {
+ iLastPrintPosition.iY -= excess;
+ }
+ else
+ {
+ iLastPrintPosition.iY += excess;
+ }
+ }
+
+
+/**
+Selects a font for text drawing but does not take a copy.
+The original must not be destroyed until SetFont(), SetFontNoDuplicate(), ResetFont()
+or the destructor is called.
+
+@param aFont A pointer to the font to be used.
+@panic DGDI 12, if aFont has no handle or is not a CFbsFont.
+*/
+EXPORT_C void CDirectGdiContext::SetFontNoDuplicate(const CDirectGdiFont* aFont)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::SetFontNoDuplicate");
+ // Note: We pass a ptr in, rather than a reference, because otherwise the caller would almost always have to do complex casting
+ GRAPHICS_ASSERT_ALWAYS(aFont->TypeUid() == KCFbsFontUid, EDirectGdiPanicInvalidFont);
+ GRAPHICS_ASSERT_ALWAYS(aFont->Handle(), EDirectGdiPanicInvalidFont);
+
+ if (iFont.Handle() == aFont->Handle())
+ {
+ return;
+ }
+
+ ResetFont();
+ iFont = *aFont;
+ iEngine->SetFont(iFont.Address()->UniqueFontId());
+ }
+
+
+/**
+Checks to see if a brush pattern is currently set.
+
+@return ETrue is a brush pattern is currently set, EFalse if no brush pattern is currently set.
+*/
+EXPORT_C TBool CDirectGdiContext::HasBrushPattern() const
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::HasBrushPattern");
+ return iBrushPatternUsed;
+ }
+
+
+/**
+Tests whether a font is used.
+
+@return ETrue, if a font is being used; EFalse, otherwise.
+*/
+EXPORT_C TBool CDirectGdiContext::HasFont() const
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::HasFont");
+ TBool result = EFalse;
+ if (iFont.Handle() != KNullHandle)
+ result = ETrue;
+ return result;
+ }
+
+
+/**
+Externalises the context and the drawing engine object to the write stream.
+It is important that the font and brush bitmap of the GC is maintained between
+calls to ExternalizeL() and InternalizeL(). The font handle and brush bitmap handle
+is externalised, not the underlying data. This is done for performance reasons.
+
+@param aWriteStream Write stream.
+
+@pre None.
+@post The context and drawing engine object states are written to the write stream.
+
+@see MDirectGdiEngine::InternalizeL
+@leave If there was an error writing to the write stream.
+*/
+EXPORT_C void CDirectGdiContext::ExternalizeL(RWriteStream& aWriteStream)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::ExternalizeL");
+ aWriteStream << KDirectGDIContext_VerNo;
+ iEngine->ExternalizeL(aWriteStream);
+
+ aWriteStream << iOrigin;
+ aWriteStream.WriteInt32L(iFont.Handle());
+ aWriteStream.WriteInt32L(iCharJustExcess);
+ aWriteStream.WriteInt32L(iCharJustNum);
+ aWriteStream.WriteInt32L(iWordJustExcess);
+ aWriteStream.WriteInt32L(iWordJustNum);
+ aWriteStream << iLastPrintPosition;
+ aWriteStream.WriteUint8L(iStrikethrough);
+ aWriteStream.WriteUint8L(iUnderline);
+ aWriteStream << iPenColor;
+ aWriteStream.WriteUint32L(iPenSize.iWidth);
+ aWriteStream.WriteUint32L(iPenSize.iHeight);
+ aWriteStream.WriteUint8L(iPenStyle);
+ aWriteStream.WriteUint8L(iDrawMode);
+ aWriteStream << iTextShadowColor;
+ aWriteStream << iBrushColor;
+ aWriteStream.WriteInt32L(iBrushPattern.Handle());
+ aWriteStream.WriteUint8L(iBrushStyle);
+ aWriteStream.WriteUint8L(iBrushPatternUsed);
+ aWriteStream << iBrushOrigin;
+ aWriteStream.WriteUint8L(iAutoUpdateJustification);
+ }
+
+
+/**
+Internalises the context and the drawing engine object from the read stream.
+It is important that the font and brush bitmap of the GC is maintained between
+calls to ExternalizeL() and InternalizeL(). The font handle and brush bitmap handle
+is externalised, not the underlying data. This is done for performance reasons.
+
+@param aReadStream Read stream.
+
+@pre The font has not been released since the last call of CDirectGdiContext::ExternalizeL on the stream
+@pre The handle of the brush pattern bitmap has not been closed since the call to CDirectGdiContext::ExternalizeL on the stream.
+@post The context and drawing engine object states are updated with the values from the read stream.
+
+@see MDirectGdiEngine::ExternalizeL
+@leave If there was an error reading from the read stream.
+*/
+EXPORT_C void CDirectGdiContext::InternalizeL(RReadStream& aReadStream)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::InternalizeL");
+ TUint16 archiveVerNo = 0;
+ aReadStream >> archiveVerNo;
+ iEngine->InternalizeL(aReadStream);
+
+ TPoint origin;
+ aReadStream >> origin;
+ SetOrigin(origin);
+ ResetFont();
+ TInt fontHandle = aReadStream.ReadInt32L();
+ if(fontHandle)
+ {
+ TInt res = iFont.Duplicate(fontHandle);
+ if(res == KErrNone)
+ {
+ iEngine->SetFont(iFont.Address()->UniqueFontId());
+ }
+ else
+ {
+ iDriver.SetError(res);
+ }
+ }
+ iCharJustExcess = aReadStream.ReadUint32L();
+ iCharJustNum = aReadStream.ReadUint32L();
+ iWordJustExcess = aReadStream.ReadUint32L();
+ iWordJustNum = aReadStream.ReadUint32L();
+ aReadStream >> iLastPrintPosition;
+ iStrikethrough = (DirectGdi::TFontStrikethrough)aReadStream.ReadUint8L();
+ iUnderline = (DirectGdi::TFontUnderline)aReadStream.ReadUint8L();
+ TRgb penColor;
+ aReadStream >> penColor;
+ SetPenColor(penColor);
+ TSize penSize;
+ penSize.iWidth = aReadStream.ReadUint32L();
+ penSize.iHeight = aReadStream.ReadUint32L();
+ SetPenSize(penSize);
+ DirectGdi::TPenStyle penStyle = (DirectGdi::TPenStyle)aReadStream.ReadUint8L();
+ SetPenStyle(penStyle);
+ DirectGdi::TDrawMode drawMode = (DirectGdi::TDrawMode)aReadStream.ReadUint8L();
+ SetDrawMode(drawMode);
+ TRgb textShadowColor;
+ aReadStream >> textShadowColor;
+ SetTextShadowColor(textShadowColor);
+ TRgb brushColor;
+ aReadStream >> brushColor;
+ SetBrushColor(brushColor);
+ TInt patternHandle = aReadStream.ReadInt32L();
+ if (patternHandle)
+ {
+ // Brush pattern must be set before style, otherwise there'll be a panic!
+ SetBrushPattern(patternHandle);
+ }
+ DirectGdi::TBrushStyle brushStyle;
+ brushStyle = (DirectGdi::TBrushStyle)aReadStream.ReadInt8L();
+ SetBrushStyle(brushStyle);
+ iBrushPatternUsed = (TBool)aReadStream.ReadUint8L();
+ TPoint brushOrigin;
+ aReadStream >> brushOrigin;
+ SetBrushOrigin(brushOrigin);
+ iAutoUpdateJustification = (TBool)aReadStream.ReadUint8L();
+ }
+
+
+/**
+Retrieves the currently set brush colour.
+
+@return The current brush colour.
+*/
+EXPORT_C TRgb CDirectGdiContext::BrushColor() const
+ {
+ return iBrushColor;
+ }
+
+
+/**
+Retrieves the currently set pen colour.
+
+@return The current pen colour.
+*/
+EXPORT_C TRgb CDirectGdiContext::PenColor() const
+ {
+ return iPenColor;
+ }
+
+/**
+Retrieves the currently set text shadow colour.
+
+@return The current text shadow colour.
+*/
+EXPORT_C TRgb CDirectGdiContext::TextShadowColor() const
+ {
+ return iTextShadowColor;
+ }
+
+/**
+Draws an image based resource which may be generated using non-native rendering API such as OpenGL ES
+or OpenVG. The resource will be drawn at the specified position in its original size with orientation
+according to the specified rotation parameter. The current clipping region applies. The resource can be
+drawn rotated using the DirectGdi::TGraphicsRotation enum which defines possible rotation values in
+clockwise degrees.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@param aPos The position of the top-left corner of the resource.
+@param aSource The resource to be drawn.
+@param aRotation The rotation to be applied to the resource before it is drawn. The default value is DirectGdi::EGraphicsRotationNone.
+
+@pre Drawing context has been activated on a rendering target. The resource has been fully constructed.
+@post Request to draw resource has been accepted. There is no guarantee that the request has been completed
+ when this method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::DrawResource(
+ const TPoint& aPos,
+ const RDirectGdiDrawableSource& aSource,
+ DirectGdi::TGraphicsRotation aRotation)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawResource");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (aSource.Handle() != KNullHandle)
+ {
+ iEngine->DrawResource(aPos, aSource, aRotation);
+ }
+ else
+ {
+ iDriver.SetError(KErrBadHandle);
+ }
+ }
+
+/**
+Draws an image based resource. The resource will be rendered to the given destination rectangle on
+rendering target in its original dimensions with orientation according to the specified rotation parameter.
+Drawing will be clipped to the given destination rectangle. The current clipping region applies.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@param aDestRect Destination rectangle to which the resource will be rendered.
+@param aSource The resource to be drawn.
+@param aRotation Rotation to be applied to the resource before it is drawn. Default value is DirectGdi::EGraphicsRotationNone.
+
+@pre Drawing context has been activated on a rendering target. The resource has been fully constructed.
+@post Request to draw resource has been accepted. There is no guarantee that the request has been completed
+ when this method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::DrawResource(const TRect& aDestRect,
+ const RDirectGdiDrawableSource& aSource,
+ DirectGdi::TGraphicsRotation aRotation)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawResource");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (aSource.Handle() != KNullHandle)
+ {
+ if ((aDestRect.Width() > 0) && (aDestRect.Height() > 0))
+ {
+ iEngine->DrawResource(aDestRect, aSource, aRotation);
+ }
+ }
+ else
+ {
+ iDriver.SetError(KErrBadHandle);
+ }
+ }
+
+
+/**
+Draws an image based resource. The resource is rendered into the given destination rectangle.
+Scaling (stretching or compression) applies if the destination rectangle is different from the
+source rectangle. The resource orientation is set based on the specified rotation parameter
+before scaling and drawing operations are performed.
+
+If the user modifies the content of the resource after issuing a DrawResource() command (from the
+same thread), the adaptation must make sure that the user’s operations are serialised within
+that thread, for example, DrawResource() is processed before the modify operations. The adaptation
+does not guarantee the result if the resource modification is performed from threads other than
+the one that issued the DrawResource() command. To achieve a guaranteed result in that case, users
+must perform synchronisation between any threads that operate on the resource and issue Finish()
+on the driver whenever necessary. When using other renderers or mappings, synchronisation is needed
+even when this is from within the same thread.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@param aDestRect The destination rectangle to which the resource will be rendered.
+@param aSource The resource to draw.
+@param aSrcRect The source rectangle specifying the area/sub-area of the resource to be rendered.
+@param aRotation Rotation to be applied to the resource before it is drawn
+
+@pre The rendering target has been activated. The resource has been fully constructed.
+@post Request to draw an image based resource has been accepted. There is no guarantee that the
+ request has been completed when this method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::DrawResource(
+ const TRect& aDestRect,
+ const RDirectGdiDrawableSource& aSource,
+ const TRect& aSrcRect,
+ DirectGdi::TGraphicsRotation aRotation)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawResource");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (aSource.Handle() != KNullHandle)
+ {
+ if ((aDestRect.Width() > 0) && (aDestRect.Height() > 0)
+ && (aSrcRect.Width() > 0) && (aSrcRect.Height() > 0))
+ {
+ iEngine->DrawResource(aDestRect, aSource, aSrcRect, aRotation);
+ }
+ }
+ else
+ {
+ iDriver.SetError(KErrBadHandle);
+ }
+ }
+
+
+/**
+Draws a non-image based resource. The resource will be rendered into the given destination rectangle.
+The current clipping region applies. The adaptation is free to interpret the parameters and may define
+their own rules on how to handle the rendering of a non-image based resource.
+
+In the event of a failure, the error state is set to one of the system-wide error codes.
+
+@param aDestRect The destination rectangle to which the resource will be rendered.
+@param aSource The resource.
+@param aParam Parameters specifying how to draw the resource.
+
+@pre The rendering target has been activated. The resource has been fully constructed.
+@post Request to draw a non-image based resource has been accepted.
+ There is no guarantee that the request has been completed when this method returns.
+
+@panic DGDI 7, if the rendering context has not been activated.
+*/
+EXPORT_C void CDirectGdiContext::DrawResource(
+ const TRect& aDestRect,
+ const RDirectGdiDrawableSource& aSource,
+ const TDesC8& aParam)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::DrawResource");
+ GRAPHICS_ASSERT_ALWAYS(iActivated, EDirectGdiPanicContextNotActivated);
+
+ if (aSource.Handle() != KNullHandle)
+ {
+ if ((aDestRect.Width() > 0) && (aDestRect.Height() > 0))
+ {
+ iEngine->DrawResource(aDestRect, aSource, aParam);
+ }
+ }
+ else
+ {
+ iDriver.SetError(KErrBadHandle);
+ }
+ }
+
+/**
+Retrieves a pointer to an instance of the appropriate extension interface implementation.
+
+@param aInterfaceId Interface identifier of the interface to be retrieved.
+@param aInterface On return, holds the specified interface, or NULL if the interface cannot be found.
+
+@pre None.
+@post None.
+
+@return KErrNone If the interface is supported, KErrNotSupported otherwise.
+ */
+EXPORT_C TInt CDirectGdiContext::GetInterface(TUid aInterfaceId, TAny*& aInterface)
+ {
+ GRAPHICS_TRACE("CDirectGdiContext::GetInterface");
+ return iEngine->GetInterface(aInterfaceId, aInterface);
+ }
+
+/**
+Release the brush pattern's handle, and mark it as no longer used.
+*/
+void CDirectGdiContext::CleanUpBrushPattern()
+ {
+ iBrushPattern.Reset();
+ iBrushPatternUsed = EFalse;
+ }
+
+/**
+@internalTechnology
+
+Returns the baseline correction associated with this font.
+This value is used to alter the underline/strikethrough position applied to linked fonts.
+
+@return The baseline correction value set by the rasterizer; or 0 if not set
+*/
+TInt CDirectGdiContext::BaselineCorrection()
+ {
+ TOpenFontMetrics metrics;
+ if (iFont.GetFontMetrics(metrics))
+ return metrics.BaselineCorrection();
+ else
+ return 0;
+ }