diff -r 000000000000 -r 5d03bc08d59c windowing/windowserver/nga/CLIENT/RGC.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/windowing/windowserver/nga/CLIENT/RGC.CPP Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,2320 @@ +// Copyright (c) 1994-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: +// Shells for window server graphics class +// +// + +#include +#include +#include "../SERVER/w32cmd.h" +#include "CLIENT.H" +#include "w32comm.h" +#include "graphicsresourcewrapper.h" +#include +#include +#include "graphics/windowserverconstants.h" + +#define KDefaultShadowColor KRgbGray +enum {EPolygonMaxHeaderSize=sizeof(TWsCmdHeader)+sizeof(TWsGcCmdSegmentedDrawPolygonData)}; + +// +// class CWindowGc::CPimpl +// + +NONSHARABLE_STRUCT(CWindowGc::CPimpl): public CBase, public MWsDrawResource +/** @internalComponent @released */ + { +public: + enum TStateType + { + EStateBrushColor = 1<<0, + EStateBrushStyle = 1<<1, + EStatePenColor = 1<<2, + EStatePenStyle = 1<<3, + EStatePenSize = 1<<4, + EStateDrawMode = 1<<5, + EStateClippingRect = 1<<6, + EStateUnderlineStyle = 1<<7, + EStateStrikethroughStyle = 1<<8, + EStateWordJustification = 1<<9, + EStateCharJustification = 1<<10, + }; + + CPimpl(CWindowGc& aGc); + void WriteAnyPendingStateChanges(); + void ResetPendingState(); + void StorePendingStateChange(TStateType aState, const TAny* aValue); + TUint32 GetState() const {return iPendingState;} + void CancelPendingClippingRect(); + ~CPimpl(); +public: //from MWsDrawResource + void DrawResource(const TPoint& aPos, const RWsDrawableSource& aSource, CWindowGc::TGraphicsRotation aRotation=CWindowGc::EGraphicsRotationNone) + { + iGc.DrawResource(aPos, aSource, aRotation); + } + void DrawResource(const TRect& aDestRect, const RWsDrawableSource& aSource, CWindowGc::TGraphicsRotation aRotation=CWindowGc::EGraphicsRotationNone) + { + iGc.DrawResource(aDestRect, aSource, aRotation); + } + void DrawResource(const TRect& aDestRect, const RWsDrawableSource& aSource, const TRect& aSrcRect, CWindowGc::TGraphicsRotation aRotation=CWindowGc::EGraphicsRotationNone) + { + iGc.DrawResource(aDestRect, aSource, aSrcRect, aRotation); + } + void DrawResource(const TRect& aDestRect, const RWsDrawableSource& aSource, const TDesC8& aParam) + { + iGc.DrawResource(aDestRect, aSource, aParam); + } +public: + CWindowGc& iGc; + CFbsFont* iFont; + TRgb iShadowColor; + TBool iForceWrite; + TBool iClippingRectSet; + +private: + TUint32 iPendingState; + + // Pending state - used to store requested state changes not yet written to wserv + TRgb iPendingBrushColor; + TBrushStyle iPendingBrushStyle; + TRgb iPendingPenColor; + TPenStyle iPendingPenStyle; + TSize iPendingPenSize; + TDrawMode iPendingDrawMode; + TRect iPendingClippingRect; + TFontUnderline iPendingUnderlineStyle; + TFontStrikethrough iPendingStrikethroughStyle; + TWsGcCmdSetJustification iPendingWordJustification; + TWsGcCmdSetJustification iPendingCharJustification; + + // Current state - values that have actually been written to wserv + TRgb iCurrentBrushColor; + TBrushStyle iCurrentBrushStyle; + TRgb iCurrentPenColor; + TPenStyle iCurrentPenStyle; + TSize iCurrentPenSize; + TDrawMode iCurrentDrawMode; + TFontUnderline iCurrentUnderlineStyle; + TFontStrikethrough iCurrentStrikethroughStyle; + TWsGcCmdSetJustification iCurrentWordJustification; + TWsGcCmdSetJustification iCurrentCharJustification; + }; + +CWindowGc::CPimpl::CPimpl(CWindowGc& aGc) + : iGc(aGc), iFont(NULL), iShadowColor(KDefaultShadowColor) + { + ResetPendingState(); + } + +CWindowGc::CPimpl::~CPimpl() + { + iFont = NULL; + } + +void CWindowGc::CPimpl::CancelPendingClippingRect() + { + iPendingState &= ~EStateClippingRect; + } + +void CWindowGc::CPimpl::WriteAnyPendingStateChanges() + { + if (iPendingState == 0) + return; + + if (iPendingState & EStateDrawMode) + { + if (iPendingDrawMode != iCurrentDrawMode) + { + iGc.WriteInt(iPendingDrawMode,EWsGcOpSetDrawMode); + iCurrentDrawMode = iPendingDrawMode; + } + } + + if (iPendingState & EStateBrushStyle) + { + if (iPendingBrushStyle != iCurrentBrushStyle) + { + iGc.WriteInt(iPendingBrushStyle,EWsGcOpSetBrushStyle); + iCurrentBrushStyle = iPendingBrushStyle; + } + } + + if (iPendingState & EStateBrushColor) + { + // Brush colour optimisation more conservative (than for other state changes) because server-side code modifies it without client's knowledge + if (iPendingBrushColor != iCurrentBrushColor || iForceWrite) + { + iGc.WriteInt(iPendingBrushColor.Internal(),EWsGcOpSetBrushColor); + iCurrentBrushColor = iPendingBrushColor; + iForceWrite = EFalse; + } + } + + if (iPendingState & EStatePenStyle) + { + if (iPendingPenStyle != iCurrentPenStyle) + { + iGc.WriteInt(iPendingPenStyle,EWsGcOpSetPenStyle); + iCurrentPenStyle = iPendingPenStyle; + } + } + + if (iPendingState & EStatePenColor) + { + if (iPendingPenColor != iCurrentPenColor) + { + iGc.WriteInt(iPendingPenColor.Internal(),EWsGcOpSetPenColor); + iCurrentPenColor = iPendingPenColor; + } + } + + if (iPendingState & EStateClippingRect) + { + iGc.WriteRect(iPendingClippingRect,EWsGcOpSetClippingRect); + iClippingRectSet = ETrue; + } + + if (iPendingState & EStateUnderlineStyle) + { + if (iPendingUnderlineStyle != iCurrentUnderlineStyle) + { + iGc.WriteInt(iPendingUnderlineStyle,EWsGcOpSetUnderlineStyle); + iCurrentUnderlineStyle = iPendingUnderlineStyle; + } + } + + if (iPendingState & EStateStrikethroughStyle) + { + if (iPendingStrikethroughStyle != iCurrentStrikethroughStyle) + { + iGc.WriteInt(iPendingStrikethroughStyle,EWsGcOpSetStrikethroughStyle); + iCurrentStrikethroughStyle = iPendingStrikethroughStyle; + } + } + + if (iPendingState & EStatePenSize) + { + if (iPendingPenSize != iCurrentPenSize) + { + iGc.WriteSize(iPendingPenSize,EWsGcOpSetPenSize); + iCurrentPenSize = iPendingPenSize; + } + } + + if (iPendingState & EStateWordJustification) + { + if (iPendingWordJustification.excessWidth != iCurrentWordJustification.excessWidth + || iPendingWordJustification.numGaps != iCurrentWordJustification.numGaps) + { + iGc.Write(&iPendingWordJustification,sizeof(iPendingWordJustification),EWsGcOpSetWordJustification); + iCurrentWordJustification = iPendingWordJustification; + } + } + + if (iPendingState & EStateCharJustification) + { + if (iPendingCharJustification.excessWidth != iCurrentCharJustification.excessWidth + || iPendingCharJustification.numGaps != iCurrentCharJustification.numGaps) + { + iGc.Write(&iPendingCharJustification,sizeof(iPendingCharJustification),EWsGcOpSetCharJustification); + iCurrentCharJustification = iPendingCharJustification; + } + } + + iPendingState = 0; + } + +void CWindowGc::CPimpl::ResetPendingState() + { + // This function should only be called from CWindowGc::Reset() + iForceWrite = EFalse; + iPendingState = 0; + + iClippingRectSet = EFalse; + + // The following default values are the same as those used by CFbsBitGc::Reset() + iPendingBrushColor = KRgbWhite; + iPendingBrushStyle = CGraphicsContext::ENullBrush; + iPendingPenColor = KRgbBlack; + iPendingPenStyle = CGraphicsContext::ESolidPen; + iPendingPenSize = TSize(1,1); + iPendingDrawMode = CGraphicsContext::EDrawModePEN; + iPendingUnderlineStyle = EUnderlineOff; + iPendingStrikethroughStyle = EStrikethroughOff; + iPendingWordJustification.excessWidth = 0; + iPendingWordJustification.numGaps = 0; + iPendingCharJustification.excessWidth = 0; + iPendingCharJustification.numGaps = 0; + + iCurrentBrushColor = iPendingBrushColor; + iCurrentBrushStyle = iPendingBrushStyle; + iCurrentPenColor = iPendingPenColor; + iCurrentPenStyle = iPendingPenStyle; + iCurrentPenSize = iPendingPenSize; + iCurrentDrawMode = iPendingDrawMode; + iCurrentUnderlineStyle = iPendingUnderlineStyle; + iCurrentStrikethroughStyle = iPendingStrikethroughStyle; + iCurrentWordJustification.excessWidth = iPendingWordJustification.excessWidth; + iCurrentWordJustification.numGaps = iPendingWordJustification.numGaps; + iCurrentCharJustification.excessWidth = iPendingCharJustification.excessWidth; + iCurrentCharJustification.numGaps = iPendingCharJustification.numGaps; + } + +void CWindowGc::CPimpl::StorePendingStateChange(TStateType aState, const TAny* aValue) + { + switch (aState) + { + case EStateBrushColor: + iPendingState |= EStateBrushColor; + iPendingBrushColor = *((TRgb*)(aValue)); + break; + case EStateBrushStyle: + iPendingState|=EStateBrushStyle; + iPendingBrushStyle = *((TBrushStyle*)(aValue)); + break; + case EStatePenColor: + iPendingState|=EStatePenColor; + iPendingPenColor = *((TRgb*)(aValue)); + break; + case EStatePenStyle: + iPendingState|=EStatePenStyle; + iPendingPenStyle = *((TPenStyle*)(aValue)); + break; + case EStateDrawMode: + iPendingState|=EStateDrawMode; + iPendingDrawMode = *((TDrawMode*)(aValue)); + break; + case EStateClippingRect: + iPendingState|=EStateClippingRect; + iPendingClippingRect = *((TRect*)(aValue)); + break; + case EStateUnderlineStyle: + iPendingState|=EStateUnderlineStyle; + iPendingUnderlineStyle = *((TFontUnderline*)(aValue)); + break; + case EStateStrikethroughStyle: + iPendingState|=EStateStrikethroughStyle; + iPendingStrikethroughStyle= *((TFontStrikethrough*)(aValue)); + break; + case EStatePenSize: + iPendingState|=EStatePenSize; + iPendingPenSize = *((TSize*)(aValue)); + break; + case EStateWordJustification: + iPendingState|=EStateWordJustification; + iPendingWordJustification = *((TWsGcCmdSetJustification*)(aValue)); + break; + case EStateCharJustification: + iPendingState|=EStateCharJustification; + iPendingCharJustification = *((TWsGcCmdSetJustification*)(aValue)); + break; + default: + break; + } + } + +// +// class CWindowGc +// + +EXPORT_C CWindowGc::CWindowGc(CWsScreenDevice *aDevice) : MWsClientClass(aDevice->iBuffer), iPimpl(NULL), iDevice(aDevice) +/** Constructor which creates, but does not initialise a graphics context. + +@param aDevice Any screen device owned by the same session. Its life time +should be at least as long as the gc itself. +@see CWsScreenDevice::CreateContext() */ + {} + +EXPORT_C CWindowGc::~CWindowGc() +/** Destructor. */ + { + if (iBuffer && iWsHandle) + Write(EWsGcOpFree); + delete iPimpl; + } + +void CWindowGc::WriteTextCommand(TAny *cmd, TInt len,const TDesC &aBuf,TInt opcode,TInt opcodePtr) const + { + if ((aBuf.Size()+len)>(TInt)(iBuffer->BufferSize()-sizeof(TWsCmdHeader))) + { + WriteReplyByProvidingRemoteReadAccess(cmd,len,&aBuf,opcodePtr); + } + else + { + Write(cmd,len,aBuf.Ptr(),aBuf.Size(),opcode); + } + } + +void CWindowGc::WriteTextCommand(TAny *cmd, TInt len,const TDesC8 &aBuf,TInt opcode,TInt opcodePtr) const + { + if ((aBuf.Size()+len)>(TInt)(iBuffer->BufferSize()-sizeof(TWsCmdHeader))) + { + WriteReplyByProvidingRemoteReadAccess(cmd,len,&aBuf,opcodePtr); + } + else + { + Write(cmd,len,aBuf.Ptr(),aBuf.Size(),opcode); + } + } + +EXPORT_C TInt CWindowGc::Construct() +/** Completes construction. + +@return KErrNone if successful, otherwise a leave error. +@panic TW32Panic 17 in debug builds if called on an already constructed object. +This function always causes a flush of the window server buffer. */ + { + __ASSERT_DEBUG(iWsHandle == KNullHandle, Panic(EW32PanicGraphicDoubleConstruction)); + iPimpl = new CPimpl(*this); + if (!iPimpl) + return KErrNoMemory; + TInt ret; + if ((ret=iBuffer->WriteReplyWs(EWsClOpCreateGc))<0) + return(ret); + iWsHandle=ret; + return(KErrNone); + } + +EXPORT_C void CWindowGc::Activate(RDrawableWindow &aDevice) +/** Activates the context for a given window and updates iDevice with the pointer to the screen device of the screen on which aDevice is found. + +When drawing is complete, the code using the context should call Deactivate(). +Draw methods invoked after an Activate() will affect the window specified. +A graphics context can only be active for one window at a time. A panic occurs +if a draw function is called before calling this function, or if Activate() +is called twice without an intervening Deactivate(). + +@param aWindow The window for which the graphics context is to be activated. */ + { + TUint devicePointer = WriteReplyInt(aDevice.WsHandle(),EWsGcOpActivate); + iDevice = (CWsScreenDevice*)devicePointer; + iPimpl->iForceWrite = ETrue; // needed because brush colour set to window background colour in CWsGc::Activate + } + +EXPORT_C void CWindowGc::Deactivate() +/** Frees the graphics context to be used with another window. + +This method should be called when the application has completed drawing to +the window. */ + { + iPimpl->ResetPendingState(); // needed because server-side state is reset on deactivation + Write(EWsGcOpDeactivate); + iPimpl->iFont=NULL; + iPimpl->iShadowColor = KDefaultShadowColor; + } + +//====================Functions from GDI.H=============================== + +EXPORT_C CGraphicsDevice* CWindowGc::Device() const +/** Returns a pointer to the device, more specifically a CWsScreenDevice, for the screen that the WindowGc was last activated on. +If the WindowGc has not been activated at all, it then returns the device that was passed to its constructor. + +The user should be careful when calling this function since it can return the screen device of any screen in the system. +Hence, the return value of this function will be useful only if the user is aware of how the WindowGc was used before this function is called. +@return A pointer to the device for the screen that the WindowGc was last activated on or the device passed at construction*/ + { + return(iDevice); + } + +EXPORT_C void CWindowGc::SetOrigin(const TPoint &aPoint) +/** Sets the position of the co-ordinate origin. + +All subsequent drawing operations are then done relative to this origin. The +default origin is (0,0), the top left corner of the window. + +@param aPoint A point for the origin, default (0,0). +@see CGraphicsContext::SetOrigin() */ + { + if ( iPimpl->GetState() & CPimpl::EStateClippingRect ) + { + iPimpl->WriteAnyPendingStateChanges(); + } + WritePoint(aPoint,EWsGcOpSetOrigin); + } + +EXPORT_C void CWindowGc::SetClippingRect(const TRect& aRect) +/** Sets a clipping rectangle. + +Graphics drawn to the window are clipped, so that only items which fall within +the rectangle are displayed. + +Note that clipping is additive. If a clipping region has been set using SetClippingRegion() +then clipping will be to the intersection of that region and this rectangle. + +@param aRect The clipping rectangle in window co-ordinates. Note that this rectangle is +tranformed by the current drawing co-ordinate origin before it is used. +The co-ordinate origin is set using SetOrigin(). + +@see SetClippingRegion() */ + { + TRect rect(aRect); + iPimpl->StorePendingStateChange(CPimpl::EStateClippingRect, &rect); + } + +EXPORT_C void CWindowGc::CancelClippingRect() +/** Cancels the clipping rectangle. + +@see SetClippingRect() */ + { + if (iPimpl->GetState() & CPimpl::EStateClippingRect) + { + iPimpl->CancelPendingClippingRect(); + } + + if (iPimpl->iClippingRectSet) + { + Write(EWsGcOpCancelClippingRect); + } + + iPimpl->iClippingRectSet = EFalse; + } + +EXPORT_C TInt CWindowGc::SetClippingRegion(const TRegion &aRegion) +/** Sets the clipping region. + +Drawing is always clipped to the visible area of a window. The region specified +by this function is in addition to that area. + +This function always causes a flush of the window server buffer. + +@param aRegion The new clipping region in window co-ordinates +as used in SetClippingRect(). The clipping region is transformed by the current +drawing origin before use. + +@return KErrNone if successful, KErrNoMemory if there is insufficient memory +to create the region on the server side, otherwise another error code. + +@see SetClippingRect() */ + { + const TInt regionCount=aRegion.Count(); + TPtrC8 ptrRect(reinterpret_cast(aRegion.RectangleList()),regionCount*sizeof(TRect)); + return(WriteReplyByProvidingRemoteReadAccess(®ionCount,sizeof(regionCount),&ptrRect,EWsGcOpSetClippingRegion)); + } + +EXPORT_C void CWindowGc::CancelClippingRegion() +/** Cancels the current clipping region. */ + { + Write(EWsGcOpCancelClippingRegion); + } + +EXPORT_C void CWindowGc::SetDrawMode(TDrawMode aDrawingMode) +/** Sets the drawing mode. + +This affects the colour that is actually drawn, because it defines the way +that the current screen colour logically combines with the current pen colour +and brush colour. + +There are 13 drawing modes (see CGraphicsContext::TDrawMode enum), each giving +different logical combinations of pen, brush and screen colours. Each mode +is produced by ORing together different combinations of seven drawing mode +components (see CGraphicsContext::TDrawModeComponents enum). + +The three most important modes are TDrawMode::EDrawModePEN, TDrawMode::EDrawModeNOTSCREEN +and TDrawMode::EDrawModeXOR. The default drawing mode is TDrawMode::EDrawModePEN. + +The drawing mode is over-ridden for line and shape drawing functions when +a wide pen line has been selected. It is forced to TDrawMode::EDrawModePEN. +This is to prevent undesired effects at line joins (vertexes). + +Notes: + +TDrawMode::EDrawModeAND gives a "colour filter" effect. For example: + +ANDing with white gives the original colour + +ANDing with black gives black + +TDrawMode::EDrawModeOR gives a "colour boost" effect. For example: + +ORing with black gives the original colour + +ORing with white gives white + +TDrawMode::EDrawModeXOR gives an "Exclusive OR" effect. For example: + +white XOR black gives white + +white XOR white gives black + +black XOR black gives black + +@param aDrawingMode A drawing mode. +@see CGraphicsContext::SetDrawMode() */ + { + iPimpl->StorePendingStateChange(CPimpl::EStateDrawMode, &aDrawingMode); + } + +EXPORT_C void CWindowGc::UseFont(const CFont *aFont) +/** Sets this context's font. + +The font is used for text drawing. If the font is already in the font and +bitmap server's memory the GDI will share that copy. + +Note that this function must be called prior to drawing text or the calling +thread will panic. + +@param aFont A device font. +@see CGraphicsContext::UseFont() */ + { + if (iPimpl->iFont!=(CFbsFont *)aFont) + { + iPimpl->iFont=(CFbsFont *)aFont; + WriteInt(iPimpl->iFont->Handle(),EWsGcOpUseFont); + } + } + +EXPORT_C void CWindowGc::DiscardFont() +/** Discards a font. + +This frees up the memory used (if the font is not being shared with some other +process). + +Note that if no font is in use when this function is called, then there is no effect. + +@see CGraphicsContext::DiscardFont() */ + { + Write(EWsGcOpDiscardFont); + iPimpl->iFont=NULL; + } + +EXPORT_C void CWindowGc::SetUnderlineStyle(TFontUnderline aUnderlineStyle) +/** Sets the underline style for all subsequently drawn text. + +@param aUnderlineStyle The underline style: either on or off. +@see CGraphicsContext::SetUnderlineStyle() */ + { + iPimpl->StorePendingStateChange(CPimpl::EStateUnderlineStyle, &aUnderlineStyle); + } + +EXPORT_C void CWindowGc::SetStrikethroughStyle(TFontStrikethrough aStrikethroughStyle) +/** Sets the strikethrough style for all subsequently drawn text. + +@param aStrikethroughStyle The strikethrough style: either on or off. +@see CGraphicsContext::SetStrikethroughStyle() */ + { + iPimpl->StorePendingStateChange(CPimpl::EStateStrikethroughStyle, &aStrikethroughStyle); + } + +void CWindowGc::SetJustification(TInt aExcessWidth,TInt aNumGaps, TInt aOpcode) + { + TWsGcCmdSetJustification justification; + + justification.excessWidth=aExcessWidth; + justification.numGaps=aNumGaps; + + if (aOpcode == EWsGcOpSetWordJustification) + { + iPimpl->StorePendingStateChange(CPimpl::EStateWordJustification, &justification); + } + else if (aOpcode == EWsGcOpSetCharJustification) + { + iPimpl->StorePendingStateChange(CPimpl::EStateCharJustification, &justification); + } + } + +EXPORT_C void CWindowGc::SetWordJustification(TInt aExcessWidth,TInt aNumGaps) +/** Sets word justification. + +This function is particularly useful for doing WYSIWYG underlining or strikethrough, +as it ensures that the lines extend correctly into the gaps between words. It is not +intended for regular use by developers. + +@param aExcessWidth The excess width (in pixels) to be distributed between +the specified number of gaps (starting immediately) +@param aNumGaps The number of gaps between words +@see CGraphicsContext::SetWordJustification() */ + { + SetJustification(aExcessWidth, aNumGaps, EWsGcOpSetWordJustification); + } + +EXPORT_C void CWindowGc::SetCharJustification(TInt aExcessWidth,TInt aNumChars) +/** Sets the character justification. + +This function is used primarily to get accurate WYSIWYG, and is not intended +for regular use by developers. + +The text line that is to be justified has a certain number of characters (this +includes the spaces between the words). It also has a distance (in pixels) +between the end of the last word and the actual end of the line (right hand +margin, usually). These excess width pixels are distributed amongst all the +characters, increasing the gaps between them, to achieve full justification +of the text line. + +This function is particularly useful for WYSIWYG underlining or strikethrough, +as it ensures that the lines extend into the gaps between characters. + +See CGraphicsContext::SetCharJustification() for more information. + +@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() */ + { + SetJustification(aExcessWidth, aNumChars, EWsGcOpSetCharJustification); + } + +EXPORT_C void CWindowGc::SetPenColor(const TRgb &aColor) +/** Sets the pen colour. + +The effective pen colour depends on the drawing mode (see SetDrawMode()). + +The default pen colour is black. + +@param aColor The RGB colour for the pen. +@see CGraphicsContext::SetPenColor() */ + { + TRgb color = aColor; + iPimpl->StorePendingStateChange(CPimpl::EStatePenColor, &color); + } + +EXPORT_C void CWindowGc::SetPenStyle(TPenStyle aPenStyle) +/** Sets the line drawing style for the pen. + +The pen is used when drawing lines and for the outline of filled shapes. There +are 6 pen styles (see CGraphicsContext::TPenStyle enum). If no pen style is +set, the default is TPenStyle::ESolidPen. + +To use a pen style, its full context must be given, e.g. for a null pen: CGraphicsContext::TPenStyle::ENullPen. + +@param aPenStyle A pen style. +@see CGraphicsContext::SetPenStyle() */ + { + iPimpl->StorePendingStateChange(CPimpl::EStatePenStyle, &aPenStyle); + } + +EXPORT_C void CWindowGc::SetPenSize(const TSize& aSize) +/** Sets the line drawing size for the pen. + +Lines of size greater than one pixel are drawn with rounded ends that extend +beyond the end points, (as if the line is drawn using a circular pen tip of +the specified size). Rounded ends of lines drawn with a wide pen are always +drawn in TDrawMode::EDrawModePEN mode, overriding whatever mode has been set +using SetDrawMode(). + +@param aSize A line size, the default being 1 pixel. +@see CGraphicsContext::SetPenSize() */ + { + TSize size(aSize); + iPimpl->StorePendingStateChange(CPimpl::EStatePenSize, &size); + } + +EXPORT_C void CWindowGc::SetBrushColor(const TRgb &aColor) +/** Sets the brush colour. + +The effective brush colour depends on the drawing mode (see SetDrawMode()). +If no brush colour has been set, it defaults to white. However the default +brush style is null, so when drawing to a window, the default appears to be +the window's background colour. + +@param aColor The RGB colour for the brush. +@see CGraphicsContext::SetBrushColor() */ + { + TRgb color = aColor; + iPimpl->StorePendingStateChange(CPimpl::EStateBrushColor, &color); + } + +EXPORT_C void CWindowGc::SetBrushStyle(TBrushStyle aBrushStyle) +/** Sets the line drawing style for the brush. + +The GDI provides ten brush styles, including six built-in hatching patterns +(see CGraphicsContext::TBrushStyle). + +Use TBrushStyle::ENullBrush to draw the outline of a fillable shape on its +own, without filling. + +If the TBrushStyle::EPatternedBrush style is set, but no bitmap pattern has +been selected using UseBrushPattern(), then the brush defaults to TBrushStyle::ENullBrush. + +Hatching lines are done in the current brush colour, set using SetBrushColor(). +Hatching can be overlaid on other graphics. The hatching pattern starts at +the brush origin, set using SetBrushOrigin(). + +@param aBrushStyle The brush style. +@see CGraphicsContext::SetBrushStyle() */ + { + iPimpl->StorePendingStateChange(CPimpl::EStateBrushStyle, &aBrushStyle); + } +EXPORT_C void CWindowGc::SetBrushOrigin(const TPoint &aOrigin) +/** Sets the brush pattern origin. + +This specifies the position of the pixel in the top left corner of a reference +pattern tile, (in absolute device co-ordinates). Other copies of the pattern +tile are then drawn around the reference one. Thus the brush origin can be +set as the top left corner of a shape. + +The brush pattern may be a built-in style (see SetBrushStyle()), or a bitmap. +To use a bitmap, the brush must have a pattern set (see UseBrushPattern()) +and the brush style must be set to TBrushStyle::EPatternedBrush. + +Notes: + +If SetBrushOrigin() is not used, then the origin defaults to (0,0). + +This brush origin remains in effect for all fillable shapes drawn subsequently, +until a new brush origin is set. Shapes can thus be considered as windows +onto a continuous pattern field (covering the whole clipping region of a screen +device, or the whole device area of a printer). + +@param aOrigin The origin point for the brush. +@see CGraphicsContext::SetBrushOrigin() */ + { + WritePoint(aOrigin,EWsGcOpSetBrushOrigin); + } + +EXPORT_C void CWindowGc::UseBrushPattern(const CFbsBitmap *aDevice) +/** Sets the brush pattern to the specified bitmap. + +For the brush to actually use the bitmap, TBrushStyle::EPatternedBrush must +be used to set the brush style (see SetBrushStyle()). When the brush pattern +is no longer required, use DiscardBrushPattern() to free up the memory used, +(if the bitmap is not being shared). If UseBrushPattern() is used again without +using DiscardBrushPattern() then the previous pattern is discarded automatically. + +Notes: + +When loading a bitmap, the GDI checks to see if the bitmap is already in memory. +If the bitmap is already there, then that copy is shared. + +The brush does not need to have a pattern set at all. There are several built-in +hatching patterns, which can be selected using SetBrushStyle(). + +@param aDevice A bitmap pattern for the brush +@see CGraphicsContext::UseBrushPattern() */ + { + WriteInt(aDevice->Handle(),EWsGcOpUseBrushPattern); + AddToBitmapArray(aDevice->Handle()); + } + +EXPORT_C void CWindowGc::DiscardBrushPattern() +/** Discards a non-built-in brush pattern. + +This frees up the memory used for the bitmap, if it is not being shared by +another process. + +If no brush pattern has been set when this function is called, it has no effect. + +@see CGraphicsContext::DiscardBrushPattern() */ + { + Write(EWsGcOpDiscardBrushPattern); + } + +EXPORT_C void CWindowGc::Plot(const TPoint &aPoint) +/** Draws a single point. + +The point is drawn with the current pen settings using the current drawing +mode. + +Note: if the pen size is greater than one pixel, a filled circle of the current +pen colour is drawn, with the pen size as the diameter and the plotted point +as the centre. If the pen size is an even number of pixels, the extra pixels +are drawn below and to the right of the centre. See SetPenSize(). + +@param aPoint The point to be drawn. +@see CGraphicsContext::Plot() */ + { + iPimpl->WriteAnyPendingStateChanges(); + WritePoint(aPoint,EWsGcOpPlot); + } + +EXPORT_C void CWindowGc::DrawLine(const TPoint &aPoint1,const TPoint &aPoint2) +/** Draws a straight line between two points. + +@param aPoint1 The point at the start of the line. +@param aPoint2 The point at the end of the line. +@see CGraphicsContext::DrawLine() */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawLine drawLine(aPoint1,aPoint2); + Write(&drawLine,sizeof(drawLine),EWsGcOpDrawLine); + } + +EXPORT_C void CWindowGc::MoveTo(const TPoint &aPoint) +/** 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. + +Notes: + +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. + +@param aPoint The point to move the internal drawing position to. +@see CGraphicsContext::MoveTo() +@see CGraphicsContext::MoveBy() */ + { + WritePoint(aPoint,EWsGcOpMoveTo); + } + +EXPORT_C void CWindowGc::MoveBy(const TPoint &aPoint) +/** Moves the internal drawing position by a vector, without drawing a line. + +The internal drawing position is moved relative to its current co-ordinates. + +@param aPoint The vector to move the internal drawing position by. +@see CGraphicsContext::MoveBy() +@see CGraphicsContext::MoveTo() */ + { + WritePoint(aPoint,EWsGcOpMoveBy); + } + +EXPORT_C void CWindowGc::DrawLineTo(const TPoint &aPoint) +/** Draws a straight line from the current internal drawing position to a point. + +@param aPoint The point at the end of the line. +@see CGraphicsContext::DrawLineTo() */ + { + iPimpl->WriteAnyPendingStateChanges(); + WritePoint(aPoint,EWsGcOpDrawTo); + } + +EXPORT_C void CWindowGc::DrawLineBy(const TPoint &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 aVector is added to the internal drawing position to give the end point +of the line + +@param aPoint The vector to add to the current internal drawing position, +giving the end point of the line. +@see CGraphicsContext::DrawLineBy() */ + { + iPimpl->WriteAnyPendingStateChanges(); + WritePoint(aPoint,EWsGcOpDrawBy); + } + +void CWindowGc::doDrawPolyLine(const CArrayFix *aPointArray, const TPoint* aPointList,TInt aNumPoints) + { + TWsGcOpcodes opcode=EWsGcOpDrawPolyLine; + TWsGcCmdDrawPolyLine polyLine; + TInt maxBufLen=(iBuffer->BufferSize()-sizeof(TWsCmdHeader)-sizeof(polyLine))/sizeof(TPoint); + TInt sent=0; + while(sentEnd(sent)-ptr; + } + else + { + ptr=aPointList+sent; + availableLen=aNumPoints-sent; + } + polyLine.numPoints=Min(availableLen,maxBufLen); + sent+=polyLine.numPoints; + polyLine.more=(sent!=aNumPoints); + Write(&polyLine,sizeof(polyLine),ptr,polyLine.numPoints*sizeof(TPoint),opcode); + polyLine.last=ptr[polyLine.numPoints-1]; + opcode=EWsGcOpDrawPolyLineContinued; + } + } + +EXPORT_C void CWindowGc::DrawPolyLine(const TPoint* aPointList,TInt aNumPoints) +/** Draws a polyline using points in a list. + +A polyline is a series of concatenated straight lines joining a set of points. + +@param aPointList Pointer to a list of points on the polyline. +@param aNumPoints The number of points in the point list. +@see CGraphicsContext::DrawPolyLine() */ + { + iPimpl->WriteAnyPendingStateChanges(); + doDrawPolyLine(NULL,aPointList,aNumPoints); + } + +EXPORT_C void CWindowGc::DrawPolyLine(const CArrayFix *aPointArray) +/** Draws a polyline using points in an array. + +A polyline is a series of concatenated straight lines joining a set of points. + +@param aPointArray An array containing the points on the polyline. +@see CGraphicsContext::DrawPolyLine() */ + { + iPimpl->WriteAnyPendingStateChanges(); + doDrawPolyLine(aPointArray,NULL,aPointArray->Count()); + } + +TInt CWindowGc::doDrawPolygon(const CArrayFix *aPointArray,const TPoint* aPointList,TInt aNumPoints,TFillRule aFillRule) + { + if (aNumPoints<=0) + return(KErrNone); + TWsGcCmdSegmentedDrawPolygonData polyData; + polyData.index=0; + TInt maxBufLen=(iBuffer->BufferSize()-EPolygonMaxHeaderSize)/sizeof(TPoint); + FOREVER + { + const TPoint *ptr; + TInt availableLen; + if (aPointArray) + { + ptr=&(*aPointArray)[polyData.index]; + availableLen=aPointArray->End(polyData.index)-ptr; + } + else + { + ptr=aPointList+polyData.index; + availableLen=aNumPoints-polyData.index; + } + polyData.numPoints=Min(availableLen,maxBufLen); + if (polyData.index==0) // First time around + { + if (polyData.numPoints==aNumPoints) // Can it be done in one go? + { + TWsGcCmdDrawPolygon drawPolygon; + drawPolygon.numPoints=aNumPoints; + drawPolygon.fillRule=aFillRule; + Write(&drawPolygon,sizeof(drawPolygon),ptr,aNumPoints*sizeof(TPoint),EWsGcOpDrawPolygon); + break; + } + TWsGcCmdStartSegmentedDrawPolygon start; + start.totalNumPoints=aNumPoints; + TInt err=WriteReply(&start,sizeof(start),EWsGcOpStartSegmentedDrawPolygon); + if (err!=KErrNone) + return(err); + } + Write(&polyData,sizeof(polyData),ptr,polyData.numPoints*sizeof(TPoint),EWsGcOpSegmentedDrawPolygonData); + polyData.index+=polyData.numPoints; + if (polyData.index==aNumPoints) + { + TWsGcCmdDrawSegmentedPolygon draw; + draw.fillRule=aFillRule; + Write(&draw,sizeof(draw),EWsGcOpDrawSegmentedPolygon); + break; + } + } + return(KErrNone); + } + +EXPORT_C TInt CWindowGc::DrawPolygon(const TPoint* aPointList,TInt aNumPoints,TFillRule aFillRule) +/** Draws and fills a polygon using points defined in a list. + +The first TPoint in the list defines the start of the first side of the polygon. +The second TPoint defines the second vertex (the end point of the first side +and the start point of the second side) and so on. The final side of the polygon +is drawn using the last TPoint from the array or list, and the line drawn +to the start point of the first side. + +Self-crossing polygons can be filled according to one of two rules, TFillRule::EAlternate +(the default), or TFillRule::EWinding. To explain the difference between these +rules, the concept of a winding number needs to be introduced. The area outside +any of the loops of the polygon has a winding number of zero, and is never +filled. An inside a loop which is bounded by an area with winding number 0 +has a winding number of 1. If an area is within a loop that is bounded by +an area with winding number 1, e.g. a loop within a loop, has a winding number +of 2, and so on. + +The filling of a polygon proceeds according to this algorithm: + +If aFillRule is TFillRule::EAlternate (default) and it has an odd winding +number, then fill the surrounding area. + +If aFillRule is TFillRule::EWinding and it has a winding number greater than +zero, then fill the surrounding area. + +This function always causes a flush of the window server buffer. + +@param aPointList Pointer to a list of points, specifying the vertices of +the polygon. +@param aNumPoints The number of points in the vertex list +@param aFillRule Either TFillRule::EAlternate (the default) or TFillRule::EWinding. +@return KErrNone if successful, otherwise another of the system-wide error +codes. +@see CGraphicsContext::DrawPolygon() */ + { + iPimpl->WriteAnyPendingStateChanges(); + return(doDrawPolygon(NULL,aPointList,aNumPoints,aFillRule)); + } + +EXPORT_C TInt CWindowGc::DrawPolygon(const CArrayFix *aPointArray,TFillRule aFillRule) +/** Draws and fills a polygon using points defined in an array. + +The first TPoint in the array defines the start of the first side of the polygon. +The second TPoint defines the second vertex (the end point of the first side +and the start point of the second side) and so on. The final side of the polygon +is drawn using the last TPoint from the array or list, and the line drawn +to the start point of the first side. + +Self-crossing polygons can be filled according to one of two rules, TFillRule::EAlternate +(the default), or TFillRule::EWinding. To explain the difference between these +rules, the concept of a winding number needs to be introduced. The area outside +any of the loops of the polygon has a winding number of zero, and is never +filled. An inside a loop which is bounded by an area with winding number 0 +has a winding number of 1. If an area is within a loop that is bounded by +an area with winding number 1, e.g. a loop within a loop, has a winding number +of 2, and so on. + +The filling of a polygon proceeds according to this algorithm: + +If aFillRule is TFillRule::EAlternate (default) and it has an odd winding +number, then fill the surrounding area. + +If aFillRule is TFillRule::EWinding and it has a winding number greater than +zero, then fill the surrounding area. + +This function always causes a flush of the window server buffer. + +@param aPointArray An array of points, specifying the vertices of the polygon. +@param aFillRule Either TFillRule::EAlternate (the default) or TFillRule::EWinding. +@return KErrNone if successful, otherwise another of the system-wide error +codes. +@see CGraphicsContext::DrawPolygon() */ + { + iPimpl->WriteAnyPendingStateChanges(); + return(doDrawPolygon(aPointArray,NULL,aPointArray->Count(),aFillRule)); + } + +void CWindowGc::DrawArcOrPie(const TRect &aRect,const TPoint &aStart,const TPoint &aEnd, TInt aOpcode) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawArcOrPie cmd(aRect,aStart,aEnd); + Write(&cmd,sizeof(cmd),aOpcode); + } + +EXPORT_C void CWindowGc::DrawArc(const TRect &aRect,const TPoint &aStart,const TPoint &aEnd) +/** Draws an arc (a portion of an ellipse). + +The point aStart is used to define one end of a line from the geometric centre +of the ellipse. The point of intersection between this line and the ellipse +defines the start point of the arc. The point aEnd is used to define one end +of a second line from the geometric centre of the ellipse. The point of intersection +between this line and the ellipse defines the end point of the arc. The pixels +at both the start point and the end point are drawn. + +The arc itself is the segment of the ellipse in an anti-clockwise direction +from the start point to the end point. + +Notes + +A rectangle is used in the construction of the ellipse of which the arc is +a segment. This rectangle is passed as an argument of type TRect. + +A wide line arc is drawn with the pixels distributed either side of a true +ellipse, in such a way that the outer edge of the line would touch the edge +of the construction rectangle. In other words, the ellipse used to construct +it is slightly smaller than that for a single pixel line size. + +If aStart or aEnd are the ellipse centre then the line that defines the start/end +of the arc defaults to one extending vertically above the centre point. + +If aStart and aEnd are the same point, or points on the same line through +the ellipse centre then a complete unfilled ellipse is drawn. + +Line drawing is subject to pen colour, width and style and draw mode + +@param aRect The rectangle in which to draw the ellipse (of which the arc is +a segment). +@param aStart A point to define the start of the arc. +@param aEnd A point to define the end of the arc. +@see CGraphicsContext::DrawArc() */ + { + iPimpl->WriteAnyPendingStateChanges(); + DrawArcOrPie(aRect,aStart,aEnd,EWsGcOpDrawArc); + } + +EXPORT_C void CWindowGc::DrawPie(const TRect &aRect,const TPoint &aStart,const TPoint &aEnd) +/** Draws and fills a pie-shaped slice of an ellipse. + +Outlines are subject to the current pen colour, width, style and draw mode. +Set the pen to ENullPen for no outline. The fill is subject to brush style +(colour, hash or pattern), the origin and the current drawing mode. Set the +brush to ENullBrush for no fill. + +The point aStart is used to define one end of a line to the centre of the +ellipse. The point of intersection between this line and the ellipse defines +the start point of the arc bounding the pie slice. The point aEnd is used +to define one end of a second line to the centre of the ellipse. The point +of intersection between this line and the ellipse defines the end point of +the arc bounding the pie slice. The pixels at the end point are not drawn. + +The pie slice itself is the area bounded by: the arc of the ellipse in an +anticlockwise direction from the start point to the end point; the straight +line from the start point from the geometric centre of the ellipse; the +straight line from the end point from the geometric centre of the ellipse. + +The line drawn by the pen goes inside the rectangle given by the aRect argument. + +Notes: + +A rectangle is used in the construction of the pie slice. This rectangle is +passed as an argument of type TRect. The curved edge of the pie slice is an +arc of an ellipse constructed within the rectangle. + +A wide line edged pie slice has the arc drawn with the pixels distributed +either side of a true ellipse. This is done in such a way that the outer edge +of the line would touch the edge of the construction rectangle. In other words, +the ellipse used to construct it is slightly smaller than that for a single +pixel line size. + +If aStart or aEnd are the ellipse centre then the line that defines the start/end +of the arc defaults to one extending vertically above the centre point. + +If aStart and aEnd are the same point, or points on the same line through +the ellipse centre then a complete filled ellipse is drawn. A line is also +drawn from the edge to the ellipse centre. + +@param aRect A rectangle in which to draw the ellipse bounding the pie slice +@param aStart A point to define the start of the pie slice +@param aEnd A point to define the end of the pie slice +@see CGraphicsContext::DrawPie() */ + { + iPimpl->WriteAnyPendingStateChanges(); + DrawArcOrPie(aRect,aStart,aEnd,EWsGcOpDrawPie); + } + +EXPORT_C void CWindowGc::DrawEllipse(const TRect &aRect) +/** Draws and fills an ellipse. + +The ellipse is drawn inside the rectangle defined by the aRect argument. Any +TRect that has odd pixel dimensions, has the bottom right corner trimmed to +give even pixel dimensions before the ellipse is constructed. + +The column and row of pixels containing the bottom right co-ordinate of the +aRect argument are not part of the rectangle. + +Note: a wide outline ellipse is drawn with the pixels distributed either side of +a true ellipse, in such a way that the outer edge of the line touches the +edge of the construction rectangle. In other words, the ellipse used to construct +it is smaller than that for a single pixel line size. + +@param aRect The rectangle in which to draw the ellipse +@see CGraphicsContext::DrawEllipse() */ + { + iPimpl->WriteAnyPendingStateChanges(); + WriteRect(aRect,EWsGcOpDrawEllipse); + } + +EXPORT_C void CWindowGc::DrawRect(const TRect &aRect) +/** Draws and fills a rectangle. + +The rectangle's border is drawn with the pen, and it is filled using the brush. + +@param aRect The rectangle to be drawn. +@see CGraphicsContext::DrawRect() */ + { + iPimpl->WriteAnyPendingStateChanges(); + WriteRect(aRect,EWsGcOpDrawRect); + } + +EXPORT_C void CWindowGc::DrawRoundRect(const TRect &aRect,const TSize &aEllipse) +/** Draws and fills a rectangle with rounded corners. + +The rounded corners are each constructed as an arc of an ellipse. The dimensions +of each corner (corner size and corner height) are given by aEllipse. See +DrawArc() for a description of arc construction. + +The line drawn by the pen (if any) goes inside the rectangle given by the +TRect argument. + +Notes: + +Dotted and dashed pen styles cannot be used for the outline of a rounded rectangle. + +If either corner size dimension is greater than half the corresponding rectangle +length, the corner size dimension is reduced to half the rectangle size. + +@param aRect The rectangle to be drawn. +@param aEllipse The dimensions of each corner. +@see CGraphicsContext::DrawRoundRect() */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawRoundRect drawRoundRect(aRect,aEllipse); + Write(&drawRoundRect,sizeof(drawRoundRect),EWsGcOpDrawRoundRect); + } + +EXPORT_C void CWindowGc::DrawBitmap(const TPoint &aTopLeft, const CFbsBitmap *aDevice) +/** Draws a bitmap at a specified point. + +The function does a compress/stretch based on its internally stored size in +twips. Note that if the twips value of the bitmap is not set then nothing +is drawn (this is the default situation). + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +Note: this member function uses the bitmap's size in twips and does a stretch/compress +blit using a linear DDA. + +@param aTopLeft The point where the top left pixel of the bitmap is to be +drawn +@param aDevice The source bitmap. +@see CGraphicsContext::DrawBitmap() */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawBitmap drawBitmap(aTopLeft,aDevice->Handle()); + Write(&drawBitmap,sizeof(drawBitmap),EWsGcOpDrawBitmap); + AddToBitmapArray(aDevice->Handle()); + } + +EXPORT_C void CWindowGc::DrawBitmap(const TRect &aDestRect, const CFbsBitmap *aDevice) +/** Draws a bitmap in a rectangle. + +The bitmap is compressed/stretched to fit the specified rectangle. Note that +if the twips value of the bitmap is not set then nothing is drawn (this is +the default situation). + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +Notes: this member function uses the bitmap's size in pixels and does a stretch/compress +blit using a linear DDA. + +@param aDestRect The rectangle within which the bitmap is to be drawn. +@param aDevice The source bitmap. +@see CGraphicsContext::DrawBitmap() */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawBitmap2 drawBitmap(aDestRect,aDevice->Handle()); + Write(&drawBitmap,sizeof(drawBitmap),EWsGcOpDrawBitmap2); + AddToBitmapArray(aDevice->Handle()); + } + +EXPORT_C void CWindowGc::DrawBitmap(const TRect &aDestRect, const CFbsBitmap *aDevice, const TRect &aSourceRect) +/** Draws a specified rectangle from a bitmap into another rectangle. + +The function compresses/stretches the specified rectangle from the bitmap +to fit the destination rectangle. Note that if the twips value of the bitmap +is not set then nothing is drawn (this is the default situation). + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +Note: this member function uses rectangle sizes in pixels and does a stretch/compress +blit using a linear DDA. + +@param aDestRect The rectangle within which the bitmap is to be drawn. +@param aDevice A source bitmap. +@param aSourceRect The rectangle in the source bitmap that is copied to the +destination rectangle. +@see CGraphicsContext::DrawBitmap() */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawBitmap3 drawBitmap(aDestRect,aDevice->Handle(),aSourceRect); + Write(&drawBitmap,sizeof(drawBitmap),EWsGcOpDrawBitmap3); + AddToBitmapArray(aDevice->Handle()); + } + +/** Draws a specified rectangle from a bitmap and its mask into another rectangle. + +The function compresses/stretches the specified rectangle from the bitmap +to fit the destination rectangle. +The mask bitmap can be used as either a positive or negative mask. Masked +pixels are not mapped to the destination rectangle. + +A black and white (binary) mask bitmap is used. With aInvertMask=EFalse, black +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. With aInvertMask=ETrue, white +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. + +If mask bitmap's display mode is EColor256, the function does AplhaBlending +and ignores aInvertMask parameter. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +Note: this member function uses rectangle sizes in pixels and does a stretch/compress +blit using a linear DDA. + +@param aDestRect The rectangle within which the masked bitmap is to be drawn. +@param aBitmap A source bitmap. +@param aSourceRect The rectangle in the source bitmap that is copied to the +destination rectangle. +@param aMaskBitmap A mask bitmap. +@param aInvertMask If false, a source pixel that is masked by a black pixel +is not transferred to the destination rectangle. If true, then a source pixel +that is masked by a white pixel is not transferred to the destination rectangle. */ +EXPORT_C void CWindowGc::DrawBitmapMasked(const TRect& aDestRect, const CFbsBitmap* aBitmap, const TRect& aSourceRect, const CFbsBitmap* aMaskBitmap, TBool aInvertMask) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawBitmapMasked drawBitmap(aDestRect,aBitmap->Handle(),aSourceRect,aMaskBitmap->Handle(),aInvertMask); + Write(&drawBitmap,sizeof(drawBitmap),EWsGcOpDrawBitmapMasked); + AddToBitmapArray(aBitmap->Handle()); + AddToBitmapArray(aMaskBitmap->Handle()); + } + +EXPORT_C void CWindowGc::DrawBitmapMasked(const TRect& aDestRect, const CWsBitmap* aBitmap, const TRect& aSourceRect, const CWsBitmap* aMaskBitmap, TBool aInvertMask) +/** Draws a specified rectangle from a wserv bitmap and its mask into +another rectangle. + +The function compresses/stretches the specified rectangle from the bitmap +to fit the destination rectangle. +The mask bitmap can be used as either a positive or negative mask. Masked +pixels are not mapped to the destination rectangle. + +A black and white (binary) mask bitmap is used. With aInvertMask=EFalse, black +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. With aInvertMask=ETrue, white +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. + +If mask bitmap's display mode is EColor256, the function does AplhaBlending +and ignores aInvertMask parameter. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +Note: this member function uses rectangle sizes in pixels and does a stretch/compress +blit using a linear DDA. + +@param aDestRect The rectangle within which the masked bitmap is to be drawn. +@param aBitmap A source wserv bitmap. +@param aSourceRect The rectangle in the source bitmap that is copied to the +destination rectangle. +@param aMaskBitmap A mask wserv bitmap. +@param aInvertMask If false, a source pixel that is masked by a black pixel +is not transferred to the destination rectangle. If true, then a source pixel +that is masked by a white pixel is not transferred to the destination rectangle. */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawBitmapMasked drawBitmap(aDestRect,aBitmap->WsHandle(),aSourceRect,aMaskBitmap->WsHandle(),aInvertMask); + Write(&drawBitmap,sizeof(drawBitmap),EWsGcOpWsDrawBitmapMasked); + AddToBitmapArray(aBitmap->Handle()); + AddToBitmapArray(aMaskBitmap->Handle()); + } +EXPORT_C void CWindowGc::DrawText(const TDesC &aBuf, const TPoint &aPos) +/** Draws horizontal text with no surrounding box. + +The appearance of the text is subject to the drawing mode, the font, pen colour, +word justification and character justification. + +A panic occurs if this function is called when there is no font: see UseFont(). + +@param aBuf The string to write. +@param aPos The point specifying the position of the baseline at the left +end of the text. +@see CGraphicsContext::DrawText() */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawText printText(aPos,aBuf.Length()); + WriteTextCommand(&printText,sizeof(printText),aBuf,EWsGcOpDrawText,EWsGcOpDrawTextPtr); + } + +EXPORT_C void CWindowGc::DrawText(const TDesC &aBuf,const TRect &aBox,TInt aBaselineOffset,TTextAlign aHoriz,TInt aLeftMrg) +/** Draws horizontal text within a cleared box. + +The appearance of the text is subject to the drawing mode, the font, pen colour, +word justification and character justification. It is also subject to the +background brush (set brush to ENullBrush for no effect on background). + +A panic occurs if this function is called when there is no font: see UseFont(). + +Note: the text is clipped to the box. You must ensure that the specified string +is not too large. + +@param aBuf The text to write. +@param aBox The box to draw the text in. +@param aBaselineOffset An offset from the top of the box to the text baseline. +Note that the baseline is the line on which letters sit, for instance below r, s, t, and +above the tail of q, and y. +@param aHoriz The text alignment mode (default is left, rather than centre +or right). +@param aLeftMrg The left margin for left-aligned text, or the right margin +for right-aligned text (default is zero). +@see CGraphicsContext::DrawText() */ + { + iPimpl->WriteAnyPendingStateChanges(); + if (aBuf.Size()<(TInt)(iBuffer->BufferSize()-sizeof(TWsCmdHeader)-sizeof(TWsGcCmdBoxTextOptimised2))) + { + if (aHoriz==ELeft && aLeftMrg==0) + { + TWsGcCmdBoxTextOptimised1 boxTextOpt1(aBox,aBaselineOffset,aBuf.Length()); + Write(&boxTextOpt1,sizeof(boxTextOpt1),aBuf.Ptr(),aBuf.Size(),EWsGcOpDrawBoxTextOptimised1); + } + else + { + TWsGcCmdBoxTextOptimised2 boxTextOpt2(aBox,aBaselineOffset,aHoriz,aLeftMrg,aBuf.Length()); + Write(&boxTextOpt2,sizeof(boxTextOpt2),aBuf.Ptr(),aBuf.Size(),EWsGcOpDrawBoxTextOptimised2); + } + } + else + { + TWsGcCmdBoxText boxText(aBox,aBaselineOffset,aHoriz,aLeftMrg,aBuf.Length(),iPimpl->iFont->TextWidthInPixels(aBuf)); + WriteTextCommand(&boxText,sizeof(boxText),aBuf,EWsGcOpDrawBoxText,EWsGcOpDrawBoxTextPtr); + } + } + +TInt CWindowGc::APIExDrawText(const TDesC& aBuf,const TTextParameters* aParam,const TPoint& aPos) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawTextInContext printTextInContext(aPos,aBuf.Length(),aParam->iStart,aParam->iEnd); + WriteTextCommand(&printTextInContext,sizeof(printTextInContext),aBuf,EWsGcOpDrawTextInContext,EWsGcOpDrawTextInContextPtr); + return KErrNone; + } + +TInt CWindowGc::APIExDrawText(const TDesC& aBuf,const TTextParameters* aParam,const TRect& aBox,TInt aBaselineOffset,TTextAlign aHoriz,TInt aLeftMrg) + { + iPimpl->WriteAnyPendingStateChanges(); + if (aBuf.Size()<(TInt)(iBuffer->BufferSize()-sizeof(TWsCmdHeader)-sizeof(TWsGcCmdBoxTextInContextOptimised2))) + { + if (aHoriz==ELeft && aLeftMrg==0) + { + TWsGcCmdBoxTextInContextOptimised1 boxTextOpt1(aBox,aBaselineOffset,aBuf.Length(),aParam->iStart,aParam->iEnd); + Write(&boxTextOpt1,sizeof(boxTextOpt1),aBuf.Ptr(),aBuf.Size(),EWsGcOpDrawBoxTextInContextOptimised1); + } + else + { + TWsGcCmdBoxTextInContextOptimised2 boxTextOpt2(aBox,aBaselineOffset,aHoriz,aLeftMrg,aBuf.Length(),aParam->iStart,aParam->iEnd); + Write(&boxTextOpt2,sizeof(boxTextOpt2),aBuf.Ptr(),aBuf.Size(),EWsGcOpDrawBoxTextInContextOptimised2); + } + } + else + { + TWsGcCmdBoxTextInContext boxText(aBox,aBaselineOffset,aHoriz,aLeftMrg,aBuf.Length(),iPimpl->iFont->TextWidthInPixels(aBuf),aParam->iStart,aParam->iEnd); + WriteTextCommand(&boxText,sizeof(boxText),aBuf,EWsGcOpDrawBoxTextInContext,EWsGcOpDrawBoxTextInContextPtr); + } + return KErrNone; + } +EXPORT_C void CWindowGc::DrawTextVertical(const TDesC& aText,const TPoint& aPos,TBool aUp) +/** Draws vertical text in the specified direction. + +A panic occurs if this function is called when there is no font: see UseFont(). + +@param aText The text to be drawn. +@param aPos Point of origin of the text baseline. +@param aUp Direction. ETrue for up, EFalse for down. */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawTextVertical printText(aPos,aText.Length(),aUp); + WriteTextCommand(&printText,sizeof(printText),aText,EWsGcOpDrawTextVertical,EWsGcOpDrawTextVerticalPtr); + } + +EXPORT_C void CWindowGc::DrawTextVertical(const TDesC& aText,const TRect& aBox,TInt aBaselineOffset,TBool aUp,TTextAlign aVert,TInt aMargin) +/** Draws text vertically in the specified direction, within a box of the specified +size. + +A panic occurs if this function is called when there is no font: see UseFont(). + +@param aText The text to be drawn. +@param aBox The bounding box within which the text should be drawn, and which +it is clipped to. +@param aBaselineOffset The height of the top of the characters from their text +baseline. +@param aUp The direction. ETrue for up, EFalse for down. +@param aVert The text alignment. +@param aMargin The margin. */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdBoxTextVertical boxText(aBox); + boxText.baselineOffset=aBaselineOffset; + boxText.up=aUp; + boxText.vert=aVert; + boxText.margin=aMargin; + boxText.length=aText.Length(); + boxText.width=iPimpl->iFont->TextWidthInPixels(aText); + WriteTextCommand(&boxText,sizeof(boxText),aText,EWsGcOpDrawBoxTextVertical,EWsGcOpDrawBoxTextVerticalPtr); + } + +TInt CWindowGc::APIExDrawTextVertical(const TDesC& aText,const TTextParameters* aParam,const TPoint& aPos,TBool aUp) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawTextInContextVertical printText(aPos,aText.Length(),aUp,aParam->iStart,aParam->iEnd); + WriteTextCommand(&printText,sizeof(printText),aText,EWsGcOpDrawTextInContextVertical,EWsGcOpDrawTextInContextVerticalPtr); + return KErrNone; + } + +TInt CWindowGc::APIExDrawTextVertical(const TDesC& aText,const TTextParameters* aParam,const TRect& aBox,TInt aBaselineOffset,TBool aUp,TTextAlign aVert,TInt aMargin) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdBoxTextInContextVertical boxText(aBox); + boxText.baselineOffset=aBaselineOffset; + boxText.up=aUp; + boxText.vert=aVert; + boxText.margin=aMargin; + boxText.length=aText.Length(); + boxText.width=iPimpl->iFont->TextWidthInPixels(aText); + boxText.start = aParam->iStart; + boxText.end = aParam->iEnd; + WriteTextCommand(&boxText,sizeof(boxText),aText,EWsGcOpDrawBoxTextInContextVertical,EWsGcOpDrawBoxTextInContextVerticalPtr); + return KErrNone; + } + +//========================Extra functions============================ + +EXPORT_C void CWindowGc::CopyRect(const TPoint &anOffset,const TRect &aRect) +/** Copies a rectangle from any part of the screen into the window that the gc +is active on. + +The copy part of the operation applies to the whole rectangle, irrespective +of whether or not it within the window, however the "paste" is clipped to +the drawing area. + +The rectangle is specified in window coordinates (if the top-left of the rectangle +is (0,0) then the area of the screen it specifies has its top-left at the +top left corner of the window, if it is (-10,-10) then it starts 10 pixels +above and to the left of the window). + +Note: shadows in the source rectangle will be copied. None of the area drawn to +will gain shadowing (even if the window is already in shadow). + +This version of this function is only really suitable for testing. + +@param anOffset The offset from the original position to the point where the +rectangle is copied. +@param aRect The rectangular area to be copied. This is in window co-ordinates, +e.g. the top left corner of the window is position (0,0) with respect to the +rectangle. +@see CBitmapContext::CopyRect() */ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdCopyRect copyRect(anOffset,aRect); + Write(©Rect,sizeof(copyRect),EWsGcOpCopyRect); + } + +EXPORT_C void CWindowGc::BitBlt(const TPoint &aPoint, const CFbsBitmap *aBitmap) +/** Performs a bitmap block transfer. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +@param aPoint The position for the top left corner of the bitmap. +@param aBitmap A memory-resident bitmap. +@see CBitmapContext::BitBlt() */ + { + if (aBitmap == NULL || !aBitmap->Handle()) + return; + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdGdiBlt2 gdiBlit(aPoint,aBitmap->Handle()); + Write(&gdiBlit,sizeof(gdiBlit),EWsGcOpGdiBlt2); + AddToBitmapArray(aBitmap->Handle()); + } + +EXPORT_C void CWindowGc::BitBlt(const TPoint &aDestination,const CFbsBitmap *aBitmap,const TRect &aSource) +/** Performs a bitmap block transfer of a rectangular piece of a bitmap. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +Note: if the rectangle aSource is larger than the bitmap then the bitmap will be padded +with white. + +@param aDestination The position for the top left corner of the bitmap. +@param aBitmap A memory-resident bitmap +@param aSource A rectangle defining the piece of the bitmap to be drawn, with +co-ordinates relative to the top left corner of the bitmap +@see CBitmapContext::BitBlt() */ + { + if (aBitmap == NULL || !aBitmap->Handle()) + return; + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdGdiBlt3 gdiBlit(aDestination,aBitmap->Handle(),aSource); + Write(&gdiBlit,sizeof(gdiBlit),EWsGcOpGdiBlt3); + AddToBitmapArray(aBitmap->Handle()); + } + +EXPORT_C void CWindowGc::BitBltMasked(const TPoint& aPoint,const CFbsBitmap* aBitmap,const TRect& aSourceRect,const CFbsBitmap* aMaskBitmap,TBool aInvertMask) +/** Performs a masked bitmap block transfer of a memory resident source bitmap. + +The mask bitmap can be used as either a positive or negative mask. Masked +pixels are not mapped to the destination rectangle. + +A black and white (binary) mask bitmap is used. With aInvertMask=EFalse, black +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. With aInvertMask=ETrue, white +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +@param aPoint A position for the top left corner of the bitmap. +@param aBitmap 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 A mask bitmap. +@param aInvertMask If false, a source pixel that is masked by a black pixel +is not transferred to the destination rectangle. If true, then a source pixel +that is masked by a white pixel is not transferred to the destination rectangle. + +@see CBitmapContext::BitBltMasked() */ + { + if (aBitmap == NULL || !aBitmap->Handle() || aMaskBitmap == NULL || !aMaskBitmap->Handle()) + return; + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdBltMasked gdiBlitMasked(aPoint,aBitmap->Handle(),aSourceRect,aMaskBitmap->Handle(),aInvertMask); + Write(&gdiBlitMasked,sizeof(gdiBlitMasked),EWsGcOpGdiBltMasked); + AddToBitmapArray(aBitmap->Handle()); + AddToBitmapArray(aMaskBitmap->Handle()); + } + +EXPORT_C void CWindowGc::BitBlt(const TPoint &aPoint, const CWsBitmap *aBitmap) +/** Performs a bitmap block transfer on a bitmap to which the window server already +has a handle. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +This function should be used in preference to the CFbsBitmap overload if the +bitmap is to be used more than once, as it is a lot quicker. + +@param aPoint The position for the top left corner of the bitmap. +@param aBitmap A window server bitmap. +@see CBitmapContext::BitBlt() */ + { + if (aBitmap == NULL || !aBitmap->Handle()) + return; + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdGdiBlt2 gdiBlit(aPoint,aBitmap->WsHandle()); + Write(&gdiBlit,sizeof(gdiBlit),EWsGcOpGdiWsBlt2); + AddToBitmapArray(aBitmap->Handle()); + } + +EXPORT_C void CWindowGc::BitBlt(const TPoint &aDestination,const CWsBitmap *aBitmap,const TRect &aSource) +/** Performs a bitmap block transfer of a rectangular piece of a bitmap to which +the window server already has a handle. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +This function should be used in preference to the CFbsBitmap overload if the +bitmap is to be used more than once, as it is a lot quicker. + +Note: if the rectangle aSource is larger than the bitmap then the bitmap will be padded +with white. + +@param aDestination The position for the top left corner of the bitmap. +@param aBitmap A window server bitmap. +@param aSource A rectangle defining the piece of the bitmap to be drawn, with +co-ordinates relative to the top left corner of the bitmap +@see CBitmapContext::BitBlt() */ + { + if (aBitmap == NULL || !aBitmap->Handle()) + return; + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdGdiBlt3 gdiBlit(aDestination,aBitmap->WsHandle(),aSource); + Write(&gdiBlit,sizeof(gdiBlit),EWsGcOpGdiWsBlt3); + AddToBitmapArray(aBitmap->Handle()); + } + +EXPORT_C void CWindowGc::BitBltMasked(const TPoint& aPoint,const CWsBitmap * aBitmap,const TRect& aSourceRect,const CWsBitmap * aMaskBitmap,TBool aInvertMask) +/** Performs a masked bitmap block transfer of a window server bitmap. + +The mask bitmap can be used as either a positive or negative mask. Masked +pixels are not mapped to the destination rectangle. + +A black and white (binary) mask bitmap is used. With aInvertMask=EFalse, black +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. With aInvertMask=ETrue, white +pixels in the mask bitmap stop corresponding pixels in the source bitmap from +being transferred to the destination rectangle. + +This function should be used in preference to the CFbsBitmap overload if the +bitmap is to be used more than once, as it is a lot quicker. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +@param aPoint A position for the top left corner of the bitmap. +@param aBitmap A window server 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 A window server mask bitmap. +@param aInvertMask If false, a source pixel that is masked by a black pixel +is not transferred to the destination rectangle. If true, then a source pixel +that is masked by a white pixel is not transferred to the destination rectangle. + +@see CBitmapContext::BitBltMasked() */ + { + if (aBitmap == NULL || !aBitmap->Handle() || aMaskBitmap == NULL || !aMaskBitmap->Handle()) + return; + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdBltMasked gdiBlitMasked(aPoint,aBitmap->WsHandle(),aSourceRect,aMaskBitmap->WsHandle(),aInvertMask); + Write(&gdiBlitMasked,sizeof(gdiBlitMasked),EWsGcOpGdiWsBltMasked); + AddToBitmapArray(aBitmap->Handle()); + AddToBitmapArray(aMaskBitmap->Handle()); + } + +/** +This method has been deprecated. It is no longer possible to re-map pixel colours +within a rectangle. Calling it has no effect. +@param aRect Ignored. +@param aColors Ignored. +@param aNumPairs Ignored. +@param aMapForwards Ignored. +@deprecated +*/ +EXPORT_C void CWindowGc::MapColors(const TRect& /*aRect*/, const TRgb* /*aColors*/, TInt /*aNumPairs*/, TBool /*aMapForwards*/) + { + } + +EXPORT_C void CWindowGc::Clear(const TRect &aRect) +/** Clears a rectangular area of a window. + +The cleared area is filled with the current brush colour. + +@param aRect The rectangle to clear. +@see CBitmapContext::Clear() */ + { + iPimpl->WriteAnyPendingStateChanges(); + WriteRect(aRect,EWsGcOpClearRect); + } + +EXPORT_C void CWindowGc::Clear() +/** Clears the whole window. + +The cleared area is filled with the current brush colour. + +@see CBitmapContext::Clear() */ + { + iPimpl->WriteAnyPendingStateChanges(); + Write(EWsGcOpClear); + } + +EXPORT_C void CWindowGc::Reset() +/** Resets the graphics context to its default settings. + +The drawing mode is set to TDrawMode::EDrawModePen (pen and brush colours used as +they are); there is no clipping rectangle; the pen settings are black, +solid, single pixel size; the brush style is null; no text font is selected. + +@see CGraphicsContext::Reset() */ + { + Write(EWsGcOpReset); + iPimpl->iFont=NULL; + iPimpl->iShadowColor = KDefaultShadowColor; + iPimpl->ResetPendingState(); + iPimpl->iForceWrite = ETrue; // needed because brush colour set to window background colour in CPlaybackGc::CommandL and CWsGc::SetGcAttribute + } + +/** +This method has been deprecated. Dithering is no longer supported. Calling it +has no effect. +@param aPoint Ignored. +@deprecated +*/ +EXPORT_C void CWindowGc::SetDitherOrigin(const TPoint& /*aPoint*/) + { + } + +EXPORT_C void CWindowGc::SetFaded(TBool aFaded) +/** Sets whether the graphics context is faded. + +Fading is used to make a window appear less colourful so that other windows +stand out. For example, a window would be faded when a dialogue is displayed +in front of it. + +@param aFaded ETrue to fade the graphics context, EFalse to unfade it. */ + { + iPimpl->WriteAnyPendingStateChanges(); + WriteInt(aFaded,EWsGcOpSetFaded); + } + +EXPORT_C void CWindowGc::SetFadingParameters(TUint8 aBlackMap,TUint8 aWhiteMap) +/** Sets the fading parameters. + +This function allows you to override the map used when drawing with a faded +graphics context. However if you draw to a faded window with a faded graphics +context, then fading on the graphics context is ignored and it will use the +fading of the window. + +Fading is used to make a window appear less colourful so that other windows stand +out. For example, a window would be faded when a dialogue is displayed +in front of it. + +You can either make a faded window closer to white or closer to black. +The fading map allows you to over-ride the default fading parameters set in +RWsSession::SetDefaultFadingParameters(). + +Fading re-maps colours to fall between the specified black and white map values. +If aBlackMap=0 and aWhiteMap=255 then the colours are mapped unchanged. As the +values converge, the colours are mapped to a smaller range, so the differences +between colours in the faded graphics context decrease. If the values are reversed +then the colours are inverted (i.e. where the gc would be black, it is now white). + +@param aBlackMap Black map fading parameter. Unfaded this is 0. +@param aWhiteMap White map fading parameter. Unfaded this is 255. +@see RWsSession::SetDefaultFadingParameters() +@see RWindowTreeNode::SetFaded() */ + { + WriteInt(WservEncoding::Encode8BitValues(aBlackMap,aWhiteMap),EWsGcOpSetFadeParams); + } + +EXPORT_C TInt CWindowGc::AlphaBlendBitmaps(const TPoint& aDestPt, const CFbsBitmap* aSrcBmp, const TRect& aSrcRect,const CFbsBitmap* aAlphaBmp, const TPoint& aAlphaPt) +/** +Performs an alpha blending of the source data, aSrcBmp, with the window, using +the data from aAlphaBmp as an alpha blending factor. +The formula used is: +(S * A + W * (255 - A)) / 255, where: +- S - a pixel from aSrcBmp; +- W - a pixel from the window; +- A - a pixel from aAlphaBmp; +The contents of source and alpha bitmap are preserved. +The calculated alpha blended pixels are written to the destination - the window image. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +This method is supported from version 8.1 +@param aDestPt Position in the target the result should be drawn to. +@param aSrcBmp A pointer to the source bitmap. +@param aSrcRect The part of the source bitmap that should be used. +@param aAlphaBmp A pointer to the bitmap used as an alpha blending factor. +@param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source + for the alpha blending. The size of the area is the same as the + source bitmap area - aSrcRect parameter. +@see CFbsBitGc::AlphaBlendBitmaps() +*/ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdAlphaBlendBitmaps alphaBlend(aDestPt, aSrcBmp->Handle(), aSrcRect, aAlphaBmp->Handle(), aAlphaPt); + Write(&alphaBlend,sizeof(alphaBlend),EWsGcOpGdiAlphaBlendBitmaps); + AddToBitmapArray(aSrcBmp->Handle()); + AddToBitmapArray(aAlphaBmp->Handle()); + return KErrNone; + } + +EXPORT_C TInt CWindowGc::AlphaBlendBitmaps(const TPoint& aDestPt, const CWsBitmap* aSrcBmp, const TRect& aSrcRect,const CWsBitmap* aAlphaBmp, const TPoint& aAlphaPt) +/** +The method performs an alpha blending of the source data, aSrcBmp, with the window, using +the data from aAlphaBmp as an alpha blending factor. +For information on how this function works, see the other overload. + +Windows that store their redraw commands will only store drawing position and a handle to bitmaps +that are drawn in it. The bitmap handle is just a pointer to the bitmap in the FBSERV heap. +At some point later WSERV may need to draw that window again and it will just replay the +stored commands including the draw bitmap. However, if the client has changed the content of the bitmap, +WSERV will effectively draw a different bitmap when it replays the commands. + +This method is supported from version 8.1 +@param aDestPt Position in the target the result should be drawn to. +@param aSrcBmp A pointer to the source bitmap. +@param aSrcRect The part of the source bitmap that should be used. +@param aAlphaBmp A pointer to the bitmap used as an alpha blending factor. +@param aAlphaPt Position of the first pixel in the alpha bitmap that should be used as a source + for the alpha blending. The size of the area is the same as the + source bitmap area - aSrcRect parameter. +@see CFbsBitGc::AlphaBlendBitmaps() +*/ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdAlphaBlendBitmaps alphaBlend(aDestPt, aSrcBmp->WsHandle(), aSrcRect, aAlphaBmp->WsHandle(), aAlphaPt); + Write(&alphaBlend,sizeof(alphaBlend),EWsGcOpGdiWsAlphaBlendBitmaps); + AddToBitmapArray(aSrcBmp->Handle()); + AddToBitmapArray(aAlphaBmp->Handle()); + return KErrNone; + } + +/** +This method has been deprecated. Calling it has no effect. +@param aDrawOpaque Ignored. +@deprecated +*/ +EXPORT_C void CWindowGc::SetOpaque(TBool aDrawOpaque) + { + iPimpl->WriteAnyPendingStateChanges(); + WriteInt(aDrawOpaque, EWsGcOpSetOpaque); + } + +/** APIExtension can contain as many additional methods as is required by +CGraphicsContext after its original conception. It takes 3 parameters. +Function is exported due to constrains of retaining BC with earlier versions. +This is not used directly by external methods, instead it is called by a named +method in CGraphicsContext which passes the relivant arguements including an +unique identifier for the required action. +@param aUid The unique identifier for the method that is required. Selected +internally by a series of "if" statements. +@see Valid Uid identifiers are listed in header gdi.h +@see CGraphicsContext +@param aOutput is a TAny pointer to a reference. Used to output data as the structure +does not need to be instantiated before the function call this adds greater +flexibility. +@param aInput is a TAny pointer used to input data. +*/ +EXPORT_C TInt CWindowGc::APIExtension(TUid aUid, TAny*& aOutput, TAny* aInput) + { + if (aUid == KGetUnderlineMetrics) + { + return APIExGetUnderlineMetrics(aOutput); + } + else if (aUid == KSetShadowColor) + { + return APIExSetShadowColor(aInput); + } + else if (aUid == KGetShadowColor) + { + return APIExGetShadowColor(aOutput); + } + else if (aUid == KDrawTextInContextUid) + { + TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput; + return APIExDrawText(contextParam->iText, &contextParam->iParam, contextParam->iPosition); + } + else if (aUid == KDrawBoxTextInContextUid) + { + TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput; + return APIExDrawText(contextParam->iText,&contextParam->iParam,contextParam->iBox,contextParam->iBaselineOffset,contextParam->iAlign,contextParam->iMargin); + } + else if (aUid == KDrawTextInContextVerticalUid) + { + TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput; + return APIExDrawTextVertical(contextParam->iText, &contextParam->iParam, contextParam->iPosition,contextParam->iUp); + } + else if (aUid == KDrawBoxTextInContextVerticalUid) + { + TDrawTextInContextInternal* contextParam = (TDrawTextInContextInternal*)aInput; + return APIExDrawTextVertical(contextParam->iText,&contextParam->iParam,contextParam->iBox,contextParam->iBaselineOffset,contextParam->iUp,contextParam->iAlign,contextParam->iMargin); + } + else if (aUid == KApiExtensionInterfaceUid) + { + return APIExInterface(aOutput, *static_cast(aInput)); + } + /* Future cases may be placed here later.*/ + else + return CBitmapContext::APIExtension(aUid, aOutput, aInput); + } + +//The methods listed above in APIExtension follow here with the prefix APIEx. +TInt CWindowGc::APIExGetUnderlineMetrics(TAny*& aOutput) + { + const TInt width = Max(iPimpl->iFont->HeightInPixels() / 10,1); + TTwoTInt* ptr = (TTwoTInt*)aOutput; + ptr->iTop = 1 + width / 2; + ptr->iBottom = (ptr->iTop) + width; + return KErrNone; + } + +TInt CWindowGc::APIExSetShadowColor(TAny* aShadowColor) + { + const TRgb shadowColor = *(reinterpret_cast (aShadowColor)); + WriteInt(shadowColor.Internal(), EWsGcOpSetShadowColor); + iPimpl->iShadowColor = shadowColor; + return KErrNone; + } + +TInt CWindowGc::APIExGetShadowColor(TAny*& aOutput) + { + TRgb* ptr = (TRgb*)aOutput; + ptr->SetInternal(iPimpl->iShadowColor.Internal()); + return KErrNone; + } + +//Default implementation of reserved virtual +EXPORT_C void CWindowGc::Reserved_CGraphicsContext_2() + { + CBitmapContext::Reserved_CGraphicsContext_2(); + } + +//Default implementation of reserved virtual +EXPORT_C void CWindowGc::Reserved_CBitmapContext_1() + { + CBitmapContext::Reserved_CBitmapContext_1(); + } + +//Default implementation of reserved virtual +EXPORT_C void CWindowGc::Reserved_CBitmapContext_2() + { + CBitmapContext::Reserved_CBitmapContext_2(); + } + +//Default implementation of reserved virtual +EXPORT_C void CWindowGc::Reserved_CBitmapContext_3() + { + CBitmapContext::Reserved_CBitmapContext_3(); + } + +// was Reserved_CWindowGc_1 +EXPORT_C void CWindowGc::DrawWsGraphic(const TWsGraphicId& aId,const TRect& aDestRect) +/** Draws an abstract artwork. +It does nothing if aDestRect values fall outside the window area. + +@param aId the identifier for the artwork +@param aDestRect the destination rect within the active window for this artwork + +@since 9.2 +@released +*/ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawWsGraphic drawWsGraphic(aId,aDestRect); + Write(&drawWsGraphic,sizeof(drawWsGraphic),EWsGcOpDrawWsGraphic); + } + +// Reserved_CWindowGc_2 +EXPORT_C void CWindowGc::DrawWsGraphic(const TWsGraphicId& aId,const TRect& aDestRect,const TDesC8& aData) +/** Draws an abstract artwork. +It does nothing if aDestRect values fall outside the window area. + +@param aId the identifier for the artwork +@param aDestRect the destination rect within the active window for this artwork +@param aData opaque datagram to associate with this occasion of drawing. The format is dependent upon the artwork + +@since 9.2 +@released +*/ + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawWsGraphic drawWsGraphic(aId,aDestRect); + drawWsGraphic.iDataLen = aData.Size(); + WriteTextCommand(&drawWsGraphic, sizeof(drawWsGraphic), aData, EWsGcOpDrawWsGraphic, EWsGcOpDrawWsGraphicPtr); + } + +/** +Gets an extension interface specified by the supplied UID, or NULL if it isn't supported. + +@param aInterfaceId The UID of the requested interface +@return A pointer to the interface, or NULL if the interface isn't supported +@publishedPartner +@prototype +*/ +EXPORT_C TAny* CWindowGc::Interface(TUid aInterfaceId) + { + TAny* interface = NULL; + if(KErrNone == APIExtension(KApiExtensionInterfaceUid, interface, &aInterfaceId)) + return interface; + return NULL; + } + +/** +Gets an extension interface specified by the supplied UID, or NULL if it isn't supported. + +@param aInterfaceId The UID of the requested interface +@return A pointer to the interface, or NULL if the interface isn't supported +@publishedPartner +@prototype +*/ +EXPORT_C const TAny* CWindowGc::Interface(TUid aInterfaceId) const + { + return const_cast(this)->Interface(aInterfaceId); + } + +TInt CWindowGc::APIExInterface(TAny*& aInterface, TUid aInterfaceId) + { + if(aInterfaceId == KMWsDrawResourceInterfaceUid) + { + aInterface = static_cast(iPimpl); + return KErrNone; + } + return KErrNotSupported; + } + +void CWindowGc::DrawResource(const TPoint& aPos, const RWsDrawableSource& aSource, TGraphicsRotation aRotation) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawResourceToPos drawWsResource(aSource.WsHandle(), aPos, aRotation); + Write(&drawWsResource, sizeof(drawWsResource), EWsGcOpDrawResourceToPos); + } + +void CWindowGc::DrawResource(const TRect& aDestRect, const RWsDrawableSource& aSource, TGraphicsRotation aRotation) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawResourceToRect drawWsResource(aSource.WsHandle(), aDestRect, aRotation); + Write(&drawWsResource, sizeof(drawWsResource), EWsGcOpDrawResourceToRect); + } + +void CWindowGc::DrawResource(const TRect& aDestRect, const RWsDrawableSource& aSource, const TRect& aSrcRect, TGraphicsRotation aRotation) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawResourceFromRectToRect drawWsResource(aSource.WsHandle(), aDestRect, aSrcRect, aRotation); + Write(&drawWsResource, sizeof(drawWsResource), EWsGcOpDrawResourceFromRectToRect); + } + +void CWindowGc::DrawResource(const TRect& aDestRect, const RWsDrawableSource& aSource, const TDesC8& aParam) + { + iPimpl->WriteAnyPendingStateChanges(); + TWsGcCmdDrawResourceWithData drawWsResource(aSource.WsHandle(), aDestRect, &aParam); + Write(&drawWsResource, sizeof(drawWsResource),EWsGcOpDrawResourceWithData); + } + +//Default implementation of reserved virtual +EXPORT_C void CWindowGc::Reserved_CWindowGc_3() + { + } + +//Default implementation of reserved virtual +EXPORT_C void CWindowGc::Reserved_CWindowGc_4() + { + } + +//Default implementation of reserved virtual +EXPORT_C void CWindowGc::Reserved_CWindowGc_5() + { + } + +/** +Default constructor. +Only for embedding instances of RWsDrawableSource into other classes as data members. +Before a RWsDrawableSource can be used the other constructor must be called. + */ +EXPORT_C RWsDrawableSource::RWsDrawableSource() + : iDrawableId(KSgNullDrawableId), iScreenNumber(KSgScreenIdMain) + { + } + +/** +Constructor. +@param aWs Session to the window server + +@pre Connection to the window server is established + */ +EXPORT_C RWsDrawableSource::RWsDrawableSource(RWsSession &aWs) + : MWsClientClass(aWs.iBuffer), iDrawableId(KSgNullDrawableId), iScreenNumber(KSgScreenIdMain) + { + } + +/** +Create window server object for resource drawing operation via window server. + +This object will be identified by a unique handle and will be associated with drawable resource which is passed as a parameter. + +This object will be created for drawing onto the default screen only. + +@see CWindowGc +@param aDrawable Drawable resource. + +@post Drawable source is created and can be used by window server. The reference counter of the underlying + image resource is incremented. + +@return KErrNone if successful, KErrArgument if the image resource is not valid, + KErrAlreadyExists if this handle is already associated with a + specific resource, otherwise one of the system-wide error codes. + */ +EXPORT_C TInt RWsDrawableSource::Create(const RSgDrawable& aDrawable) + { + return Create(aDrawable, KSgScreenIdMain); + } + +/** +Create window server object for resource drawing operation via window server. + +This object will be identified by unique handle and will be associated with drawable resource which is passed as a parameter. + +This object will be created for drawing onto the specified screen only. + +@see CWindowGc +@param aDrawable Drawable resource. +@param aScreenNumber The screen onto which this drawable resource can be drawn. + +@post Drawable source is created and can be used by window server. The reference counter of the underlying + image resource is incremented. + +@return KErrNone if successful, KErrArgument if the image resource is not valid + or if the specified screen is invalid, KErrAlreadyExists if this handle + is already associated with a specific resource, otherwise one of the + system-wide error codes. + */ +EXPORT_C TInt RWsDrawableSource::Create(const RSgDrawable& aDrawable, TInt aScreenNumber) + { + if (iWsHandle) + { + return KErrAlreadyExists; + } + CGraphicsResourceWrapperFactory* grwFactory = new CGraphicsResourceWrapperFactory(); + if (!grwFactory) + return KErrNoMemory; + CGraphicsResourceWrapper* graphicsResource = grwFactory->NewGraphicsResourceWrapper(); + if(!graphicsResource) + { + delete grwFactory; + return KErrNotSupported; + } + if (graphicsResource->IsNull(aDrawable) || aScreenNumber < 0) + { + delete graphicsResource; + delete grwFactory; + return KErrArgument; + } + TWsClCmdCreateDrawableSource create(graphicsResource->Id(aDrawable), aScreenNumber); + TInt ret; + if ((ret = iBuffer->WriteReplyWs(&create, sizeof(TWsClCmdCreateDrawableSource), EWsClOpCreateDrawableSource)) < 0) + { + delete graphicsResource; + delete grwFactory; + return ret; + } + iWsHandle = ret; + iDrawableId = graphicsResource->Id(aDrawable); + iScreenNumber = aScreenNumber; + delete graphicsResource; + delete grwFactory; + return KErrNone; + } + +/** +Destroy the window server drawable source. +Calling this method on a object that is not associated with any RSgDrawable +resource will have no effect. Once Close() is called, this drawable source object can be reused. + +@post The window server drawable object is destroyed. The instance is no longer associated + with a RSgDrawable specific resource. The reference counter of the underlying + image resource is decremented. +*/ +EXPORT_C void RWsDrawableSource::Close() + { + if (iWsHandle) + { + Write(EWsDrawableSourceOpFree); + iWsHandle = 0; + iDrawableId = KSgNullDrawableId; + iScreenNumber = KSgScreenIdMain; + } + } + +/** + Get the unique ID of the associated drawable resource. + */ +EXPORT_C const TSgDrawableId& RWsDrawableSource::DrawableId() const + { + return iDrawableId; + } + +/** + Get the screen number of the drawable source. + */ +EXPORT_C TInt RWsDrawableSource::ScreenNumber() const + { + return iScreenNumber; + }