os/graphics/windowing/windowserver/nga/SERVER/openwfc/gc.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 <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