--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nga/SERVER/openwfc/playbackgc.cpp Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1391 @@
+// 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:
+// GC and Graphics functions
+//
+//
+
+#include "playbackgc.h"
+
+#include <e32std.h>
+#include <s32mem.h>
+
+#include "panics.h"
+#include "ScrDev.H"
+#include "windowgroup.h"
+#include "wsfont.h"
+#include "wstop.h"
+#include "Graphics/WSGRAPHICDRAWER.H"
+#include "Graphics/surfaceconfiguration.h"
+#include "windowelementset.h"
+
+#include <graphics/wsgraphicscontext.h>
+#include <graphics/wsuibuffer.h>
+#include "bitgditomwsgraphicscontextmappings.h"
+
+#include "graphicscontextstate.h"
+#include "drawresource.h"
+#include "devicemap.h"
+
+CPlaybackGc * CPlaybackGc::iSelf=NULL;
+
+GLREF_C RWsRegion* InternalizeRegionL(RReadStream& aReadStream);
+
+/*CPlaybackGc*/
+
+void CPlaybackGc::InitStaticsL()
+ {
+ iSelf=new(ELeave) CPlaybackGc();
+ iSelf->ConstructL();
+ }
+
+void CPlaybackGc::DeleteStatics()
+ {
+ delete iSelf;
+ iSelf = 0;
+ }
+
+CPlaybackGc::CPlaybackGc()
+ {
+ }
+
+void CPlaybackGc::ConstructL()
+ {
+ iGcBuf = CBufSeg::NewL(512);
+ }
+
+CPlaybackGc::~CPlaybackGc()
+ {
+ delete iPolyPoints;
+ delete iGcBuf;
+ iCurrentClippingRegion = NULL;
+ iIntersectedRegion.Close();
+ }
+
+void CPlaybackGc::Activate(CWsClientWindow * aWin, MWsGraphicsContext * aGc, const TRegion * aRegion)
+ {
+ iWin = aWin;
+ iGc = aGc;
+ iTargetRegion = aRegion;
+
+ iDrawRegion = iTargetRegion;
+ iMasterOrigin = iWin->Origin();
+ iOrigin.SetXY(0,0);
+ iSendOrigin = ETrue;
+ iGc->SetBrushColor(iWin->BackColor());
+ ResetClippingRect();
+ }
+
+void CPlaybackGc::Deactivate()
+ {
+ iWin = 0;
+ iGc = 0;
+ iTargetRegion = 0;
+ iDrawRegion = 0;
+ CancelUserClippingRegion();
+ }
+
+void CPlaybackGc::CancelUserClippingRegion()
+ {
+ if (iUserDefinedClippingRegion)
+ {
+ iUserDefinedClippingRegion->Destroy();
+ iUserDefinedClippingRegion = 0;
+ iDrawRegion = iTargetRegion;
+ }
+ }
+
+void CPlaybackGc::SetClippingRect(const TRect &aRect)
+ {
+ iClippingRect=aRect;
+ iClippingRect.Move(iOrigin);
+ iClippingRectSet=ETrue;
+ }
+
+void CPlaybackGc::ResetClippingRect()
+ {
+ iClippingRectSet=EFalse;
+ }
+
+void CPlaybackGc::CheckPolyData(const TAny* aDataPtr, TInt aHeaderSize, TInt aNumPoints)
+ {
+ TInt maxDataLen;
+ if (CWsClient::iCurrentCommand.iOpcode>0)
+ {
+ maxDataLen=CWsClient::EndOfCommandBuffer()-static_cast<const TUint8*>(aDataPtr);
+ }
+ else
+ {
+ maxDataLen=CWsClient::iCurrentCommand.iCmdLength;
+ }
+ const TInt dataSize=aHeaderSize+aNumPoints*sizeof(TPoint);
+ if (dataSize>maxDataLen)
+ GcOwnerPanic(EWservPanicBadPolyData);
+ }
+
+void CPlaybackGc::DoDrawPolygon(const TWsGcCmdDrawPolygon *aDrawPolygon)
+ {
+ CheckPolyData(aDrawPolygon, sizeof(TWsGcCmdDrawPolygon), aDrawPolygon->numPoints);
+ TArrayWrapper<TPoint> points((TPoint*)(aDrawPolygon + 1), aDrawPolygon->numPoints);
+ iGc->DrawPolygon(points, BitGdiToMWsGraphicsContextMappings::Convert(aDrawPolygon->fillRule));
+ }
+
+void CPlaybackGc::StartSegmentedDrawPolygonL(const TWsGcCmdStartSegmentedDrawPolygon *aDrawPolygon)
+ {
+// In case a Playback have been done before all the segment is in the RedrawStore
+// (This allocation is deleted only thanks to the EWsGcOpDrawSegmentedPolygon opcode
+// which arrive after all the segments)
+ if (iPolyPoints)
+ {
+ delete iPolyPoints;
+ iPolyPoints=NULL;
+ }
+ if(!Rng(0, aDrawPolygon->totalNumPoints, KMaxTInt/2 - 1))
+ GcOwnerPanic(EWservPanicBadPolyData);
+ iPolyPoints=(TPoint *)User::AllocL(aDrawPolygon->totalNumPoints*sizeof(TPoint));
+ iPolyPointListSize=aDrawPolygon->totalNumPoints;
+ }
+
+void CPlaybackGc::SegmentedDrawPolygonData(const TWsGcCmdSegmentedDrawPolygonData *aDrawPolygon)
+ {
+ if (aDrawPolygon->index<0 || (aDrawPolygon->index + aDrawPolygon->numPoints) > iPolyPointListSize)
+ GcOwnerPanic(EWservPanicBadPolyData);
+ Mem::Copy(iPolyPoints+aDrawPolygon->index,aDrawPolygon+1,aDrawPolygon->numPoints*sizeof(TPoint));
+ }
+
+void CPlaybackGc::EndSegmentedPolygon()
+ {
+ delete iPolyPoints;
+ iPolyPoints=NULL;
+ }
+
+void CPlaybackGc::DoDrawPolyLine(const TWsGcCmdDrawPolyLine *aDrawPolyLine, TBool aContinued)
+ {
+ TInt numPoints=aDrawPolyLine->numPoints;
+ CheckPolyData(aDrawPolyLine, sizeof(TWsGcCmdDrawPolyLine), numPoints);
+ const TPoint *points=(TPoint *)(aDrawPolyLine+1);
+ if (aContinued)
+ {
+ numPoints++;
+ points=&aDrawPolyLine->last;
+ }
+ TArrayWrapper<TPoint> pointsArr(points, numPoints);
+ if (aDrawPolyLine->more) // more to come so don't draw the end point
+ iGc->DrawPolyLineNoEndPoint(pointsArr);
+ else
+ iGc->DrawPolyLine(pointsArr);
+ }
+
+void CPlaybackGc::GcOwnerPanic(TClientPanic aPanic)
+ {
+ iGc->ResetClippingRegion();
+ iCurrentClippingRegion = NULL;
+ EndSegmentedPolygon();
+ iWin->WsOwner()->PPanic(aPanic);
+ }
+
+// implementing MWsGc
+
+MWsClient& CPlaybackGc::Client()
+ {
+ return *(iWin->WsOwner());
+ }
+
+MWsScreen& CPlaybackGc::Screen()
+ {
+ return *(iWin->Screen());
+ }
+
+const TTime& CPlaybackGc::Now() const
+ {
+ return iWin->Screen()->Now();
+ }
+
+void CPlaybackGc::ScheduleAnimation(const TRect& aRect,const TTimeIntervalMicroSeconds& aFromNow)
+ {
+ ScheduleAnimation(aRect,aFromNow,0,0);
+ }
+
+void CPlaybackGc::ScheduleAnimation(const TRect& aRect,const TTimeIntervalMicroSeconds& aFromNow,const TTimeIntervalMicroSeconds& aFreq,const TTimeIntervalMicroSeconds& aStop)
+ {
+ // convert window rect to screen rect
+ TRect rect(aRect);
+ rect.Move(iGc->Origin());
+ // clip rect to window extent
+ rect.Intersection(iWin->Abs());
+ if (!rect.IsEmpty())
+ {
+ // and schedule it
+ iWin->Screen()->ScheduleAnimation(ECrpAnim, rect, aFromNow, aFreq, aStop, iWin);
+ }
+ }
+
+void CPlaybackGc::SetGcOrigin(const TPoint& aOrigin)
+ {
+ iOrigin = aOrigin - iMasterOrigin;
+ }
+
+void CPlaybackGc::RemoteReadDataAndDrawL(const CWsGraphicDrawer* aGraphic, CWsClient* aOwner, const TWsGcCmdUnion &aData)
+ {
+ TPtrC8 data;
+ HBufC8* dataBuf = NULL;
+ const TInt len = aData.WsGraphic->iDataLen;
+
+ if ((len >= KMaxTInt / 4) || (len < 0))
+ {
+ aOwner->PPanic(EWservPanicBuffer);
+ }
+ dataBuf = HBufC8::NewLC(len);
+ TPtr8 des = dataBuf->Des();
+ aOwner->RemoteRead(des, 0);
+
+ if(des.Size() != len)
+ {
+ aOwner->PPanic(EWservPanicBuffer);
+ }
+ data.Set(des);
+ aGraphic->Draw(*this, aData.WsGraphic->iRect, data);
+ CleanupStack::PopAndDestroy(dataBuf);
+ }
+
+TPtrC CPlaybackGc::BufferTPtr(TText* aStart,TInt aLen, const TDesC8& aCmdData)
+ {
+ if ((reinterpret_cast<TUint8*>(aStart) < aCmdData.Ptr()
+ || reinterpret_cast<TUint8*>(aStart+aLen) > (aCmdData.Ptr() + aCmdData.Size()) ))
+ {
+ GcOwnerPanic(EWservPanicBufferPtr);
+ }
+ TPtrC gcPtr;
+ gcPtr.Set(aStart,aLen);
+ return(gcPtr);
+ }
+
+void CPlaybackGc::DoDrawCommand(TWsGcOpcodes aOpcode, const TDesC8& aCmdData, const TRegion *aRegion)
+ {
+ if (aRegion->Count()==0)
+ return;
+
+ TWsGcCmdUnion pData;
+ // coverity[returned_pointer]
+ pData.any=aCmdData.Ptr();
+
+ SendClippingRegionIfRequired(aRegion);
+
+ WS_ASSERT_DEBUG(!iCurrentClippingRegion, EWsPanicDrawCommandsInvalidState);
+ iCurrentClippingRegion = aRegion;
+
+ CGraphicsContext::TTextParameters contextParam;
+
+ TBool bGcDrawingOccurred = ETrue; //most commands in here draw using the gc
+
+ switch(aOpcode)
+ {
+ case EWsGcOpDrawWsGraphic:
+ case EWsGcOpDrawWsGraphicPtr:
+ {
+ bGcDrawingOccurred = EFalse; //best guess if the drawer did no happen
+ TRect screenRect(pData.WsGraphic->iRect);
+ screenRect.Move(iGc->Origin());
+ if(iCurrentClippingRegion->Intersects(screenRect))
+ {
+ const TInt dataLen = pData.WsGraphic->iDataLen;
+ TGraphicDrawerId id;
+ id.iId = pData.WsGraphic->iId;
+ id.iIsUid = (pData.WsGraphic->iFlags & EWsGraphicIdUid);
+ CWsClient* owner = iWin->WsOwner();
+ const CWsGraphicDrawer* graphic = CWsTop::WindowServer()->ResolveGraphic(id);
+ TInt lastDrawCount=GcDrawingCount();
+ if(graphic && graphic->IsSharedWith(owner->SecureId()))
+ {
+ if(aOpcode == EWsGcOpDrawWsGraphicPtr)
+ {
+ TRAPD(err, RemoteReadDataAndDrawL(graphic, owner, pData))
+ if(err)
+ WS_PANIC_DEBUG(EWsPanicWsGraphic);
+ }
+ else
+ graphic->Draw(*this,pData.WsGraphic->iRect,CWsClient::BufferTPtr8((TUint8*)(pData.WsGraphic+1),dataLen));
+
+ WS_ASSERT_DEBUG(!iGcBuf->Size(),EWsPanicWsGraphic);
+ iGcBuf->Reset();
+ }
+ if (lastDrawCount!=GcDrawingCount())
+ {
+ // Changes to the GcDrawingCount are used to tag placed and background surfaces as dirty.
+ // If drawing occurs inside a CRP and perhaps PlaceSurface occurs inside the CRP
+ // then we tag to count again to cause the placed surface to get marked as dirty later.
+ bGcDrawingOccurred = ETrue; //some GC drawing did occurr at some point
+ }
+ }
+ break;
+ }
+ case EWsGcOpMapColorsLocal:
+ GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
+ break;
+ case EWsGcOpDrawPolyLineLocalBufLen:
+ {
+ TArrayWrapper<TPoint> points(pData.DrawPolyLineLocalBufLen->points, pData.DrawPolyLineLocalBufLen->length);
+ iGc->DrawPolyLine(points);
+ break;
+ }
+ case EWsGcOpDrawPolyLineLocal:
+ iGc->DrawPolyLine(pData.PointList->Array());
+ break;
+ case EWsGcOpDrawPolygonLocalBufLen:
+ {
+ TArrayWrapper<TPoint> points(pData.DrawPolygonLocalBufLen->points, pData.DrawPolygonLocalBufLen->length);
+ iGc->DrawPolygon(points, BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawPolygonLocalBufLen->fillRule));
+ break;
+ }
+ case EWsGcOpDrawPolygonLocal:
+ iGc->DrawPolygon(pData.DrawPolygonLocal->pointList->Array(),BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawPolygonLocal->fillRule));
+ break;
+ case EWsGcOpDrawBitmapLocal:
+ {
+ // DrawBitmap(TPoint&, ) uses the size of the bitmap in twips, but
+ // MWsGraphicsContext::DrawBitmap() takes a TRect in pixels, so we need to convert
+ TRect destRect(iWin->Screen()->DeviceMap().TwipsToPixels(pData.BitmapLocal->bitmap->SizeInTwips()));
+ destRect.Move(pData.BitmapLocal->pos); //pos is defined in pixels, that's why we're not converting it
+ iGc->DrawBitmap(destRect, *pData.BitmapLocal->bitmap);
+ break;
+ }
+ case EWsGcOpDrawBitmap2Local:
+ iGc->DrawBitmap(pData.Bitmap2Local->rect, *pData.Bitmap2Local->bitmap);
+ break;
+ case EWsGcOpDrawBitmap3Local:
+ iGc->DrawBitmap(pData.Bitmap3Local->rect, *pData.Bitmap3Local->bitmap, pData.Bitmap3Local->srcRect);
+ break;
+ case EWsGcOpDrawBitmapMaskedLocal:
+ iGc->DrawBitmapMasked(pData.iBitmapMaskedLocal->iRect, *pData.iBitmapMaskedLocal->iBitmap, pData.iBitmapMaskedLocal->iSrcRect, *pData.iBitmapMaskedLocal->iMaskBitmap,pData.iBitmapMaskedLocal->iInvertMask);
+ break;
+ case EWsGcOpAlphaBlendBitmapsLocal:
+ iGc->BitBltMasked(pData.AlphaBlendBitmapsLocal->point, *pData.AlphaBlendBitmapsLocal->iBitmap,
+ pData.AlphaBlendBitmapsLocal->source, *pData.AlphaBlendBitmapsLocal->iAlpha,
+ pData.AlphaBlendBitmapsLocal->alphaPoint);
+ break;
+ case EWsGcOpDrawText:
+ if (iGc->HasFont())
+ iGc->DrawText(BufferTPtr((TText *)(pData.DrawText+1),pData.DrawText->length,aCmdData), NULL, pData.DrawText->pos);
+ break;
+ case EWsGcOpDrawBoxTextOptimised1:
+ if (iGc->HasFont())
+ iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length,aCmdData), NULL, pData.BoxTextO1->box,
+ pData.BoxTextO1->baselineOffset,MWsGraphicsContext::ELeft,0);
+ break;
+ case EWsGcOpDrawBoxTextOptimised2:
+ if (iGc->HasFont())
+ iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length,aCmdData), NULL, pData.BoxTextO2->box,
+ pData.BoxTextO2->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextO2->horiz),pData.BoxTextO2->leftMrg);
+ break;
+ case EWsGcOpDrawTextPtr:
+ if (iGc->HasFont())
+ iGc->DrawText(*pData.DrawTextPtr->text, NULL, pData.DrawTextPtr->pos);
+ break;
+ case EWsGcOpDrawTextPtr1:
+ if (iGc->HasFont())
+ iGc->DrawText(*pData.DrawTextPtr->text, NULL);
+ break;
+ case EWsGcOpDrawBoxText:
+ if (iGc->HasFont())
+ iGc->DrawText(BufferTPtr((TText *)(pData.BoxText+1),pData.BoxText->length,aCmdData), NULL, pData.BoxText->box,
+ pData.BoxText->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxText->horiz),pData.BoxText->leftMrg);
+ break;
+ case EWsGcOpDrawBoxTextPtr:
+ if (iGc->HasFont())
+ iGc->DrawText(*pData.DrawBoxTextPtr->text, NULL, pData.DrawBoxTextPtr->box,pData.DrawBoxTextPtr->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextPtr->horiz),pData.DrawBoxTextPtr->leftMrg);
+ break;
+ case EWsGcOpDrawBoxTextPtr1:
+ if (iGc->HasFont())
+ iGc->DrawText(*pData.DrawBoxTextPtr->text, NULL, pData.DrawBoxTextPtr->box);
+ break;
+ case EWsGcOpDrawTextVertical:
+ if (iGc->HasFont())
+ iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length,aCmdData),NULL,pData.DrawTextVertical->pos
+ ,pData.DrawTextVertical->up);
+ break;
+ case EWsGcOpDrawTextVerticalPtr:
+ if (iGc->HasFont())
+ iGc->DrawTextVertical(*pData.DrawTextVerticalPtr->text,NULL,pData.DrawTextVerticalPtr->pos,pData.DrawTextVerticalPtr->up);
+ break;
+ case EWsGcOpDrawTextVerticalPtr1:
+ if (iGc->HasFont())
+ iGc->DrawTextVertical(*pData.DrawTextVerticalPtr->text,NULL,pData.DrawTextVerticalPtr->up);
+ break;
+ case EWsGcOpDrawBoxTextVertical:
+ if (iGc->HasFont())
+ iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length,aCmdData), NULL,
+ pData.DrawBoxTextVertical->box, pData.DrawBoxTextVertical->baselineOffset,
+ pData.DrawBoxTextVertical->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextVertical->vert),pData.DrawBoxTextVertical->margin);
+ break;
+ case EWsGcOpDrawBoxTextVerticalPtr:
+ if (iGc->HasFont())
+ iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,NULL,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->baselineOffset
+ ,pData.DrawBoxTextVerticalPtr->width,pData.DrawBoxTextVerticalPtr->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextVerticalPtr->vert),pData.DrawBoxTextVerticalPtr->margin);
+ break;
+ case EWsGcOpDrawBoxTextVerticalPtr1:
+ if (iGc->HasFont())
+ iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,NULL,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->up);
+ break;
+ case EWsGcOpDrawTextLocal:
+ if (iGc->HasFont())
+ iGc->DrawText(*pData.DrawTextLocal->desc, NULL, pData.DrawTextLocal->pos);
+ break;
+ case EWsGcOpDrawBoxTextLocal:
+ if (iGc->HasFont())
+ iGc->DrawText(*pData.BoxTextLocal->desc, NULL, pData.BoxTextLocal->box,pData.BoxTextLocal->baselineOffset,
+ BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextLocal->horiz),pData.BoxTextLocal->leftMrg);
+ break;
+ /************* DrawText in Context function calls*********************************************/
+ case EWsGcOpDrawTextInContext:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(BufferTPtr((TText *)(pData.DrawTextInContext+1),pData.DrawTextInContext->length,aCmdData),BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContext->pos);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextOptimised1:
+ contextParam.iStart = pData.BoxTextInContextO1->start;
+ contextParam.iEnd = pData.BoxTextInContextO1->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContextO1+1),pData.BoxTextInContextO1->length,aCmdData),BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContextO1->box,
+ pData.BoxTextInContextO1->baselineOffset,MWsGraphicsContext::ELeft,0);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextOptimised2:
+ contextParam.iStart = pData.BoxTextInContextO2->start;
+ contextParam.iEnd = pData.BoxTextInContextO2->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContextO2+1),pData.BoxTextInContextO2->length,aCmdData),BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContextO2->box,
+ pData.BoxTextInContextO2->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextInContextO2->horiz),pData.BoxTextInContextO2->leftMrg);
+ }
+ break;
+ case EWsGcOpDrawTextInContextPtr:
+ contextParam.iStart = pData.DrawTextInContextPtr->start;
+ contextParam.iEnd = pData.DrawTextInContextPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(*pData.DrawTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextPtr->pos);
+ }
+ break;
+ case EWsGcOpDrawTextInContextPtr1:
+ contextParam.iStart = pData.DrawTextInContextPtr->start;
+ contextParam.iEnd = pData.DrawTextInContextPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(*pData.DrawTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContext:
+ contextParam.iStart = pData.BoxTextInContext->start;
+ contextParam.iEnd = pData.BoxTextInContext->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContext+1),pData.BoxTextInContext->length,aCmdData),
+ BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContext->box,pData.BoxTextInContext->baselineOffset,
+ BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextInContext->horiz),pData.BoxTextInContext->leftMrg);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextPtr:
+ contextParam.iStart = pData.DrawBoxTextInContextPtr->start;
+ contextParam.iEnd = pData.DrawBoxTextInContextPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(*pData.DrawBoxTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextInContextPtr->box,pData.DrawBoxTextInContextPtr->baselineOffset,
+ BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextInContextPtr->horiz),pData.DrawBoxTextInContextPtr->leftMrg);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextPtr1:
+ contextParam.iStart = pData.DrawBoxTextInContextPtr->start;
+ contextParam.iEnd = pData.DrawBoxTextInContextPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(*pData.DrawBoxTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextInContextPtr->box);
+ }
+ break;
+ case EWsGcOpDrawTextInContextVertical:
+ contextParam.iStart = pData.DrawTextInContextVertical->start;
+ contextParam.iEnd = pData.DrawTextInContextVertical->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawTextInContextVertical+1),pData.DrawTextInContextVertical->length,aCmdData),
+ BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextVertical->pos,pData.DrawTextInContextVertical->up);
+ }
+ break;
+ case EWsGcOpDrawTextInContextVerticalPtr:
+ contextParam.iStart = pData.DrawTextInContextVerticalPtr->start;
+ contextParam.iEnd = pData.DrawTextInContextVerticalPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawTextVertical(*pData.DrawTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),
+ pData.DrawTextInContextVerticalPtr->pos,pData.DrawTextInContextVerticalPtr->up);
+ }
+ break;
+ case EWsGcOpDrawTextInContextVerticalPtr1:
+ contextParam.iStart = pData.DrawTextInContextVerticalPtr->start;
+ contextParam.iEnd = pData.DrawTextInContextVerticalPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawTextVertical(*pData.DrawTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextVerticalPtr->up);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextVertical:
+ contextParam.iStart = pData.DrawBoxTextInContextVertical->start;
+ contextParam.iEnd = pData.DrawBoxTextInContextVertical->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawBoxTextInContextVertical+1),pData.DrawBoxTextInContextVertical->length,aCmdData),
+ BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextInContextVertical->box,pData.DrawBoxTextInContextVertical->baselineOffset,
+ pData.DrawBoxTextInContextVertical->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextInContextVertical->vert),pData.DrawBoxTextInContextVertical->margin);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextVerticalPtr:
+ contextParam.iStart = pData.DrawBoxTextInContextVerticalPtr->start;
+ contextParam.iEnd = pData.DrawBoxTextInContextVerticalPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->baselineOffset
+ ,pData.DrawBoxTextVerticalPtr->width,pData.DrawBoxTextVerticalPtr->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextVerticalPtr->vert),pData.DrawBoxTextVerticalPtr->margin);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextVerticalPtr1:
+ contextParam.iStart = pData.DrawBoxTextInContextVerticalPtr->start;
+ contextParam.iEnd = pData.DrawBoxTextInContextVerticalPtr->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->up);
+ }
+ break;
+ case EWsGcOpDrawTextInContextLocal:
+ contextParam.iStart = pData.DrawTextInContextLocal->start;
+ contextParam.iEnd = pData.DrawTextInContextLocal->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(*pData.DrawTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextLocal->pos);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextLocal:
+ contextParam.iStart = pData.BoxTextInContextLocal->start;
+ contextParam.iEnd = pData.BoxTextInContextLocal->end;
+ if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
+ {
+ iGc->DrawText(*pData.BoxTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContextLocal->box,pData.BoxTextInContextLocal->baselineOffset,
+ BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextInContextLocal->horiz),pData.BoxTextInContextLocal->leftMrg);
+ }
+ break;
+ case EWsGcOpDrawLine:
+ iGc->DrawLine(pData.DrawLine->pnt1,pData.DrawLine->pnt2);
+ break;
+ case EWsGcOpDrawTo:
+ iGc->DrawLine(iLinePos,*pData.Point);
+ break;
+ case EWsGcOpDrawBy:
+ iGc->DrawLine(iLinePos,iLinePos+(*pData.Point));
+ break;
+ case EWsGcOpPlot:
+ iGc->Plot(*pData.Point);
+ break;
+ case EWsGcOpMoveTo:
+ case EWsGcOpMoveBy:
+ break;
+ case EWsGcOpGdiBlt2Local:
+ iGc->BitBlt(pData.GdiBlt2Local->pos,*pData.GdiBlt2Local->bitmap);
+ break;
+ case EWsGcOpGdiBlt3Local:
+ iGc->BitBlt(pData.GdiBlt3Local->pos,*pData.GdiBlt3Local->bitmap, pData.GdiBlt3Local->rect);
+ break;
+ case EWsGcOpGdiBltMaskedLocal:
+ iGc->BitBltMasked(pData.GdiBltMaskedLocal->pos,*pData.GdiBltMaskedLocal->bitmap,
+ pData.GdiBltMaskedLocal->rect,*pData.GdiBltMaskedLocal->maskBitmap,
+ pData.GdiBltMaskedLocal->invertMask);
+ break;
+ case EWsGcOpGdiWsBlt2:
+ case EWsGcOpGdiWsBlt3:
+ case EWsGcOpGdiWsBltMasked:
+ case EWsGcOpGdiWsAlphaBlendBitmaps:
+ case EWsGcOpWsDrawBitmapMasked:
+ {
+ CFbsBitmap* scratchBitmap = NULL;
+ CFbsBitmap* scratchMaskBimap = NULL;
+ TInt maskHandle=0;
+ TInt handle=WsBitmapHandle(aOpcode,pData, maskHandle);
+ CWsClient* owner=iWin->WsOwner();
+ if (owner!=NULL)
+ {
+ TInt wsBmpErr = KErrNone;
+ DWsBitmap *bitmap=(DWsBitmap *)owner->HandleToObj(handle, WS_HANDLE_BITMAP);
+ if (!bitmap)
+ wsBmpErr = KErrNotFound;
+ else
+ scratchBitmap=bitmap->FbsBitmap();
+ if (wsBmpErr == KErrNone)
+ if (aOpcode==EWsGcOpGdiWsBltMasked || aOpcode==EWsGcOpGdiWsAlphaBlendBitmaps || aOpcode==EWsGcOpWsDrawBitmapMasked)
+ {
+ DWsBitmap *bitmap2=(DWsBitmap *)owner->HandleToObj(maskHandle, WS_HANDLE_BITMAP);
+ if (!bitmap2)
+ wsBmpErr = KErrNotFound;
+ else
+ scratchMaskBimap=bitmap2->FbsBitmap();
+ }
+ if (wsBmpErr == KErrNone)
+ {
+ switch(aOpcode)
+ {
+ case EWsGcOpGdiWsBlt2:
+ iGc->BitBlt(pData.GdiBlt2->pos,*scratchBitmap);
+ break;
+ case EWsGcOpGdiWsBlt3:
+ iGc->BitBlt(pData.GdiBlt3->pos,*scratchBitmap, pData.GdiBlt3->rect);
+ break;
+ case EWsGcOpGdiWsBltMasked:
+ {
+ iGc->BitBltMasked(pData.GdiBltMasked->destination,*scratchBitmap,
+ pData.GdiBltMasked->source, *scratchMaskBimap,
+ pData.GdiBltMasked->invertMask);
+ }
+ break;
+ case EWsGcOpGdiWsAlphaBlendBitmaps:
+ {
+ iGc->BitBltMasked(pData.AlphaBlendBitmaps->point,*scratchBitmap,
+ pData.AlphaBlendBitmaps->source, *scratchMaskBimap,
+ pData.AlphaBlendBitmaps->alphaPoint);
+ }
+ break;
+ case EWsGcOpWsDrawBitmapMasked:
+ {
+ iGc->DrawBitmapMasked(pData.iBitmapMasked->iRect,*scratchBitmap,
+ pData.iBitmapMasked->iSrcRect,*scratchMaskBimap,
+ pData.iBitmapMasked->iInvertMask);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case EWsGcOpGdiBlt2:
+ case EWsGcOpGdiBlt3:
+ case EWsGcOpDrawBitmap:
+ case EWsGcOpDrawBitmap2:
+ case EWsGcOpDrawBitmap3:
+ {
+ TInt bitmapMaskHandle=0;
+ TInt bitmapHandle = FbsBitmapHandle(aOpcode, pData, bitmapMaskHandle);
+ const CFbsBitmap* bitmap = iWin->Redraw()->BitmapFromHandle(bitmapHandle);
+ if(!bitmap)
+ {
+ WS_PANIC_DEBUG(EWsPanicBitmapNotFound);
+ break;
+ }
+
+ switch(aOpcode)
+ {
+ case EWsGcOpGdiBlt2:
+ iGc->BitBlt(pData.GdiBlt2->pos,*bitmap);
+ break;
+ case EWsGcOpGdiBlt3:
+ iGc->BitBlt(pData.GdiBlt3->pos,*bitmap, pData.GdiBlt3->rect);
+ break;
+ case EWsGcOpDrawBitmap:
+ {
+ // DrawBitmap(TPoint&, ) uses the size of the bitmap in twips, but
+ // MWsGraphicsContext::DrawBitmap() takes a TRect in pixels, so we need to convert
+ TRect destRect(iWin->Screen()->DeviceMap().TwipsToPixels(bitmap->SizeInTwips()));
+ destRect.Move(pData.Bitmap->pos); //pos is defined in pixels, that's why we're not converting it
+ iGc->DrawBitmap(destRect, *bitmap);
+ break;
+ }
+ case EWsGcOpDrawBitmap2:
+ iGc->DrawBitmap(pData.Bitmap2->rect, *bitmap);
+ break;
+ case EWsGcOpDrawBitmap3:
+ iGc->DrawBitmap(pData.Bitmap3->rect, *bitmap, pData.Bitmap3->srcRect);
+ break;
+ }
+ break;
+ }
+ case EWsGcOpGdiBltMasked:
+ case EWsGcOpGdiAlphaBlendBitmaps:
+ case EWsGcOpDrawBitmapMasked:
+ {
+ TInt bitmapMaskHandle=0;
+ TInt bitmapHandle = FbsBitmapHandle(aOpcode, pData, bitmapMaskHandle);
+ const CFbsBitmap* bitmap = iWin->Redraw()->BitmapFromHandle(bitmapHandle);
+ if(!bitmap)
+ {
+ WS_PANIC_DEBUG(EWsPanicBitmapNotFound);
+ break;
+ }
+
+ CFbsBitmap* bitmapMask = iWin->Redraw()->BitmapFromHandle(bitmapMaskHandle);
+ if(!bitmapMask)
+ {
+ WS_PANIC_DEBUG(EWsPanicBitmapNotFound);
+ break;
+ }
+
+ switch(aOpcode)
+ {
+ case EWsGcOpGdiBltMasked:
+ {
+ iGc->BitBltMasked(pData.GdiBltMasked->destination,*bitmap,
+ pData.GdiBltMasked->source, *bitmapMask,
+ pData.GdiBltMasked->invertMask);
+ break;
+ }
+ case EWsGcOpGdiAlphaBlendBitmaps:
+ {
+ iGc->BitBltMasked(pData.AlphaBlendBitmaps->point, *bitmap,
+ pData.AlphaBlendBitmaps->source, *bitmapMask,
+ pData.AlphaBlendBitmaps->alphaPoint);
+ break;
+ }
+ case EWsGcOpDrawBitmapMasked:
+ {
+ iGc->DrawBitmapMasked(pData.iBitmapMasked->iRect, *bitmap,
+ pData.iBitmapMasked->iSrcRect, *bitmapMask,
+ pData.iBitmapMasked->iInvertMask);
+ break;
+ }
+ }
+ break;
+ }
+ case EWsGcOpDrawSegmentedPolygon:
+ {
+ TArrayWrapper<TPoint> points(iPolyPoints, iPolyPointListSize);
+ iGc->DrawPolygon(points, BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawSegmentedPolygon->fillRule));
+ break;
+ }
+ case EWsGcOpDrawPolygon:
+ DoDrawPolygon(pData.Polygon);
+ break;
+ case EWsGcOpDrawPolyLine:
+ DoDrawPolyLine(pData.PolyLine, EFalse);
+ break;
+ case EWsGcOpDrawPolyLineContinued:
+ DoDrawPolyLine(pData.PolyLine, ETrue);
+ break;
+ case EWsGcOpClear:
+ iGc->Clear(TRect(iWin->Size()));
+ break;
+ case EWsGcOpClearRect:
+ iGc->Clear(*pData.Rect);
+ break;
+ case EWsGcOpDrawRect:
+ iGc->DrawRect(*pData.Rect);
+ break;
+ case EWsGcOpDrawEllipse:
+ iGc->DrawEllipse(*pData.Rect);
+ break;
+ case EWsGcOpDrawRoundRect:
+ iGc->DrawRoundRect(*pData.Rect,pData.RoundRect->ellipse);
+ break;
+ case EWsGcOpDrawArc:
+ iGc->DrawArc(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
+ break;
+ case EWsGcOpDrawPie:
+ iGc->DrawPie(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
+ break;
+ case EWsGcOpCopyRect:
+ iGc->CopyRect(pData.CopyRect->pos,*pData.Rect);
+ break;
+ case EWsGcOpMapColors:
+ GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
+ break;
+ case EWsGcOpSetShadowColor:
+ iGc->SetTextShadowColor(*pData.rgb);
+ break;
+ case EWsGcOpDrawResourceToPos:
+ case EWsGcOpDrawResourceToRect:
+ case EWsGcOpDrawResourceFromRectToRect:
+ case EWsGcOpDrawResourceWithData:
+ DoDrawResource(aOpcode, pData);
+ break;
+ default:
+ TRAP_IGNORE(iWin->OwnerPanic(EWservPanicOpcode));
+ break;
+ }
+ iGc->ResetClippingRegion();
+ iCurrentClippingRegion = NULL;
+ if (bGcDrawingOccurred)
+ {
+ GcDrawingDone(); //up the count (again for CRPs)
+ }
+ }
+/**
+ Helper function for drawing resources.
+ It extracts DWsDrawableSource objects which corresponds RWsDrawableResource object on the server side and then redirect call to concrete implementation.
+ @param aOpcode GC opcodes
+ @param aData An extra data which will be used for resource drawing
+ */
+void CPlaybackGc::DoDrawResource(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &aData)
+ {
+ CWsClient* owner=iWin->WsOwner(); // We can't just use iWsOwner - it can be null for stored commands
+ if (owner!=NULL)
+ {
+ CWsDrawableSource *drawable = static_cast<CWsDrawableSource*>(owner->HandleToObj(*aData.Int, WS_HANDLE_DRAWABLE_SOURCE));
+ if (!drawable)
+ return;
+
+ switch(aOpcode)
+ {
+ case EWsGcOpDrawResourceToPos:
+ drawable->DrawResource(iGc, aData.DrawWsResourceToPos->pos, aData.DrawWsResourceToPos->rotation);
+ break;
+ case EWsGcOpDrawResourceToRect:
+ drawable->DrawResource(iGc, aData.DrawWsResourceToRect->rect, aData.DrawWsResourceToRect->rotation);
+ break;
+ case EWsGcOpDrawResourceFromRectToRect:
+ drawable->DrawResource(iGc, aData.DrawWsResourceFromRectToRect->rectDest, aData.DrawWsResourceFromRectToRect->rectSrc, aData.DrawWsResourceFromRectToRect->rotation);
+ break;
+ case EWsGcOpDrawResourceWithData:
+ drawable->DrawResource(iGc, aData.DrawWsResourceWithData->rect, *aData.DrawWsResourceWithData->desc);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+TInt CPlaybackGc::WsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle)
+ {
+ TInt handle=0;
+ switch(aOpcode)
+ {
+ case EWsGcOpGdiWsBlt2:
+ handle=pData.GdiBlt2->handle;
+ break;
+ case EWsGcOpGdiWsBlt3:
+ handle=pData.GdiBlt3->handle;
+ break;
+ case EWsGcOpGdiWsBltMasked:
+ handle=pData.GdiBltMasked->handle;
+ aMaskHandle = pData.GdiBltMasked->maskHandle;
+ break;
+ case EWsGcOpGdiWsAlphaBlendBitmaps:
+ handle=pData.AlphaBlendBitmaps->bitmapHandle;
+ aMaskHandle = pData.AlphaBlendBitmaps->alphaHandle;
+ break;
+ case EWsGcOpWsDrawBitmapMasked:
+ handle=pData.iBitmapMasked->iHandle;
+ aMaskHandle=pData.iBitmapMasked->iMaskHandle;
+ break;
+ }
+ return handle;
+ }
+
+TInt CPlaybackGc::FbsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle)
+ {
+ TInt handle=0;
+ aMaskHandle=0;
+ switch(aOpcode)
+ {
+ case EWsGcOpGdiBlt2:
+ handle=pData.GdiBlt2->handle;
+ break;
+ case EWsGcOpGdiBlt3:
+ handle=pData.GdiBlt3->handle;
+ break;
+ case EWsGcOpGdiBltMasked:
+ handle=pData.GdiBltMasked->handle;
+ aMaskHandle=pData.GdiBltMasked->maskHandle;
+ break;
+ case EWsGcOpGdiAlphaBlendBitmaps:
+ handle=pData.AlphaBlendBitmaps->bitmapHandle;
+ aMaskHandle=pData.AlphaBlendBitmaps->alphaHandle;
+ break;
+ case EWsGcOpDrawBitmap:
+ handle=pData.Bitmap->handle;
+ break;
+ case EWsGcOpDrawBitmap2:
+ handle=pData.Bitmap2->handle;
+ break;
+ case EWsGcOpDrawBitmap3:
+ handle=pData.Bitmap3->handle;
+ break;
+ case EWsGcOpDrawBitmapMasked:
+ handle=pData.iBitmapMasked->iHandle;
+ aMaskHandle=pData.iBitmapMasked->iMaskHandle;
+ break;
+ default:
+ WS_ASSERT_DEBUG(EFalse, EWsPanicInvalidOperation);
+ break;
+ }
+ return handle;
+ }
+
+void CPlaybackGc::UpdateJustification(TText* aText,TInt aLen,const TDesC8& aCmdData,CGraphicsContext::TTextParameters* aParam)
+ {
+ iGc->UpdateJustification(BufferTPtr(aText,aLen,aCmdData), BitGdiToMWsGraphicsContextMappings::Convert(aParam));
+ }
+
+void CPlaybackGc::SendOriginIfRequired()
+ {
+ const TPoint currentOrigin(iMasterOrigin + iOrigin);
+ if (iSendOrigin || currentOrigin != iLastSentOrigin)
+ {
+ iGc->SetOrigin(currentOrigin);
+ iLastSentOrigin = currentOrigin;
+ iSendOrigin = EFalse;
+ }
+ }
+
+void CPlaybackGc::SendClippingRegionIfRequired(const TRegion* aRegion)
+ {
+ if (iUserDefinedClippingRegion || iClippingRectSet || !iWin->Screen()->ChangeTracking())
+ {
+ iGc->SetClippingRegion(*aRegion);
+ }
+ }
+
+void CPlaybackGc::DoDrawing(TWsGcOpcodes aOpcode, const TDesC8& aCmdData)
+ {
+ TWsGcCmdUnion pData;
+ // coverity[returned_pointer]
+ pData.any=aCmdData.Ptr();
+
+ iIntersectedRegion.Clear();
+ iIntersectedRegion.Copy(*iDrawRegion);
+
+ if (iClippingRectSet)
+ {
+ // MWsGraphicsContext doesn't provide a SetClippingRect API. If a client calls SetClippingRect
+ // the rect is passed to the render stage using MWsGraphicsContext::SetClippingRegion
+ TRect clippingRectRelativeToScreen(iClippingRect);
+ clippingRectRelativeToScreen.Move(iMasterOrigin);
+ iIntersectedRegion.ClipRect(clippingRectRelativeToScreen);
+ iIntersectedRegion.ClipRect(iWin->AbsRect());
+ }
+
+ SendOriginIfRequired();
+
+ DoDrawCommand(aOpcode,aCmdData,&iIntersectedRegion);
+
+ CGraphicsContext::TTextParameters contextParam;
+ switch(aOpcode)
+ {
+ case EWsGcOpDrawLine:
+ iLinePos=pData.DrawLine->pnt2;
+ break;
+ case EWsGcOpDrawTo:
+ case EWsGcOpMoveTo:
+ case EWsGcOpPlot:
+ iLinePos=(*pData.Point);
+ break;
+ case EWsGcOpDrawBy:
+ case EWsGcOpMoveBy:
+ iLinePos+=(*pData.Point);
+ break;
+ case EWsGcOpDrawSegmentedPolygon:
+ EndSegmentedPolygon();
+ break;
+ case EWsGcOpDrawText:
+ UpdateJustification((TText *)(pData.DrawText+1),pData.DrawText->length,aCmdData,NULL);
+ break;
+ case EWsGcOpDrawTextVertical:
+ UpdateJustification((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length,aCmdData,NULL);
+ break;
+ case EWsGcOpDrawBoxText:
+ UpdateJustification((TText *)(pData.BoxText+1),pData.BoxText->length,aCmdData,NULL);
+ break;
+ case EWsGcOpDrawBoxTextOptimised1:
+ UpdateJustification((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length,aCmdData,NULL);
+ break;
+ case EWsGcOpDrawBoxTextOptimised2:
+ UpdateJustification((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length,aCmdData,NULL);
+ break;
+ case EWsGcOpDrawBoxTextVertical:
+ UpdateJustification((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length,aCmdData,NULL);
+ break;
+ case EWsGcOpDrawTextLocal:
+ iGc->UpdateJustification(*pData.DrawTextLocal->desc,NULL);
+ break;
+ case EWsGcOpDrawBoxTextLocal:
+ iGc->UpdateJustification(*pData.BoxTextLocal->desc,NULL);
+ break;
+ case EWsGcOpDrawTextPtr:
+ iGc->UpdateJustification(*pData.DrawTextPtr->text,NULL);
+ break;
+ case EWsGcOpDrawTextVerticalPtr:
+ iGc->UpdateJustification(*pData.DrawTextVerticalPtr->text,NULL);
+ break;
+ case EWsGcOpDrawBoxTextPtr:
+ iGc->UpdateJustification(*pData.DrawBoxTextPtr->text,NULL);
+ break;
+ case EWsGcOpDrawBoxTextVerticalPtr:
+ iGc->UpdateJustification(*pData.DrawBoxTextVerticalPtr->text,NULL);
+ break;
+ /***************DrawTextInContext*****************************************************************/
+ case EWsGcOpDrawTextInContext:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ UpdateJustification((TText *)(pData.DrawTextInContext+1),pData.DrawTextInContext->length,aCmdData,&contextParam);
+ }
+ break;
+ case EWsGcOpDrawTextInContextVertical:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ UpdateJustification((TText *)(pData.DrawTextInContextVertical+1),pData.DrawTextInContextVertical->length,aCmdData,&contextParam);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContext:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ UpdateJustification((TText *)(pData.BoxTextInContext+1),pData.BoxTextInContext->length,aCmdData,&contextParam);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextOptimised1:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ UpdateJustification((TText *)(pData.BoxTextInContextO1+1),pData.BoxTextInContextO1->length,aCmdData,&contextParam);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextOptimised2:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ UpdateJustification((TText *)(pData.BoxTextInContextO2+1),pData.BoxTextInContextO2->length,aCmdData,&contextParam);
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextVertical:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ UpdateJustification((TText *)(pData.DrawBoxTextInContextVertical+1),pData.DrawBoxTextInContextVertical->length,aCmdData,&contextParam);
+ }
+ break;
+ case EWsGcOpDrawTextInContextLocal:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ iGc->UpdateJustification(*pData.DrawTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextLocal:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ iGc->UpdateJustification(*pData.BoxTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
+ }
+ break;
+ case EWsGcOpDrawTextInContextPtr:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ iGc->UpdateJustification(*pData.DrawTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
+ }
+ break;
+ case EWsGcOpDrawTextInContextVerticalPtr:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ iGc->UpdateJustification(*pData.DrawTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextPtr:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ iGc->UpdateJustification(*pData.DrawBoxTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
+ }
+ break;
+ case EWsGcOpDrawBoxTextInContextVerticalPtr:
+ contextParam.iStart = pData.DrawTextInContext->start;
+ contextParam.iEnd = pData.DrawTextInContext->end;
+ if(contextParam.iStart < contextParam.iEnd)
+ {
+ iGc->UpdateJustification(*pData.DrawBoxTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
+ }
+ break;
+ }
+ }
+
+void CPlaybackGc::CommandL(TWsGcOpcodes aOpcode, const TDesC8& aCmdData)
+ {
+ WS_ASSERT_DEBUG(iWin,EWsPanicWindowNull);
+ TWsGcCmdUnion pData;
+ // coverity[returned_pointer]
+ pData.any=aCmdData.Ptr();
+
+ switch(aOpcode)
+ {
+ case EWsGcOpStartSegmentedDrawPolygon:
+ StartSegmentedDrawPolygonL(pData.StartSegmentedDrawPolygon);
+ break;
+ case EWsGcOpSegmentedDrawPolygonData:
+ SegmentedDrawPolygonData(pData.SegmentedDrawPolygonData);
+ break;
+ case EWsGcOpSetClippingRegion:
+ WS_ASSERT_DEBUG(aOpcode != EWsGcOpSetClippingRegion, EWsPanicDrawCommandsInvalidState);
+ break;
+ case EWsGcOpSetClippingRect:
+ SetClippingRect(*pData.Rect);
+ break;
+ case EWsGcOpCancelClippingRect:
+ ResetClippingRect();
+ break;
+ case EWsGcOpCancelClippingRegion:
+ CancelUserClippingRegion();
+ break;
+ case EWsGcOpSetFaded: // deprecated
+ // do nothing
+ break;
+ case EWsGcOpSetFadeParams: // deprecated
+ // do nothing
+ break;
+ case EWsGcOpSetDrawMode:
+ iGc->SetDrawMode(BitGdiToMWsGraphicsContextMappings::LossyConvert((CGraphicsContext::TDrawMode)*pData.UInt));
+ break;
+ case EWsGcOpUseFont:
+ if (CWsFontCache::Instance()->UseFont(iFont, *pData.UInt))
+ {
+ CFbsBitGcFont font;
+ if(font.Duplicate(*pData.UInt) == KErrNone)
+ iGc->SetFont(&font);
+ font.Reset();
+ }
+ else
+ iGc->SetFontNoDuplicate(iFont);
+ break;
+ case EWsGcOpDiscardFont:
+ CWsFontCache::Instance()->ReleaseFont(iFont);
+ iGc->ResetFont();
+ break;
+ case EWsGcOpSetUnderlineStyle:
+ iGc->SetUnderlineStyle(BitGdiToMWsGraphicsContextMappings::Convert(*pData.SetUnderlineStyle));
+ break;
+ case EWsGcOpSetStrikethroughStyle:
+ iGc->SetStrikethroughStyle(BitGdiToMWsGraphicsContextMappings::Convert(*pData.SetStrikethroughStyle));
+ break;
+ case EWsGcOpUseBrushPattern:
+ iGc->SetBrushPattern(*pData.handle);
+ break;
+ case EWsGcOpDiscardBrushPattern:
+ iGc->ResetBrushPattern();
+ break;
+ case EWsGcOpSetBrushColor:
+ iGc->SetBrushColor(*pData.rgb);
+ break;
+ case EWsGcOpSetPenColor:
+ iGc->SetPenColor(*pData.rgb);
+ break;
+ case EWsGcOpSetPenStyle:
+ iGc->SetPenStyle(BitGdiToMWsGraphicsContextMappings::Convert((CGraphicsContext::TPenStyle)*pData.UInt));
+ break;
+ case EWsGcOpSetPenSize:
+ iGc->SetPenSize(*pData.Size);
+ break;
+ case EWsGcOpSetBrushStyle:
+ {
+ MWsGraphicsContext::TBrushStyle style = BitGdiToMWsGraphicsContextMappings::Convert((CGraphicsContext::TBrushStyle)*pData.UInt);
+ if (iGc->HasBrushPattern() || style != MWsGraphicsContext::EPatternedBrush)
+ {
+ iGc->SetBrushStyle(style);
+ }
+ break;
+ }
+ case EWsGcOpReset:
+ CWsFontCache::Instance()->ReleaseFont(iFont);
+ iGc->Reset();
+ iOrigin.SetXY(0,0);
+ iSendOrigin = ETrue; // we must call SetOrigin at next opportunity because it's likely the render stage implementation of Reset (when resetting origin) doesn't take into account the window origin
+ ResetClippingRect();
+ iGc->SetBrushColor(iWin->BackColor());
+ break;
+ case EWsGcOpSetBrushOrigin:
+ iGc->SetBrushOrigin(*pData.Point);
+ break;
+ case EWsGcOpSetDitherOrigin:
+ GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
+ break;
+ case EWsGcOpSetWordJustification:
+ iGc->SetWordJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
+ break;
+ case EWsGcOpSetCharJustification:
+ iGc->SetCharJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
+ break;
+ case EWsGcOpSetOrigin:
+ SetOrigin(*pData.Point);
+ break;
+ case EWsGcOpSetOpaque: // deprecated
+ // do nothing
+ break;
+ default: // Assume remaining functions will draw
+ {
+ DoDrawing(aOpcode,aCmdData);
+ return;
+ }
+ }
+ }
+
+
+void CPlaybackGc::SetOrigin(const TPoint &aOrigin)
+ {
+ iOrigin=aOrigin;
+ }
+
+/*------------------------------------------------------------------------------
+ Description: Retrieves graphics context information back from a given buffer
+ from a given start position.
+ -----------------------------------------------------------------------------*/
+void CPlaybackGc::InternalizeL(const CBufBase& aBuffer,TInt& aStartPos)
+ {
+ // Open the stream used for the input from the given start position
+ // in the buffer.
+ RBufReadStream bufReadStream;
+ bufReadStream.Open(aBuffer,aStartPos);
+ CleanupClosePushL(bufReadStream);
+
+ // Read the font/bitmap server data
+ TInternalGcStatus::InternalizeGcAttributesL(iGc, bufReadStream);
+
+ iOrigin.iX = bufReadStream.ReadInt32L();
+ iOrigin.iY = bufReadStream.ReadInt32L();
+ iSendOrigin = ETrue;
+
+ iClippingRectSet=bufReadStream.ReadInt8L();
+
+ // If there is a clipping rectangle data read it.
+ if (iClippingRectSet)
+ bufReadStream>>iClippingRect;
+
+ // Read the clipping region data
+ InternalizeClippingRegionL(bufReadStream);
+
+ // Read the Alpha values for Brush and Pen colors.
+ InternalizeAlphaValueL(bufReadStream);
+
+ CleanupStack::PopAndDestroy(&bufReadStream);
+ }
+
+/*------------------------------------------------------------------------------
+ Description: Retrieves TRgb::alpha value information back from a given buffer
+ and updates the Brushcolor with the same.
+ -----------------------------------------------------------------------------*/
+void CPlaybackGc::InternalizeAlphaValueL(RReadStream& aReadStream)
+ {
+ TRgb brushColor(iGc->BrushColor());
+ brushColor.SetAlpha(aReadStream.ReadUint8L());
+ iGc->SetBrushColor(brushColor);
+ TRgb penColor(iGc->PenColor());
+ penColor.SetAlpha(aReadStream.ReadUint8L());
+ iGc->SetPenColor(penColor);
+ }
+
+/*------------------------------------------------------------------------------
+ Description: Helper method to retrieve clipping region data from a given
+ read stream.
+ -----------------------------------------------------------------------------*/
+void CPlaybackGc::InternalizeClippingRegionL(RReadStream& aReadStream)
+ {
+ WS_ASSERT_DEBUG(iTargetRegion, EWsPanicDrawCommandsInvalidState);
+ // Read flag to indicate if client had defined a clipping region
+ TBool clipRegion = aReadStream.ReadInt8L();
+ CancelUserClippingRegion();
+ if (clipRegion)
+ {
+ // Note that this clipping region is in window relative coordinates when
+ // received from the client (and being stored) but is in screen relative
+ // coordinates after being retrieved from the redraw store.
+ iUserDefinedClippingRegion = InternalizeRegionL(aReadStream);
+ iUserDefinedClippingRegion->Offset(iWin->Origin());
+ iUserDefinedClippingRegion->Intersect(*iTargetRegion);
+ if (iUserDefinedClippingRegion->CheckError()) // fallback to no user clipping region
+ {
+ CancelUserClippingRegion();
+ }
+ else
+ {
+ iDrawRegion = iUserDefinedClippingRegion;
+ }
+ }
+ }
+
+/**
+* @deprecated
+*/
+TInt CPlaybackGc::PlaceSurface(const TSurfaceConfiguration& /*aConfig*/)
+ {
+ return KErrNotSupported;
+ }
+
+/** Get the drawing occurred indication counter.
+ Callers can detect if drawing has occurred between two points
+ by detecting that this count has changed.
+ Note that the changed value does not necessarily represent the exact number of operations which occurred.
+ @return value which changes each time GC drawing occurrs.
+ **/
+TInt CPlaybackGc::GcDrawingCount()
+ {
+ return iGcDrawingCounter;
+ }
+
+/** Update the drawing occurred indication counter.
+ Called internally each time a drawing operation updates the UI content
+ **/
+void CPlaybackGc::GcDrawingDone()
+ {
+ iGcDrawingCounter++;
+ }
+
+
+/**
+This pretty much replaces the whole of what was TDrawDestination
+This can only be sensibly called from outside a sequence of drawing commands,
+since it negates any user defined clipping regions.
+*/
+void CPlaybackGc::SetTargetRegion(const TRegion* aRegion)
+ {
+ iTargetRegion = aRegion;
+ iDrawRegion = iTargetRegion;
+ CancelUserClippingRegion();
+ }
+
+void CPlaybackGc::Reset()
+ {
+ iGc->Reset();
+ }
+
+TAny * CPlaybackGc::ResolveObjectInterface(TUint aId)
+ {
+ switch (aId)
+ {
+ case MWsSurfacePlacement::EWsObjectInterfaceId:
+ return static_cast<MWsSurfacePlacement *>(this); //deprecated
+ case MWsWindow::EWsObjectInterfaceId:
+ return dynamic_cast<MWsWindow *>(iWin);
+ case MWsGraphicsContext::EWsObjectInterfaceId:
+ return static_cast<MWsGraphicsContext*>(iGc);
+ case MWsUiBuffer::EWsObjectInterfaceId:
+ case MWsFader::EWsObjectInterfaceId:
+ return iWin->Screen()->ResolveObjectInterface(aId);
+ }
+ return NULL;
+ }