windowing/windowserver/nonnga/SERVER/gc.cpp
changeset 0 5d03bc08d59c
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 CFbsBitmap *CWsGc::iScratchBitmap=NULL;
       
    30 CFbsBitmap *CWsGc::iScratchMaskBitmap=NULL;
       
    31 
       
    32 GLREF_C TInt ExternalizeRegionL(RWriteStream& aWriteStream, const RWsRegion& aRegion);
       
    33 
       
    34 /*CWsGc*/
       
    35 
       
    36 CWsGc* CWsGc::NewL(CWsClient *aOwner)	
       
    37 	{
       
    38 	CWsGc* self = new(ELeave) CWsGc(aOwner);
       
    39 	CleanupStack::PushL(self);
       
    40 	self->ConstructL();
       
    41 	CleanupStack::Pop(self);
       
    42 	return self;
       
    43 	}
       
    44 
       
    45 void CWsGc::InitStaticsL()
       
    46 	{
       
    47 	iScratchBitmap=new(ELeave) CFbsBitmap();
       
    48 	iScratchMaskBitmap=new(ELeave) CFbsBitmap();
       
    49 	}
       
    50 
       
    51 void CWsGc::DeleteStatics()
       
    52 	{
       
    53 	delete iScratchBitmap;
       
    54 	delete iScratchMaskBitmap;
       
    55 	}
       
    56 
       
    57 CWsGc::CWsGc(CWsClient *owner) : CWsObject(owner,WS_HANDLE_GC)
       
    58 	{
       
    59 	__DECLARE_NAME(_S("CWsGc"));
       
    60 	}
       
    61 
       
    62 void CWsGc::ConstructL()
       
    63 	{
       
    64 	NewObjL();
       
    65 	iGdi=CFbsBitGc::NewL();
       
    66 	}
       
    67 
       
    68 void CWsGc::Activate(CWsClientWindow *win)
       
    69 	{
       
    70 	if (iWin!=NULL)
       
    71 		{
       
    72 		if (CWsClient::iCurrentCommand.iOpcode==0)
       
    73 			{
       
    74 			WS_PANIC_ALWAYS(EWsPanicDrawCommandsInvalidState);
       
    75 			}
       
    76 		else
       
    77 			{
       
    78 			OwnerPanic(EWservPanicGcActive);
       
    79 			}
       
    80 		}
       
    81 	iWin=win;
       
    82 	iGdi->ActivateNoJustAutoUpdate(iWin->Redraw()->OutputDevice());
       
    83 	iWin->GcActivated(this);
       
    84 	iGdi->SetBrushColor(iWin->BackColor());
       
    85 	iOrigin.SetXY(0,0);
       
    86 	ResetClippingRect();
       
    87 	if(iWsOwner)
       
    88 		{
       
    89 		CWsWindowGroup *winGp = iWin->WinGroup();
       
    90 		if(!winGp->Device())
       
    91 			OwnerPanic(EWservPanicGroupWinScreenDeviceDeleted);		
       
    92 		SetReply(winGp->Device()->ClientDevicePointer());			
       
    93 		}	
       
    94 	}
       
    95 
       
    96 void CWsGc::Activate(const TInt &aHandle)
       
    97 	{
       
    98 	CWsClientWindow *win;
       
    99 	iWsOwner->HandleToClientWindow(aHandle,&win);
       
   100 	if (!win->BaseParent())
       
   101 		OwnerPanic(EWservPanicParentDeleted);
       
   102 	Activate(win);
       
   103 	}
       
   104 
       
   105 void CWsGc::Reactivate()
       
   106 	{
       
   107 	WS_ASSERT_DEBUG(iWin != NULL, EWsPanicDrawCommandsInvalidState);
       
   108 	iGdi->ActivateNoJustAutoUpdate(iWin->Redraw()->OutputDevice());
       
   109 	}
       
   110 
       
   111 CWsGc::~CWsGc()
       
   112 	{
       
   113 	if (iWin!=NULL)
       
   114 		Deactivate();
       
   115 	delete iGdi;
       
   116 	delete iPolyPoints;
       
   117 	}
       
   118 
       
   119 void CWsGc::Deactivate()
       
   120 	{
       
   121 	if (iWin)	// Protect against deactivating an already deactivated GC, this is allowed to aid clean up code.
       
   122 		{
       
   123 		CWsFontCache::Instance()->ReleaseFont(iFont);
       
   124 		iGdi->Reset();
       
   125 		iWin->GcDeactivated(this);
       
   126 		CancelClippingRegion();
       
   127 		iWin->Redraw()->GcDeactivate(this);
       
   128 		iWin=NULL;
       
   129 		}
       
   130 	}
       
   131 
       
   132 void CWsGc::Reset()
       
   133 	{
       
   134 	iGdi->Reset();
       
   135 	}
       
   136 
       
   137 void CWsGc::SetClippingRect(const TRect &aRect)
       
   138 	{
       
   139 	iClippingRect=aRect;
       
   140 	iClippingRect.Move(iOrigin);
       
   141 	iClippingRectSet=ETrue;
       
   142 	}
       
   143 
       
   144 void CWsGc::ResetClippingRect()
       
   145 	{
       
   146 	iClippingRectSet=EFalse;
       
   147 	}
       
   148 
       
   149 void CWsGc::SetClippingRegionL(TInt aRegionCount)
       
   150 	{
       
   151 	RWsRegion *newRegion=GetRegionFromClientL(iWsOwner, aRegionCount);
       
   152 	CancelClippingRegion();
       
   153 	iUserDefinedClippingRegion=newRegion;
       
   154 
       
   155 	if (iUserDefinedClippingRegion)
       
   156 		{
       
   157 		iUserDefinedClippingRegion->Offset(iOrigin);
       
   158 		}
       
   159 	}
       
   160 
       
   161 void CWsGc::CancelClippingRegion()
       
   162 	{
       
   163 	if (iUserDefinedClippingRegion)
       
   164 		{
       
   165 		iUserDefinedClippingRegion->Destroy();
       
   166 		iUserDefinedClippingRegion=NULL;
       
   167 		}
       
   168 	}
       
   169 
       
   170 void CWsGc::CheckPolyData(const TAny* aDataPtr, TInt aHeaderSize, TInt aNumPoints)
       
   171 	{
       
   172 	TInt maxDataLen;
       
   173 	if (CWsClient::iCurrentCommand.iOpcode>0)
       
   174 		{
       
   175 		maxDataLen=CWsClient::EndOfCommandBuffer()-static_cast<const TUint8*>(aDataPtr);
       
   176 		}
       
   177 	else	// Playing back from redraw store
       
   178 		{
       
   179 		maxDataLen=CWsClient::iCurrentCommand.iCmdLength;
       
   180 		}
       
   181 	const TInt dataSize=aHeaderSize+aNumPoints*sizeof(TPoint);
       
   182 	if (dataSize>maxDataLen)
       
   183 		GcOwnerPanic(EWservPanicBadPolyData);
       
   184 	}
       
   185 
       
   186 void CWsGc::DoDrawPolygon(const TWsGcCmdDrawPolygon *aDrawPolygon)
       
   187 	{
       
   188 	CheckPolyData(aDrawPolygon,sizeof(TWsGcCmdDrawPolygon),aDrawPolygon->numPoints);
       
   189 	iGdi->DrawPolygon((TPoint *)(aDrawPolygon+1),aDrawPolygon->numPoints,aDrawPolygon->fillRule);
       
   190 	}
       
   191 
       
   192 void CWsGc::StartSegmentedDrawPolygonL(const TWsGcCmdStartSegmentedDrawPolygon* aDrawPolygon)
       
   193 	{
       
   194 	if (iPolyPoints || !Rng(0, aDrawPolygon->totalNumPoints, KMaxTInt/2 - 1))	// Restarting without finishing old polygon or invalid size
       
   195 		GcOwnerPanic(EWservPanicBadPolyData);
       
   196 	iPolyPoints=(TPoint *)User::AllocL(aDrawPolygon->totalNumPoints*sizeof(TPoint));
       
   197 	iPolyPointListSize=aDrawPolygon->totalNumPoints;
       
   198 	}
       
   199 
       
   200 void CWsGc::SegmentedDrawPolygonData(const TWsGcCmdSegmentedDrawPolygonData* aDrawPolygon)
       
   201 	{
       
   202 	if (aDrawPolygon->index<0 || (aDrawPolygon->index+aDrawPolygon->numPoints)>iPolyPointListSize)
       
   203 		GcOwnerPanic(EWservPanicBadPolyData);
       
   204 	Mem::Copy(iPolyPoints+aDrawPolygon->index,aDrawPolygon+1,aDrawPolygon->numPoints*sizeof(TPoint));
       
   205 	}
       
   206 
       
   207 void CWsGc::EndSegmentedPolygon()
       
   208 	{
       
   209 	delete iPolyPoints;
       
   210 	iPolyPoints=NULL;
       
   211 	iPolyPointListSize = 0;
       
   212 	}
       
   213 
       
   214 void CWsGc::DoDrawPolyLine(const TWsGcCmdDrawPolyLine *aDrawPolyLine, TBool aContinued)
       
   215 	{
       
   216 	TInt numPoints=aDrawPolyLine->numPoints;
       
   217 	CheckPolyData(aDrawPolyLine,sizeof(TWsGcCmdDrawPolyLine),numPoints);
       
   218 	const TPoint *points=(TPoint *)(aDrawPolyLine+1);
       
   219 	if (aContinued)
       
   220 		{
       
   221 		numPoints++;
       
   222 		points=&aDrawPolyLine->last;
       
   223 		}
       
   224 	if (aDrawPolyLine->more)	// more to come so don't draw the end point
       
   225 		iGdi->DrawPolyLineNoEndPoint(points,numPoints);
       
   226 	else
       
   227 		iGdi->DrawPolyLine(points,numPoints);
       
   228 	}
       
   229 
       
   230 void CWsGc::GcOwnerPanic(TClientPanic aPanic)
       
   231 	{
       
   232 	iGdi->SetClippingRegion(NULL);
       
   233 	EndSegmentedPolygon();
       
   234 	iWin->WsOwner()->PPanic(aPanic);
       
   235 	}
       
   236 	
       
   237 TPtrC CWsGc::BufferTPtr(TText* aStart,TInt aLen)
       
   238 	{
       
   239 	TPtrC gcPtr;
       
   240 	if (!CWsClient::BufferTPtrGc(aStart,aLen,gcPtr))
       
   241 		GcOwnerPanic(EWservPanicBufferPtr);
       
   242 	return(gcPtr);
       
   243 	}
       
   244 
       
   245 void CWsGc::DoDrawCommand(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData, const TRegion *aRegion)
       
   246 	{
       
   247 	if (aRegion)
       
   248 		{
       
   249 		WS_ASSERT_DEBUG(iWin,EWsPanicWindowNull);
       
   250 		if (aRegion->Count()==0)
       
   251 			return;
       
   252 		if (aRegion->IsContainedBy(TRect(TPoint(0,0), iGdi->Device()->SizeInPixels())))
       
   253 			{
       
   254 			iGdi->SetClippingRegion(aRegion);
       
   255 			}
       
   256 		}
       
   257 	switch(aOpcode)
       
   258 		{
       
   259 		case EWsGcOpDrawWsGraphic:
       
   260 		case EWsGcOpDrawWsGraphicPtr:
       
   261 			{
       
   262 			// CWsGc doesn't support CRPs.  CPlaybackGc does.  This means backedup windows
       
   263 			// don't get to play with them yet.
       
   264 			break;
       
   265 			}
       
   266 		case EWsGcOpMapColorsLocal:
       
   267 			iGdi->MapColors(pData.MapColorsLocal->rect, pData.MapColorsLocal->colors,pData.MapColorsLocal->numPairs,pData.MapColorsLocal->mapForwards);
       
   268 			break;
       
   269 		case EWsGcOpDrawPolyLineLocalBufLen:
       
   270 			iGdi->DrawPolyLine(pData.DrawPolyLineLocalBufLen->points,pData.DrawPolyLineLocalBufLen->length);
       
   271 			break;
       
   272 		case EWsGcOpDrawPolyLineLocal:
       
   273 			iGdi->DrawPolyLine(pData.PointList);
       
   274 			break;
       
   275 		case EWsGcOpDrawPolygonLocalBufLen:
       
   276 			iGdi->DrawPolygon(pData.DrawPolygonLocalBufLen->points,pData.DrawPolygonLocalBufLen->length,pData.DrawPolygonLocalBufLen->fillRule);
       
   277 			break;
       
   278 		case EWsGcOpDrawPolygonLocal:
       
   279 			iGdi->DrawPolygon(pData.DrawPolygonLocal->pointList,pData.DrawPolygonLocal->fillRule);
       
   280 			break;
       
   281 		case EWsGcOpDrawBitmapLocal:
       
   282 			iGdi->DrawBitmap(pData.BitmapLocal->pos, pData.BitmapLocal->bitmap);
       
   283 			break;
       
   284 		case EWsGcOpDrawBitmap2Local:
       
   285 			iGdi->DrawBitmap(pData.Bitmap2Local->rect, pData.Bitmap2Local->bitmap);
       
   286 			break;
       
   287 		case EWsGcOpDrawBitmap3Local:
       
   288 			iGdi->DrawBitmap(pData.Bitmap3Local->rect, pData.Bitmap3Local->bitmap, pData.Bitmap3Local->srcRect);
       
   289 			break;
       
   290 		case EWsGcOpDrawBitmapMaskedLocal:
       
   291 			iGdi->DrawBitmapMasked(pData.iBitmapMaskedLocal->iRect, pData.iBitmapMaskedLocal->iBitmap, pData.iBitmapMaskedLocal->iSrcRect, pData.iBitmapMaskedLocal->iMaskBitmap,pData.iBitmapMaskedLocal->iInvertMask);
       
   292 			break;
       
   293 		case EWsGcOpAlphaBlendBitmapsLocal:
       
   294 			iGdi->AlphaBlendBitmaps(pData.AlphaBlendBitmapsLocal->point,pData.AlphaBlendBitmapsLocal->iBitmap,
       
   295 						   			pData.AlphaBlendBitmapsLocal->source, pData.AlphaBlendBitmapsLocal->iAlpha,
       
   296 									pData.AlphaBlendBitmapsLocal->alphaPoint);
       
   297 
       
   298 			break;
       
   299 		case EWsGcOpDrawText:
       
   300 			iGdi->DrawText(BufferTPtr((TText *)(pData.DrawText+1),pData.DrawText->length),pData.DrawText->pos);
       
   301 			break;
       
   302 		case EWsGcOpDrawBoxTextOptimised1:
       
   303 			iGdi->DrawText(BufferTPtr((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length),pData.BoxTextO1->box,
       
   304 							pData.BoxTextO1->baselineOffset,CGraphicsContext::ELeft,0);
       
   305 			break;
       
   306 		case EWsGcOpDrawBoxTextOptimised2:
       
   307 			iGdi->DrawText(BufferTPtr((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length),pData.BoxTextO2->box,
       
   308 							pData.BoxTextO2->baselineOffset,pData.BoxTextO2->horiz,pData.BoxTextO2->leftMrg);
       
   309 			break;
       
   310 		case EWsGcOpDrawTextPtr:
       
   311 			iGdi->DrawText(*pData.DrawTextPtr->text,pData.DrawTextPtr->pos);
       
   312 			break;
       
   313 		case EWsGcOpDrawTextPtr1:
       
   314 		   	iGdi->DrawText(*pData.DrawTextPtr->text);
       
   315 			break;
       
   316 		case EWsGcOpDrawBoxText:
       
   317 			iGdi->DrawText(BufferTPtr((TText *)(pData.BoxText+1),pData.BoxText->length),pData.BoxText->box,pData.BoxText->baselineOffset,pData.BoxText->width,pData.BoxText->horiz,pData.BoxText->leftMrg);
       
   318 			break;
       
   319 		case EWsGcOpDrawBoxTextPtr:
       
   320 			iGdi->DrawText(*pData.DrawBoxTextPtr->text,pData.DrawBoxTextPtr->box,pData.DrawBoxTextPtr->baselineOffset,pData.DrawBoxTextPtr->width,pData.DrawBoxTextPtr->horiz,pData.DrawBoxTextPtr->leftMrg);
       
   321 			break;
       
   322 		case EWsGcOpDrawBoxTextPtr1:
       
   323 			iGdi->DrawText(*pData.DrawBoxTextPtr->text,pData.DrawBoxTextPtr->box);
       
   324 			break;
       
   325 		case EWsGcOpDrawTextVertical:
       
   326 			iGdi->DrawTextVertical(BufferTPtr((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length),pData.DrawTextVertical->pos
       
   327 							,pData.DrawTextVertical->up);
       
   328 			break;
       
   329 		case EWsGcOpDrawTextVerticalPtr:
       
   330 			iGdi->DrawTextVertical(*pData.DrawTextVerticalPtr->text,pData.DrawTextVerticalPtr->pos,pData.DrawTextVerticalPtr->up);
       
   331 			break;
       
   332 		case EWsGcOpDrawTextVerticalPtr1:
       
   333 			iGdi->DrawTextVertical(*pData.DrawTextVerticalPtr->text,pData.DrawTextVerticalPtr->up);
       
   334 			break;
       
   335 		case EWsGcOpDrawBoxTextVertical:
       
   336 			iGdi->DrawTextVertical(BufferTPtr((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length),
       
   337 							pData.DrawBoxTextVertical->box,	pData.DrawBoxTextVertical->baselineOffset,
       
   338 							pData.DrawBoxTextVertical->up,(CGraphicsContext::TTextAlign)pData.DrawBoxTextVertical->vert,pData.DrawBoxTextVertical->margin);
       
   339 			break;
       
   340 		case EWsGcOpDrawBoxTextVerticalPtr:
       
   341 			iGdi->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->baselineOffset
       
   342 							,pData.DrawBoxTextVerticalPtr->width,pData.DrawBoxTextVerticalPtr->up,pData.DrawBoxTextVerticalPtr->vert,pData.DrawBoxTextVerticalPtr->margin);
       
   343 			break;
       
   344 		case EWsGcOpDrawBoxTextVerticalPtr1:
       
   345 			iGdi->DrawTextVertical(*pData.DrawBoxTextVerticalPtr->text,pData.DrawBoxTextVerticalPtr->box,pData.DrawBoxTextVerticalPtr->up);
       
   346 			break;
       
   347 		case EWsGcOpDrawTextLocal:
       
   348 			iGdi->DrawText(*pData.DrawTextLocal->desc,pData.DrawTextLocal->pos);
       
   349 			break;
       
   350 		case EWsGcOpDrawBoxTextLocal:
       
   351 			iGdi->DrawText(*pData.BoxTextLocal->desc,pData.BoxTextLocal->box,pData.BoxTextLocal->baselineOffset,
       
   352 							pData.BoxTextLocal->horiz,pData.BoxTextLocal->leftMrg);
       
   353 			break;
       
   354 		case EWsGcOpDrawLine:
       
   355 			iGdi->DrawLine(pData.DrawLine->pnt1,pData.DrawLine->pnt2);
       
   356 			break;
       
   357 		case EWsGcOpDrawTo:
       
   358 			iGdi->DrawLine(iLinePos,*pData.Point);
       
   359 			break;
       
   360 		case EWsGcOpDrawBy:
       
   361 			iGdi->DrawLine(iLinePos,iLinePos+(*pData.Point));
       
   362 			break;
       
   363 		case EWsGcOpPlot:
       
   364 			iGdi->Plot(*pData.Point);
       
   365 			break;
       
   366 		case EWsGcOpMoveTo:
       
   367 		case EWsGcOpMoveBy:
       
   368 			break;
       
   369 		case EWsGcOpGdiBlt2Local:
       
   370 			iGdi->BitBlt(pData.GdiBlt2Local->pos,pData.GdiBlt2Local->bitmap);
       
   371 			break;
       
   372 		case EWsGcOpGdiBlt3Local:
       
   373 			iGdi->BitBlt(pData.GdiBlt3Local->pos,pData.GdiBlt3Local->bitmap, pData.GdiBlt3Local->rect);
       
   374 			break;
       
   375 		case EWsGcOpGdiBltMaskedLocal:
       
   376 			iGdi->BitBltMasked(pData.GdiBltMaskedLocal->pos,pData.GdiBltMaskedLocal->bitmap,
       
   377 								pData.GdiBltMaskedLocal->rect,pData.GdiBltMaskedLocal->maskBitmap,
       
   378 								pData.GdiBltMaskedLocal->invertMask);
       
   379 			break;
       
   380 		case EWsGcOpGdiWsBlt2:
       
   381 		case EWsGcOpGdiWsBlt3:
       
   382 		case EWsGcOpGdiWsBltMasked:
       
   383 		case EWsGcOpGdiWsAlphaBlendBitmaps:
       
   384 		case EWsGcOpWsDrawBitmapMasked:
       
   385 			{
       
   386 			CFbsBitmap* scratchBimap=iScratchBitmap;
       
   387 			CFbsBitmap* scratchMaskBimap=iScratchMaskBitmap;
       
   388 			TInt maskHandle=0;
       
   389 			TInt handle=WsBitmapHandle(aOpcode,pData, maskHandle);
       
   390 			CWsClient* owner=iWin->WsOwner(); // We can't just use iWsOwner - it can be null for stored commands
       
   391 			if (owner!=NULL)
       
   392 				{
       
   393 				DWsBitmap *bitmap=(DWsBitmap *)owner->HandleToObj(handle, WS_HANDLE_BITMAP);
       
   394 				if (!bitmap)
       
   395 					GcOwnerPanic(EWservPanicBitmap);
       
   396 				scratchBimap=bitmap->FbsBitmap();
       
   397 				if (aOpcode==EWsGcOpGdiWsBltMasked || aOpcode==EWsGcOpGdiWsAlphaBlendBitmaps || aOpcode==EWsGcOpWsDrawBitmapMasked)
       
   398 					{
       
   399 					DWsBitmap *bitmap2=(DWsBitmap *)owner->HandleToObj(maskHandle, WS_HANDLE_BITMAP);
       
   400 					if (!bitmap2)
       
   401 						GcOwnerPanic(EWservPanicBitmap);
       
   402 					scratchMaskBimap=bitmap2->FbsBitmap();
       
   403 					}
       
   404 				}
       
   405 			else 
       
   406 				{
       
   407 				GcOwnerPanic(EWservPanicBitmap);
       
   408 				}
       
   409 			switch(aOpcode)
       
   410 				{
       
   411 				case EWsGcOpGdiWsBlt2:
       
   412 					iGdi->BitBlt(pData.GdiBlt2->pos,scratchBimap);
       
   413 					break;
       
   414 				case EWsGcOpGdiWsBlt3:
       
   415 					iGdi->BitBlt(pData.GdiBlt3->pos,scratchBimap, pData.GdiBlt3->rect);
       
   416 					break;
       
   417 				case EWsGcOpGdiWsBltMasked:
       
   418 					{
       
   419 					iGdi->BitBltMasked(pData.GdiBltMasked->destination,scratchBimap,
       
   420 									pData.GdiBltMasked->source, scratchMaskBimap,
       
   421 									pData.GdiBltMasked->invertMask);
       
   422 					}
       
   423 					break;
       
   424 				case EWsGcOpGdiWsAlphaBlendBitmaps:
       
   425 					{
       
   426 					iGdi->AlphaBlendBitmaps(pData.AlphaBlendBitmaps->point,scratchBimap,
       
   427 									   pData.AlphaBlendBitmaps->source, scratchMaskBimap,
       
   428 									   pData.AlphaBlendBitmaps->alphaPoint);
       
   429 					}
       
   430 					break;
       
   431 				case EWsGcOpWsDrawBitmapMasked:
       
   432 					{
       
   433 					iGdi->DrawBitmapMasked(pData.iBitmapMasked->iRect,scratchBimap, 
       
   434 										pData.iBitmapMasked->iSrcRect,scratchMaskBimap,
       
   435 										pData.iBitmapMasked->iInvertMask);
       
   436 					}
       
   437 					break;
       
   438 				}
       
   439 			break;
       
   440 			}
       
   441 		case EWsGcOpGdiBlt2:
       
   442 		case EWsGcOpGdiBlt3:
       
   443 		case EWsGcOpGdiBltMasked:
       
   444 		case EWsGcOpGdiAlphaBlendBitmaps:
       
   445 		case EWsGcOpDrawBitmap:
       
   446 		case EWsGcOpDrawBitmap2:
       
   447 		case EWsGcOpDrawBitmap3:
       
   448 		case EWsGcOpDrawBitmapMasked:
       
   449 			{
       
   450 			TInt maskHandle=0;
       
   451 			TInt ret = iScratchBitmap->Duplicate(FbsBitmapHandle(aOpcode, pData,maskHandle));
       
   452 			if(ret == KErrNoMemory)
       
   453 				break;	
       
   454 			if (ret !=KErrNone)
       
   455 				GcOwnerPanic(EWservPanicBitmap);
       
   456 			
       
   457 			switch(aOpcode)
       
   458 				{
       
   459 				case EWsGcOpGdiBlt2:
       
   460 					iGdi->BitBlt(pData.GdiBlt2->pos,iScratchBitmap);
       
   461 					break;
       
   462 				case EWsGcOpGdiBlt3:
       
   463 					iGdi->BitBlt(pData.GdiBlt3->pos,iScratchBitmap, pData.GdiBlt3->rect);
       
   464 					break;
       
   465 				case EWsGcOpGdiBltMasked:
       
   466 					{
       
   467 					TInt ret = iScratchMaskBitmap->Duplicate(pData.GdiBltMasked->maskHandle);
       
   468 					if(ret == KErrNoMemory)
       
   469 						break;	
       
   470 					if (ret !=KErrNone)
       
   471 						GcOwnerPanic(EWservPanicBitmap);
       
   472 			
       
   473 					iGdi->BitBltMasked(pData.GdiBltMasked->destination,iScratchBitmap,
       
   474 										pData.GdiBltMasked->source, iScratchMaskBitmap,
       
   475 										 pData.GdiBltMasked->invertMask);
       
   476 					iScratchMaskBitmap->Reset();
       
   477 					}
       
   478 					break;
       
   479 				case EWsGcOpGdiAlphaBlendBitmaps:
       
   480 					{
       
   481 					TInt ret = iScratchMaskBitmap->Duplicate(pData.AlphaBlendBitmaps->alphaHandle);
       
   482 					if (ret == KErrNoMemory)
       
   483 						break;	
       
   484 					if (ret != KErrNone)
       
   485 						GcOwnerPanic(EWservPanicBitmap);
       
   486 
       
   487 					iGdi->AlphaBlendBitmaps(pData.AlphaBlendBitmaps->point, iScratchBitmap,
       
   488 									   pData.AlphaBlendBitmaps->source, iScratchMaskBitmap,
       
   489 									   pData.AlphaBlendBitmaps->alphaPoint);
       
   490 					iScratchMaskBitmap->Reset();
       
   491 					break;
       
   492 					}
       
   493 				case EWsGcOpDrawBitmap:
       
   494 					iGdi->DrawBitmap(pData.Bitmap->pos, iScratchBitmap);
       
   495 					break;
       
   496 				case EWsGcOpDrawBitmap2:
       
   497 					iGdi->DrawBitmap(pData.Bitmap2->rect, iScratchBitmap);
       
   498 					break;
       
   499 				case EWsGcOpDrawBitmap3:
       
   500 					iGdi->DrawBitmap(pData.Bitmap3->rect, iScratchBitmap, pData.Bitmap3->srcRect);
       
   501 					break;
       
   502 				case EWsGcOpDrawBitmapMasked:
       
   503 					{
       
   504 					TInt ret = iScratchMaskBitmap->Duplicate(pData.iBitmapMasked->iMaskHandle);
       
   505 					if (ret == KErrNoMemory)
       
   506 						break;	
       
   507 					if (ret != KErrNone)
       
   508 						GcOwnerPanic(EWservPanicBitmap);
       
   509 
       
   510 					iGdi->DrawBitmapMasked(pData.iBitmapMasked->iRect, iScratchBitmap, 
       
   511 										pData.iBitmapMasked->iSrcRect, iScratchMaskBitmap,
       
   512 										pData.iBitmapMasked->iInvertMask);
       
   513 					iScratchMaskBitmap->Reset();
       
   514 					}
       
   515 					break;
       
   516 				}
       
   517 			iScratchBitmap->Reset();
       
   518 			break;
       
   519 			}
       
   520 		case EWsGcOpDrawSegmentedPolygon:
       
   521 			iGdi->DrawPolygon(iPolyPoints,iPolyPointListSize,pData.DrawSegmentedPolygon->fillRule);
       
   522 			break;
       
   523 		case EWsGcOpDrawPolygon:
       
   524 			DoDrawPolygon(pData.Polygon);
       
   525 			break;
       
   526 		case EWsGcOpDrawPolyLine:
       
   527 			DoDrawPolyLine(pData.PolyLine, EFalse);
       
   528 			break;
       
   529 		case EWsGcOpDrawPolyLineContinued:
       
   530 			DoDrawPolyLine(pData.PolyLine, ETrue);
       
   531 			break;
       
   532 		case EWsGcOpClear:
       
   533 			iGdi->Clear(TRect(iWin->Size()));
       
   534 			break;
       
   535 		case EWsGcOpClearRect:
       
   536 			iGdi->Clear(*pData.Rect);
       
   537 			break;
       
   538 		case EWsGcOpDrawRect:
       
   539 			iGdi->DrawRect(*pData.Rect);
       
   540 			break;
       
   541 		case EWsGcOpDrawEllipse:
       
   542 			iGdi->DrawEllipse(*pData.Rect);
       
   543 			break;
       
   544 		case EWsGcOpDrawRoundRect:
       
   545 			iGdi->DrawRoundRect(*pData.Rect,pData.RoundRect->ellipse);
       
   546 			break;
       
   547 		case EWsGcOpDrawArc:
       
   548 			iGdi->DrawArc(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
       
   549 			break;
       
   550 		case EWsGcOpDrawPie:
       
   551 			iGdi->DrawPie(*pData.Rect,pData.ArcOrPie->start,pData.ArcOrPie->end);
       
   552 			break;
       
   553 		case EWsGcOpCopyRect:
       
   554 			iGdi->CopyRect(pData.CopyRect->pos,*pData.Rect);
       
   555 			break;
       
   556 		case EWsGcOpMapColors:
       
   557 			iGdi->MapColors(pData.MapColors->rect,(TRgb *)(pData.MapColors+1),pData.MapColors->numPairs,pData.MapColors->mapForwards);
       
   558 			break;
       
   559 			
       
   560 		default:
       
   561 			GcOwnerPanic(EWservPanicOpcode);
       
   562 		}
       
   563 	iGdi->SetClippingRegion(NULL);
       
   564 	}
       
   565 
       
   566 TInt CWsGc::WsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle) 
       
   567 	{
       
   568 	TInt handle=0;
       
   569 	switch(aOpcode)
       
   570 		{
       
   571 		case EWsGcOpGdiWsBlt2:
       
   572 			handle=pData.GdiBlt2->handle;
       
   573 			break;
       
   574 		case EWsGcOpGdiWsBlt3:
       
   575 			handle=pData.GdiBlt3->handle;
       
   576 			break;
       
   577 		case EWsGcOpGdiWsBltMasked:
       
   578 			handle=pData.GdiBltMasked->handle;
       
   579 			aMaskHandle = pData.GdiBltMasked->maskHandle;
       
   580 			break;
       
   581 		case EWsGcOpGdiWsAlphaBlendBitmaps:
       
   582 			handle=pData.AlphaBlendBitmaps->bitmapHandle;
       
   583 			aMaskHandle = pData.AlphaBlendBitmaps->alphaHandle;
       
   584 			break;
       
   585 		case EWsGcOpWsDrawBitmapMasked:
       
   586 			handle=pData.iBitmapMasked->iHandle;
       
   587 			aMaskHandle=pData.iBitmapMasked->iMaskHandle;
       
   588 			break;
       
   589 		default:
       
   590 			OwnerPanic(EWservPanicOpcode);
       
   591 		}
       
   592 	return handle;
       
   593 	}		
       
   594 
       
   595 TInt CWsGc::FbsBitmapHandle(TInt aOpcode, const TWsGcCmdUnion &pData, TInt& aMaskHandle)
       
   596 	{
       
   597 	TInt handle=0;
       
   598 	aMaskHandle=0;
       
   599 	switch(aOpcode)
       
   600 		{
       
   601 		case EWsGcOpGdiBlt2:
       
   602 			handle=pData.GdiBlt2->handle;
       
   603 			break;
       
   604 		case EWsGcOpGdiBlt3:
       
   605 			handle=pData.GdiBlt3->handle;
       
   606 			break;
       
   607 		case EWsGcOpGdiBltMasked:
       
   608 			handle=pData.GdiBltMasked->handle;
       
   609 			aMaskHandle=pData.GdiBltMasked->maskHandle;
       
   610 			break;
       
   611 		case EWsGcOpGdiAlphaBlendBitmaps:
       
   612 			handle=pData.AlphaBlendBitmaps->bitmapHandle;
       
   613 			aMaskHandle=pData.AlphaBlendBitmaps->alphaHandle;
       
   614 			break;
       
   615 		case EWsGcOpDrawBitmap:
       
   616 			handle=pData.Bitmap->handle;
       
   617 			break;
       
   618 		case EWsGcOpDrawBitmap2:
       
   619 			handle=pData.Bitmap2->handle;
       
   620 			break;
       
   621 		case EWsGcOpDrawBitmap3:
       
   622 			handle=pData.Bitmap3->handle;
       
   623 			break;
       
   624 		case EWsGcOpDrawBitmapMasked:
       
   625 			handle=pData.iBitmapMasked->iHandle;
       
   626 			aMaskHandle=pData.iBitmapMasked->iMaskHandle;
       
   627 			break;
       
   628 		default:
       
   629 			OwnerPanic(EWservPanicOpcode);
       
   630 		}
       
   631 	return handle;
       
   632 	}
       
   633 
       
   634 
       
   635 void CWsGc::UpdateJustification(TText* aText,TInt aLen)
       
   636 	{
       
   637 	iGdi->UpdateJustification(BufferTPtr(aText,aLen));
       
   638 	}
       
   639 
       
   640 void CWsGc::DoDrawing2(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData)
       
   641 	{
       
   642 	iGdi->SetUserDisplayMode(iWin->DisplayMode());
       
   643 	if (iClippingRectSet)
       
   644 		{
       
   645 		iGdi->SetOrigin(TPoint(0,0));
       
   646 		iGdi->SetClippingRect(iClippingRect);
       
   647 		}
       
   648 	iGdi->SetOrigin(iOrigin);
       
   649 	
       
   650 	DoDrawCommand(aOpcode,pData,iUserDefinedClippingRegion);
       
   651 
       
   652 	iGdi->SetUserDisplayMode(ENone);
       
   653 	iGdi->CancelClippingRect();
       
   654 	switch(aOpcode)
       
   655 		{
       
   656 		case EWsGcOpDrawLine:
       
   657 			iLinePos=pData.DrawLine->pnt2;
       
   658 			break;
       
   659 		case EWsGcOpDrawTo:
       
   660 		case EWsGcOpMoveTo:
       
   661 		case EWsGcOpPlot:
       
   662 			iLinePos=(*pData.Point);
       
   663 			break;
       
   664 		case EWsGcOpDrawBy:
       
   665 		case EWsGcOpMoveBy:
       
   666 			iLinePos+=(*pData.Point);
       
   667 			break;
       
   668 		case EWsGcOpDrawSegmentedPolygon:
       
   669 			EndSegmentedPolygon();
       
   670 			break;
       
   671 		case EWsGcOpDrawText:
       
   672 			UpdateJustification((TText *)(pData.DrawText+1),pData.DrawText->length);
       
   673 			break;
       
   674 		case EWsGcOpDrawTextVertical:
       
   675 			UpdateJustification((TText *)(pData.DrawTextVertical+1),pData.DrawTextVertical->length);
       
   676 			break;
       
   677 		case EWsGcOpDrawBoxText:
       
   678 			UpdateJustification((TText *)(pData.BoxText+1),pData.BoxText->length);
       
   679 			break;
       
   680 		case EWsGcOpDrawBoxTextOptimised1:
       
   681 			UpdateJustification((TText *)(pData.BoxTextO1+1),pData.BoxTextO1->length);
       
   682 			break;
       
   683 		case EWsGcOpDrawBoxTextOptimised2:
       
   684 			UpdateJustification((TText *)(pData.BoxTextO2+1),pData.BoxTextO2->length);
       
   685 			break;
       
   686 		case EWsGcOpDrawBoxTextVertical:
       
   687 			UpdateJustification((TText *)(pData.DrawBoxTextVertical+1),pData.DrawBoxTextVertical->length);
       
   688 			break;
       
   689 		case EWsGcOpDrawTextLocal:
       
   690 			iGdi->UpdateJustification(*pData.DrawTextLocal->desc);
       
   691 			break;
       
   692 		case EWsGcOpDrawBoxTextLocal:
       
   693 			iGdi->UpdateJustification(*pData.BoxTextLocal->desc);
       
   694 			break;
       
   695 		case EWsGcOpDrawTextPtr:
       
   696 			iGdi->UpdateJustification(*pData.DrawTextPtr->text);
       
   697 			break;
       
   698 		case EWsGcOpDrawTextVerticalPtr:
       
   699 			iGdi->UpdateJustification(*pData.DrawTextVerticalPtr->text);
       
   700 			break;
       
   701 		case EWsGcOpDrawBoxTextPtr:
       
   702 			iGdi->UpdateJustification(*pData.DrawBoxTextPtr->text);
       
   703 			break;
       
   704 		case EWsGcOpDrawBoxTextVerticalPtr:
       
   705 			iGdi->UpdateJustification(*pData.DrawBoxTextVerticalPtr->text);
       
   706 			break;
       
   707 		}
       
   708 	}
       
   709 
       
   710 void CWsGc::DoDrawing1(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData)
       
   711 	{
       
   712 	TWsGcLargeStruct newData;
       
   713 	TWsGcCmdUnion pNewData;
       
   714 	TWsGcOpcodes opcode;
       
   715 	TDesC **string;
       
   716 	TInt toGo;
       
   717 	pNewData.LargeStruct=&newData;
       
   718 	switch (aOpcode)
       
   719 		{
       
   720 		case EWsGcOpDrawTextPtr:
       
   721 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdDrawTextPtr), EWsPanicGcStructSizeError);
       
   722 			opcode=EWsGcOpDrawTextPtr1;
       
   723 			toGo=pData.DrawText->length;
       
   724 			pNewData.DrawTextPtr->pos=pData.DrawText->pos;
       
   725 			string=&(pNewData.DrawTextPtr->text);
       
   726 			break;
       
   727 		case EWsGcOpDrawTextVerticalPtr:
       
   728 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdDrawTextVerticalPtr), EWsPanicGcStructSizeError);
       
   729 			opcode=EWsGcOpDrawTextVerticalPtr1;
       
   730 			toGo=pData.DrawTextVertical->length;
       
   731 			pNewData.DrawTextVerticalPtr->pos=pData.DrawTextVertical->pos;
       
   732 			pNewData.DrawTextVerticalPtr->up=pData.DrawTextVertical->up;
       
   733 			string=&(pNewData.DrawTextVerticalPtr->text);
       
   734 			break;
       
   735 			
       
   736 		case EWsGcOpDrawBoxTextPtr:
       
   737 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdBoxTextPtr), EWsPanicGcStructSizeError);
       
   738 			opcode=EWsGcOpDrawBoxTextPtr1;
       
   739 			toGo=pData.BoxText->length;
       
   740 			pNewData.DrawBoxTextPtr->box=pData.BoxText->box;
       
   741 			pNewData.DrawBoxTextPtr->baselineOffset=pData.BoxText->baselineOffset;
       
   742 			pNewData.DrawBoxTextPtr->horiz=pData.BoxText->horiz;
       
   743 			pNewData.DrawBoxTextPtr->leftMrg=pData.BoxText->leftMrg;
       
   744 			pNewData.DrawBoxTextPtr->width=pData.BoxText->width;
       
   745 			string=&(pNewData.DrawBoxTextPtr->text);
       
   746 			break;
       
   747 			
       
   748 		case EWsGcOpDrawBoxTextVerticalPtr:
       
   749 			WS_ASSERT_DEBUG(sizeof(TWsGcLargeStruct)>=sizeof(TWsGcCmdBoxTextVerticalPtr), EWsPanicGcStructSizeError);
       
   750 			opcode=EWsGcOpDrawBoxTextVerticalPtr1;
       
   751 			toGo=pData.DrawBoxTextVertical->length;
       
   752 			pNewData.DrawBoxTextVerticalPtr->box=pData.DrawBoxTextVertical->box;
       
   753 			pNewData.DrawBoxTextVerticalPtr->baselineOffset=pData.DrawBoxTextVertical->baselineOffset;
       
   754 			pNewData.DrawBoxTextVerticalPtr->up=pData.DrawBoxTextVertical->up;
       
   755 			pNewData.DrawBoxTextVerticalPtr->vert=pData.DrawBoxTextVertical->vert;
       
   756 			pNewData.DrawBoxTextVerticalPtr->margin=pData.DrawBoxTextVertical->margin;
       
   757 			pNewData.DrawBoxTextVerticalPtr->width=pData.DrawBoxTextVertical->width;
       
   758 			string=&(pNewData.DrawBoxTextVerticalPtr->text);
       
   759 			break;
       
   760 
       
   761 		default:
       
   762 			DoDrawing2(aOpcode,pData);
       
   763 			return;
       
   764 		}
       
   765 
       
   766 	TBuf<ETextPtrBufLen> buf;
       
   767 	TInt len=ETextPtrBufLen;
       
   768 	TInt bufOffset=0;
       
   769 	*string=&buf;
       
   770 	while(toGo>0)
       
   771 		{
       
   772 		if (len>toGo)
       
   773 			len=toGo;
       
   774 		iWsOwner->RemoteRead(buf,bufOffset);
       
   775 		DoDrawing2(aOpcode,pNewData);
       
   776 		aOpcode=opcode;
       
   777 		bufOffset+=len;
       
   778 		toGo-=len;
       
   779 		}
       
   780 	}
       
   781 
       
   782 void CWsGc::SetGcAttribute(TInt aOpcode, TWsGcCmdUnion pData)
       
   783 	{
       
   784 	switch(aOpcode)
       
   785 		{
       
   786 		case EWsGcOpSetDrawMode:
       
   787 			iGdi->SetDrawMode((CGraphicsContext::TDrawMode)*pData.UInt);
       
   788 			break;
       
   789 		case EWsGcOpUseFont:
       
   790 			if (CWsFontCache::Instance()->UseFont(iFont, *pData.UInt))
       
   791 				{	// Couldn't cache it
       
   792 				TInt ret = iGdi->UseFont(*pData.UInt);
       
   793 				if (ret == KErrNoMemory)
       
   794 					return;
       
   795 				if (ret != KErrNone)
       
   796 					OwnerPanic(EWservPanicFont);
       
   797 				}
       
   798 			else
       
   799 				{
       
   800 				if (iFont==NULL)
       
   801 					OwnerPanic(EWservPanicFont);
       
   802 				iGdi->UseFontNoDuplicate(iFont);
       
   803 				}
       
   804 			break;
       
   805 		case EWsGcOpDiscardFont:
       
   806 			CWsFontCache::Instance()->ReleaseFont(iFont);
       
   807 			iGdi->DiscardFont();
       
   808 			break;
       
   809 		case EWsGcOpSetUnderlineStyle:
       
   810 			iGdi->SetUnderlineStyle(*pData.SetUnderlineStyle);
       
   811 			break;
       
   812 		case EWsGcOpSetStrikethroughStyle:
       
   813 			iGdi->SetStrikethroughStyle(*pData.SetStrikethroughStyle);
       
   814 			break;
       
   815 		case EWsGcOpUseBrushPattern:
       
   816 			{
       
   817 			TInt ret = iGdi->UseBrushPattern(*pData.handle);
       
   818 			if (ret == KErrNoMemory)
       
   819 				return;	
       
   820 			if (ret != KErrNone)
       
   821 				OwnerPanic(EWservPanicBitmap);
       
   822 			}
       
   823 			break;
       
   824 		case EWsGcOpDiscardBrushPattern:
       
   825 			iGdi->DiscardBrushPattern();
       
   826 			break;
       
   827 		case EWsGcOpSetBrushColor:
       
   828 			iGdi->SetBrushColor(*pData.rgb);
       
   829 			break;
       
   830 		case EWsGcOpSetPenColor:
       
   831 			iGdi->SetPenColor(*pData.rgb);
       
   832 			break;
       
   833 		case EWsGcOpSetPenStyle:
       
   834 			iGdi->SetPenStyle((CGraphicsContext::TPenStyle)*pData.UInt);
       
   835 			break;
       
   836 		case EWsGcOpSetPenSize:
       
   837 			iGdi->SetPenSize(*pData.Size);
       
   838 			break;
       
   839 		case EWsGcOpSetBrushStyle:
       
   840 			if ((CGraphicsContext::TBrushStyle)*pData.UInt==CGraphicsContext::EPatternedBrush &&
       
   841 				!iGdi->IsBrushPatternUsed())
       
   842 				OwnerPanic(EWservPanicNoBrush);
       
   843 			iGdi->SetBrushStyle((CGraphicsContext::TBrushStyle)*pData.UInt);
       
   844 			break;
       
   845 		case EWsGcOpReset:
       
   846 			CWsFontCache::Instance()->ReleaseFont(iFont);
       
   847 			iGdi->Reset();
       
   848 			iOrigin.SetXY(0,0);
       
   849 			ResetClippingRect();
       
   850 			iGdi->SetBrushColor(iWin->BackColor());
       
   851 			break;
       
   852 		case EWsGcOpSetBrushOrigin:
       
   853 			iGdi->SetBrushOrigin(*pData.Point);
       
   854 			break;
       
   855 		case EWsGcOpSetDitherOrigin:
       
   856 			iGdi->SetDitherOrigin(*pData.Point);
       
   857 			break;
       
   858 		case EWsGcOpSetWordJustification:
       
   859 			iGdi->SetWordJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
       
   860 			break;
       
   861 		case EWsGcOpSetCharJustification:
       
   862 			iGdi->SetCharJustification(pData.SetJustification->excessWidth, pData.SetJustification->numGaps);
       
   863 			break;
       
   864 		case EWsGcOpSetOrigin:
       
   865 			SetOrigin(*pData.Point);
       
   866 			break;
       
   867 		case EWsGcOpSetOpaque:
       
   868 			//SetOpaque(*pData.Bool);
       
   869 			break;
       
   870 		case EWsGcOpSetShadowColor:
       
   871 			iGdi->SetShadowColor(*pData.rgb);
       
   872 			break;
       
   873 		}
       
   874 	}
       
   875 
       
   876 void CWsGc::DoDrawing0L(TWsGcOpcodes aOpcode, const TWsGcCmdUnion &pData)
       
   877 	{
       
   878 	if (iWin==NULL)
       
   879 		{
       
   880 		OwnerPanic(EWservPanicGcNotActive);
       
   881 		return;
       
   882 		}
       
   883 			
       
   884 	switch(aOpcode)
       
   885 		{
       
   886 	case EWsGcOpStartSegmentedDrawPolygon:
       
   887 		// Andy - why are these two special cased like this?
       
   888 		//tell Redraw Store about the drawing data, so that it is stored and CWsGc::ExternalizeL can be called if required
       
   889 		if (iWin->Redraw()->DrawCommand(this,pData.any))
       
   890 			StartSegmentedDrawPolygonL(pData.StartSegmentedDrawPolygon);
       
   891 		return;
       
   892 	case EWsGcOpSegmentedDrawPolygonData:
       
   893 		//tell Redraw Store about the drawing data, so that it is stored and CWsGc::ExternalizeL can be called if required
       
   894 		if (iWin->Redraw()->DrawCommand(this,pData.any))
       
   895 				SegmentedDrawPolygonData(pData.SegmentedDrawPolygonData);
       
   896 		return;
       
   897 	case EWsGcOpSetClippingRegion:
       
   898 		SetClippingRegionL(*pData.Int);
       
   899 		break;
       
   900 	case EWsGcOpSetClippingRect:
       
   901 		SetClippingRect(*pData.Rect);
       
   902 		break;
       
   903 	case EWsGcOpCancelClippingRect:
       
   904 		ResetClippingRect();
       
   905 		break;
       
   906 	case EWsGcOpCancelClippingRegion:
       
   907 		CancelClippingRegion();
       
   908 		break;
       
   909 	case EWsGcOpSetFaded:
       
   910 		iGdi->SetFaded(*pData.Bool);
       
   911 		break;
       
   912 	case EWsGcOpSetFadeParams:
       
   913 		iGdi->SetFadingParameters(WservEncoding::ExtractFirst8BitValue(*pData.UInt),WservEncoding::ExtractSecond8BitValue(*pData.UInt));
       
   914 		break;
       
   915 	case EWsGcOpSetDrawMode:
       
   916 	case EWsGcOpUseFont:
       
   917 	case EWsGcOpDiscardFont:
       
   918 	case EWsGcOpUseBrushPattern:
       
   919 	case EWsGcOpDiscardBrushPattern:
       
   920 	case EWsGcOpSetBrushColor:
       
   921 	case EWsGcOpSetPenColor:
       
   922 	case EWsGcOpSetPenStyle:
       
   923 	case EWsGcOpSetPenSize:
       
   924 	case EWsGcOpSetBrushStyle:
       
   925 	case EWsGcOpReset:
       
   926 	case EWsGcOpSetBrushOrigin:
       
   927 	case EWsGcOpSetDitherOrigin:
       
   928 	case EWsGcOpSetUnderlineStyle:
       
   929 	case EWsGcOpSetStrikethroughStyle:
       
   930 	case EWsGcOpSetWordJustification:
       
   931 	case EWsGcOpSetCharJustification:
       
   932 	case EWsGcOpSetOrigin:
       
   933 	case EWsGcOpSetOpaque:
       
   934 	case EWsGcOpSetShadowColor:
       
   935 		{
       
   936 		SetGcAttribute(aOpcode,pData);
       
   937 		break;
       
   938 		}
       
   939 	case EWsGcOpDrawBoxText:	
       
   940 	case EWsGcOpDrawBoxTextOptimised1:
       
   941 	case EWsGcOpDrawBoxTextOptimised2:
       
   942 	case EWsGcOpDrawBoxTextPtr:
       
   943 	case EWsGcOpDrawBoxTextPtr1:
       
   944 	case EWsGcOpDrawTextPtr:
       
   945 	case EWsGcOpDrawTextPtr1:
       
   946 	case EWsGcOpDrawText:
       
   947 	case EWsGcOpDrawTextVertical:
       
   948 	case EWsGcOpDrawTextVerticalPtr:
       
   949 	case EWsGcOpDrawTextVerticalPtr1:
       
   950 	case EWsGcOpDrawBoxTextVertical:
       
   951 	case EWsGcOpDrawBoxTextVerticalPtr:
       
   952 	case EWsGcOpDrawBoxTextVerticalPtr1:
       
   953 	case EWsGcOpDrawTextLocal:
       
   954 	case EWsGcOpDrawBoxTextLocal:
       
   955 		{
       
   956 		//Make sure a font is set before any text related opcodes are used.
       
   957 		if (!iGdi->IsFontUsed())
       
   958 			OwnerPanic(EWservPanicNoFont);
       
   959 		//fall through
       
   960 		}
       
   961 	default:	// Assume remaining functions will draw
       
   962 		{
       
   963 		if (iWin->WinType()!=EWinTypeRoot)
       
   964 			{
       
   965 			if (!iWin->BaseParent())
       
   966 				OwnerPanic(EWservPanicParentDeleted);
       
   967 			if (iWin->WinType()!=EWinTypeClient)
       
   968 				OwnerPanic(EWservPanicReadOnlyDrawable);
       
   969 			}
       
   970 		if (iWin->Redraw()->DrawCommand(this,pData.any))
       
   971 			DoDrawing1(aOpcode,pData);
       
   972 		return;
       
   973 		}
       
   974 		}
       
   975 	iWin->Redraw()->GcAttributeChange(this,pData.any);
       
   976 	}
       
   977 
       
   978 void CWsGc::CommandL(TInt aOpcode, const TAny *aCmdData)
       
   979 	{
       
   980 	TWsGcOpcodes opcode = static_cast<TWsGcOpcodes>(aOpcode);
       
   981 
       
   982 	TWsGcCmdUnion pData;
       
   983 	pData.any=aCmdData;
       
   984 	switch(opcode)
       
   985 		{
       
   986 		case EWsGcOpActivate:
       
   987 			Activate(*pData.handle);
       
   988 			break;
       
   989 		case EWsGcOpDeactivate:
       
   990 			Deactivate();
       
   991 			break;
       
   992 		case EWsGcOpFree:
       
   993 			delete this;
       
   994 			break;
       
   995 		case EWsGcOpTestInvariant:
       
   996 			break;
       
   997 		default:
       
   998 			DoDrawing0L(opcode,pData);
       
   999 			break;
       
  1000 		}
       
  1001 	}
       
  1002 
       
  1003 void CWsGc::SetOrigin(const TPoint &aOrigin)
       
  1004 	{
       
  1005 	iOrigin=aOrigin;
       
  1006 	}
       
  1007 	
       
  1008 
       
  1009 void CWsGc::SetOpaque(TBool /*aDrawOpaque*/)
       
  1010 	{
       
  1011 	}
       
  1012 
       
  1013 /*------------------------------------------------------------------------------
       
  1014   Description: Saves graphics context information into a given buffer from a
       
  1015                given start position rather than just streaming data to the end.
       
  1016                This variant allows for buffers that are not fully utilised.
       
  1017  -----------------------------------------------------------------------------*/
       
  1018 TInt CWsGc::ExternalizeL(CBufBase& aBuffer, TInt aStartPos)
       
  1019 	{
       
  1020 	WS_ASSERT_DEBUG(!IsPolyPointData(), EWsPanicDrawCommandsInvalidState);
       
  1021 
       
  1022 	// Open the stream used for the output from the given start position
       
  1023 	// in the buffer.
       
  1024 	RBufWriteStream bufWriteStream;
       
  1025 	bufWriteStream.Open(aBuffer, aStartPos);
       
  1026 	CleanupClosePushL(bufWriteStream);
       
  1027 
       
  1028 	// Font/Bitmap Server data is serialised below in a call to 
       
  1029 	// CFbsBitGc::ExternalizeL(). As this method does not return the amount of
       
  1030 	// the data externalised we use methods in the underlying stream to 
       
  1031 	// calculate it. We do this because we need to return an accurate count of
       
  1032 	// data serialised from this method so that the caller can update its 
       
  1033 	// buffer write counter.
       
  1034 	MStreamBuf* ptrToRawStream = bufWriteStream.Sink();	// This is the real stream
       
  1035 
       
  1036 	// Position of read seek pointer before externalise
       
  1037 	TStreamPos size1 = ptrToRawStream->TellL(MStreamBuf::EWrite); 
       
  1038 
       
  1039 	// Save the font/bitmap server data
       
  1040 	iGdi->ExternalizeL(bufWriteStream);
       
  1041 
       
  1042 	bufWriteStream.WriteInt32L(iOrigin.iX);
       
  1043 	bufWriteStream.WriteInt32L(iOrigin.iY);
       
  1044 
       
  1045 	bufWriteStream.WriteInt8L(iClippingRectSet);
       
  1046 
       
  1047 	// If there is a clipping rectangle output that too.
       
  1048 	if (iClippingRectSet)
       
  1049 		{
       
  1050 		bufWriteStream << iClippingRect;
       
  1051 		}
       
  1052 		
       
  1053 	// Save clipping region data.
       
  1054 	ExternalizeClippingRegionL(bufWriteStream);
       
  1055 
       
  1056 	// Save the Alpha values for Brush and Pen colors.
       
  1057 	ExternalizeAlphaValueL(bufWriteStream);
       
  1058 
       
  1059 	// Position of read seek pointer after externalise
       
  1060 	TStreamPos size2 = ptrToRawStream->TellL(MStreamBuf::EWrite);
       
  1061 	CleanupStack::PopAndDestroy(&bufWriteStream);
       
  1062 
       
  1063 	// Return actual size of data serialized
       
  1064 	return (size2 - size1);
       
  1065 	}
       
  1066 
       
  1067 /*------------------------------------------------------------------------------
       
  1068   Description: Saves TRgb::alpha value information into a given buffer.
       
  1069   ----------------------------------------------------------------------------*/
       
  1070 void CWsGc::ExternalizeAlphaValueL(RWriteStream& aWriteStream)
       
  1071 	{
       
  1072 	aWriteStream.WriteUint8L(iGdi->BrushColor().Alpha());
       
  1073 	aWriteStream.WriteUint8L(iGdi->PenColor().Alpha());
       
  1074 	}
       
  1075 
       
  1076 /*------------------------------------------------------------------------------
       
  1077   Description: Helper method to store clipping region data to a given
       
  1078                write stream.
       
  1079  -----------------------------------------------------------------------------*/
       
  1080 TInt CWsGc::ExternalizeClippingRegionL(RWriteStream& aWriteStream)
       
  1081 	{
       
  1082 	TBool clipRegion = (iUserDefinedClippingRegion != NULL);
       
  1083 	// Store flag to indicate if client has defined a clipping region
       
  1084 	aWriteStream.WriteInt8L(clipRegion);
       
  1085 	// Store client clipping region data if it exists
       
  1086 	if (clipRegion)
       
  1087 		{
       
  1088 		return ExternalizeRegionL(aWriteStream, *iUserDefinedClippingRegion) + sizeof(TInt8);
       
  1089 		}
       
  1090 	return sizeof(TInt8);
       
  1091 	}
       
  1092