windowing/windowserver/nga/SERVER/openwfc/gc.cpp
changeset 0 5d03bc08d59c
child 19 bbf46f59e123
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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 <e32std.h>
       
    19 #include <s32mem.h> 
       
    20 #include "gc.h"
       
    21 #include "backedupwindow.h"
       
    22 #include "windowgroup.h"
       
    23 #include "ScrDev.H"
       
    24 #include "wstop.h"
       
    25 #include "panics.h"
       
    26 #include "Graphics/WSGRAPHICDRAWER.H"
       
    27 #include "wsfont.h"
       
    28 
       
    29 class TPlacedAttributes;
       
    30 
       
    31 CFbsBitmap *CWsGc::iScratchBitmap=NULL;
       
    32 CFbsBitmap *CWsGc::iScratchMaskBitmap=NULL;
       
    33 
       
    34 GLREF_C TInt ExternalizeRegionL(RWriteStream& aWriteStream, const RWsRegion& aRegion);
       
    35 
       
    36 /*CWsGc*/
       
    37 
       
    38 CWsGc* CWsGc::NewL(CWsClient *aOwner)	
       
    39 	{
       
    40 	CWsGc* self = new(ELeave) CWsGc(aOwner);
       
    41 	CleanupStack::PushL(self);
       
    42 	self->ConstructL();
       
    43 	CleanupStack::Pop(self);
       
    44 	return self;
       
    45 	}
       
    46 
       
    47 void CWsGc::InitStaticsL()
       
    48 	{
       
    49 	iScratchBitmap=new(ELeave) CFbsBitmap();
       
    50 	iScratchMaskBitmap=new(ELeave) CFbsBitmap();
       
    51 	}
       
    52 
       
    53 void CWsGc::DeleteStatics()
       
    54 	{
       
    55 	delete iScratchBitmap;
       
    56 	delete iScratchMaskBitmap;
       
    57 	}
       
    58 
       
    59 CWsGc::CWsGc(CWsClient *owner) : CWsObject(owner,WS_HANDLE_GC)
       
    60 	{
       
    61 	__DECLARE_NAME(_S("CWsGc"));
       
    62 	}
       
    63 
       
    64 void CWsGc::ConstructL()
       
    65 	{
       
    66 	NewObjL();
       
    67 	iBackedUpWinGc=CFbsBitGc::NewL();
       
    68 	iInternalStatus.ResetInternalStatus(iWin);
       
    69 	}
       
    70 
       
    71 void CWsGc::Activate(CWsClientWindow *win)
       
    72 	{
       
    73 	if (iWin!=NULL)
       
    74 		{
       
    75 		if (CWsClient::iCurrentCommand.iOpcode==0)
       
    76 			{
       
    77 			WS_PANIC_ALWAYS(EWsPanicDrawCommandsInvalidState);
       
    78 			}
       
    79 		else
       
    80 			{
       
    81 			OwnerPanic(EWservPanicGcActive);
       
    82 			}
       
    83 		}
       
    84 
       
    85 	iWin = win;
       
    86 	if (iWin->Redraw()->OutputDevice()) // Activated on a backed up window
       
    87 		iBackedUpWinGc->ActivateNoJustAutoUpdate(iWin->Redraw()->OutputDevice());
       
    88 	iWin->GcActivated(this);
       
    89 	iInternalStatus.iBrushColor = iWin->BackColor();
       
    90 	if (iWin->Redraw()->OutputDevice())
       
    91 		iBackedUpWinGc->SetBrushColor(iInternalStatus.iBrushColor);
       
    92 	iOrigin.SetXY(0,0);
       
    93 	ResetClippingRect();
       
    94 	if(iWsOwner)
       
    95 		{
       
    96 		CWsWindowGroup *winGp = iWin->WinGroup();
       
    97 		if(!winGp->Device())
       
    98 			OwnerPanic(EWservPanicGroupWinScreenDeviceDeleted);		
       
    99 		SetReply(winGp->Device()->ClientDevicePointer());			
       
   100 		}	
       
   101 	}
       
   102 
       
   103 void CWsGc::Activate(const TInt &aHandle)
       
   104 	{
       
   105 	CWsClientWindow *win;
       
   106 	iWsOwner->HandleToClientWindow(aHandle,&win);
       
   107 	if (!win->BaseParent())
       
   108 		OwnerPanic(EWservPanicParentDeleted);
       
   109 	Activate(win);
       
   110 	}
       
   111 
       
   112 void CWsGc::Reactivate()
       
   113 	{
       
   114 	WS_ASSERT_DEBUG(iWin != NULL, EWsPanicDrawCommandsInvalidState);
       
   115 	if (iWin->Redraw()->OutputDevice()) // Activated on a backed up window
       
   116 		iBackedUpWinGc->ActivateNoJustAutoUpdate(iWin->Redraw()->OutputDevice());
       
   117 	}
       
   118 
       
   119 CWsGc::~CWsGc()
       
   120 	{
       
   121 	if (iWin!=NULL)
       
   122 		Deactivate();
       
   123 	delete iBackedUpWinGc;
       
   124 	delete iPolyPoints;
       
   125 	}
       
   126 
       
   127 void CWsGc::Deactivate()
       
   128 	{
       
   129 	if (iWin)	// Protect against deactivating an already deactivated GC, this is allowed to aid clean up code.
       
   130 		{
       
   131 		CWsFontCache::Instance()->ReleaseFont(iFont);
       
   132 		iBackedUpWinGc->Reset();
       
   133 		iInternalStatus.ResetInternalStatus(iWin);
       
   134 		iWin->GcDeactivated(this);
       
   135 		CancelClippingRegion();
       
   136 		iWin->Redraw()->GcDeactivate(this);
       
   137 		iWin=NULL;
       
   138 		}
       
   139 	}
       
   140 
       
   141 void CWsGc::SetClippingRect(const TRect &aRect)
       
   142 	{
       
   143 	iClippingRect=aRect;
       
   144 	iClippingRect.Move(iOrigin);
       
   145 	iClippingRectSet=ETrue;
       
   146 	}
       
   147 
       
   148 void CWsGc::ResetClippingRect()
       
   149 	{
       
   150 	iClippingRectSet=EFalse;
       
   151 	}
       
   152 
       
   153 void CWsGc::SetClippingRegionL(TInt aRegionCount)
       
   154 	{
       
   155 	RWsRegion *newRegion=GetRegionFromClientL(iWsOwner, aRegionCount);
       
   156 	CancelClippingRegion();
       
   157 	iUserDefinedClippingRegion=newRegion;
       
   158 
       
   159 	if (iUserDefinedClippingRegion)
       
   160 		{
       
   161 		iUserDefinedClippingRegion->Offset(iOrigin);
       
   162 		}
       
   163 	}
       
   164 
       
   165 void CWsGc::CancelClippingRegion()
       
   166 	{
       
   167 	if (iUserDefinedClippingRegion)
       
   168 		{
       
   169 		iUserDefinedClippingRegion->Destroy();
       
   170 		iUserDefinedClippingRegion=NULL;
       
   171 		}
       
   172 	}
       
   173 
       
   174 void CWsGc::CheckPolyData(const TAny* aDataPtr, TInt aHeaderSize, TInt aNumPoints)
       
   175 	{
       
   176 	TInt maxDataLen;
       
   177 	if (CWsClient::iCurrentCommand.iOpcode>0)
       
   178 		{
       
   179 		maxDataLen=CWsClient::EndOfCommandBuffer()-static_cast<const TUint8*>(aDataPtr);
       
   180 		}
       
   181 	else	// Playing back from redraw store??
       
   182 		{
       
   183 		maxDataLen=CWsClient::iCurrentCommand.iCmdLength;
       
   184 		}
       
   185 	const TInt dataSize=aHeaderSize+aNumPoints*sizeof(TPoint);
       
   186 	if (dataSize>maxDataLen)
       
   187 		GcOwnerPanic(EWservPanicBadPolyData);
       
   188 	}
       
   189 
       
   190 void CWsGc::DoDrawPolygon(const TWsGcCmdDrawPolygon *aDrawPolygon)
       
   191 	{
       
   192 	CheckPolyData(aDrawPolygon,sizeof(TWsGcCmdDrawPolygon),aDrawPolygon->numPoints);
       
   193 	iBackedUpWinGc->DrawPolygon((TPoint *)(aDrawPolygon+1),aDrawPolygon->numPoints,aDrawPolygon->fillRule);
       
   194 	}
       
   195 
       
   196 void CWsGc::StartSegmentedDrawPolygonL(const TWsGcCmdStartSegmentedDrawPolygon* aDrawPolygon)
       
   197 	{
       
   198 	WS_ASSERT_DEBUG(iWin->Redraw()->OutputDevice(), EWsPanicWindowType);
       
   199 	if (iPolyPoints || !Rng(0, aDrawPolygon->totalNumPoints, KMaxTInt/2 - 1))	// Restarting without finishing old polygon or invalid size
       
   200 		GcOwnerPanic(EWservPanicBadPolyData);
       
   201 	iPolyPoints=(TPoint *)User::AllocL(aDrawPolygon->totalNumPoints*sizeof(TPoint));
       
   202 	iPolyPointListSize=aDrawPolygon->totalNumPoints;
       
   203 	}
       
   204 
       
   205 void CWsGc::SegmentedDrawPolygonData(const TWsGcCmdSegmentedDrawPolygonData* aDrawPolygon)
       
   206 	{
       
   207 	WS_ASSERT_DEBUG(iWin->Redraw()->OutputDevice(), EWsPanicWindowType);
       
   208 	if (aDrawPolygon->index<0 || (aDrawPolygon->index+aDrawPolygon->numPoints)>iPolyPointListSize)
       
   209 		GcOwnerPanic(EWservPanicBadPolyData);
       
   210 	Mem::Copy(iPolyPoints+aDrawPolygon->index,aDrawPolygon+1,aDrawPolygon->numPoints*sizeof(TPoint));
       
   211 	}
       
   212 
       
   213 void CWsGc::EndSegmentedPolygon()
       
   214 	{
       
   215 	delete iPolyPoints;
       
   216 	iPolyPoints=NULL;
       
   217 	iPolyPointListSize = 0;
       
   218 	}
       
   219 
       
   220 void CWsGc::DoDrawPolyLine(const TWsGcCmdDrawPolyLine *aDrawPolyLine, TBool aContinued)
       
   221 	{
       
   222 	TInt numPoints=aDrawPolyLine->numPoints;
       
   223 	CheckPolyData(aDrawPolyLine,sizeof(TWsGcCmdDrawPolyLine),numPoints);
       
   224 	const TPoint *points=(TPoint *)(aDrawPolyLine+1);
       
   225 	if (aContinued)
       
   226 		{
       
   227 		numPoints++;
       
   228 		points=&aDrawPolyLine->last;
       
   229 		}
       
   230 	if (aDrawPolyLine->more)	// more to come so don't draw the end point
       
   231 		iBackedUpWinGc->DrawPolyLineNoEndPoint(points,numPoints);
       
   232 	else
       
   233 		iBackedUpWinGc->DrawPolyLine(points,numPoints);
       
   234 	}
       
   235 
       
   236 void CWsGc::GcOwnerPanic(TClientPanic aPanic)
       
   237 	{
       
   238 	iBackedUpWinGc->SetClippingRegion(NULL);
       
   239 	EndSegmentedPolygon();
       
   240 	iWin->WsOwner()->PPanic(aPanic);
       
   241 	}
       
   242 	
       
   243 TPtrC CWsGc::BufferTPtr(TText* aStart,TInt aLen)
       
   244 	{
       
   245 	TPtrC gcPtr;
       
   246 	if (!CWsClient::BufferTPtrGc(aStart,aLen,gcPtr))
       
   247 		GcOwnerPanic(EWservPanicBufferPtr);
       
   248 	return(gcPtr);
       
   249 	}
       
   250 
       
   251 void CWsGc::DoDrawCommand(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData)
       
   252 	{
       
   253 	WS_ASSERT_DEBUG(iWin,EWsPanicWindowNull);
       
   254 	WS_ASSERT_DEBUG(iWin->Redraw()->OutputDevice(), EWsPanicWindowType); // Must be activated on a backed up window
       
   255 
       
   256 	if (iUserDefinedClippingRegion)
       
   257 		{
       
   258 		if (iUserDefinedClippingRegion->Count()==0)
       
   259 			return;
       
   260 		if (iUserDefinedClippingRegion->IsContainedBy(TRect(TPoint(0,0), iBackedUpWinGc->Device()->SizeInPixels())))
       
   261 			{
       
   262 			iBackedUpWinGc->SetClippingRegion(iUserDefinedClippingRegion);
       
   263 			}
       
   264 		}
       
   265 	CGraphicsContext::TTextParameters contextParam;
       
   266 	switch(aOpcode)
       
   267 		{
       
   268 		case EWsGcOpDrawWsGraphic:
       
   269 		case EWsGcOpDrawWsGraphicPtr:
       
   270 			{
       
   271 			// CWsGc doesn't support CRPs.  CPlaybackGc does.  This means backedup windows
       
   272 			// don't get to play with them yet.
       
   273 			break;
       
   274 			}
       
   275 		case EWsGcOpMapColorsLocal:
       
   276 			GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
       
   277 			break;
       
   278 		case EWsGcOpDrawPolyLineLocalBufLen:
       
   279 			iBackedUpWinGc->DrawPolyLine(pData.DrawPolyLineLocalBufLen->points,pData.DrawPolyLineLocalBufLen->length);
       
   280 			break;
       
   281 		case EWsGcOpDrawPolyLineLocal:
       
   282 			iBackedUpWinGc->DrawPolyLine(pData.PointList);
       
   283 			break;
       
   284 		case EWsGcOpDrawPolygonLocalBufLen:
       
   285 			iBackedUpWinGc->DrawPolygon(pData.DrawPolygonLocalBufLen->points,pData.DrawPolygonLocalBufLen->length,pData.DrawPolygonLocalBufLen->fillRule);
       
   286 			break;
       
   287 		case EWsGcOpDrawPolygonLocal:
       
   288 			iBackedUpWinGc->DrawPolygon(pData.DrawPolygonLocal->pointList,pData.DrawPolygonLocal->fillRule);
       
   289 			break;
       
   290 		case EWsGcOpDrawBitmapLocal:
       
   291 			iBackedUpWinGc->DrawBitmap(pData.BitmapLocal->pos, pData.BitmapLocal->bitmap);
       
   292 			break;
       
   293 		case EWsGcOpDrawBitmap2Local:
       
   294 			iBackedUpWinGc->DrawBitmap(pData.Bitmap2Local->rect, pData.Bitmap2Local->bitmap);
       
   295 			break;
       
   296 		case EWsGcOpDrawBitmap3Local:
       
   297 			iBackedUpWinGc->DrawBitmap(pData.Bitmap3Local->rect, pData.Bitmap3Local->bitmap, pData.Bitmap3Local->srcRect);
       
   298 			break;
       
   299 		case EWsGcOpDrawBitmapMaskedLocal:
       
   300 			iBackedUpWinGc->DrawBitmapMasked(pData.iBitmapMaskedLocal->iRect, pData.iBitmapMaskedLocal->iBitmap, pData.iBitmapMaskedLocal->iSrcRect, pData.iBitmapMaskedLocal->iMaskBitmap,pData.iBitmapMaskedLocal->iInvertMask);
       
   301 			break;
       
   302 		case EWsGcOpAlphaBlendBitmapsLocal:
       
   303 			iBackedUpWinGc->AlphaBlendBitmaps(pData.AlphaBlendBitmapsLocal->point,pData.AlphaBlendBitmapsLocal->iBitmap,
       
   304 						   			pData.AlphaBlendBitmapsLocal->source, pData.AlphaBlendBitmapsLocal->iAlpha,
       
   305 									pData.AlphaBlendBitmapsLocal->alphaPoint);
       
   306 
       
   307 			break;
       
   308 		case EWsGcOpDrawText:
       
   309 			iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.DrawText+1),pData.DrawText->length),pData.DrawText->pos);
       
   310 			break;
       
   311 		case EWsGcOpDrawBoxTextOptimised1:
       
   312 			iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length),pData.BoxTextO1->box,
       
   313 							pData.BoxTextO1->baselineOffset,CGraphicsContext::ELeft,0);
       
   314 			break;
       
   315 		case EWsGcOpDrawBoxTextOptimised2:
       
   316 			iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length),pData.BoxTextO2->box,
       
   317 							pData.BoxTextO2->baselineOffset,pData.BoxTextO2->horiz,pData.BoxTextO2->leftMrg);
       
   318 			break;
       
   319 		case EWsGcOpDrawTextPtr:
       
   320 			iBackedUpWinGc->DrawText(*pData.DrawTextPtr->text,pData.DrawTextPtr->pos);
       
   321 			break;
       
   322 		case EWsGcOpDrawTextPtr1:
       
   323 		   	iBackedUpWinGc->DrawText(*pData.DrawTextPtr->text);
       
   324 			break;
       
   325 		case EWsGcOpDrawBoxText:
       
   326 			iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.BoxText+1),pData.BoxText->length),pData.BoxText->box,pData.BoxText->baselineOffset,pData.BoxText->width,pData.BoxText->horiz,pData.BoxText->leftMrg);
       
   327 			break;
       
   328 		case EWsGcOpDrawBoxTextPtr:
       
   329 			iBackedUpWinGc->DrawText(*pData.DrawBoxTextPtr->text,pData.DrawBoxTextPtr->box,pData.DrawBoxTextPtr->baselineOffset,pData.DrawBoxTextPtr->width,pData.DrawBoxTextPtr->horiz,pData.DrawBoxTextPtr->leftMrg);
       
   330 			break;
       
   331 		case EWsGcOpDrawBoxTextPtr1:
       
   332 			iBackedUpWinGc->DrawText(*pData.DrawBoxTextPtr->text,pData.DrawBoxTextPtr->box);
       
   333 			break;
       
   334 		case EWsGcOpDrawTextVertical:
       
   335 			iBackedUpWinGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length),pData.DrawTextVertical->pos
       
   336 							,pData.DrawTextVertical->up);
       
   337 			break;
       
   338 		case EWsGcOpDrawTextVerticalPtr:
       
   339 			iBackedUpWinGc->DrawTextVertical(*pData.DrawTextVerticalPtr->text,pData.DrawTextVerticalPtr->pos,pData.DrawTextVerticalPtr->up);
       
   340 			break;
       
   341 		case EWsGcOpDrawTextVerticalPtr1:
       
   342 			iBackedUpWinGc->DrawTextVertical(*pData.DrawTextVerticalPtr->text,pData.DrawTextVerticalPtr->up);
       
   343 			break;
       
   344 		case EWsGcOpDrawBoxTextVertical:
       
   345 			iBackedUpWinGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length),
       
   346 							pData.DrawBoxTextVertical->box,	pData.DrawBoxTextVertical->baselineOffset,
       
   347 							pData.DrawBoxTextVertical->up,(CGraphicsContext::TTextAlign)pData.DrawBoxTextVertical->vert,pData.DrawBoxTextVertical->margin);
       
   348 			break;
       
   349 		case EWsGcOpDrawBoxTextVerticalPtr:
       
   350 			iBackedUpWinGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->baselineOffset
       
   351 							,pData.DrawBoxTextVerticalPtr->width,pData.DrawBoxTextVerticalPtr->up,pData.DrawBoxTextVerticalPtr->vert,pData.DrawBoxTextVerticalPtr->margin);
       
   352 			break;
       
   353 		case EWsGcOpDrawBoxTextVerticalPtr1:
       
   354 			iBackedUpWinGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->up);
       
   355 			break;
       
   356 		case EWsGcOpDrawTextLocal:
       
   357 			iBackedUpWinGc->DrawText(*pData.DrawTextLocal->desc,pData.DrawTextLocal->pos);
       
   358 			break;
       
   359 		case EWsGcOpDrawBoxTextLocal:
       
   360 			iBackedUpWinGc->DrawText(*pData.BoxTextLocal->desc,pData.BoxTextLocal->box,pData.BoxTextLocal->baselineOffset,
       
   361 							pData.BoxTextLocal->horiz,pData.BoxTextLocal->leftMrg);
       
   362 			break;
       
   363 		/************* DrawText in Context function calls*********************************************/
       
   364 		case EWsGcOpDrawTextInContext:
       
   365 			contextParam.iStart = pData.DrawTextInContext->start;
       
   366 			contextParam.iEnd = pData.DrawTextInContext->end;
       
   367 			if(contextParam.iStart < contextParam.iEnd)
       
   368 				{
       
   369 				iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.DrawTextInContext+1),pData.DrawTextInContext->length),&contextParam,pData.DrawTextInContext->pos);
       
   370 				}
       
   371 			else
       
   372 				{
       
   373 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   374 				}
       
   375 			break;
       
   376 		case EWsGcOpDrawBoxTextInContextOptimised1:
       
   377 			contextParam.iStart = pData.BoxTextInContextO1->start;
       
   378 			contextParam.iEnd = pData.BoxTextInContextO1->end;
       
   379 			if(contextParam.iStart < contextParam.iEnd)
       
   380 				{
       
   381 				iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContextO1+1),pData.BoxTextInContextO1->length),&contextParam,pData.BoxTextInContextO1->box,
       
   382 						pData.BoxTextInContextO1->baselineOffset,CGraphicsContext::ELeft,0);
       
   383 				}
       
   384 			else
       
   385 				{
       
   386 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   387 				}
       
   388 			break;
       
   389 		case EWsGcOpDrawBoxTextInContextOptimised2:
       
   390 			contextParam.iStart = pData.BoxTextInContextO2->start;
       
   391 			contextParam.iEnd = pData.BoxTextInContextO2->end;
       
   392 			if(contextParam.iStart < contextParam.iEnd)
       
   393 				{
       
   394 				iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContextO2+1),pData.BoxTextInContextO2->length),&contextParam,pData.BoxTextInContextO2->box,
       
   395 						pData.BoxTextInContextO2->baselineOffset,pData.BoxTextInContextO2->horiz,pData.BoxTextInContextO2->leftMrg);
       
   396 				}
       
   397 			else
       
   398 				{
       
   399 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   400 				}
       
   401 			break;
       
   402 		case EWsGcOpDrawTextInContextPtr:
       
   403 			contextParam.iStart = pData.DrawTextInContextPtr->start;
       
   404 			contextParam.iEnd = pData.DrawTextInContextPtr->end;
       
   405 			if(contextParam.iStart < contextParam.iEnd)
       
   406 				{
       
   407 				iBackedUpWinGc->DrawText(*pData.DrawTextInContextPtr->text,&contextParam,pData.DrawTextInContextPtr->pos);
       
   408 				}
       
   409 			else
       
   410 				{
       
   411 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   412 				}
       
   413 			break;
       
   414 		case EWsGcOpDrawTextInContextPtr1:
       
   415 			contextParam.iStart = pData.DrawTextInContextPtr->start;
       
   416 			contextParam.iEnd = pData.DrawTextInContextPtr->end;
       
   417 			if(contextParam.iStart < contextParam.iEnd)
       
   418 				{
       
   419 				iBackedUpWinGc->DrawText(*pData.DrawTextInContextPtr->text,&contextParam);
       
   420 				}
       
   421 			else
       
   422 				{
       
   423 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   424 				}
       
   425 			break;
       
   426 		case EWsGcOpDrawBoxTextInContext:
       
   427 			contextParam.iStart = pData.BoxTextInContext->start;
       
   428 			contextParam.iEnd = pData.BoxTextInContext->end;
       
   429 			if(contextParam.iStart < contextParam.iEnd)
       
   430 				{
       
   431 				iBackedUpWinGc->DrawText(BufferTPtr((TText *)(pData.BoxTextInContext+1),pData.BoxTextInContext->length),&contextParam,
       
   432 						pData.BoxTextInContext->box,pData.BoxTextInContext->baselineOffset,pData.BoxTextInContext->width,pData.BoxTextInContext->horiz,pData.BoxTextInContext->leftMrg);
       
   433 				}
       
   434 			else
       
   435 				{
       
   436 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   437 				}
       
   438 			break;
       
   439 		case EWsGcOpDrawBoxTextInContextPtr:
       
   440 			contextParam.iStart = pData.DrawBoxTextInContextPtr->start;
       
   441 			contextParam.iEnd = pData.DrawBoxTextInContextPtr->end;
       
   442 			if(contextParam.iStart < contextParam.iEnd)
       
   443 				{
       
   444 				iBackedUpWinGc->DrawText(*pData.DrawBoxTextInContextPtr->text,&contextParam,pData.DrawBoxTextInContextPtr->box,pData.DrawBoxTextInContextPtr->baselineOffset,pData.DrawBoxTextInContextPtr->width,pData.DrawBoxTextInContextPtr->horiz,pData.DrawBoxTextInContextPtr->leftMrg);
       
   445 				}
       
   446 			else
       
   447 				{
       
   448 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   449 				}
       
   450 			break;
       
   451 		case EWsGcOpDrawBoxTextInContextPtr1:
       
   452 			contextParam.iStart = pData.DrawBoxTextInContextPtr->start;
       
   453 			contextParam.iEnd = pData.DrawBoxTextInContextPtr->end;
       
   454 			if(contextParam.iStart < contextParam.iEnd)
       
   455 				{
       
   456 				iBackedUpWinGc->DrawText(*pData.DrawBoxTextInContextPtr->text,&contextParam,pData.DrawBoxTextInContextPtr->box);
       
   457 				}
       
   458 			else
       
   459 				{
       
   460 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   461 				}
       
   462 			break;
       
   463 		case EWsGcOpDrawTextInContextVertical:
       
   464 			contextParam.iStart = pData.DrawTextInContextVertical->start;
       
   465 			contextParam.iEnd = pData.DrawTextInContextVertical->end;
       
   466 			if(contextParam.iStart < contextParam.iEnd)
       
   467 				{
       
   468 				iBackedUpWinGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawTextInContextVertical+1),pData.DrawTextInContextVertical->length),&contextParam,pData.DrawTextInContextVertical->pos
       
   469 						,pData.DrawTextInContextVertical->up);
       
   470 				}
       
   471 			else
       
   472 				{
       
   473 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   474 				}
       
   475 			break;
       
   476 		case EWsGcOpDrawTextInContextVerticalPtr:
       
   477 			contextParam.iStart = pData.DrawTextInContextVerticalPtr->start;
       
   478 			contextParam.iEnd = pData.DrawTextInContextVerticalPtr->end;
       
   479 			if(contextParam.iStart < contextParam.iEnd)
       
   480 				{
       
   481 				iBackedUpWinGc->DrawTextVertical(*pData.DrawTextInContextVerticalPtr->text,&contextParam,pData.DrawTextInContextVerticalPtr->pos,pData.DrawTextInContextVerticalPtr->up);
       
   482 				}
       
   483 			else
       
   484 				{
       
   485 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   486 				}
       
   487 			break;
       
   488 		case EWsGcOpDrawTextInContextVerticalPtr1:
       
   489 			contextParam.iStart = pData.DrawTextInContextVerticalPtr->start;
       
   490 			contextParam.iEnd = pData.DrawTextInContextVerticalPtr->end;
       
   491 			if(contextParam.iStart < contextParam.iEnd)
       
   492 				{
       
   493 				iBackedUpWinGc->DrawTextVertical(*pData.DrawTextInContextVerticalPtr->text,&contextParam,pData.DrawTextInContextVerticalPtr->up);
       
   494 				}
       
   495 			else
       
   496 				{
       
   497 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   498 				}
       
   499 			break;
       
   500 		case EWsGcOpDrawBoxTextInContextVertical:
       
   501 			contextParam.iStart = pData.DrawBoxTextInContextVertical->start;
       
   502 			contextParam.iEnd = pData.DrawBoxTextInContextVertical->end;
       
   503 			if(contextParam.iStart < contextParam.iEnd)
       
   504 				{
       
   505 				iBackedUpWinGc->DrawTextVertical(BufferTPtr((TText *)(pData.DrawBoxTextInContextVertical+1),pData.DrawBoxTextInContextVertical->length),&contextParam,
       
   506 						pData.DrawBoxTextInContextVertical->box,pData.DrawBoxTextInContextVertical->baselineOffset,
       
   507 						pData.DrawBoxTextInContextVertical->up,(CGraphicsContext::TTextAlign)pData.DrawBoxTextInContextVertical->vert,pData.DrawBoxTextInContextVertical->margin);
       
   508 				}
       
   509 			else
       
   510 				{
       
   511 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   512 				}
       
   513 			break;
       
   514 		case EWsGcOpDrawBoxTextInContextVerticalPtr:
       
   515 			contextParam.iStart = pData.DrawBoxTextInContextVerticalPtr->start;
       
   516 			contextParam.iEnd = pData.DrawBoxTextInContextVerticalPtr->end;
       
   517 			if(contextParam.iStart < contextParam.iEnd)
       
   518 				{
       
   519 				iBackedUpWinGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,&contextParam,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->baselineOffset
       
   520 						,pData.DrawBoxTextVerticalPtr->width,pData.DrawBoxTextVerticalPtr->up,pData.DrawBoxTextVerticalPtr->vert,pData.DrawBoxTextVerticalPtr->margin);
       
   521 				}
       
   522 			else
       
   523 				{
       
   524 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   525 				}
       
   526 			break;
       
   527 		case EWsGcOpDrawBoxTextInContextVerticalPtr1:
       
   528 			contextParam.iStart = pData.DrawBoxTextInContextVerticalPtr->start;
       
   529 			contextParam.iEnd = pData.DrawBoxTextInContextVerticalPtr->end;
       
   530 			if(contextParam.iStart < contextParam.iEnd)
       
   531 				{
       
   532 				iBackedUpWinGc->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,&contextParam,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->up);
       
   533 				}
       
   534 			else
       
   535 				{
       
   536 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   537 				}
       
   538 			break;
       
   539 		case EWsGcOpDrawTextInContextLocal:
       
   540 			contextParam.iStart = pData.DrawTextInContextLocal->start;
       
   541 			contextParam.iEnd = pData.DrawTextInContextLocal->end;
       
   542 			if(contextParam.iStart < contextParam.iEnd)
       
   543 				{
       
   544 				iBackedUpWinGc->DrawText(*pData.DrawTextInContextLocal->desc,&contextParam,pData.DrawTextInContextLocal->pos);
       
   545 				}
       
   546 			else
       
   547 				{
       
   548 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   549 				}
       
   550 			break;
       
   551 		case EWsGcOpDrawBoxTextInContextLocal:
       
   552 			contextParam.iStart = pData.BoxTextInContextLocal->start;
       
   553 			contextParam.iEnd = pData.BoxTextInContextLocal->end;
       
   554 			if(contextParam.iStart < contextParam.iEnd)
       
   555 				{
       
   556 				iBackedUpWinGc->DrawText(*pData.BoxTextInContextLocal->desc,pData.BoxTextInContextLocal->box,pData.BoxTextInContextLocal->baselineOffset,
       
   557 						pData.BoxTextInContextLocal->horiz,pData.BoxTextInContextLocal->leftMrg);
       
   558 				}
       
   559 			else
       
   560 				{
       
   561 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   562 				}
       
   563 			break;
       
   564 		case EWsGcOpDrawLine:
       
   565 			iBackedUpWinGc->DrawLine(pData.DrawLine->pnt1,pData.DrawLine->pnt2);
       
   566 			break;
       
   567 		case EWsGcOpDrawTo:
       
   568 			iBackedUpWinGc->DrawLine(iLinePos,*pData.Point);
       
   569 			break;
       
   570 		case EWsGcOpDrawBy:
       
   571 			iBackedUpWinGc->DrawLine(iLinePos,iLinePos+(*pData.Point));
       
   572 			break;
       
   573 		case EWsGcOpPlot:
       
   574 			iBackedUpWinGc->Plot(*pData.Point);
       
   575 			break;
       
   576 		case EWsGcOpMoveTo:
       
   577 		case EWsGcOpMoveBy:
       
   578 			break;
       
   579 		case EWsGcOpGdiBlt2Local:
       
   580 			iBackedUpWinGc->BitBlt(pData.GdiBlt2Local->pos,pData.GdiBlt2Local->bitmap);
       
   581 			break;
       
   582 		case EWsGcOpGdiBlt3Local:
       
   583 			iBackedUpWinGc->BitBlt(pData.GdiBlt3Local->pos,pData.GdiBlt3Local->bitmap, pData.GdiBlt3Local->rect);
       
   584 			break;
       
   585 		case EWsGcOpGdiBltMaskedLocal:
       
   586 			iBackedUpWinGc->BitBltMasked(pData.GdiBltMaskedLocal->pos,pData.GdiBltMaskedLocal->bitmap,
       
   587 								pData.GdiBltMaskedLocal->rect,pData.GdiBltMaskedLocal->maskBitmap,
       
   588 								pData.GdiBltMaskedLocal->invertMask);
       
   589 			break;
       
   590 		case EWsGcOpGdiWsBlt2:
       
   591 		case EWsGcOpGdiWsBlt3:
       
   592 		case EWsGcOpGdiWsBltMasked:
       
   593 		case EWsGcOpGdiWsAlphaBlendBitmaps:
       
   594 		case EWsGcOpWsDrawBitmapMasked:
       
   595 			{
       
   596 			CFbsBitmap* scratchBimap=iScratchBitmap;
       
   597 			CFbsBitmap* scratchMaskBimap=iScratchMaskBitmap;
       
   598 			TInt maskHandle=0;
       
   599 			TInt handle=WsBitmapHandle(aOpcode,pData, maskHandle);
       
   600 			CWsClient* owner=iWin->WsOwner(); // We can't just use iWsOwner - it can be null for stored commands
       
   601 			if (owner!=NULL)
       
   602 				{
       
   603 				DWsBitmap *bitmap=(DWsBitmap *)owner->HandleToObj(handle, WS_HANDLE_BITMAP);
       
   604 				if (!bitmap)
       
   605 					GcOwnerPanic(EWservPanicBitmap);
       
   606 				scratchBimap=bitmap->FbsBitmap();
       
   607 				if (aOpcode==EWsGcOpGdiWsBltMasked || aOpcode==EWsGcOpGdiWsAlphaBlendBitmaps || aOpcode==EWsGcOpWsDrawBitmapMasked)
       
   608 					{
       
   609 					DWsBitmap *bitmap2=(DWsBitmap *)owner->HandleToObj(maskHandle, WS_HANDLE_BITMAP);
       
   610 					if (!bitmap2)
       
   611 						GcOwnerPanic(EWservPanicBitmap);
       
   612 					scratchMaskBimap=bitmap2->FbsBitmap();
       
   613 					}
       
   614 				}
       
   615 			else 
       
   616 				{
       
   617 				GcOwnerPanic(EWservPanicBitmap);
       
   618 				}
       
   619 			switch(aOpcode)
       
   620 				{
       
   621 				case EWsGcOpGdiWsBlt2:
       
   622 					iBackedUpWinGc->BitBlt(pData.GdiBlt2->pos,scratchBimap);
       
   623 					break;
       
   624 				case EWsGcOpGdiWsBlt3:
       
   625 					iBackedUpWinGc->BitBlt(pData.GdiBlt3->pos,scratchBimap, pData.GdiBlt3->rect);
       
   626 					break;
       
   627 				case EWsGcOpGdiWsBltMasked:
       
   628 					{
       
   629 					iBackedUpWinGc->BitBltMasked(pData.GdiBltMasked->destination,scratchBimap,
       
   630 									pData.GdiBltMasked->source, scratchMaskBimap,
       
   631 									pData.GdiBltMasked->invertMask);
       
   632 					}
       
   633 					break;
       
   634 				case EWsGcOpGdiWsAlphaBlendBitmaps:
       
   635 					{
       
   636 					iBackedUpWinGc->AlphaBlendBitmaps(pData.AlphaBlendBitmaps->point,scratchBimap,
       
   637 									   pData.AlphaBlendBitmaps->source, scratchMaskBimap,
       
   638 									   pData.AlphaBlendBitmaps->alphaPoint);
       
   639 					}
       
   640 					break;
       
   641 				case EWsGcOpWsDrawBitmapMasked:
       
   642 					{
       
   643 					iBackedUpWinGc->DrawBitmapMasked(pData.iBitmapMasked->iRect,scratchBimap, 
       
   644 										pData.iBitmapMasked->iSrcRect,scratchMaskBimap,
       
   645 										pData.iBitmapMasked->iInvertMask);
       
   646 					}
       
   647 					break;
       
   648 				}
       
   649 			break;
       
   650 			}
       
   651 		case EWsGcOpGdiBlt2:
       
   652 		case EWsGcOpGdiBlt3:
       
   653 		case EWsGcOpGdiBltMasked:
       
   654 		case EWsGcOpGdiAlphaBlendBitmaps:
       
   655 		case EWsGcOpDrawBitmap:
       
   656 		case EWsGcOpDrawBitmap2:
       
   657 		case EWsGcOpDrawBitmap3:
       
   658 		case EWsGcOpDrawBitmapMasked:
       
   659 			{
       
   660 			TInt maskHandle=0;
       
   661 			TInt ret = iScratchBitmap->Duplicate(FbsBitmapHandle(aOpcode, pData,maskHandle));
       
   662 			if(ret == KErrNoMemory)
       
   663 				break;	
       
   664 			if (ret !=KErrNone)
       
   665 				GcOwnerPanic(EWservPanicBitmap);
       
   666 			
       
   667 			switch(aOpcode)
       
   668 				{
       
   669 				case EWsGcOpGdiBlt2:
       
   670 					iBackedUpWinGc->BitBlt(pData.GdiBlt2->pos,iScratchBitmap);
       
   671 					break;
       
   672 				case EWsGcOpGdiBlt3:
       
   673 					iBackedUpWinGc->BitBlt(pData.GdiBlt3->pos,iScratchBitmap, pData.GdiBlt3->rect);
       
   674 					break;
       
   675 				case EWsGcOpGdiBltMasked:
       
   676 					{
       
   677 					TInt ret = iScratchMaskBitmap->Duplicate(pData.GdiBltMasked->maskHandle);
       
   678 					if(ret == KErrNoMemory)
       
   679 						break;	
       
   680 					if (ret !=KErrNone)
       
   681 						GcOwnerPanic(EWservPanicBitmap);
       
   682 			
       
   683 					iBackedUpWinGc->BitBltMasked(pData.GdiBltMasked->destination,iScratchBitmap,
       
   684 										pData.GdiBltMasked->source, iScratchMaskBitmap,
       
   685 										 pData.GdiBltMasked->invertMask);
       
   686 					iScratchMaskBitmap->Reset();
       
   687 					}
       
   688 					break;
       
   689 				case EWsGcOpGdiAlphaBlendBitmaps:
       
   690 					{
       
   691 					TInt ret = iScratchMaskBitmap->Duplicate(pData.AlphaBlendBitmaps->alphaHandle);
       
   692 					if (ret == KErrNoMemory)
       
   693 						break;	
       
   694 					if (ret != KErrNone)
       
   695 						GcOwnerPanic(EWservPanicBitmap);
       
   696 
       
   697 					iBackedUpWinGc->AlphaBlendBitmaps(pData.AlphaBlendBitmaps->point, iScratchBitmap,
       
   698 									   pData.AlphaBlendBitmaps->source, iScratchMaskBitmap,
       
   699 									   pData.AlphaBlendBitmaps->alphaPoint);
       
   700 					iScratchMaskBitmap->Reset();
       
   701 					break;
       
   702 					}
       
   703 				case EWsGcOpDrawBitmap:
       
   704 					iBackedUpWinGc->DrawBitmap(pData.Bitmap->pos, iScratchBitmap);
       
   705 					break;
       
   706 				case EWsGcOpDrawBitmap2:
       
   707 					iBackedUpWinGc->DrawBitmap(pData.Bitmap2->rect, iScratchBitmap);
       
   708 					break;
       
   709 				case EWsGcOpDrawBitmap3:
       
   710 					iBackedUpWinGc->DrawBitmap(pData.Bitmap3->rect, iScratchBitmap, pData.Bitmap3->srcRect);
       
   711 					break;
       
   712 				case EWsGcOpDrawBitmapMasked:
       
   713 					{
       
   714 					TInt ret = iScratchMaskBitmap->Duplicate(pData.iBitmapMasked->iMaskHandle);
       
   715 					if (ret == KErrNoMemory)
       
   716 						break;	
       
   717 					if (ret != KErrNone)
       
   718 						GcOwnerPanic(EWservPanicBitmap);
       
   719 
       
   720 					iBackedUpWinGc->DrawBitmapMasked(pData.iBitmapMasked->iRect, iScratchBitmap, 
       
   721 										pData.iBitmapMasked->iSrcRect, iScratchMaskBitmap,
       
   722 										pData.iBitmapMasked->iInvertMask);
       
   723 					iScratchMaskBitmap->Reset();
       
   724 					}
       
   725 					break;
       
   726 				}
       
   727 			iScratchBitmap->Reset();
       
   728 			break;
       
   729 			}
       
   730 		case EWsGcOpDrawSegmentedPolygon:
       
   731 			iBackedUpWinGc->DrawPolygon(iPolyPoints,iPolyPointListSize,pData.DrawSegmentedPolygon->fillRule);
       
   732 			break;
       
   733 		case EWsGcOpDrawPolygon:
       
   734 			DoDrawPolygon(pData.Polygon);
       
   735 			break;
       
   736 		case EWsGcOpDrawPolyLine:
       
   737 			DoDrawPolyLine(pData.PolyLine, EFalse);
       
   738 			break;
       
   739 		case EWsGcOpDrawPolyLineContinued:
       
   740 			DoDrawPolyLine(pData.PolyLine, ETrue);
       
   741 			break;
       
   742 		case EWsGcOpClear:
       
   743 			iBackedUpWinGc->Clear(TRect(iWin->Size()));
       
   744 			break;
       
   745 		case EWsGcOpClearRect:
       
   746 			iBackedUpWinGc->Clear(*pData.Rect);
       
   747 			break;
       
   748 		case EWsGcOpDrawRect:
       
   749 			iBackedUpWinGc->DrawRect(*pData.Rect);
       
   750 			break;
       
   751 		case EWsGcOpDrawEllipse:
       
   752 			iBackedUpWinGc->DrawEllipse(*pData.Rect);
       
   753 			break;
       
   754 		case EWsGcOpDrawRoundRect:
       
   755 			iBackedUpWinGc->DrawRoundRect(*pData.Rect,pData.RoundRect->ellipse);
       
   756 			break;
       
   757 		case EWsGcOpDrawArc:
       
   758 			iBackedUpWinGc->DrawArc(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
       
   759 			break;
       
   760 		case EWsGcOpDrawPie:
       
   761 			iBackedUpWinGc->DrawPie(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
       
   762 			break;
       
   763 		case EWsGcOpCopyRect:
       
   764 			iBackedUpWinGc->CopyRect(pData.CopyRect->pos,*pData.Rect);
       
   765 			break;
       
   766 		case EWsGcOpMapColors:
       
   767 			GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
       
   768 			break;
       
   769 			
       
   770 		default:
       
   771 			GcOwnerPanic(EWservPanicOpcode);
       
   772 		}
       
   773 	iBackedUpWinGc->SetClippingRegion(NULL);
       
   774 	}
       
   775 
       
   776 TInt CWsGc::WsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle) 
       
   777 	{
       
   778 	TInt handle=0;
       
   779 	switch(aOpcode)
       
   780 		{
       
   781 		case EWsGcOpGdiWsBlt2:
       
   782 			handle=pData.GdiBlt2->handle;
       
   783 			break;
       
   784 		case EWsGcOpGdiWsBlt3:
       
   785 			handle=pData.GdiBlt3->handle;
       
   786 			break;
       
   787 		case EWsGcOpGdiWsBltMasked:
       
   788 			handle=pData.GdiBltMasked->handle;
       
   789 			aMaskHandle = pData.GdiBltMasked->maskHandle;
       
   790 			break;
       
   791 		case EWsGcOpGdiWsAlphaBlendBitmaps:
       
   792 			handle=pData.AlphaBlendBitmaps->bitmapHandle;
       
   793 			aMaskHandle = pData.AlphaBlendBitmaps->alphaHandle;
       
   794 			break;
       
   795 		case EWsGcOpWsDrawBitmapMasked:
       
   796 			handle=pData.iBitmapMasked->iHandle;
       
   797 			aMaskHandle=pData.iBitmapMasked->iMaskHandle;
       
   798 			break;
       
   799 		default:
       
   800 			OwnerPanic(EWservPanicOpcode);
       
   801 		}
       
   802 	return handle;
       
   803 	}		
       
   804 
       
   805 TInt CWsGc::FbsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle)
       
   806 	{
       
   807 	TInt handle=0;
       
   808 	aMaskHandle=0;
       
   809 	switch(aOpcode)
       
   810 		{
       
   811 		case EWsGcOpGdiBlt2:
       
   812 			handle=pData.GdiBlt2->handle;
       
   813 			break;
       
   814 		case EWsGcOpGdiBlt3:
       
   815 			handle=pData.GdiBlt3->handle;
       
   816 			break;
       
   817 		case EWsGcOpGdiBltMasked:
       
   818 			handle=pData.GdiBltMasked->handle;
       
   819 			aMaskHandle=pData.GdiBltMasked->maskHandle;
       
   820 			break;
       
   821 		case EWsGcOpGdiAlphaBlendBitmaps:
       
   822 			handle=pData.AlphaBlendBitmaps->bitmapHandle;
       
   823 			aMaskHandle=pData.AlphaBlendBitmaps->alphaHandle;
       
   824 			break;
       
   825 		case EWsGcOpDrawBitmap:
       
   826 			handle=pData.Bitmap->handle;
       
   827 			break;
       
   828 		case EWsGcOpDrawBitmap2:
       
   829 			handle=pData.Bitmap2->handle;
       
   830 			break;
       
   831 		case EWsGcOpDrawBitmap3:
       
   832 			handle=pData.Bitmap3->handle;
       
   833 			break;
       
   834 		case EWsGcOpDrawBitmapMasked:
       
   835 			handle=pData.iBitmapMasked->iHandle;
       
   836 			aMaskHandle=pData.iBitmapMasked->iMaskHandle;
       
   837 			break;
       
   838 		default:
       
   839 			OwnerPanic(EWservPanicOpcode);
       
   840 		}
       
   841 	return handle;
       
   842 	}
       
   843 
       
   844 TInt CWsGc::WsDrawableSourceHandle(TInt aOpcode, const TWsGcCmdUnion &aData) 
       
   845 	{
       
   846 	TInt handle=0;
       
   847 	switch(aOpcode)
       
   848 		{
       
   849 		case EWsGcOpDrawResourceToPos:
       
   850 			handle=aData.DrawWsResourceToPos->wsHandle;
       
   851 			break;
       
   852 		case EWsGcOpDrawResourceToRect:
       
   853 			handle=aData.DrawWsResourceToRect->wsHandle;
       
   854 			break;
       
   855 		case EWsGcOpDrawResourceFromRectToRect:
       
   856 			handle=aData.DrawWsResourceFromRectToRect->wsHandle;
       
   857 			break;
       
   858 		case EWsGcOpDrawResourceWithData:
       
   859 			handle=aData.DrawWsResourceWithData->wsHandle;
       
   860 			break;
       
   861 		default:
       
   862 			OwnerPanic(EWservPanicOpcode);
       
   863 		}
       
   864 	return handle;
       
   865 	}		
       
   866 
       
   867 void CWsGc::UpdateJustification(TText* aText,TInt aLen)
       
   868 	{
       
   869 	iBackedUpWinGc->UpdateJustification(BufferTPtr(aText,aLen));
       
   870 	}
       
   871 
       
   872 void CWsGc::UpdateJustification(TText* aText,TInt aLen,CGraphicsContext::TTextParameters* aParam)
       
   873 	{
       
   874 	iBackedUpWinGc->UpdateJustification(BufferTPtr(aText,aLen),aParam);
       
   875 	}
       
   876 
       
   877 void CWsGc::DoDrawing2(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData)
       
   878 	{
       
   879 	WS_ASSERT_DEBUG(iWin->Redraw()->OutputDevice(), EWsPanicWindowType);
       
   880 
       
   881 	iBackedUpWinGc->SetUserDisplayMode(iWin->DisplayMode());
       
   882 	if (iClippingRectSet)
       
   883 		{
       
   884 		iBackedUpWinGc->SetOrigin(TPoint(0,0));
       
   885 		iBackedUpWinGc->SetClippingRect(iClippingRect);
       
   886 		}
       
   887 	iBackedUpWinGc->SetOrigin(iOrigin);
       
   888 	iInternalStatus.iOrigin = iOrigin;
       
   889 	
       
   890 	DoDrawCommand(aOpcode,pData);
       
   891 
       
   892 	iBackedUpWinGc->SetUserDisplayMode(ENone);
       
   893 	iBackedUpWinGc->CancelClippingRect();
       
   894 	CGraphicsContext::TTextParameters contextParam;
       
   895 	switch(aOpcode)
       
   896 		{
       
   897 		case EWsGcOpDrawLine:
       
   898 			iLinePos=pData.DrawLine->pnt2;
       
   899 			break;
       
   900 		case EWsGcOpDrawTo:
       
   901 		case EWsGcOpMoveTo:
       
   902 		case EWsGcOpPlot:
       
   903 			iLinePos=(*pData.Point);
       
   904 			break;
       
   905 		case EWsGcOpDrawBy:
       
   906 		case EWsGcOpMoveBy:
       
   907 			iLinePos+=(*pData.Point);
       
   908 			break;
       
   909 		case EWsGcOpDrawSegmentedPolygon:
       
   910 			EndSegmentedPolygon();
       
   911 			break;
       
   912 		case EWsGcOpDrawText:
       
   913 			UpdateJustification((TText *)(pData.DrawText+1),pData.DrawText->length);
       
   914 			break;
       
   915 		case EWsGcOpDrawTextVertical:
       
   916 			UpdateJustification((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length);
       
   917 			break;
       
   918 		case EWsGcOpDrawBoxText:
       
   919 			UpdateJustification((TText *)(pData.BoxText+1),pData.BoxText->length);
       
   920 			break;
       
   921 		case EWsGcOpDrawBoxTextOptimised1:
       
   922 			UpdateJustification((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length);
       
   923 			break;
       
   924 		case EWsGcOpDrawBoxTextOptimised2:
       
   925 			UpdateJustification((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length);
       
   926 			break;
       
   927 		case EWsGcOpDrawBoxTextVertical:
       
   928 			UpdateJustification((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length);
       
   929 			break;
       
   930 		case EWsGcOpDrawTextLocal:
       
   931 			iBackedUpWinGc->UpdateJustification(*pData.DrawTextLocal->desc);
       
   932 			break;
       
   933 		case EWsGcOpDrawBoxTextLocal:
       
   934 			iBackedUpWinGc->UpdateJustification(*pData.BoxTextLocal->desc);
       
   935 			break;
       
   936 		case EWsGcOpDrawTextPtr:
       
   937 			iBackedUpWinGc->UpdateJustification(*pData.DrawTextPtr->text);
       
   938 			break;
       
   939 		case EWsGcOpDrawTextVerticalPtr:
       
   940 			iBackedUpWinGc->UpdateJustification(*pData.DrawTextVerticalPtr->text);
       
   941 			break;
       
   942 		case EWsGcOpDrawBoxTextPtr:
       
   943 			iBackedUpWinGc->UpdateJustification(*pData.DrawBoxTextPtr->text);
       
   944 			break;
       
   945 		case EWsGcOpDrawBoxTextVerticalPtr:
       
   946 			iBackedUpWinGc->UpdateJustification(*pData.DrawBoxTextVerticalPtr->text);
       
   947 			break;
       
   948 		/***************DrawTextInContext*****************************************************************/
       
   949 		case EWsGcOpDrawTextInContext:
       
   950 			contextParam.iStart = pData.DrawTextInContext->start;
       
   951 			contextParam.iEnd = pData.DrawTextInContext->end;
       
   952 			if(contextParam.iStart < contextParam.iEnd)
       
   953 				{
       
   954 				UpdateJustification((TText *)(pData.DrawTextInContext+1),pData.DrawTextInContext->length,&contextParam);
       
   955 				}
       
   956 			else
       
   957 				{
       
   958 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   959 				}
       
   960 			break;
       
   961 		case EWsGcOpDrawTextInContextVertical:
       
   962 			contextParam.iStart = pData.DrawTextInContext->start;
       
   963 			contextParam.iEnd = pData.DrawTextInContext->end;
       
   964 			if(contextParam.iStart < contextParam.iEnd)
       
   965 				{
       
   966 				UpdateJustification((TText *)(pData.DrawTextInContextVertical+1),pData.DrawTextInContextVertical->length,&contextParam);
       
   967 				}
       
   968 			else
       
   969 				{
       
   970 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   971 				}
       
   972 			break;
       
   973 		case EWsGcOpDrawBoxTextInContext:
       
   974 			contextParam.iStart = pData.DrawTextInContext->start;
       
   975 			contextParam.iEnd = pData.DrawTextInContext->end;
       
   976 			if(contextParam.iStart < contextParam.iEnd)
       
   977 				{
       
   978 				UpdateJustification((TText *)(pData.BoxTextInContext+1),pData.BoxTextInContext->length,&contextParam);
       
   979 				}
       
   980 			else
       
   981 				{
       
   982 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   983 				}
       
   984 			break;
       
   985 		case EWsGcOpDrawBoxTextInContextOptimised1:
       
   986 			contextParam.iStart = pData.DrawTextInContext->start;
       
   987 			contextParam.iEnd = pData.DrawTextInContext->end;
       
   988 			if(contextParam.iStart < contextParam.iEnd)
       
   989 				{
       
   990 				UpdateJustification((TText *)(pData.BoxTextInContextO1+1),pData.BoxTextInContextO1->length,&contextParam);
       
   991 				}
       
   992 			else
       
   993 				{
       
   994 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
   995 				}
       
   996 			break;
       
   997 		case EWsGcOpDrawBoxTextInContextOptimised2:
       
   998 			contextParam.iStart = pData.DrawTextInContext->start;
       
   999 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1000 			if(contextParam.iStart < contextParam.iEnd)
       
  1001 				{
       
  1002 				UpdateJustification((TText *)(pData.BoxTextInContextO2+1),pData.BoxTextInContextO2->length,&contextParam);
       
  1003 				}
       
  1004 			else
       
  1005 				{
       
  1006 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1007 				}
       
  1008 			break;
       
  1009 		case EWsGcOpDrawBoxTextInContextVertical:
       
  1010 			contextParam.iStart = pData.DrawTextInContext->start;
       
  1011 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1012 			if(contextParam.iStart < contextParam.iEnd)
       
  1013 				{
       
  1014 				UpdateJustification((TText *)(pData.DrawBoxTextInContextVertical+1),pData.DrawBoxTextInContextVertical->length,&contextParam);
       
  1015 				}
       
  1016 			else
       
  1017 				{
       
  1018 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1019 				}
       
  1020 			break;
       
  1021 		case EWsGcOpDrawTextInContextLocal:
       
  1022 			contextParam.iStart = pData.DrawTextInContext->start;
       
  1023 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1024 			if(contextParam.iStart < contextParam.iEnd)
       
  1025 				{
       
  1026 				iBackedUpWinGc->UpdateJustification(*pData.DrawTextInContextLocal->desc,&contextParam);
       
  1027 				}
       
  1028 			else
       
  1029 				{
       
  1030 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1031 				}
       
  1032 			break;
       
  1033 		case EWsGcOpDrawBoxTextInContextLocal:
       
  1034 			contextParam.iStart = pData.DrawTextInContext->start;
       
  1035 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1036 			if(contextParam.iStart < contextParam.iEnd)
       
  1037 				{
       
  1038 				iBackedUpWinGc->UpdateJustification(*pData.BoxTextInContextLocal->desc,&contextParam);
       
  1039 				}
       
  1040 			else
       
  1041 				{
       
  1042 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1043 				}
       
  1044 			break;
       
  1045 		case EWsGcOpDrawTextInContextPtr:
       
  1046 			contextParam.iStart = pData.DrawTextInContext->start;
       
  1047 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1048 			if(contextParam.iStart < contextParam.iEnd)
       
  1049 				{
       
  1050 				iBackedUpWinGc->UpdateJustification(*pData.DrawTextInContextPtr->text,&contextParam);
       
  1051 				}
       
  1052 			else
       
  1053 				{
       
  1054 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1055 				}
       
  1056 			break;
       
  1057 		case EWsGcOpDrawTextInContextVerticalPtr:
       
  1058 			contextParam.iStart = pData.DrawTextInContext->start;
       
  1059 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1060 			if(contextParam.iStart < contextParam.iEnd)
       
  1061 				{
       
  1062 				iBackedUpWinGc->UpdateJustification(*pData.DrawTextInContextVerticalPtr->text,&contextParam);
       
  1063 				}
       
  1064 			else
       
  1065 				{
       
  1066 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1067 				}
       
  1068 			break;
       
  1069 		case EWsGcOpDrawBoxTextInContextPtr:
       
  1070 			contextParam.iStart = pData.DrawTextInContext->start;
       
  1071 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1072 			if(contextParam.iStart < contextParam.iEnd)
       
  1073 				{
       
  1074 				iBackedUpWinGc->UpdateJustification(*pData.DrawBoxTextInContextPtr->text,&contextParam);
       
  1075 				}
       
  1076 			else
       
  1077 				{
       
  1078 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1079 				}
       
  1080 			break;
       
  1081 		case EWsGcOpDrawBoxTextInContextVerticalPtr:
       
  1082 			contextParam.iStart = pData.DrawTextInContext->start;
       
  1083 			contextParam.iEnd = pData.DrawTextInContext->end;
       
  1084 			if(contextParam.iStart < contextParam.iEnd)
       
  1085 				{
       
  1086 				iBackedUpWinGc->UpdateJustification(*pData.DrawBoxTextInContextVerticalPtr->text,&contextParam);
       
  1087 				}
       
  1088 			else
       
  1089 				{
       
  1090 				iWin->WsOwner()->PPanic(EWservPanicInvalidParameter);
       
  1091 				}
       
  1092 			break;
       
  1093 		}
       
  1094 	}
       
  1095 
       
  1096 void CWsGc::DoDrawing1(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData)
       
  1097 	{
       
  1098 	WS_ASSERT_DEBUG(iWin->Redraw()->OutputDevice(), EWsPanicWindowType);
       
  1099 
       
  1100 	TWsGcLargeStruct newData;
       
  1101 	TWsGcCmdUnion pNewData;
       
  1102 	TWsGcOpcodes opcode;
       
  1103 	TDesC **string;
       
  1104 	TInt toGo;
       
  1105 	pNewData.LargeStruct=&newData;
       
  1106 	switch (aOpcode)
       
  1107 		{
       
  1108 		case EWsGcOpDrawTextPtr:
       
  1109 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdDrawTextPtr), EWsPanicGcStructSizeError);
       
  1110 			opcode=EWsGcOpDrawTextPtr1;
       
  1111 			toGo=pData.DrawText->length;
       
  1112 			pNewData.DrawTextPtr->pos=pData.DrawText->pos;
       
  1113 			string=&(pNewData.DrawTextPtr->text);
       
  1114 			break;
       
  1115 		case EWsGcOpDrawTextVerticalPtr:
       
  1116 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdDrawTextVerticalPtr), EWsPanicGcStructSizeError);
       
  1117 			opcode=EWsGcOpDrawTextVerticalPtr1;
       
  1118 			toGo=pData.DrawTextVertical->length;
       
  1119 			pNewData.DrawTextVerticalPtr->pos=pData.DrawTextVertical->pos;
       
  1120 			pNewData.DrawTextVerticalPtr->up=pData.DrawTextVertical->up;
       
  1121 			string=&(pNewData.DrawTextVerticalPtr->text);
       
  1122 			break;
       
  1123 			
       
  1124 		case EWsGcOpDrawBoxTextPtr:
       
  1125 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdBoxTextPtr), EWsPanicGcStructSizeError);
       
  1126 			opcode=EWsGcOpDrawBoxTextPtr1;
       
  1127 			toGo=pData.BoxText->length;
       
  1128 			pNewData.DrawBoxTextPtr->box=pData.BoxText->box;
       
  1129 			pNewData.DrawBoxTextPtr->baselineOffset=pData.BoxText->baselineOffset;
       
  1130 			pNewData.DrawBoxTextPtr->horiz=pData.BoxText->horiz;
       
  1131 			pNewData.DrawBoxTextPtr->leftMrg=pData.BoxText->leftMrg;
       
  1132 			pNewData.DrawBoxTextPtr->width=pData.BoxText->width;
       
  1133 			string=&(pNewData.DrawBoxTextPtr->text);
       
  1134 			break;
       
  1135 			
       
  1136 		case EWsGcOpDrawBoxTextVerticalPtr:
       
  1137 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdBoxTextVerticalPtr), EWsPanicGcStructSizeError);
       
  1138 			opcode=EWsGcOpDrawBoxTextVerticalPtr1;
       
  1139 			toGo=pData.DrawBoxTextVertical->length;
       
  1140 			pNewData.DrawBoxTextVerticalPtr->box=pData.DrawBoxTextVertical->box;
       
  1141 			pNewData.DrawBoxTextVerticalPtr->baselineOffset=pData.DrawBoxTextVertical->baselineOffset;
       
  1142 			pNewData.DrawBoxTextVerticalPtr->up=pData.DrawBoxTextVertical->up;
       
  1143 			pNewData.DrawBoxTextVerticalPtr->vert=pData.DrawBoxTextVertical->vert;
       
  1144 			pNewData.DrawBoxTextVerticalPtr->margin=pData.DrawBoxTextVertical->margin;
       
  1145 			pNewData.DrawBoxTextVerticalPtr->width=pData.DrawBoxTextVertical->width;
       
  1146 			string=&(pNewData.DrawBoxTextVerticalPtr->text);
       
  1147 			break;
       
  1148 
       
  1149 		case EWsGcOpDrawTextInContextPtr:
       
  1150 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdDrawTextInContextPtr), EWsPanicGcStructSizeError);
       
  1151 			opcode=EWsGcOpDrawTextInContextPtr1;
       
  1152 			toGo=pData.DrawTextInContext->length;
       
  1153 			pNewData.DrawTextInContextPtr->pos=pData.DrawTextInContext->pos;
       
  1154 			pNewData.DrawTextInContextPtr->start=pData.DrawTextInContext->start;
       
  1155 			pNewData.DrawTextInContextPtr->end=pData.DrawTextInContext->end;
       
  1156 			string=&(pNewData.DrawTextInContextPtr->text);
       
  1157 			break;
       
  1158 			
       
  1159 		case EWsGcOpDrawTextInContextVerticalPtr:
       
  1160 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdDrawTextInContextVerticalPtr), EWsPanicGcStructSizeError);
       
  1161 			opcode=EWsGcOpDrawTextInContextVerticalPtr1;
       
  1162 			toGo=pData.DrawTextInContextVertical->length;
       
  1163   			pNewData.DrawTextInContextVerticalPtr->pos=pData.DrawTextInContextVerticalPtr->pos;
       
  1164   			pNewData.DrawTextInContextVerticalPtr->up=pData.DrawTextInContextVerticalPtr->up;
       
  1165   			pNewData.DrawTextInContextVerticalPtr->start=pData.DrawTextInContextVerticalPtr->start;
       
  1166   			pNewData.DrawTextInContextVerticalPtr->end=pData.DrawTextInContextVerticalPtr->end;
       
  1167 			string=&(pNewData.DrawTextVerticalPtr->text);
       
  1168 			break;
       
  1169 			
       
  1170 		case EWsGcOpDrawBoxTextInContextPtr:
       
  1171 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdBoxTextInContextPtr), EWsPanicGcStructSizeError);
       
  1172 			opcode=EWsGcOpDrawBoxTextInContextPtr1;
       
  1173 			toGo=pData.BoxTextInContext->length;
       
  1174    			pNewData.DrawBoxTextInContextPtr->box=pData.BoxTextInContext->box;
       
  1175    			pNewData.DrawBoxTextInContextPtr->baselineOffset=pData.BoxTextInContext->baselineOffset;
       
  1176    			pNewData.DrawBoxTextInContextPtr->horiz=pData.BoxTextInContext->horiz;
       
  1177    			pNewData.DrawBoxTextInContextPtr->leftMrg=pData.BoxTextInContext->leftMrg;
       
  1178    			pNewData.DrawBoxTextInContextPtr->width=pData.BoxTextInContext->width;
       
  1179    			pNewData.DrawBoxTextInContextPtr->start=pData.BoxTextInContext->start;
       
  1180   			pNewData.DrawBoxTextInContextPtr->end=pData.BoxTextInContext->end;
       
  1181 			string=&(pNewData.DrawBoxTextPtr->text);
       
  1182 			break;
       
  1183 			
       
  1184 		case EWsGcOpDrawBoxTextInContextVerticalPtr:
       
  1185 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdBoxTextInContextVerticalPtr), EWsPanicGcStructSizeError);
       
  1186 			opcode=EWsGcOpDrawBoxTextInContextVerticalPtr1;
       
  1187 			toGo=pData.DrawBoxTextInContextVertical->length;
       
  1188    			pNewData.DrawBoxTextInContextVerticalPtr->box=pData.DrawBoxTextInContextVertical->box;
       
  1189    			pNewData.DrawBoxTextInContextVerticalPtr->baselineOffset=pData.DrawBoxTextInContextVertical->baselineOffset;
       
  1190    			pNewData.DrawBoxTextInContextVerticalPtr->up=pData.DrawBoxTextInContextVertical->up;
       
  1191    			pNewData.DrawBoxTextInContextVerticalPtr->vert=pData.DrawBoxTextInContextVertical->vert;
       
  1192    			pNewData.DrawBoxTextInContextVerticalPtr->margin=pData.DrawBoxTextInContextVertical->margin;
       
  1193    			pNewData.DrawBoxTextInContextVerticalPtr->width=pData.DrawBoxTextInContextVertical->width;
       
  1194    			pNewData.DrawBoxTextInContextVerticalPtr->start=pData.DrawBoxTextInContextVertical->start;
       
  1195    			pNewData.DrawBoxTextInContextVerticalPtr->end=pData.DrawBoxTextInContextVertical->end;
       
  1196  			string=&(pNewData.DrawBoxTextInContextVerticalPtr->text);			
       
  1197 			break;
       
  1198 
       
  1199 		default:
       
  1200 			DoDrawing2(aOpcode,pData);
       
  1201 			return;
       
  1202 		}
       
  1203 
       
  1204 	TBuf<ETextPtrBufLen> buf;
       
  1205 	TInt len=ETextPtrBufLen;
       
  1206 	TInt bufOffset=0;
       
  1207 	*string=&buf;
       
  1208 	while(toGo>0)
       
  1209 		{
       
  1210 		if (len>toGo)
       
  1211 			len=toGo;
       
  1212 		iWsOwner->RemoteRead(buf,bufOffset);
       
  1213 		DoDrawing2(aOpcode,pNewData);
       
  1214 		aOpcode=opcode;
       
  1215 		bufOffset+=len;
       
  1216 		toGo-=len;
       
  1217 		}
       
  1218 	}
       
  1219 
       
  1220 void CWsGc::SetGcAttribute(TInt aOpcode, TWsGcCmdUnion pData)
       
  1221 	{
       
  1222 	switch(aOpcode)
       
  1223 		{
       
  1224 		case EWsGcOpSetDrawMode:
       
  1225 			iInternalStatus.iDrawMode = (CGraphicsContext::TDrawMode) (*pData.UInt);
       
  1226 			if (iWin->Redraw()->OutputDevice())
       
  1227 				iBackedUpWinGc->SetDrawMode(iInternalStatus.iDrawMode);
       
  1228 			break;
       
  1229 		case EWsGcOpUseFont:
       
  1230 			if (CWsFontCache::Instance()->UseFont(iFont, *pData.UInt))
       
  1231 				{	// Couldn't cache it
       
  1232 				if (iWin->Redraw()->OutputDevice())
       
  1233 					{
       
  1234 					TInt ret = iBackedUpWinGc->UseFont(*pData.UInt);
       
  1235 					if (ret == KErrNoMemory)
       
  1236 						return;
       
  1237 					if (ret != KErrNone)
       
  1238 						GcOwnerPanic(EWservPanicFont);
       
  1239 					}
       
  1240 				iInternalStatus.iFontHandle = *pData.UInt;
       
  1241 				}
       
  1242 			else
       
  1243 				{
       
  1244 				if (iFont==NULL)
       
  1245 					{
       
  1246 					iInternalStatus.iFontHandle = NULL;
       
  1247 					GcOwnerPanic(EWservPanicFont);
       
  1248 					}
       
  1249 				if (iWin->Redraw()->OutputDevice())
       
  1250 					iBackedUpWinGc->UseFontNoDuplicate(iFont);
       
  1251 				iInternalStatus.iFontHandle = iFont->Handle();
       
  1252 				}
       
  1253 			break;
       
  1254 		case EWsGcOpDiscardFont:
       
  1255 			CWsFontCache::Instance()->ReleaseFont(iFont);
       
  1256 			if (iWin->Redraw()->OutputDevice())
       
  1257 				iBackedUpWinGc->DiscardFont();
       
  1258 			iInternalStatus.iFontHandle = NULL;
       
  1259 			break;
       
  1260 		case EWsGcOpSetUnderlineStyle:
       
  1261 			if (iWin->Redraw()->OutputDevice())
       
  1262 				iBackedUpWinGc->SetUnderlineStyle(*pData.SetUnderlineStyle);
       
  1263 			iInternalStatus.iUnderline = *pData.SetUnderlineStyle;
       
  1264 			break;
       
  1265 		case EWsGcOpSetStrikethroughStyle:
       
  1266 			if (iWin->Redraw()->OutputDevice())
       
  1267 				iBackedUpWinGc->SetStrikethroughStyle(*pData.SetStrikethroughStyle);
       
  1268 			iInternalStatus.iStrikethrough = *pData.SetStrikethroughStyle;
       
  1269 			break;
       
  1270 		case EWsGcOpUseBrushPattern:
       
  1271 			if (iWin->Redraw()->OutputDevice())
       
  1272 				{
       
  1273 				TInt ret = iBackedUpWinGc->UseBrushPattern(*pData.handle);
       
  1274 				if (ret == KErrNoMemory)
       
  1275 					return;
       
  1276 				if (ret != KErrNone)
       
  1277 					GcOwnerPanic(EWservPanicBitmap);
       
  1278 				}
       
  1279 			else
       
  1280 				{
       
  1281 				// Make sure the bitmap handle is valid
       
  1282 				TInt ret = iScratchBitmap->Duplicate(*pData.handle);
       
  1283 				if (ret == KErrNoMemory)
       
  1284 					return;
       
  1285 				if (ret != KErrNone)
       
  1286 					GcOwnerPanic(EWservPanicBitmap);
       
  1287 				iScratchBitmap->Reset();
       
  1288 				}
       
  1289 			iInternalStatus.iBrushPatternHandle = *pData.handle;
       
  1290 			break;
       
  1291 		case EWsGcOpDiscardBrushPattern:
       
  1292 			if (iWin->Redraw()->OutputDevice())
       
  1293 				iBackedUpWinGc->DiscardBrushPattern();
       
  1294 			iInternalStatus.iBrushPatternHandle = NULL;
       
  1295 			if (iInternalStatus.iBrushStyle == CGraphicsContext::EPatternedBrush)
       
  1296 				iInternalStatus.iBrushStyle = CGraphicsContext::ENullBrush;
       
  1297 			break;
       
  1298 		case EWsGcOpSetBrushColor:
       
  1299 			if (iWin->Redraw()->OutputDevice())
       
  1300 				iBackedUpWinGc->SetBrushColor(*pData.rgb);
       
  1301 			iInternalStatus.iBrushColor = *pData.rgb; 
       
  1302 			break;
       
  1303 		case EWsGcOpSetPenColor:
       
  1304 			if (iWin->Redraw()->OutputDevice())
       
  1305 				iBackedUpWinGc->SetPenColor(*pData.rgb);
       
  1306 			iInternalStatus.iPenColor = *pData.rgb;
       
  1307 			break;
       
  1308 		case EWsGcOpSetPenStyle:
       
  1309 			iInternalStatus.iPenStyle = (CGraphicsContext::TPenStyle) (*pData.UInt);
       
  1310 			if (iWin->Redraw()->OutputDevice())
       
  1311 				iBackedUpWinGc->SetPenStyle(iInternalStatus.iPenStyle);
       
  1312 			break;
       
  1313 		case EWsGcOpSetPenSize:
       
  1314 			if (iWin->Redraw()->OutputDevice())
       
  1315 				iBackedUpWinGc->SetPenSize(*pData.Size);
       
  1316 			iInternalStatus.iPenSize = *pData.Size; 
       
  1317 			break;
       
  1318 		case EWsGcOpSetBrushStyle:
       
  1319 			if ((CGraphicsContext::TBrushStyle)*pData.UInt==CGraphicsContext::EPatternedBrush && !iInternalStatus.iBrushPatternHandle)
       
  1320 				GcOwnerPanic(EWservPanicNoBrush);
       
  1321 			iInternalStatus.iBrushStyle = (CGraphicsContext::TBrushStyle) (*pData.UInt);
       
  1322 			if (iWin->Redraw()->OutputDevice())
       
  1323 				iBackedUpWinGc->SetBrushStyle(iInternalStatus.iBrushStyle); 
       
  1324 			break;
       
  1325 		case EWsGcOpReset:
       
  1326 			CWsFontCache::Instance()->ReleaseFont(iFont);
       
  1327 			iBackedUpWinGc->Reset();
       
  1328 			iOrigin.SetXY(0,0);
       
  1329 			ResetClippingRect();
       
  1330 			iInternalStatus.ResetInternalStatus(iWin);
       
  1331 			if (iWin->Redraw()->OutputDevice())
       
  1332 				iBackedUpWinGc->SetBrushColor(iWin->BackColor());
       
  1333 			iInternalStatus.iBrushColor = iWin->BackColor();
       
  1334 			break;
       
  1335 		case EWsGcOpSetBrushOrigin:
       
  1336 			if (iWin->Redraw()->OutputDevice())
       
  1337 				iBackedUpWinGc->SetBrushOrigin(*pData.Point);
       
  1338 			iInternalStatus.iBrushOrigin = *pData.Point; 
       
  1339 			break;
       
  1340 		case EWsGcOpSetDitherOrigin:
       
  1341 			GcOwnerPanic(EWservPanicOpcode); //deprecated, the client should never generate this op
       
  1342 			break;
       
  1343 		case EWsGcOpSetWordJustification:
       
  1344 			if (iWin->Redraw()->OutputDevice())
       
  1345 				iBackedUpWinGc->SetWordJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
       
  1346 			iInternalStatus.iWordExcessWidth = pData.SetJustification->excessWidth;
       
  1347 			iInternalStatus.iWordNumChars = pData.SetJustification->numGaps;
       
  1348 			break;
       
  1349 		case EWsGcOpSetCharJustification:
       
  1350 			if (iWin->Redraw()->OutputDevice())
       
  1351 				iBackedUpWinGc->SetCharJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
       
  1352 			iInternalStatus.iCharExcessWidth = pData.SetJustification->excessWidth;
       
  1353 			iInternalStatus.iCharNumChars = pData.SetJustification->numGaps;
       
  1354 			break;
       
  1355 		case EWsGcOpSetOrigin:
       
  1356 			SetOrigin(*pData.Point);
       
  1357 			iInternalStatus.iOrigin = *pData.Point; 
       
  1358 			break;
       
  1359 		case EWsGcOpSetOpaque: // deprecated
       
  1360 			// do nothing
       
  1361 			break;
       
  1362 		case EWsGcOpSetShadowColor:
       
  1363 			if (iWin->Redraw()->OutputDevice())
       
  1364 				iBackedUpWinGc->SetShadowColor(*pData.rgb);
       
  1365 			iInternalStatus.iShadowColor = *pData.rgb; 
       
  1366 			break;
       
  1367 		}
       
  1368 	}
       
  1369 
       
  1370 void CWsGc::DoDrawing0L(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData)
       
  1371 	{
       
  1372 	if (iWin==NULL)
       
  1373 		{
       
  1374 		OwnerPanic(EWservPanicGcNotActive);
       
  1375 		return;
       
  1376 		}
       
  1377 	
       
  1378 	iWin->SetValidRedraw();
       
  1379 
       
  1380 	switch(aOpcode)
       
  1381 		{
       
  1382 	case EWsGcOpStartSegmentedDrawPolygon:
       
  1383 
       
  1384 		//tell Redraw Store about the drawing data, so that it is stored and CWsGc::ExternalizeL can be called if required
       
  1385 		if (iWin->Redraw()->DrawCommand(this,pData.any))
       
  1386 			StartSegmentedDrawPolygonL(pData.StartSegmentedDrawPolygon);
       
  1387 		return;
       
  1388 	case EWsGcOpSegmentedDrawPolygonData:
       
  1389 		//tell Redraw Store about the drawing data, so that it is stored and CWsGc::ExternalizeL can be called if required
       
  1390 		if (iWin->Redraw()->DrawCommand(this,pData.any))
       
  1391 			SegmentedDrawPolygonData(pData.SegmentedDrawPolygonData);
       
  1392 		return;
       
  1393 	case EWsGcOpSetClippingRegion:
       
  1394 		SetClippingRegionL(*pData.Int);
       
  1395 		break;
       
  1396 	case EWsGcOpSetClippingRect:
       
  1397 		SetClippingRect(*pData.Rect);
       
  1398 		break;
       
  1399 	case EWsGcOpCancelClippingRect:
       
  1400 		ResetClippingRect();
       
  1401 		break;
       
  1402 	case EWsGcOpCancelClippingRegion:
       
  1403 		CancelClippingRegion();
       
  1404 		break;
       
  1405 	case EWsGcOpSetFaded:
       
  1406 		if (iWin->Redraw()->OutputDevice())
       
  1407 			iBackedUpWinGc->SetFaded(*pData.Bool);
       
  1408 		break;
       
  1409 	case EWsGcOpSetFadeParams:
       
  1410 		if (iWin->Redraw()->OutputDevice())
       
  1411 			iBackedUpWinGc->SetFadingParameters(WservEncoding::ExtractFirst8BitValue(*pData.UInt),WservEncoding::ExtractSecond8BitValue(*pData.UInt));
       
  1412 		break;
       
  1413 	case EWsGcOpSetDrawMode:
       
  1414 	case EWsGcOpUseFont:
       
  1415 	case EWsGcOpDiscardFont:
       
  1416 	case EWsGcOpUseBrushPattern:
       
  1417 	case EWsGcOpDiscardBrushPattern:
       
  1418 	case EWsGcOpSetBrushColor:
       
  1419 	case EWsGcOpSetPenColor:
       
  1420 	case EWsGcOpSetPenStyle:
       
  1421 	case EWsGcOpSetPenSize:
       
  1422 	case EWsGcOpSetBrushStyle:
       
  1423 	case EWsGcOpReset:
       
  1424 	case EWsGcOpSetBrushOrigin:
       
  1425 	case EWsGcOpSetDitherOrigin:
       
  1426 	case EWsGcOpSetUnderlineStyle:
       
  1427 	case EWsGcOpSetStrikethroughStyle:
       
  1428 	case EWsGcOpSetWordJustification:
       
  1429 	case EWsGcOpSetCharJustification:
       
  1430 	case EWsGcOpSetOrigin:
       
  1431 	case EWsGcOpSetOpaque:
       
  1432 	case EWsGcOpSetShadowColor:
       
  1433 		{
       
  1434 		SetGcAttribute(aOpcode,pData);
       
  1435 		break;
       
  1436 		}
       
  1437 	case EWsGcOpDrawBoxText:	
       
  1438 	case EWsGcOpDrawBoxTextOptimised1:
       
  1439 	case EWsGcOpDrawBoxTextOptimised2:
       
  1440 	case EWsGcOpDrawBoxTextPtr:
       
  1441 	case EWsGcOpDrawBoxTextPtr1:
       
  1442 	case EWsGcOpDrawTextPtr:
       
  1443 	case EWsGcOpDrawTextPtr1:
       
  1444 	case EWsGcOpDrawText:
       
  1445 	case EWsGcOpDrawTextVertical:
       
  1446 	case EWsGcOpDrawTextVerticalPtr:
       
  1447 	case EWsGcOpDrawTextVerticalPtr1:
       
  1448 	case EWsGcOpDrawBoxTextVertical:
       
  1449 	case EWsGcOpDrawBoxTextVerticalPtr:
       
  1450 	case EWsGcOpDrawBoxTextVerticalPtr1:
       
  1451 	case EWsGcOpDrawTextLocal:
       
  1452 	case EWsGcOpDrawBoxTextLocal:
       
  1453 		{
       
  1454 		//Make sure a font is set before any text related opcodes are used.
       
  1455 		if (!iInternalStatus.iFontHandle)
       
  1456 			OwnerPanic(EWservPanicNoFont);
       
  1457 		//fall through
       
  1458 		}
       
  1459 	default:	// Assume remaining functions will draw
       
  1460 		{
       
  1461 		if (iWin->WinType()!=EWinTypeRoot)
       
  1462 			{
       
  1463 			if (!iWin->BaseParent())
       
  1464 				OwnerPanic(EWservPanicParentDeleted);
       
  1465 			if (iWin->WinType()!=EWinTypeClient)
       
  1466 				OwnerPanic(EWservPanicReadOnlyDrawable);
       
  1467 			}
       
  1468 		if (iWin->Redraw()->DrawCommand(this,pData.any))
       
  1469 			DoDrawing1(aOpcode,pData);
       
  1470 		return;
       
  1471 		}
       
  1472 		}
       
  1473 	iWin->Redraw()->GcAttributeChange(this,pData.any);
       
  1474 	}
       
  1475 
       
  1476 void CWsGc::CommandL(TInt aOpcode, const TAny *aCmdData)
       
  1477 	{
       
  1478 	TWsGcOpcodes opcode = static_cast<TWsGcOpcodes>(aOpcode);
       
  1479 
       
  1480 	TWsGcCmdUnion pData;
       
  1481 	pData.any=aCmdData;
       
  1482 	switch(opcode)
       
  1483 		{
       
  1484 		case EWsGcOpActivate:
       
  1485 			Activate(*pData.handle);
       
  1486 			break;
       
  1487 		case EWsGcOpDeactivate:
       
  1488 			Deactivate();
       
  1489 			break;
       
  1490 		case EWsGcOpFree:
       
  1491 			delete this;
       
  1492 			break;
       
  1493 		case EWsGcOpTestInvariant:
       
  1494 			break;
       
  1495 		default:
       
  1496 			DoDrawing0L(opcode,pData);
       
  1497 			break;
       
  1498 		}
       
  1499 	}
       
  1500 
       
  1501 void CWsGc::SetOrigin(const TPoint &aOrigin)
       
  1502 	{
       
  1503 	iOrigin=aOrigin;
       
  1504 	}
       
  1505 	
       
  1506 
       
  1507 /*------------------------------------------------------------------------------
       
  1508   Description: Saves graphics context information into a given buffer from a
       
  1509                given start position rather than just streaming data to the end.
       
  1510                This variant allows for buffers that are not fully utilised.
       
  1511  -----------------------------------------------------------------------------*/
       
  1512 TInt CWsGc::ExternalizeL(CBufBase& aBuffer, TInt aStartPos)
       
  1513 	{
       
  1514 	WS_ASSERT_DEBUG(!IsPolyPointData(), EWsPanicDrawCommandsInvalidState);
       
  1515 
       
  1516 	// Open the stream used for the output from the given start position
       
  1517 	// in the buffer.
       
  1518 	RBufWriteStream bufWriteStream;
       
  1519 	bufWriteStream.Open(aBuffer, aStartPos);
       
  1520 	CleanupClosePushL(bufWriteStream);
       
  1521 
       
  1522 	// Font/Bitmap Server data is serialised below in a call to 
       
  1523 	// ExternalizeGcAttributesL(). As this method does not return the amount of
       
  1524 	// the data externalised we use methods in the underlying stream to 
       
  1525 	// calculate it. We do this because we need to return an accurate count of
       
  1526 	// data serialised from this method so that the caller can update its 
       
  1527 	// buffer write counter.
       
  1528 	MStreamBuf* ptrToRawStream = bufWriteStream.Sink();	// This is the real stream
       
  1529 
       
  1530 	// Position of read seek pointer before externalise
       
  1531 	TStreamPos size1 = ptrToRawStream->TellL(MStreamBuf::EWrite); 
       
  1532 
       
  1533 	// Save the font/bitmap server data
       
  1534 	iInternalStatus.ExternalizeGcAttributesL(bufWriteStream);
       
  1535 
       
  1536 	bufWriteStream.WriteInt32L(iOrigin.iX);
       
  1537 	bufWriteStream.WriteInt32L(iOrigin.iY);
       
  1538 
       
  1539 	bufWriteStream.WriteInt8L(iClippingRectSet);
       
  1540 
       
  1541 	// If there is a clipping rectangle output that too.
       
  1542 	if (iClippingRectSet)
       
  1543 		{
       
  1544 		bufWriteStream << iClippingRect;
       
  1545 		}
       
  1546 		
       
  1547 	// Save clipping region data.
       
  1548 	ExternalizeClippingRegionL(bufWriteStream);
       
  1549 
       
  1550 	// Save the Alpha values for Brush and Pen colors.
       
  1551 	ExternalizeAlphaValueL(bufWriteStream);
       
  1552 
       
  1553 	// Position of read seek pointer after externalise
       
  1554 	TStreamPos size2 = ptrToRawStream->TellL(MStreamBuf::EWrite);
       
  1555 	CleanupStack::PopAndDestroy(&bufWriteStream);
       
  1556 
       
  1557 	// Return actual size of data serialized
       
  1558 	return (size2 - size1);
       
  1559 	}
       
  1560 
       
  1561 /*------------------------------------------------------------------------------
       
  1562   Description: Saves TRgb::alpha value information into a given buffer.
       
  1563   ----------------------------------------------------------------------------*/
       
  1564 void CWsGc::ExternalizeAlphaValueL(RWriteStream& aWriteStream)
       
  1565 	{
       
  1566 	aWriteStream.WriteUint8L(iInternalStatus.iBrushColor.Alpha());
       
  1567 	aWriteStream.WriteUint8L(iInternalStatus.iPenColor.Alpha());
       
  1568 	}
       
  1569 
       
  1570 /*------------------------------------------------------------------------------
       
  1571   Description: Helper method to store clipping region data to a given
       
  1572                write stream.
       
  1573  -----------------------------------------------------------------------------*/
       
  1574 TInt CWsGc::ExternalizeClippingRegionL(RWriteStream& aWriteStream)
       
  1575 	{
       
  1576 	TBool clipRegion = (iUserDefinedClippingRegion != NULL);
       
  1577 	// Store flag to indicate if client has defined a clipping region
       
  1578 	aWriteStream.WriteInt8L(clipRegion);
       
  1579 	// Store client clipping region data if it exists
       
  1580 	if (clipRegion)
       
  1581 		{
       
  1582 		return ExternalizeRegionL(aWriteStream, *iUserDefinedClippingRegion) + sizeof(TInt8);
       
  1583 		}
       
  1584 	return sizeof(TInt8);
       
  1585 	}
       
  1586