os/graphics/windowing/windowserver/nga/SERVER/openwfc/playbackgc.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // GC and Graphics functions
    15 // 
    16 //
    17 
    18 #include "playbackgc.h"
    19 
    20 #include <e32std.h>
    21 #include <s32mem.h> 
    22 
    23 #include "panics.h"
    24 #include "ScrDev.H"
    25 #include "windowgroup.h"
    26 #include "wsfont.h"
    27 #include "wstop.h"
    28 #include "graphics/WSGRAPHICDRAWER.H"
    29 #include "graphics/surfaceconfiguration.h"
    30 #include "windowelementset.h"
    31 
    32 #include <graphics/wsgraphicscontext.h>
    33 #include <graphics/wsuibuffer.h>
    34 #include "bitgditomwsgraphicscontextmappings.h"
    35 
    36 #include "graphicscontextstate.h"
    37 #include "drawresource.h"
    38 #include "devicemap.h"
    39 
    40 CPlaybackGc * CPlaybackGc::iSelf=NULL;
    41 
    42 GLREF_C RWsRegion* InternalizeRegionL(RReadStream& aReadStream);
    43 
    44 /*CPlaybackGc*/
    45 
    46 void CPlaybackGc::InitStaticsL()
    47 	{
    48 	iSelf=new(ELeave) CPlaybackGc();
    49 	iSelf->ConstructL();
    50 	}
    51 
    52 void CPlaybackGc::DeleteStatics()
    53 	{
    54 	delete iSelf;
    55 	iSelf = 0;
    56 	}
    57 
    58 CPlaybackGc::CPlaybackGc()
    59 	{
    60 	}
    61 
    62 void CPlaybackGc::ConstructL()
    63 	{
    64 	iGcBuf = CBufSeg::NewL(512);
    65 	}
    66 
    67 CPlaybackGc::~CPlaybackGc()
    68 	{
    69 	delete iPolyPoints;
    70 	delete iGcBuf;
    71 	iCurrentClippingRegion = NULL;
    72 	iIntersectedRegion.Close();
    73 	}
    74 
    75 void CPlaybackGc::Activate(CWsClientWindow * aWin, MWsGraphicsContext * aGc, const TRegion * aRegion)
    76 	{
    77 	iWin = aWin;
    78 	iGc = aGc;
    79 	iTargetRegion = aRegion;
    80 	
    81 	iDrawRegion = iTargetRegion;
    82 	iMasterOrigin = iWin->Origin();
    83 	iOrigin.SetXY(0,0);
    84 	iSendOrigin = ETrue;
    85 	iGc->SetBrushColor(iWin->BackColor());
    86 	ResetClippingRect();
    87 	}
    88 	
    89 void CPlaybackGc::Deactivate()
    90 	{
    91 	iWin = 0;
    92 	iGc = 0;
    93 	iTargetRegion = 0;
    94 	iDrawRegion = 0;
    95 	CancelUserClippingRegion();
    96 	}
    97 	
    98 void CPlaybackGc::CancelUserClippingRegion()
    99 	{
   100 	if (iUserDefinedClippingRegion)
   101 		{
   102 		iUserDefinedClippingRegion->Destroy();
   103 		iUserDefinedClippingRegion = 0;
   104 		iDrawRegion = iTargetRegion;
   105 		}
   106 	}
   107 	
   108 void CPlaybackGc::SetClippingRect(const TRect &aRect)
   109 	{
   110 	iClippingRect=aRect;
   111 	iClippingRect.Move(iOrigin);
   112 	iClippingRectSet=ETrue;
   113 	}
   114 
   115 void CPlaybackGc::ResetClippingRect()
   116 	{
   117 	iClippingRectSet=EFalse;
   118 	}
   119 
   120 void CPlaybackGc::CheckPolyData(const TAny* aDataPtr, TInt aHeaderSize, TInt aNumPoints)
   121 	{
   122 	TInt maxDataLen;
   123 	if (CWsClient::iCurrentCommand.iOpcode>0)
   124 		{
   125 		maxDataLen=CWsClient::EndOfCommandBuffer()-static_cast<const TUint8*>(aDataPtr);
   126 		}
   127 	else
   128 		{
   129 		maxDataLen=CWsClient::iCurrentCommand.iCmdLength;
   130 		}
   131 	const TInt dataSize=aHeaderSize+aNumPoints*sizeof(TPoint);
   132 	if (dataSize>maxDataLen)
   133 		GcOwnerPanic(EWservPanicBadPolyData);
   134 	}
   135 
   136 void CPlaybackGc::DoDrawPolygon(const TWsGcCmdDrawPolygon *aDrawPolygon)
   137 	{
   138 	CheckPolyData(aDrawPolygon, sizeof(TWsGcCmdDrawPolygon), aDrawPolygon->numPoints);
   139 	TArrayWrapper<TPoint> points((TPoint*)(aDrawPolygon + 1), aDrawPolygon->numPoints);
   140 	iGc->DrawPolygon(points, BitGdiToMWsGraphicsContextMappings::Convert(aDrawPolygon->fillRule));
   141 	}
   142 
   143 void CPlaybackGc::StartSegmentedDrawPolygonL(const TWsGcCmdStartSegmentedDrawPolygon *aDrawPolygon)
   144 	{
   145 // In case a Playback have been done before all the segment is in the RedrawStore
   146 // (This allocation is deleted only thanks to the EWsGcOpDrawSegmentedPolygon opcode
   147 //  which arrive after all the segments)
   148 	if (iPolyPoints)
   149 		{
   150 		delete iPolyPoints;
   151 		iPolyPoints=NULL;	
   152 		}
   153 	if(!Rng(0, aDrawPolygon->totalNumPoints, KMaxTInt/2 - 1))
   154 		GcOwnerPanic(EWservPanicBadPolyData);	
   155 	iPolyPoints=(TPoint *)User::AllocL(aDrawPolygon->totalNumPoints*sizeof(TPoint));
   156 	iPolyPointListSize=aDrawPolygon->totalNumPoints;
   157 	}
   158 
   159 void CPlaybackGc::SegmentedDrawPolygonData(const TWsGcCmdSegmentedDrawPolygonData *aDrawPolygon)
   160 	{
   161 	if (aDrawPolygon->index<0 || (aDrawPolygon->index + aDrawPolygon->numPoints) > iPolyPointListSize)
   162 		GcOwnerPanic(EWservPanicBadPolyData);
   163 	Mem::Copy(iPolyPoints+aDrawPolygon->index,aDrawPolygon+1,aDrawPolygon->numPoints*sizeof(TPoint));
   164 	}
   165 
   166 void CPlaybackGc::EndSegmentedPolygon()
   167 	{
   168 	delete iPolyPoints;
   169 	iPolyPoints=NULL;
   170 	}
   171 
   172 void CPlaybackGc::DoDrawPolyLine(const TWsGcCmdDrawPolyLine *aDrawPolyLine, TBool aContinued)
   173 	{
   174 	TInt numPoints=aDrawPolyLine->numPoints;
   175 	CheckPolyData(aDrawPolyLine, sizeof(TWsGcCmdDrawPolyLine), numPoints);
   176 	const TPoint *points=(TPoint *)(aDrawPolyLine+1);
   177 	if (aContinued)
   178 		{
   179 		numPoints++;
   180 		points=&aDrawPolyLine->last;
   181 		}
   182 	TArrayWrapper<TPoint> pointsArr(points, numPoints);
   183 	if (aDrawPolyLine->more)	// more to come so don't draw the end point
   184 		iGc->DrawPolyLineNoEndPoint(pointsArr);
   185 	else
   186 		iGc->DrawPolyLine(pointsArr);
   187 	}
   188 
   189 void CPlaybackGc::GcOwnerPanic(TClientPanic aPanic)
   190 	{
   191 	iGc->ResetClippingRegion();
   192 	iCurrentClippingRegion = NULL;
   193 	EndSegmentedPolygon();
   194 	iWin->WsOwner()->PPanic(aPanic);
   195 	}
   196 	
   197 // implementing MWsGc
   198 
   199 MWsClient& CPlaybackGc::Client()
   200 	{
   201 	return *(iWin->WsOwner());
   202 	}
   203 
   204 MWsScreen& CPlaybackGc::Screen()
   205 	{
   206 	return *(iWin->Screen());
   207 	}
   208 
   209 const TTime& CPlaybackGc::Now() const
   210 	{
   211 	return iWin->Screen()->Now();
   212 	}
   213 	
   214 void CPlaybackGc::ScheduleAnimation(const TRect& aRect,const TTimeIntervalMicroSeconds& aFromNow)
   215 	{
   216 	ScheduleAnimation(aRect,aFromNow,0,0);
   217 	}
   218 
   219 void CPlaybackGc::ScheduleAnimation(const TRect& aRect,const TTimeIntervalMicroSeconds& aFromNow,const TTimeIntervalMicroSeconds& aFreq,const TTimeIntervalMicroSeconds& aStop)
   220 	{
   221 	// convert window rect to screen rect
   222 	TRect rect(aRect);
   223 	rect.Move(iGc->Origin());
   224 	// clip rect to window extent
   225 	rect.Intersection(iWin->Abs());
   226 	if (!rect.IsEmpty())
   227 		{
   228 		// and schedule it
   229 		iWin->Screen()->ScheduleAnimation(ECrpAnim, rect, aFromNow, aFreq, aStop, iWin);
   230 		}
   231 	}
   232 
   233 void CPlaybackGc::SetGcOrigin(const TPoint& aOrigin) 
   234 	{
   235 	iOrigin = aOrigin - iMasterOrigin;
   236 	} 
   237 
   238 void CPlaybackGc::RemoteReadDataAndDrawL(const CWsGraphicDrawer* aGraphic, CWsClient* aOwner, const TWsGcCmdUnion &aData)
   239 	{
   240 	TPtrC8 data;
   241 	HBufC8* dataBuf = NULL;
   242 	const TInt len = aData.WsGraphic->iDataLen;
   243 	
   244 	if ((len >= KMaxTInt / 4) || (len < 0))
   245 		{
   246 		aOwner->PPanic(EWservPanicBuffer);	
   247 		}	
   248 	dataBuf = HBufC8::NewLC(len);
   249 	TPtr8 des = dataBuf->Des();
   250 	aOwner->RemoteRead(des, 0);
   251 
   252 	if(des.Size() != len)
   253 		{
   254 		aOwner->PPanic(EWservPanicBuffer);
   255 		}
   256 	data.Set(des);																
   257 	aGraphic->Draw(*this, aData.WsGraphic->iRect, data);
   258 	CleanupStack::PopAndDestroy(dataBuf);		
   259 	}
   260 
   261 TPtrC CPlaybackGc::BufferTPtr(TText* aStart,TInt aLen, const TDesC8& aCmdData)
   262 	{
   263 	if ((reinterpret_cast<TUint8*>(aStart) < aCmdData.Ptr()
   264 									|| reinterpret_cast<TUint8*>(aStart+aLen) > (aCmdData.Ptr() + aCmdData.Size()) ))
   265 		{
   266 		GcOwnerPanic(EWservPanicBufferPtr);
   267 		}
   268 	TPtrC gcPtr;
   269 	gcPtr.Set(aStart,aLen);
   270 	return(gcPtr);
   271 	} 
   272 
   273 void CPlaybackGc::DoDrawCommand(TWsGcOpcodes aOpcode, const TDesC8& aCmdData, const TRegion *aRegion)
   274 	{
   275     if (aRegion->Count()==0)
   276         return;
   277 
   278     TWsGcCmdUnion pData;
   279 	// coverity[returned_pointer]
   280 	pData.any=aCmdData.Ptr();
   281 
   282 	SendClippingRegionIfRequired(aRegion);
   283 
   284 	WS_ASSERT_DEBUG(!iCurrentClippingRegion, EWsPanicDrawCommandsInvalidState);
   285 	iCurrentClippingRegion = aRegion;
   286 
   287 	CGraphicsContext::TTextParameters contextParam;
   288 	
   289 	TBool bGcDrawingOccurred = ETrue;	//most commands in here draw using the gc
   290 	
   291 	switch(aOpcode)
   292 		{
   293 		case EWsGcOpDrawWsGraphic:
   294 		case EWsGcOpDrawWsGraphicPtr:
   295 			{
   296 			bGcDrawingOccurred = EFalse;	//best guess if the drawer did no happen 
   297 			TRect screenRect(pData.WsGraphic->iRect);
   298 			screenRect.Move(iGc->Origin());
   299 			if(iCurrentClippingRegion->Intersects(screenRect))
   300 				{
   301 				const TInt dataLen = pData.WsGraphic->iDataLen;
   302 				TGraphicDrawerId id;
   303 				id.iId = pData.WsGraphic->iId;
   304 				id.iIsUid = (pData.WsGraphic->iFlags & EWsGraphicIdUid);
   305 				CWsClient* owner = iWin->WsOwner();
   306 				const CWsGraphicDrawer* graphic = CWsTop::WindowServer()->ResolveGraphic(id);
   307 				TInt lastDrawCount=GcDrawingCount();
   308 				if(graphic && graphic->IsSharedWith(owner->SecureId()))
   309 					{
   310 					if(aOpcode == EWsGcOpDrawWsGraphicPtr)
   311 						{
   312 						TRAPD(err, RemoteReadDataAndDrawL(graphic, owner, pData))
   313 						if(err)
   314 							WS_PANIC_DEBUG(EWsPanicWsGraphic);
   315 						}
   316 					else
   317 						graphic->Draw(*this,pData.WsGraphic->iRect,CWsClient::BufferTPtr8((TUint8*)(pData.WsGraphic+1),dataLen));
   318 	
   319 					WS_ASSERT_DEBUG(!iGcBuf->Size(),EWsPanicWsGraphic);
   320 					iGcBuf->Reset();
   321 					}
   322 				if (lastDrawCount!=GcDrawingCount())
   323 					{
   324 					// Changes to the GcDrawingCount are used to tag placed and background surfaces as dirty.
   325 					// If drawing occurs inside a CRP and perhaps PlaceSurface occurs inside the CRP 
   326 					// then we tag to count again to cause the placed surface to get marked as dirty later.
   327 					bGcDrawingOccurred = ETrue;	//some GC drawing did occurr at some point
   328 					}
   329 				}
   330 			break;
   331 			}
   332 		case EWsGcOpMapColorsLocal:
   333 			GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
   334 			break;
   335 		case EWsGcOpDrawPolyLineLocalBufLen:
   336 			{
   337 			TArrayWrapper<TPoint> points(pData.DrawPolyLineLocalBufLen->points, pData.DrawPolyLineLocalBufLen->length);
   338 			iGc->DrawPolyLine(points);
   339 			break;
   340 			}
   341 		case EWsGcOpDrawPolyLineLocal:
   342 			iGc->DrawPolyLine(pData.PointList->Array());
   343 			break;
   344 		case EWsGcOpDrawPolygonLocalBufLen:
   345 			{
   346 			TArrayWrapper<TPoint> points(pData.DrawPolygonLocalBufLen->points, pData.DrawPolygonLocalBufLen->length);
   347 			iGc->DrawPolygon(points, BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawPolygonLocalBufLen->fillRule));
   348 			break;
   349 			}
   350 		case EWsGcOpDrawPolygonLocal:
   351 			iGc->DrawPolygon(pData.DrawPolygonLocal->pointList->Array(),BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawPolygonLocal->fillRule));
   352 			break;
   353 		case EWsGcOpDrawBitmapLocal:
   354 			{
   355 			// DrawBitmap(TPoint&, ) uses the size of the bitmap in twips, but 
   356 			// MWsGraphicsContext::DrawBitmap() takes a TRect in pixels, so we need to convert
   357 			TRect destRect(iWin->Screen()->DeviceMap().TwipsToPixels(pData.BitmapLocal->bitmap->SizeInTwips()));
   358 			destRect.Move(pData.BitmapLocal->pos); //pos is defined in pixels, that's why we're not converting it
   359 			iGc->DrawBitmap(destRect, *pData.BitmapLocal->bitmap);
   360 			break;
   361 			}
   362 		case EWsGcOpDrawBitmap2Local:
   363 			iGc->DrawBitmap(pData.Bitmap2Local->rect, *pData.Bitmap2Local->bitmap);
   364 			break;
   365 		case EWsGcOpDrawBitmap3Local:
   366 			iGc->DrawBitmap(pData.Bitmap3Local->rect, *pData.Bitmap3Local->bitmap, pData.Bitmap3Local->srcRect);
   367 			break;
   368 		case EWsGcOpDrawBitmapMaskedLocal:
   369 			iGc->DrawBitmapMasked(pData.iBitmapMaskedLocal->iRect, *pData.iBitmapMaskedLocal->iBitmap, pData.iBitmapMaskedLocal->iSrcRect, *pData.iBitmapMaskedLocal->iMaskBitmap,pData.iBitmapMaskedLocal->iInvertMask);
   370 			break;
   371 		case EWsGcOpAlphaBlendBitmapsLocal:
   372 			iGc->BitBltMasked(pData.AlphaBlendBitmapsLocal->point, *pData.AlphaBlendBitmapsLocal->iBitmap,
   373 						                  pData.AlphaBlendBitmapsLocal->source, *pData.AlphaBlendBitmapsLocal->iAlpha,
   374 						                  pData.AlphaBlendBitmapsLocal->alphaPoint);
   375 			break;
   376 		case EWsGcOpDrawText:
   377 			if (iGc->HasFont())
   378 				iGc->DrawText(BufferTPtr((TText *)(pData.DrawText+1),pData.DrawText->length,aCmdData), NULL, pData.DrawText->pos);
   379 			break;
   380 		case EWsGcOpDrawBoxTextOptimised1:
   381 			if (iGc->HasFont())
   382 				iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length,aCmdData), NULL, pData.BoxTextO1->box,
   383 							  pData.BoxTextO1->baselineOffset,MWsGraphicsContext::ELeft,0);
   384 			break;
   385 		case EWsGcOpDrawBoxTextOptimised2:
   386 			if (iGc->HasFont())
   387 				iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length,aCmdData), NULL, pData.BoxTextO2->box,
   388 							  pData.BoxTextO2->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextO2->horiz),pData.BoxTextO2->leftMrg);
   389 			break;
   390 		case EWsGcOpDrawTextPtr:
   391 			if (iGc->HasFont())
   392 				iGc->DrawText(*pData.DrawTextPtr->text, NULL, pData.DrawTextPtr->pos);
   393 			break;
   394 		case EWsGcOpDrawTextPtr1:
   395 			if (iGc->HasFont())
   396 				iGc->DrawText(*pData.DrawTextPtr->text, NULL);
   397 			break;
   398 		case EWsGcOpDrawBoxText:
   399 			if (iGc->HasFont())
   400 				iGc->DrawText(BufferTPtr((TText *)(pData.BoxText+1),pData.BoxText->length,aCmdData), NULL, pData.BoxText->box,
   401 							  pData.BoxText->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxText->horiz),pData.BoxText->leftMrg);
   402 			break;
   403 		case EWsGcOpDrawBoxTextPtr:
   404 			if (iGc->HasFont())
   405 				iGc->DrawText(*pData.DrawBoxTextPtr->text, NULL, pData.DrawBoxTextPtr->box,pData.DrawBoxTextPtr->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextPtr->horiz),pData.DrawBoxTextPtr->leftMrg);
   406 			break;
   407 		case EWsGcOpDrawBoxTextPtr1:
   408 			if (iGc->HasFont())
   409 				iGc->DrawText(*pData.DrawBoxTextPtr->text, NULL, pData.DrawBoxTextPtr->box);
   410 			break;
   411 		case EWsGcOpDrawTextVertical:
   412 			if (iGc->HasFont())
   413 				iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length,aCmdData),NULL,pData.DrawTextVertical->pos
   414 							          ,pData.DrawTextVertical->up);
   415 			break;
   416 		case EWsGcOpDrawTextVerticalPtr:
   417 			if (iGc->HasFont())
   418 				iGc->DrawTextVertical(*pData.DrawTextVerticalPtr->text,NULL,pData.DrawTextVerticalPtr->pos,pData.DrawTextVerticalPtr->up);
   419 			break;
   420 		case EWsGcOpDrawTextVerticalPtr1:
   421 			if (iGc->HasFont())
   422 				iGc->DrawTextVertical(*pData.DrawTextVerticalPtr->text,NULL,pData.DrawTextVerticalPtr->up);
   423 			break;
   424 		case EWsGcOpDrawBoxTextVertical:
   425 			if (iGc->HasFont())
   426 				iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length,aCmdData), NULL,
   427 									  pData.DrawBoxTextVertical->box,	pData.DrawBoxTextVertical->baselineOffset,
   428 									  pData.DrawBoxTextVertical->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextVertical->vert),pData.DrawBoxTextVertical->margin);
   429 			break;
   430 		case EWsGcOpDrawBoxTextVerticalPtr:
   431 			if (iGc->HasFont())
   432 				iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,NULL,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->baselineOffset
   433 									  ,pData.DrawBoxTextVerticalPtr->width,pData.DrawBoxTextVerticalPtr->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextVerticalPtr->vert),pData.DrawBoxTextVerticalPtr->margin);
   434 			break;
   435 		case EWsGcOpDrawBoxTextVerticalPtr1:
   436 			if (iGc->HasFont())
   437 				iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,NULL,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->up);
   438 			break;
   439 		case EWsGcOpDrawTextLocal:
   440 			if (iGc->HasFont())
   441 				iGc->DrawText(*pData.DrawTextLocal->desc, NULL, pData.DrawTextLocal->pos);
   442 			break;
   443 		case EWsGcOpDrawBoxTextLocal:
   444 			if (iGc->HasFont())
   445 				iGc->DrawText(*pData.BoxTextLocal->desc, NULL, pData.BoxTextLocal->box,pData.BoxTextLocal->baselineOffset,
   446 							  BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextLocal->horiz),pData.BoxTextLocal->leftMrg);
   447 			break;
   448 		/************* DrawText in Context function calls*********************************************/
   449 		case EWsGcOpDrawTextInContext:
   450 			contextParam.iStart = pData.DrawTextInContext->start;
   451 			contextParam.iEnd = pData.DrawTextInContext->end;
   452 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   453 				{
   454 				iGc->DrawText(BufferTPtr((TText *)(pData.DrawTextInContext+1),pData.DrawTextInContext->length,aCmdData),BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContext->pos);
   455 				}
   456 			break;
   457 		case EWsGcOpDrawBoxTextInContextOptimised1:
   458 			contextParam.iStart = pData.BoxTextInContextO1->start;
   459 			contextParam.iEnd = pData.BoxTextInContextO1->end;
   460 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   461 				{
   462 				iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContextO1+1),pData.BoxTextInContextO1->length,aCmdData),BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContextO1->box,
   463 							  pData.BoxTextInContextO1->baselineOffset,MWsGraphicsContext::ELeft,0);
   464 				}
   465 			break;
   466 		case EWsGcOpDrawBoxTextInContextOptimised2:
   467 			contextParam.iStart = pData.BoxTextInContextO2->start;
   468 			contextParam.iEnd = pData.BoxTextInContextO2->end;
   469 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   470 				{
   471 				iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContextO2+1),pData.BoxTextInContextO2->length,aCmdData),BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContextO2->box,
   472 							  pData.BoxTextInContextO2->baselineOffset,BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextInContextO2->horiz),pData.BoxTextInContextO2->leftMrg);
   473 				}
   474 			break;
   475 		case EWsGcOpDrawTextInContextPtr:
   476 			contextParam.iStart = pData.DrawTextInContextPtr->start;
   477 			contextParam.iEnd = pData.DrawTextInContextPtr->end;
   478 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   479 				{
   480 				iGc->DrawText(*pData.DrawTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextPtr->pos);
   481 				}
   482 			break;
   483 		case EWsGcOpDrawTextInContextPtr1:
   484 			contextParam.iStart = pData.DrawTextInContextPtr->start;
   485 			contextParam.iEnd = pData.DrawTextInContextPtr->end;
   486 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   487 				{
   488 				iGc->DrawText(*pData.DrawTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
   489 				}
   490 			break;
   491 		case EWsGcOpDrawBoxTextInContext:
   492 			contextParam.iStart = pData.BoxTextInContext->start;
   493 			contextParam.iEnd = pData.BoxTextInContext->end;
   494 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   495 				{
   496 				iGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContext+1),pData.BoxTextInContext->length,aCmdData),
   497 							  BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContext->box,pData.BoxTextInContext->baselineOffset,
   498 							  BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextInContext->horiz),pData.BoxTextInContext->leftMrg);
   499 				}
   500 			break;
   501 		case EWsGcOpDrawBoxTextInContextPtr:
   502 			contextParam.iStart = pData.DrawBoxTextInContextPtr->start;
   503 			contextParam.iEnd = pData.DrawBoxTextInContextPtr->end;
   504 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   505 				{
   506 				iGc->DrawText(*pData.DrawBoxTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextInContextPtr->box,pData.DrawBoxTextInContextPtr->baselineOffset,
   507 							  BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextInContextPtr->horiz),pData.DrawBoxTextInContextPtr->leftMrg);
   508 				}
   509 			break;
   510 		case EWsGcOpDrawBoxTextInContextPtr1:
   511 			contextParam.iStart = pData.DrawBoxTextInContextPtr->start;
   512 			contextParam.iEnd = pData.DrawBoxTextInContextPtr->end;
   513 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   514 				{
   515 				iGc->DrawText(*pData.DrawBoxTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextInContextPtr->box);
   516 				}
   517 			break;
   518 		case EWsGcOpDrawTextInContextVertical:
   519 			contextParam.iStart = pData.DrawTextInContextVertical->start;
   520 			contextParam.iEnd = pData.DrawTextInContextVertical->end;
   521 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   522 				{
   523 				iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawTextInContextVertical+1),pData.DrawTextInContextVertical->length,aCmdData),
   524 									  BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextVertical->pos,pData.DrawTextInContextVertical->up);
   525 				}
   526 			break;
   527 		case EWsGcOpDrawTextInContextVerticalPtr:
   528 			contextParam.iStart = pData.DrawTextInContextVerticalPtr->start;
   529 			contextParam.iEnd = pData.DrawTextInContextVerticalPtr->end;
   530 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   531 				{
   532 				iGc->DrawTextVertical(*pData.DrawTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),
   533 									  pData.DrawTextInContextVerticalPtr->pos,pData.DrawTextInContextVerticalPtr->up);
   534 				}
   535 			break;
   536 		case EWsGcOpDrawTextInContextVerticalPtr1:
   537 			contextParam.iStart = pData.DrawTextInContextVerticalPtr->start;
   538 			contextParam.iEnd = pData.DrawTextInContextVerticalPtr->end;
   539 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   540 				{
   541 				iGc->DrawTextVertical(*pData.DrawTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextVerticalPtr->up);
   542 				}
   543 			break;
   544 		case EWsGcOpDrawBoxTextInContextVertical:
   545 			contextParam.iStart = pData.DrawBoxTextInContextVertical->start;
   546 			contextParam.iEnd = pData.DrawBoxTextInContextVertical->end;
   547 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   548 				{
   549 				iGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawBoxTextInContextVertical+1),pData.DrawBoxTextInContextVertical->length,aCmdData),
   550 									  BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextInContextVertical->box,pData.DrawBoxTextInContextVertical->baselineOffset,
   551 									  pData.DrawBoxTextInContextVertical->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextInContextVertical->vert),pData.DrawBoxTextInContextVertical->margin);
   552 				}
   553 			break;
   554 		case EWsGcOpDrawBoxTextInContextVerticalPtr:
   555 			contextParam.iStart = pData.DrawBoxTextInContextVerticalPtr->start;
   556 			contextParam.iEnd = pData.DrawBoxTextInContextVerticalPtr->end;
   557 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   558 				{
   559 				iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->baselineOffset
   560 									  ,pData.DrawBoxTextVerticalPtr->width,pData.DrawBoxTextVerticalPtr->up,BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawBoxTextVerticalPtr->vert),pData.DrawBoxTextVerticalPtr->margin);
   561 				}
   562 			break;
   563 		case EWsGcOpDrawBoxTextInContextVerticalPtr1:
   564 			contextParam.iStart = pData.DrawBoxTextInContextVerticalPtr->start;
   565 			contextParam.iEnd = pData.DrawBoxTextInContextVerticalPtr->end;
   566 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   567 				{
   568 				iGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->up);
   569 				}
   570 			break;
   571 		case EWsGcOpDrawTextInContextLocal:
   572 			contextParam.iStart = pData.DrawTextInContextLocal->start;
   573 			contextParam.iEnd = pData.DrawTextInContextLocal->end;
   574 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   575 				{
   576 				iGc->DrawText(*pData.DrawTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.DrawTextInContextLocal->pos);
   577 				}
   578 			break;
   579 		case EWsGcOpDrawBoxTextInContextLocal:
   580 			contextParam.iStart = pData.BoxTextInContextLocal->start;
   581 			contextParam.iEnd = pData.BoxTextInContextLocal->end;
   582 			if((contextParam.iStart < contextParam.iEnd) && (iGc->HasFont()))
   583 				{
   584 				iGc->DrawText(*pData.BoxTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam),pData.BoxTextInContextLocal->box,pData.BoxTextInContextLocal->baselineOffset,
   585 							  BitGdiToMWsGraphicsContextMappings::Convert(pData.BoxTextInContextLocal->horiz),pData.BoxTextInContextLocal->leftMrg);
   586 				}
   587 			break;
   588 		case EWsGcOpDrawLine:
   589 			iGc->DrawLine(pData.DrawLine->pnt1,pData.DrawLine->pnt2);
   590 			break;
   591 		case EWsGcOpDrawTo:
   592 			iGc->DrawLine(iLinePos,*pData.Point);
   593 			break;
   594 		case EWsGcOpDrawBy:
   595 			iGc->DrawLine(iLinePos,iLinePos+(*pData.Point));
   596 			break;
   597 		case EWsGcOpPlot:
   598 			iGc->Plot(*pData.Point);
   599 			break;
   600 		case EWsGcOpMoveTo:
   601 		case EWsGcOpMoveBy:
   602 			break;
   603 		case EWsGcOpGdiBlt2Local:
   604 			iGc->BitBlt(pData.GdiBlt2Local->pos,*pData.GdiBlt2Local->bitmap);
   605 			break;
   606 		case EWsGcOpGdiBlt3Local:
   607 			iGc->BitBlt(pData.GdiBlt3Local->pos,*pData.GdiBlt3Local->bitmap, pData.GdiBlt3Local->rect);
   608 			break;
   609 		case EWsGcOpGdiBltMaskedLocal:
   610 			iGc->BitBltMasked(pData.GdiBltMaskedLocal->pos,*pData.GdiBltMaskedLocal->bitmap,
   611 								pData.GdiBltMaskedLocal->rect,*pData.GdiBltMaskedLocal->maskBitmap,
   612 								pData.GdiBltMaskedLocal->invertMask);
   613 			break;
   614 		case EWsGcOpGdiWsBlt2:
   615 		case EWsGcOpGdiWsBlt3:
   616 		case EWsGcOpGdiWsBltMasked:
   617 		case EWsGcOpGdiWsAlphaBlendBitmaps:
   618 		case EWsGcOpWsDrawBitmapMasked:
   619 			{
   620 			CFbsBitmap* scratchBitmap = NULL;
   621 			CFbsBitmap* scratchMaskBimap = NULL;
   622 			TInt maskHandle=0;
   623 			TInt handle=WsBitmapHandle(aOpcode,pData, maskHandle);
   624 			CWsClient* owner=iWin->WsOwner();
   625 			if (owner!=NULL)
   626 				{
   627 				TInt wsBmpErr = KErrNone;
   628 				DWsBitmap *bitmap=(DWsBitmap *)owner->HandleToObj(handle, WS_HANDLE_BITMAP);
   629 				if (!bitmap)
   630 					wsBmpErr = KErrNotFound;
   631 				else
   632 					scratchBitmap=bitmap->FbsBitmap();
   633 				if (wsBmpErr == KErrNone)
   634 					if (aOpcode==EWsGcOpGdiWsBltMasked || aOpcode==EWsGcOpGdiWsAlphaBlendBitmaps || aOpcode==EWsGcOpWsDrawBitmapMasked)
   635 						{
   636 						DWsBitmap *bitmap2=(DWsBitmap *)owner->HandleToObj(maskHandle, WS_HANDLE_BITMAP);
   637 						if (!bitmap2)
   638 							wsBmpErr = KErrNotFound;
   639 						else
   640 							scratchMaskBimap=bitmap2->FbsBitmap();
   641 						}
   642 				if (wsBmpErr == KErrNone)
   643 					{
   644 					switch(aOpcode)
   645 						{
   646 						case EWsGcOpGdiWsBlt2:
   647 							iGc->BitBlt(pData.GdiBlt2->pos,*scratchBitmap);
   648 							break;
   649 						case EWsGcOpGdiWsBlt3:
   650 							iGc->BitBlt(pData.GdiBlt3->pos,*scratchBitmap, pData.GdiBlt3->rect);
   651 							break;
   652 						case EWsGcOpGdiWsBltMasked:
   653 							{
   654 							iGc->BitBltMasked(pData.GdiBltMasked->destination,*scratchBitmap,
   655 											pData.GdiBltMasked->source, *scratchMaskBimap,
   656 											pData.GdiBltMasked->invertMask);
   657 							}
   658 							break;
   659 						case EWsGcOpGdiWsAlphaBlendBitmaps:
   660 							{
   661 							iGc->BitBltMasked(pData.AlphaBlendBitmaps->point,*scratchBitmap,
   662 											   pData.AlphaBlendBitmaps->source, *scratchMaskBimap,
   663 											   pData.AlphaBlendBitmaps->alphaPoint);
   664 							}
   665 							break;
   666 						case EWsGcOpWsDrawBitmapMasked:
   667 							{
   668 							iGc->DrawBitmapMasked(pData.iBitmapMasked->iRect,*scratchBitmap, 
   669 												pData.iBitmapMasked->iSrcRect,*scratchMaskBimap,
   670 												pData.iBitmapMasked->iInvertMask);
   671 							}
   672 							break;
   673 						}
   674 					}
   675 				}
   676 			break;
   677 			}
   678 		case EWsGcOpGdiBlt2:
   679 		case EWsGcOpGdiBlt3:
   680         case EWsGcOpDrawBitmap:
   681         case EWsGcOpDrawBitmap2:
   682         case EWsGcOpDrawBitmap3:
   683             {
   684 			TInt bitmapMaskHandle=0;
   685             TInt bitmapHandle = FbsBitmapHandle(aOpcode, pData, bitmapMaskHandle);
   686             const CFbsBitmap* bitmap = iWin->Redraw()->BitmapFromHandle(bitmapHandle);
   687 			if(!bitmap)
   688 			    {
   689 			    WS_PANIC_DEBUG(EWsPanicBitmapNotFound);
   690 			    break;
   691 			    }
   692 			
   693             switch(aOpcode)
   694                 {
   695                 case EWsGcOpGdiBlt2:
   696                     iGc->BitBlt(pData.GdiBlt2->pos,*bitmap);
   697                     break;
   698                 case EWsGcOpGdiBlt3:
   699                     iGc->BitBlt(pData.GdiBlt3->pos,*bitmap, pData.GdiBlt3->rect);
   700                     break;
   701                 case EWsGcOpDrawBitmap:
   702                     {
   703                     // DrawBitmap(TPoint&, ) uses the size of the bitmap in twips, but 
   704                     // MWsGraphicsContext::DrawBitmap() takes a TRect in pixels, so we need to convert
   705                     TRect destRect(iWin->Screen()->DeviceMap().TwipsToPixels(bitmap->SizeInTwips()));
   706                     destRect.Move(pData.Bitmap->pos); //pos is defined in pixels, that's why we're not converting it
   707                     iGc->DrawBitmap(destRect, *bitmap);
   708                     break;
   709                     }
   710                 case EWsGcOpDrawBitmap2:
   711                     iGc->DrawBitmap(pData.Bitmap2->rect, *bitmap);
   712                     break;
   713                 case EWsGcOpDrawBitmap3:
   714                     iGc->DrawBitmap(pData.Bitmap3->rect, *bitmap, pData.Bitmap3->srcRect);
   715                     break;
   716                 }
   717 			break;
   718             }
   719         case EWsGcOpGdiBltMasked:
   720         case EWsGcOpGdiAlphaBlendBitmaps:
   721         case EWsGcOpDrawBitmapMasked:
   722             {
   723             TInt bitmapMaskHandle=0;
   724             TInt bitmapHandle = FbsBitmapHandle(aOpcode, pData, bitmapMaskHandle);
   725             const CFbsBitmap* bitmap = iWin->Redraw()->BitmapFromHandle(bitmapHandle);
   726             if(!bitmap)
   727                 {
   728                 WS_PANIC_DEBUG(EWsPanicBitmapNotFound);
   729                 break;
   730                 }
   731             
   732             CFbsBitmap* bitmapMask = iWin->Redraw()->BitmapFromHandle(bitmapMaskHandle);
   733             if(!bitmapMask)
   734                 {
   735                 WS_PANIC_DEBUG(EWsPanicBitmapNotFound);
   736                 break;
   737                 }
   738                         
   739             switch(aOpcode)
   740                 {
   741                 case EWsGcOpGdiBltMasked:
   742                     {
   743                     iGc->BitBltMasked(pData.GdiBltMasked->destination,*bitmap,
   744                                         pData.GdiBltMasked->source, *bitmapMask,
   745                                         pData.GdiBltMasked->invertMask);
   746                     break;
   747                     }
   748                 case EWsGcOpGdiAlphaBlendBitmaps:
   749                     {
   750                     iGc->BitBltMasked(pData.AlphaBlendBitmaps->point, *bitmap,
   751                                         pData.AlphaBlendBitmaps->source, *bitmapMask,
   752                                         pData.AlphaBlendBitmaps->alphaPoint);
   753                     break;
   754                     }
   755                 case EWsGcOpDrawBitmapMasked:
   756                     {
   757                     iGc->DrawBitmapMasked(pData.iBitmapMasked->iRect, *bitmap, 
   758                                         pData.iBitmapMasked->iSrcRect, *bitmapMask,
   759                                         pData.iBitmapMasked->iInvertMask);
   760                     break;
   761                     }
   762                 }
   763 			break;
   764 			}
   765 		case EWsGcOpDrawSegmentedPolygon:
   766 			{
   767 			TArrayWrapper<TPoint> points(iPolyPoints, iPolyPointListSize);
   768 			iGc->DrawPolygon(points, BitGdiToMWsGraphicsContextMappings::Convert(pData.DrawSegmentedPolygon->fillRule));
   769 			break;
   770 			}
   771 		case EWsGcOpDrawPolygon:
   772 			DoDrawPolygon(pData.Polygon);
   773 			break;
   774 		case EWsGcOpDrawPolyLine:
   775 			DoDrawPolyLine(pData.PolyLine, EFalse);
   776 			break;
   777 		case EWsGcOpDrawPolyLineContinued:
   778 			DoDrawPolyLine(pData.PolyLine, ETrue);
   779 			break;
   780 		case EWsGcOpClear:
   781 			iGc->Clear(TRect(iWin->Size()));
   782 			break;
   783 		case EWsGcOpClearRect:
   784 			iGc->Clear(*pData.Rect);
   785 			break;
   786 		case EWsGcOpDrawRect:
   787 			iGc->DrawRect(*pData.Rect);
   788 			break;
   789 		case EWsGcOpDrawEllipse:
   790 			iGc->DrawEllipse(*pData.Rect);
   791 			break;
   792 		case EWsGcOpDrawRoundRect:
   793 			iGc->DrawRoundRect(*pData.Rect,pData.RoundRect->ellipse);
   794 			break;
   795 		case EWsGcOpDrawArc:
   796 			iGc->DrawArc(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
   797 			break;
   798 		case EWsGcOpDrawPie:
   799 			iGc->DrawPie(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
   800 			break;
   801 		case EWsGcOpCopyRect:
   802 			iGc->CopyRect(pData.CopyRect->pos,*pData.Rect);
   803 			break;
   804 		case EWsGcOpMapColors:
   805 			GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
   806 			break;
   807 		case EWsGcOpSetShadowColor:
   808 			iGc->SetTextShadowColor(*pData.rgb);
   809 			break;
   810 		case EWsGcOpDrawResourceToPos:
   811 		case EWsGcOpDrawResourceToRect:
   812 		case EWsGcOpDrawResourceFromRectToRect:
   813 		case EWsGcOpDrawResourceWithData:
   814 			DoDrawResource(aOpcode, pData);
   815 			break;
   816 		default:
   817 			TRAP_IGNORE(iWin->OwnerPanic(EWservPanicOpcode));
   818 			break;
   819 		}
   820 	iGc->ResetClippingRegion();
   821 	iCurrentClippingRegion = NULL;
   822 	if (bGcDrawingOccurred)
   823 		{
   824 		GcDrawingDone();	//up the count (again for CRPs)
   825 		}
   826 	}
   827 /**
   828  Helper function for drawing resources. 
   829  It extracts DWsDrawableSource objects which corresponds RWsDrawableResource object on the server side and then redirect call to concrete implementation. 
   830  @param aOpcode GC opcodes
   831  @param aData An extra data which will be used for resource drawing 
   832  */
   833 void CPlaybackGc::DoDrawResource(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &aData)
   834 	{
   835 	CWsClient* owner=iWin->WsOwner(); // We can't just use iWsOwner - it can be null for stored commands
   836 	if (owner!=NULL)
   837 		{
   838 		CWsDrawableSource *drawable = static_cast<CWsDrawableSource*>(owner->HandleToObj(*aData.Int, WS_HANDLE_DRAWABLE_SOURCE));
   839 		if (!drawable)
   840 			return;
   841 		
   842 		switch(aOpcode)
   843 			{
   844 		case EWsGcOpDrawResourceToPos:
   845 			drawable->DrawResource(iGc, aData.DrawWsResourceToPos->pos, aData.DrawWsResourceToPos->rotation);
   846 			break;
   847 		case EWsGcOpDrawResourceToRect:
   848 			drawable->DrawResource(iGc, aData.DrawWsResourceToRect->rect, aData.DrawWsResourceToRect->rotation);
   849 			break;
   850 		case EWsGcOpDrawResourceFromRectToRect:
   851 			drawable->DrawResource(iGc, aData.DrawWsResourceFromRectToRect->rectDest, aData.DrawWsResourceFromRectToRect->rectSrc, aData.DrawWsResourceFromRectToRect->rotation);
   852 			break;
   853 		case EWsGcOpDrawResourceWithData:
   854 			drawable->DrawResource(iGc, aData.DrawWsResourceWithData->rect, *aData.DrawWsResourceWithData->desc);
   855 			break;
   856 		default:
   857 			break;
   858 			}
   859 		}
   860 	}
   861 
   862 TInt CPlaybackGc::WsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle) 
   863 	{
   864 	TInt handle=0;
   865 	switch(aOpcode)
   866 		{
   867 		case EWsGcOpGdiWsBlt2:
   868 			handle=pData.GdiBlt2->handle;
   869 			break;
   870 		case EWsGcOpGdiWsBlt3:
   871 			handle=pData.GdiBlt3->handle;
   872 			break;
   873 		case EWsGcOpGdiWsBltMasked:
   874 			handle=pData.GdiBltMasked->handle;
   875 			aMaskHandle = pData.GdiBltMasked->maskHandle;
   876 			break;
   877 		case EWsGcOpGdiWsAlphaBlendBitmaps:
   878 			handle=pData.AlphaBlendBitmaps->bitmapHandle;
   879 			aMaskHandle = pData.AlphaBlendBitmaps->alphaHandle;
   880 			break;
   881 		case EWsGcOpWsDrawBitmapMasked:
   882 			handle=pData.iBitmapMasked->iHandle;
   883 			aMaskHandle=pData.iBitmapMasked->iMaskHandle;
   884 			break;
   885 		}
   886 	return handle;
   887 	}		
   888 
   889 TInt CPlaybackGc::FbsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle)
   890 	{
   891 	TInt handle=0;
   892 	aMaskHandle=0;
   893 	switch(aOpcode)
   894 		{
   895 		case EWsGcOpGdiBlt2:
   896 			handle=pData.GdiBlt2->handle;
   897 			break;
   898 		case EWsGcOpGdiBlt3:
   899 			handle=pData.GdiBlt3->handle;
   900 			break;
   901 		case EWsGcOpGdiBltMasked:
   902 			handle=pData.GdiBltMasked->handle;
   903 			aMaskHandle=pData.GdiBltMasked->maskHandle;
   904 			break;
   905 		case EWsGcOpGdiAlphaBlendBitmaps:
   906 			handle=pData.AlphaBlendBitmaps->bitmapHandle;
   907 			aMaskHandle=pData.AlphaBlendBitmaps->alphaHandle;
   908 			break;
   909 		case EWsGcOpDrawBitmap:
   910 			handle=pData.Bitmap->handle;
   911 			break;
   912 		case EWsGcOpDrawBitmap2:
   913 			handle=pData.Bitmap2->handle;
   914 			break;
   915 		case EWsGcOpDrawBitmap3:
   916 			handle=pData.Bitmap3->handle;
   917 			break;
   918 		case EWsGcOpDrawBitmapMasked:
   919 			handle=pData.iBitmapMasked->iHandle;
   920 			aMaskHandle=pData.iBitmapMasked->iMaskHandle;
   921 			break;
   922 		default:
   923 			WS_ASSERT_DEBUG(EFalse, EWsPanicInvalidOperation);
   924 			break;
   925 		}
   926 	return handle;
   927 	}
   928 
   929 void CPlaybackGc::UpdateJustification(TText* aText,TInt aLen,const TDesC8& aCmdData,CGraphicsContext::TTextParameters* aParam)
   930 	{
   931 	iGc->UpdateJustification(BufferTPtr(aText,aLen,aCmdData), BitGdiToMWsGraphicsContextMappings::Convert(aParam));
   932 	}
   933 
   934 void CPlaybackGc::SendOriginIfRequired()
   935     {
   936     const TPoint currentOrigin(iMasterOrigin + iOrigin); 
   937     if (iSendOrigin || currentOrigin != iLastSentOrigin)
   938         {
   939         iGc->SetOrigin(currentOrigin);
   940         iLastSentOrigin = currentOrigin;
   941         iSendOrigin = EFalse;
   942         }
   943     }
   944 
   945 void CPlaybackGc::SendClippingRegionIfRequired(const TRegion* aRegion)
   946     {
   947     if (iUserDefinedClippingRegion || iClippingRectSet || !iWin->Screen()->ChangeTracking())
   948         {
   949         iGc->SetClippingRegion(*aRegion);
   950         }
   951     }
   952 
   953 void CPlaybackGc::DoDrawing(TWsGcOpcodes aOpcode, const TDesC8& aCmdData)
   954 	{
   955 	TWsGcCmdUnion pData;
   956 	// coverity[returned_pointer]
   957 	pData.any=aCmdData.Ptr();
   958 
   959 	iIntersectedRegion.Clear();
   960 	iIntersectedRegion.Copy(*iDrawRegion);
   961 	
   962 	if (iClippingRectSet)
   963 		{
   964 	    // MWsGraphicsContext doesn't provide a SetClippingRect API. If a client calls SetClippingRect
   965 	    // the rect is passed to the render stage using MWsGraphicsContext::SetClippingRegion
   966         TRect clippingRectRelativeToScreen(iClippingRect);
   967         clippingRectRelativeToScreen.Move(iMasterOrigin);
   968 		iIntersectedRegion.ClipRect(clippingRectRelativeToScreen);
   969         iIntersectedRegion.ClipRect(iWin->AbsRect());
   970 		}
   971 
   972 	SendOriginIfRequired();
   973 	
   974 	DoDrawCommand(aOpcode,aCmdData,&iIntersectedRegion);
   975 
   976 	CGraphicsContext::TTextParameters contextParam;
   977 	switch(aOpcode)
   978 		{
   979 		case EWsGcOpDrawLine:
   980 			iLinePos=pData.DrawLine->pnt2;
   981 			break;
   982 		case EWsGcOpDrawTo:
   983 		case EWsGcOpMoveTo:
   984 		case EWsGcOpPlot:
   985 			iLinePos=(*pData.Point);
   986 			break;
   987 		case EWsGcOpDrawBy:
   988 		case EWsGcOpMoveBy:
   989 			iLinePos+=(*pData.Point);
   990 			break;
   991 		case EWsGcOpDrawSegmentedPolygon:
   992 			EndSegmentedPolygon();
   993 			break;
   994 		case EWsGcOpDrawText:
   995 			UpdateJustification((TText *)(pData.DrawText+1),pData.DrawText->length,aCmdData,NULL);
   996 			break;
   997 		case EWsGcOpDrawTextVertical:
   998 			UpdateJustification((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length,aCmdData,NULL);
   999 			break;
  1000 		case EWsGcOpDrawBoxText:
  1001 			UpdateJustification((TText *)(pData.BoxText+1),pData.BoxText->length,aCmdData,NULL);
  1002 			break;
  1003 		case EWsGcOpDrawBoxTextOptimised1:
  1004 			UpdateJustification((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length,aCmdData,NULL);
  1005 			break;
  1006 		case EWsGcOpDrawBoxTextOptimised2:
  1007 			UpdateJustification((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length,aCmdData,NULL);
  1008 			break;
  1009 		case EWsGcOpDrawBoxTextVertical:
  1010 			UpdateJustification((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length,aCmdData,NULL);
  1011 			break;
  1012 		case EWsGcOpDrawTextLocal:
  1013 			iGc->UpdateJustification(*pData.DrawTextLocal->desc,NULL);
  1014 			break;
  1015 		case EWsGcOpDrawBoxTextLocal:
  1016 			iGc->UpdateJustification(*pData.BoxTextLocal->desc,NULL);
  1017 			break;
  1018 		case EWsGcOpDrawTextPtr:
  1019 			iGc->UpdateJustification(*pData.DrawTextPtr->text,NULL);
  1020 			break;
  1021 		case EWsGcOpDrawTextVerticalPtr:
  1022 			iGc->UpdateJustification(*pData.DrawTextVerticalPtr->text,NULL);
  1023 			break;
  1024 		case EWsGcOpDrawBoxTextPtr:
  1025 			iGc->UpdateJustification(*pData.DrawBoxTextPtr->text,NULL);
  1026 			break;
  1027 		case EWsGcOpDrawBoxTextVerticalPtr:
  1028 			iGc->UpdateJustification(*pData.DrawBoxTextVerticalPtr->text,NULL);
  1029 			break;
  1030 		/***************DrawTextInContext*****************************************************************/
  1031 		case EWsGcOpDrawTextInContext:
  1032 			contextParam.iStart = pData.DrawTextInContext->start;
  1033 			contextParam.iEnd = pData.DrawTextInContext->end;
  1034 			if(contextParam.iStart < contextParam.iEnd)
  1035 				{
  1036 				UpdateJustification((TText *)(pData.DrawTextInContext+1),pData.DrawTextInContext->length,aCmdData,&contextParam);
  1037 				}
  1038 			break;
  1039 		case EWsGcOpDrawTextInContextVertical:
  1040 			contextParam.iStart = pData.DrawTextInContext->start;
  1041 			contextParam.iEnd = pData.DrawTextInContext->end;
  1042 			if(contextParam.iStart < contextParam.iEnd)
  1043 				{
  1044 				UpdateJustification((TText *)(pData.DrawTextInContextVertical+1),pData.DrawTextInContextVertical->length,aCmdData,&contextParam);
  1045 				}
  1046 			break;
  1047 		case EWsGcOpDrawBoxTextInContext:
  1048 			contextParam.iStart = pData.DrawTextInContext->start;
  1049 			contextParam.iEnd = pData.DrawTextInContext->end;
  1050 			if(contextParam.iStart < contextParam.iEnd)
  1051 				{
  1052 				UpdateJustification((TText *)(pData.BoxTextInContext+1),pData.BoxTextInContext->length,aCmdData,&contextParam);
  1053 				}
  1054 			break;
  1055 		case EWsGcOpDrawBoxTextInContextOptimised1:
  1056 			contextParam.iStart = pData.DrawTextInContext->start;
  1057 			contextParam.iEnd = pData.DrawTextInContext->end;
  1058 			if(contextParam.iStart < contextParam.iEnd)
  1059 				{
  1060 				UpdateJustification((TText *)(pData.BoxTextInContextO1+1),pData.BoxTextInContextO1->length,aCmdData,&contextParam);
  1061 				}
  1062 			break;
  1063 		case EWsGcOpDrawBoxTextInContextOptimised2:
  1064 			contextParam.iStart = pData.DrawTextInContext->start;
  1065 			contextParam.iEnd = pData.DrawTextInContext->end;
  1066 			if(contextParam.iStart < contextParam.iEnd)
  1067 				{
  1068 				UpdateJustification((TText *)(pData.BoxTextInContextO2+1),pData.BoxTextInContextO2->length,aCmdData,&contextParam);
  1069 				}
  1070 			break;
  1071 		case EWsGcOpDrawBoxTextInContextVertical:
  1072 			contextParam.iStart = pData.DrawTextInContext->start;
  1073 			contextParam.iEnd = pData.DrawTextInContext->end;
  1074 			if(contextParam.iStart < contextParam.iEnd)
  1075 				{
  1076 				UpdateJustification((TText *)(pData.DrawBoxTextInContextVertical+1),pData.DrawBoxTextInContextVertical->length,aCmdData,&contextParam);
  1077 				}
  1078 			break;
  1079 		case EWsGcOpDrawTextInContextLocal:
  1080 			contextParam.iStart = pData.DrawTextInContext->start;
  1081 			contextParam.iEnd = pData.DrawTextInContext->end;
  1082 			if(contextParam.iStart < contextParam.iEnd)
  1083 				{
  1084 				iGc->UpdateJustification(*pData.DrawTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
  1085 				}
  1086 			break;
  1087 		case EWsGcOpDrawBoxTextInContextLocal:
  1088 			contextParam.iStart = pData.DrawTextInContext->start;
  1089 			contextParam.iEnd = pData.DrawTextInContext->end;
  1090 			if(contextParam.iStart < contextParam.iEnd)
  1091 				{
  1092 				iGc->UpdateJustification(*pData.BoxTextInContextLocal->desc,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
  1093 				}
  1094 			break;
  1095 		case EWsGcOpDrawTextInContextPtr:
  1096 			contextParam.iStart = pData.DrawTextInContext->start;
  1097 			contextParam.iEnd = pData.DrawTextInContext->end;
  1098 			if(contextParam.iStart < contextParam.iEnd)
  1099 				{
  1100 				iGc->UpdateJustification(*pData.DrawTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
  1101 				}
  1102 			break;
  1103 		case EWsGcOpDrawTextInContextVerticalPtr:
  1104 			contextParam.iStart = pData.DrawTextInContext->start;
  1105 			contextParam.iEnd = pData.DrawTextInContext->end;
  1106 			if(contextParam.iStart < contextParam.iEnd)
  1107 				{
  1108 				iGc->UpdateJustification(*pData.DrawTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
  1109 				}
  1110 			break;
  1111 		case EWsGcOpDrawBoxTextInContextPtr:
  1112 			contextParam.iStart = pData.DrawTextInContext->start;
  1113 			contextParam.iEnd = pData.DrawTextInContext->end;
  1114 			if(contextParam.iStart < contextParam.iEnd)
  1115 				{
  1116 				iGc->UpdateJustification(*pData.DrawBoxTextInContextPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
  1117 				}
  1118 			break;
  1119 		case EWsGcOpDrawBoxTextInContextVerticalPtr:
  1120 			contextParam.iStart = pData.DrawTextInContext->start;
  1121 			contextParam.iEnd = pData.DrawTextInContext->end;
  1122 			if(contextParam.iStart < contextParam.iEnd)
  1123 				{
  1124 				iGc->UpdateJustification(*pData.DrawBoxTextInContextVerticalPtr->text,BitGdiToMWsGraphicsContextMappings::Convert(&contextParam));
  1125 				}
  1126 			break;
  1127 		}
  1128 	}
  1129 
  1130 void CPlaybackGc::CommandL(TWsGcOpcodes aOpcode, const TDesC8& aCmdData)
  1131 	{
  1132     WS_ASSERT_DEBUG(iWin,EWsPanicWindowNull);
  1133 	TWsGcCmdUnion pData;
  1134 	// coverity[returned_pointer]
  1135 	pData.any=aCmdData.Ptr();
  1136 	
  1137 	switch(aOpcode)
  1138 		{
  1139 	case EWsGcOpStartSegmentedDrawPolygon:
  1140 		StartSegmentedDrawPolygonL(pData.StartSegmentedDrawPolygon);
  1141 		break;
  1142 	case EWsGcOpSegmentedDrawPolygonData:
  1143 		SegmentedDrawPolygonData(pData.SegmentedDrawPolygonData);
  1144 		break;
  1145 	case EWsGcOpSetClippingRegion:
  1146 		WS_ASSERT_DEBUG(aOpcode != EWsGcOpSetClippingRegion, EWsPanicDrawCommandsInvalidState);
  1147 		break;
  1148 	case EWsGcOpSetClippingRect:
  1149 		SetClippingRect(*pData.Rect);
  1150 		break;
  1151 	case EWsGcOpCancelClippingRect:
  1152 		ResetClippingRect();
  1153 		break;
  1154 	case EWsGcOpCancelClippingRegion:
  1155 		CancelUserClippingRegion();
  1156 		break;
  1157 	case EWsGcOpSetFaded: // deprecated
  1158 		// do nothing
  1159 		break;
  1160 	case EWsGcOpSetFadeParams: // deprecated
  1161 		// do nothing
  1162 		break;
  1163 	case EWsGcOpSetDrawMode:
  1164 		iGc->SetDrawMode(BitGdiToMWsGraphicsContextMappings::LossyConvert((CGraphicsContext::TDrawMode)*pData.UInt));
  1165 		break;
  1166 	case EWsGcOpUseFont:
  1167 		if (CWsFontCache::Instance()->UseFont(iFont, *pData.UInt))
  1168 			{
  1169 			CFbsBitGcFont font;
  1170 			if(font.Duplicate(*pData.UInt) == KErrNone)
  1171 				iGc->SetFont(&font);
  1172 			font.Reset();
  1173 			}
  1174 		else
  1175 			iGc->SetFontNoDuplicate(iFont);
  1176 		break;
  1177 	case EWsGcOpDiscardFont:
  1178 		CWsFontCache::Instance()->ReleaseFont(iFont);
  1179 		iGc->ResetFont();
  1180 		break;
  1181 	case EWsGcOpSetUnderlineStyle:
  1182 		iGc->SetUnderlineStyle(BitGdiToMWsGraphicsContextMappings::Convert(*pData.SetUnderlineStyle));
  1183 		break;
  1184 	case EWsGcOpSetStrikethroughStyle:
  1185 		iGc->SetStrikethroughStyle(BitGdiToMWsGraphicsContextMappings::Convert(*pData.SetStrikethroughStyle));
  1186 		break;
  1187 	case EWsGcOpUseBrushPattern:
  1188 		iGc->SetBrushPattern(*pData.handle);
  1189 		break;
  1190 	case EWsGcOpDiscardBrushPattern:
  1191 		iGc->ResetBrushPattern();
  1192 		break;
  1193 	case EWsGcOpSetBrushColor:
  1194 		iGc->SetBrushColor(*pData.rgb);
  1195 		break;
  1196 	case EWsGcOpSetPenColor:
  1197 		iGc->SetPenColor(*pData.rgb);
  1198 		break;
  1199 	case EWsGcOpSetPenStyle:
  1200 		iGc->SetPenStyle(BitGdiToMWsGraphicsContextMappings::Convert((CGraphicsContext::TPenStyle)*pData.UInt));
  1201 		break;
  1202 	case EWsGcOpSetPenSize:
  1203 		iGc->SetPenSize(*pData.Size);
  1204 		break;
  1205 	case EWsGcOpSetBrushStyle:
  1206 		{
  1207 		MWsGraphicsContext::TBrushStyle style = BitGdiToMWsGraphicsContextMappings::Convert((CGraphicsContext::TBrushStyle)*pData.UInt); 
  1208 		if (iGc->HasBrushPattern() || style != MWsGraphicsContext::EPatternedBrush)
  1209 			{
  1210 			iGc->SetBrushStyle(style);
  1211 			}
  1212 		break;
  1213 		}
  1214 	case EWsGcOpReset:
  1215 		CWsFontCache::Instance()->ReleaseFont(iFont);
  1216 		iGc->Reset();
  1217 		iOrigin.SetXY(0,0);
  1218 		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
  1219 		ResetClippingRect();
  1220 		iGc->SetBrushColor(iWin->BackColor());
  1221 		break;
  1222 	case EWsGcOpSetBrushOrigin:
  1223 		iGc->SetBrushOrigin(*pData.Point);
  1224 		break;
  1225 	case EWsGcOpSetDitherOrigin:
  1226 		GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
  1227 		break;
  1228 	case EWsGcOpSetWordJustification:
  1229 		iGc->SetWordJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
  1230 		break;
  1231 	case EWsGcOpSetCharJustification:
  1232 		iGc->SetCharJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
  1233 		break;
  1234 	case EWsGcOpSetOrigin:
  1235 		SetOrigin(*pData.Point);
  1236 		break;
  1237 	case EWsGcOpSetOpaque: // deprecated
  1238 		// do nothing
  1239 		break;
  1240 	default:	// Assume remaining functions will draw
  1241 		{
  1242 		DoDrawing(aOpcode,aCmdData);
  1243 		return;
  1244 		}
  1245 		}
  1246 	}
  1247 
  1248 
  1249 void CPlaybackGc::SetOrigin(const TPoint &aOrigin)
  1250 	{
  1251 	iOrigin=aOrigin;
  1252 	}
  1253 	
  1254 /*------------------------------------------------------------------------------
  1255   Description: Retrieves graphics context information back from a given buffer
  1256                from a given start position.
  1257  -----------------------------------------------------------------------------*/
  1258 void CPlaybackGc::InternalizeL(const CBufBase& aBuffer,TInt& aStartPos)
  1259 	{
  1260 	// Open the stream used for the input from the given start position
  1261 	// in the buffer.
  1262 	RBufReadStream bufReadStream;
  1263 	bufReadStream.Open(aBuffer,aStartPos);
  1264 	CleanupClosePushL(bufReadStream);
  1265 	
  1266 	// Read the font/bitmap server data
  1267 	TInternalGcStatus::InternalizeGcAttributesL(iGc, bufReadStream);
  1268 
  1269 	iOrigin.iX = bufReadStream.ReadInt32L();
  1270 	iOrigin.iY = bufReadStream.ReadInt32L();
  1271 	iSendOrigin = ETrue;
  1272 
  1273 	iClippingRectSet=bufReadStream.ReadInt8L();
  1274 	
  1275 	// If there is a clipping rectangle data read it.
  1276 	if (iClippingRectSet)
  1277 		bufReadStream>>iClippingRect;
  1278 		
  1279 	// Read the clipping region data
  1280 	InternalizeClippingRegionL(bufReadStream);
  1281 
  1282 	// Read the Alpha values for Brush and Pen colors.
  1283 	InternalizeAlphaValueL(bufReadStream);
  1284 	
  1285 	CleanupStack::PopAndDestroy(&bufReadStream);
  1286 	}
  1287 
  1288 /*------------------------------------------------------------------------------
  1289   Description: Retrieves TRgb::alpha value information back from a given buffer
  1290                and updates the Brushcolor with the same.
  1291  -----------------------------------------------------------------------------*/
  1292 void CPlaybackGc::InternalizeAlphaValueL(RReadStream& aReadStream)
  1293 	{
  1294 	TRgb brushColor(iGc->BrushColor());
  1295 	brushColor.SetAlpha(aReadStream.ReadUint8L());
  1296 	iGc->SetBrushColor(brushColor);
  1297 	TRgb penColor(iGc->PenColor());
  1298 	penColor.SetAlpha(aReadStream.ReadUint8L());
  1299 	iGc->SetPenColor(penColor);
  1300 	}
  1301 
  1302 /*------------------------------------------------------------------------------
  1303   Description: Helper method to retrieve clipping region data from a given
  1304                read stream.
  1305  -----------------------------------------------------------------------------*/
  1306 void CPlaybackGc::InternalizeClippingRegionL(RReadStream& aReadStream)
  1307 	{
  1308 	WS_ASSERT_DEBUG(iTargetRegion, EWsPanicDrawCommandsInvalidState);
  1309 	// Read flag to indicate if client had defined a clipping region
  1310 	TBool clipRegion = aReadStream.ReadInt8L();
  1311 	CancelUserClippingRegion();
  1312 	if (clipRegion)
  1313 		{
  1314 		// Note that this clipping region is in window relative coordinates when
  1315 		// received from the client (and being stored) but is in screen relative
  1316 		// coordinates after being retrieved from the redraw store.
  1317 		iUserDefinedClippingRegion = InternalizeRegionL(aReadStream);
  1318 		iUserDefinedClippingRegion->Offset(iWin->Origin());
  1319 		iUserDefinedClippingRegion->Intersect(*iTargetRegion);
  1320 		if (iUserDefinedClippingRegion->CheckError()) // fallback to no user clipping region
  1321 			{
  1322 			CancelUserClippingRegion();
  1323 			}
  1324 		else
  1325 			{
  1326 			iDrawRegion = iUserDefinedClippingRegion;
  1327 			}
  1328 		}
  1329 	}
  1330 
  1331 /**
  1332 * @deprecated
  1333 */
  1334 TInt CPlaybackGc::PlaceSurface(const TSurfaceConfiguration& /*aConfig*/)
  1335     {
  1336     return KErrNotSupported;
  1337     }
  1338 
  1339 /**	Get the drawing occurred indication counter.	
  1340   	Callers can detect if drawing has occurred between two points 
  1341  	by detecting that this count has changed.
  1342  	Note that the changed value does not necessarily represent the exact number of operations which occurred.
  1343   	@return value which changes each time GC drawing occurrs.
  1344  **/
  1345 TInt CPlaybackGc::GcDrawingCount()
  1346 	{
  1347 	return iGcDrawingCounter;
  1348 	}
  1349 
  1350 /**	Update the drawing occurred indication counter.	
  1351  	Called internally each time a drawing operation updates the UI content 
  1352  **/
  1353 void CPlaybackGc::GcDrawingDone()
  1354 	{
  1355 	iGcDrawingCounter++;
  1356 	}
  1357 
  1358 
  1359 /**
  1360 This pretty much replaces the whole of what was TDrawDestination
  1361 This can only be sensibly called from outside a sequence of drawing commands,
  1362 since it negates any user defined clipping regions.
  1363 */
  1364 void CPlaybackGc::SetTargetRegion(const TRegion* aRegion)
  1365 	{
  1366 	iTargetRegion = aRegion;
  1367 	iDrawRegion = iTargetRegion;
  1368 	CancelUserClippingRegion();
  1369 	}
  1370 	
  1371 void CPlaybackGc::Reset()
  1372 	{
  1373 	iGc->Reset();
  1374 	}
  1375 
  1376 TAny * CPlaybackGc::ResolveObjectInterface(TUint aId)
  1377 	{
  1378 	switch (aId)
  1379 		{
  1380 	    case MWsSurfacePlacement::EWsObjectInterfaceId:
  1381 	        return static_cast<MWsSurfacePlacement *>(this); //deprecated
  1382 		case MWsWindow::EWsObjectInterfaceId:
  1383 			return dynamic_cast<MWsWindow *>(iWin);
  1384 		case MWsGraphicsContext::EWsObjectInterfaceId:
  1385 			return static_cast<MWsGraphicsContext*>(iGc);
  1386 		case MWsUiBuffer::EWsObjectInterfaceId:
  1387 		case MWsFader::EWsObjectInterfaceId:	
  1388 			return iWin->Screen()->ResolveObjectInterface(aId);
  1389 		}
  1390 	return NULL;
  1391 	}