os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdipiearc.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdipiearc.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,815 @@
     1.4 +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include "swdirectgdiengine.h"
    1.20 +#include "swdirectgdiellipse.h"
    1.21 +
    1.22 +
    1.23 +/**
    1.24 +A utility class to efficiently draw arcs.
    1.25 +@see CSwDirectGdiEngine::PieArcOutline
    1.26 +
    1.27 +@internalComponent
    1.28 +*/
    1.29 +class TSwDirectGdiArc : public TSwDirectGdiEllipse
    1.30 +	{
    1.31 +public:
    1.32 +	void Construct(const TRect& aRect,const TPoint& aStart,const TPoint& aEnd);
    1.33 +	TBool SingleStep(TPoint& aTl,TBool& aDoTl,TPoint& aTr,TBool& aDoTr,TPoint& aBl,TBool& aDoBl,TPoint& aBr,TBool& aDoBr);
    1.34 +	void Step(TPoint& aTl,TBool& aDoTl,TPoint& aTr,TBool& aDoTr,TPoint& aBl,TBool& aDoBl,TPoint& aBr,TBool& aDoBr);
    1.35 +public:
    1.36 +	TPoint iStart;
    1.37 +	TPoint iEnd;
    1.38 +private:
    1.39 +	TBool iTlquad;
    1.40 +	TBool iTrquad;
    1.41 +	TBool iBlquad;
    1.42 +	TBool iBrquad;
    1.43 +	TBool iStartquadenabled;
    1.44 +	TBool iEndquadenabled;
    1.45 +	TBool iStartquaddone;
    1.46 +	TBool iEndquaddone;
    1.47 +	TInt iStartquad;
    1.48 +	TInt iEndquad;
    1.49 +	TBool iSlice;
    1.50 +	};
    1.51 +
    1.52 +/**
    1.53 +Constructs a TSwDirectGdiArc. 
    1.54 +@param aRect   The bounding rectangle. 
    1.55 +@param aStart  The arc start point.
    1.56 +@param aEnd	   The arc end point.
    1.57 +@see CSwDirectGdiEngine::PieArcOutline
    1.58 +*/
    1.59 +void TSwDirectGdiArc::Construct(const TRect& aRect,const TPoint& aStart,const TPoint& aEnd)
    1.60 +	{
    1.61 +	iStart=Intersection(aRect,aStart);
    1.62 +	iEnd=Intersection(aRect,aEnd);
    1.63 +	TSwDirectGdiEllipse::Construct(aRect);
    1.64 +	iTlquad=EFalse;
    1.65 +	iTrquad=EFalse;
    1.66 +	iBlquad=EFalse;
    1.67 +	iBrquad=EFalse;
    1.68 +	iStartquadenabled=EFalse;
    1.69 +	iEndquadenabled=EFalse;
    1.70 +	iSlice=EFalse;
    1.71 +	iStartquad=0;
    1.72 +	iEndquad=0;
    1.73 +	TPoint center=aRect.Center();
    1.74 +	if (iStart.iX>=center.iX) iStartquad=1;
    1.75 +	if (iStart.iY>=center.iY) iStartquad+=2;
    1.76 +	if (iEnd.iX>=center.iX) iEndquad=1;
    1.77 +	if (iEnd.iY>=center.iY) iEndquad+=2;
    1.78 +	if (iStartquad!=iEndquad)
    1.79 +		{
    1.80 +		if (iStartquad==0 && iEndquad==1)
    1.81 +			{
    1.82 +			iBlquad=ETrue;
    1.83 +			iBrquad=ETrue;
    1.84 +			}
    1.85 +		else if (iStartquad==0 && iEndquad==3)
    1.86 +			iBlquad=ETrue;
    1.87 +		else if (iStartquad==1 && iEndquad==2)
    1.88 +			iTlquad=ETrue;
    1.89 +		else if (iStartquad==1 && iEndquad==3)
    1.90 +			{
    1.91 +			iTlquad=ETrue;
    1.92 +			iBlquad=ETrue;
    1.93 +			}
    1.94 +		else if (iStartquad==2 && iEndquad==0)
    1.95 +			{
    1.96 +			iTrquad=ETrue;
    1.97 +			iBrquad=ETrue;
    1.98 +			}
    1.99 +		else if (iStartquad==2 && iEndquad==1)
   1.100 +			iBrquad=ETrue;
   1.101 +		else if (iStartquad==3 && iEndquad==0)
   1.102 +			iTrquad=ETrue;
   1.103 +		else if (iStartquad==3 && iEndquad==2)
   1.104 +			{
   1.105 +			iTlquad=ETrue;
   1.106 +			iTrquad=ETrue;
   1.107 +			}
   1.108 +		}
   1.109 +	else if (iStart==iEnd)
   1.110 +		{
   1.111 +		iTlquad=ETrue;
   1.112 +		iTrquad=ETrue;
   1.113 +		iBlquad=ETrue;
   1.114 +		iBrquad=ETrue;
   1.115 +		}
   1.116 +	else
   1.117 +		{
   1.118 +		iSlice=ETrue;
   1.119 +		if (iStartquad==0 && (iStart.iX<iEnd.iX || iStart.iY>iEnd.iY))
   1.120 +			{
   1.121 +			iTrquad=ETrue;
   1.122 +			iBlquad=ETrue;
   1.123 +			iBrquad=ETrue;
   1.124 +			iSlice=EFalse;
   1.125 +			}
   1.126 +		else if (iStartquad==1 && (iStart.iX<iEnd.iX || iStart.iY<iEnd.iY))
   1.127 +			{
   1.128 +			iTlquad=ETrue;
   1.129 +			iBlquad=ETrue;
   1.130 +			iBrquad=ETrue;
   1.131 +			iSlice=EFalse;
   1.132 +			}
   1.133 +		else if (iStartquad==2 && (iStart.iX>iEnd.iX || iStart.iY>iEnd.iY))
   1.134 +			{
   1.135 +			iTlquad=ETrue;
   1.136 +			iTrquad=ETrue;
   1.137 +			iBrquad=ETrue;
   1.138 +			iSlice=EFalse;
   1.139 +			}
   1.140 +		else if (iStartquad==3 && (iStart.iX>iEnd.iX || iStart.iY<iEnd.iY))
   1.141 +			{
   1.142 +			iTlquad=ETrue;
   1.143 +			iTrquad=ETrue;
   1.144 +			iBlquad=ETrue;
   1.145 +			iSlice=EFalse;
   1.146 +			}
   1.147 +		}
   1.148 +	if (iStartquad==1 || iStartquad==2)
   1.149 +		iStartquadenabled=ETrue;
   1.150 +	if (iEndquad==0 || iEndquad==3)
   1.151 +		iEndquadenabled=ETrue;
   1.152 +	iStartquaddone=EFalse;
   1.153 +	iEndquaddone=EFalse;
   1.154 +	}
   1.155 +
   1.156 +/**
   1.157 +Produces the next stage creating an arc, taking four points (the corners of 
   1.158 +the rectangle the arc should fill) as parameters.
   1.159 +
   1.160 +@param aTopLeft Top left corner of rectangle.
   1.161 +@param aDoTl Span the top left quadrant.
   1.162 +@param aTopRight Top right corner of rectangle.
   1.163 +@param aDoTr Span the top right quadrant.
   1.164 +@param aBottomLeft Bottom left corner of rectangle.
   1.165 +@param aDoBl Span the bottom left quadrant.
   1.166 +@param aBottomRight Bottom right corner of rectangle.
   1.167 +@param aDoBr Span the bottom right quadrant.
   1.168 +@return TBool ETrue if step completed successfully.
   1.169 +@see TSwDirectGdiEllipse::SingleStep
   1.170 +*/
   1.171 +TBool TSwDirectGdiArc::SingleStep(TPoint& aTopLeft,TBool& aDoTl,TPoint& aTopRight,
   1.172 +					   TBool& aDoTr,TPoint& aBottomLeft,TBool& aDoBl,
   1.173 +					   TPoint& aBottomRight,TBool& aDoBr)
   1.174 +	{
   1.175 +	TBool finished=TSwDirectGdiEllipse::SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
   1.176 +	Step(aTopLeft,aDoTl,aTopRight,aDoTr,aBottomLeft,aDoBl,aBottomRight,aDoBr);
   1.177 +
   1.178 +	return finished;
   1.179 +	}
   1.180 +
   1.181 +/**
   1.182 +Determines how many quadrants are left to draw.
   1.183 +
   1.184 +@param aTopLeft Top left corner of rectangle.
   1.185 +@param aDoTl Span the top left quadrant.
   1.186 +@param aTopRight Top right corner of rectangle.
   1.187 +@param aDoTr Span the top right quadrant.
   1.188 +@param aBottomLeft Bottom left corner of rectangle.
   1.189 +@param aDoBl Span the bottom left quadrant.
   1.190 +@param aBottomRight Bottom right corner of rectangle.
   1.191 +@param aDoBr Span the bottom right quadrant.
   1.192 +@see TSwDirectGdiArc::SingleStep
   1.193 +@see TSwDirectGdiArc::Construct
   1.194 +*/
   1.195 +void TSwDirectGdiArc::Step(TPoint& aTopLeft,TBool& aDoTl,TPoint& aTopRight,TBool& aDoTr,
   1.196 +				TPoint& aBottomLeft,TBool& aDoBl,TPoint& aBottomRight,TBool& aDoBr)
   1.197 +	{
   1.198 +	aDoTl=iTlquad;
   1.199 +	aDoTr=iTrquad;
   1.200 +	aDoBl=iBlquad;
   1.201 +	aDoBr=iBrquad;
   1.202 +	if (!iStartquaddone)
   1.203 +		{
   1.204 +		if (!iStartquadenabled)
   1.205 +			{
   1.206 +			if (iStartquad==0 && aTopLeft.iX<=iStart.iX && aTopLeft.iY>=iStart.iY)
   1.207 +				{
   1.208 +				iStartquadenabled=ETrue;
   1.209 +				iStartquaddone=ETrue;
   1.210 +				}
   1.211 +			if (iStartquad==3 && aBottomRight.iX>=iStart.iX && aBottomRight.iY<=iStart.iY)
   1.212 +				{
   1.213 +				iStartquadenabled=ETrue;
   1.214 +				iStartquaddone=ETrue;
   1.215 +				}
   1.216 +			}
   1.217 +		else
   1.218 +			{
   1.219 +			if (iStartquad==1 && (aTopRight.iX>iStart.iX || aTopRight.iY>iStart.iY))
   1.220 +				{
   1.221 +				iStartquadenabled=EFalse;
   1.222 +				iStartquaddone=ETrue;
   1.223 +				}
   1.224 +			if (iStartquad==2 && (aBottomLeft.iX<iStart.iX || aBottomLeft.iY<iStart.iY))
   1.225 +				{
   1.226 +				iStartquadenabled=EFalse;
   1.227 +				iStartquaddone=ETrue;
   1.228 +				}
   1.229 +			}
   1.230 +		}
   1.231 +	if (!iEndquaddone)
   1.232 +		{
   1.233 +		if (iEndquadenabled)
   1.234 +			{
   1.235 +			if (iEndquad==0 && (aTopLeft.iX<iEnd.iX || aTopLeft.iY>iEnd.iY))
   1.236 +				{
   1.237 +				iEndquadenabled=EFalse;
   1.238 +				iEndquaddone=ETrue;
   1.239 +				}
   1.240 +			if (iEndquad==3 && (aBottomRight.iX>iEnd.iX || aBottomRight.iY<iEnd.iY))
   1.241 +				{
   1.242 +				iEndquadenabled=EFalse;
   1.243 +				iEndquaddone=ETrue;
   1.244 +				}
   1.245 +			}
   1.246 +		else
   1.247 +			{
   1.248 +			if (iEndquad==1 && aTopRight.iX>=iEnd.iX && aTopRight.iY>=iEnd.iY)
   1.249 +				{
   1.250 +				iEndquadenabled=ETrue;
   1.251 +				iEndquaddone=ETrue;
   1.252 +				}
   1.253 +			if (iEndquad==2 && aBottomLeft.iX<=iEnd.iX && aBottomLeft.iY<=iEnd.iY)
   1.254 +				{
   1.255 +				iEndquadenabled=ETrue;
   1.256 +				iEndquaddone=ETrue;
   1.257 +				}
   1.258 +			}
   1.259 +		}
   1.260 +	if (iStartquad!=iEndquad)
   1.261 +		{
   1.262 +		if (iStartquadenabled)
   1.263 +			{
   1.264 +			if (iStartquad==0) aDoTl=ETrue;
   1.265 +			else if (iStartquad==1) aDoTr=ETrue;
   1.266 +			else if (iStartquad==2) aDoBl=ETrue;
   1.267 +			else if (iStartquad==3) aDoBr=ETrue;
   1.268 +			}
   1.269 +		if (iEndquadenabled)
   1.270 +			{
   1.271 +			if (iEndquad==0) aDoTl=ETrue;
   1.272 +			else if (iEndquad==1) aDoTr=ETrue;
   1.273 +			else if (iEndquad==2) aDoBl=ETrue;
   1.274 +			else if (iEndquad==3) aDoBr=ETrue;
   1.275 +			}
   1.276 +		}
   1.277 +	else
   1.278 +		{
   1.279 +		if (iSlice)
   1.280 +			{
   1.281 +			if (iStartquadenabled && iEndquadenabled)
   1.282 +				{
   1.283 +				if (iStartquad==0) aDoTl=ETrue;
   1.284 +				else if (iStartquad==1) aDoTr=ETrue;
   1.285 +				else if (iStartquad==2) aDoBl=ETrue;
   1.286 +				else if (iStartquad==3) aDoBr=ETrue;
   1.287 +				}
   1.288 +			}
   1.289 +		else
   1.290 +			{
   1.291 +			if (iStartquadenabled || iEndquadenabled)
   1.292 +				{
   1.293 +				if (iStartquad==0) aDoTl=ETrue;
   1.294 +				else if (iStartquad==1) aDoTr=ETrue;
   1.295 +				else if (iStartquad==2) aDoBl=ETrue;
   1.296 +				else if (iStartquad==3) aDoBr=ETrue;
   1.297 +				}
   1.298 +			}
   1.299 +		}
   1.300 +	if (aTopLeft.iX==aTopRight.iX)
   1.301 +		{
   1.302 +		if (aDoTl && aDoTr) aDoTr=EFalse;
   1.303 +		if (aDoBl && aDoBr) aDoBr=EFalse;
   1.304 +		}
   1.305 +	}
   1.306 +
   1.307 +//
   1.308 +// Pie and Arc drawing functions
   1.309 +//
   1.310 +
   1.311 +/**
   1.312 +@see MDirectGdiEngine::DrawArc()
   1.313 +*/
   1.314 +void CSwDirectGdiEngine::DrawArc(const TRect& aRect,const TPoint& aStart,
   1.315 +								 const TPoint& aEnd)
   1.316 +	{
   1.317 +	TRect rcpy(aRect);
   1.318 +	rcpy.Move(iOrigin);
   1.319 +	TruncateRect(rcpy);
   1.320 +	TRect targetRect(rcpy);
   1.321 +	targetRect.Grow((iPenSize.iWidth>>1)+1,(iPenSize.iHeight>>1)+1);
   1.322 +	PieArcOutline(rcpy,aStart+iOrigin,aEnd+iOrigin,EFalse);
   1.323 +	}
   1.324 +
   1.325 +/**
   1.326 +@see MDirectGdiEngine::DrawPie()
   1.327 +*/
   1.328 +void CSwDirectGdiEngine::DrawPie(const TRect& aRect,const TPoint& aStart,
   1.329 +								 const TPoint& aEnd)
   1.330 +	{
   1.331 +	TRect rcpy(aRect);
   1.332 +	rcpy.Move(iOrigin);
   1.333 +	TruncateRect(rcpy);
   1.334 +	TPoint startIntersect = aStart + iOrigin, endIntersect = aEnd + iOrigin;
   1.335 +	TInt startQuadrant, endQuadrant;
   1.336 +	TBool quadrants[5];
   1.337 +	const TBool isEllipse = AnalyseEllipse(
   1.338 +		rcpy, startIntersect, endIntersect, startQuadrant, endQuadrant, quadrants);
   1.339 +
   1.340 +	if (iBrushStyle!=DirectGdi::ENullBrush)
   1.341 +		{
   1.342 +		if (isEllipse)
   1.343 +			EllipseFill(rcpy);
   1.344 +		else
   1.345 +			PieFill(rcpy, startIntersect, endIntersect, startQuadrant, endQuadrant, quadrants);
   1.346 +		}
   1.347 +	if ((iPenStyle!=DirectGdi::ENullPen) && (iPenSize.iWidth>0) && (iPenSize.iHeight>0))
   1.348 +		PieArcOutline(rcpy,aStart+iOrigin,aEnd+iOrigin,ETrue);
   1.349 +	}
   1.350 +
   1.351 +/**
   1.352 +Calculates which quadrants are completely filled and which quadrants contain the 
   1.353 +start and end points.
   1.354 +
   1.355 +@param aRect      The bounding rectangle. 
   1.356 +@param aStart     The arc start point.
   1.357 +@param aEnd	      The arc end point.
   1.358 +@param aStartQuad On return, contains the quadrant which contains aStart. 
   1.359 +@param aEndQuad   On return, contains the quadrant which contains aEnd.
   1.360 +@param aQuads     On return, populates an array of full quadrants to fill.
   1.361 +@pre Input params aRect, aStart, aEnd are to be given.
   1.362 +@post Output params aStart, aEnd, aStartQuad, aEndQuad, aQuads will be populated.
   1.363 +@return ETrue if the pie is an ellipse, otherwise EFalse.
   1.364 +*/
   1.365 +TBool CSwDirectGdiEngine::AnalyseEllipse(const TRect& aRect,TPoint& aStart,TPoint& aEnd,
   1.366 +							   TInt& aStartQuad,TInt& aEndQuad,TBool* aQuads)
   1.367 +	{
   1.368 +	aStartQuad=0;
   1.369 +	aEndQuad=0;
   1.370 +	const TPoint center = aRect.Center();
   1.371 +	TSwDirectGdiEllipse ellipse;
   1.372 +	aStart=ellipse.Intersection(aRect,aStart);
   1.373 +	aEnd=ellipse.Intersection(aRect,aEnd);
   1.374 +	if (aStart==aEnd)
   1.375 +		{
   1.376 +		aQuads[0]=EFalse;
   1.377 +		aQuads[1]=ETrue;
   1.378 +		aQuads[2]=ETrue;
   1.379 +		aQuads[3]=ETrue;
   1.380 +		aQuads[4]=ETrue;
   1.381 +		return ETrue;
   1.382 +		}
   1.383 +	const TInt startx = aStart.iX - center.iX, starty = aStart.iY - center.iY;
   1.384 +	const TInt endx = aEnd.iX - center.iX, endy = aEnd.iY - center.iY;
   1.385 +	if (startx>=0) aStartQuad=1;
   1.386 +	if (starty>=0) aStartQuad+=2;
   1.387 +	if (endx>=0) aEndQuad=1;
   1.388 +	if (endy>=0) aEndQuad+=2;
   1.389 +	aQuads[1]=EFalse,aQuads[2]=EFalse,aQuads[3]=EFalse,aQuads[4]=EFalse; // complete quadrants to draw
   1.390 +	aQuads[0]=EFalse; // ellipse is a sliver completely within a quadrant
   1.391 +	if (aStartQuad==aEndQuad)
   1.392 +		{
   1.393 +		if (aStartQuad==0 && (startx<endx || starty>endy))
   1.394 +			{
   1.395 +			aQuads[2]=ETrue;
   1.396 +			aQuads[3]=ETrue;
   1.397 +			aQuads[4]=ETrue;
   1.398 +			}
   1.399 +		else if (aStartQuad==1 && (startx<endx || starty<endy))
   1.400 +			{
   1.401 +			aQuads[1]=ETrue;
   1.402 +			aQuads[3]=ETrue;
   1.403 +			aQuads[4]=ETrue;
   1.404 +			}
   1.405 +		else if (aStartQuad==2 && (startx>endx || starty>endy))
   1.406 +			{
   1.407 +			aQuads[1]=ETrue;
   1.408 +			aQuads[2]=ETrue;
   1.409 +			aQuads[4]=ETrue;
   1.410 +			}
   1.411 +		else if (aStartQuad==3 && (startx>endx || starty<endy))
   1.412 +			{
   1.413 +			aQuads[1]=ETrue;
   1.414 +			aQuads[2]=ETrue;
   1.415 +			aQuads[3]=ETrue;
   1.416 +			}
   1.417 +		else aQuads[0]=ETrue; // "slice"
   1.418 +		}
   1.419 +	else
   1.420 +		{
   1.421 +		if (aStartQuad==0 && aEndQuad==1)
   1.422 +			{
   1.423 +			aQuads[3]=ETrue;
   1.424 +			aQuads[4]=ETrue;
   1.425 +			}
   1.426 +		else if (aStartQuad==0 && aEndQuad==3)
   1.427 +			aQuads[3]=ETrue;
   1.428 +		else if (aStartQuad==1 && aEndQuad==2)
   1.429 +			aQuads[1]=ETrue;
   1.430 +		else if (aStartQuad==1 && aEndQuad==3)
   1.431 +			{
   1.432 +			aQuads[1]=ETrue;
   1.433 +			aQuads[3]=ETrue;
   1.434 +			}
   1.435 +		else if (aStartQuad==2 && aEndQuad==0)
   1.436 +			{
   1.437 +			aQuads[2]=ETrue;
   1.438 +			aQuads[4]=ETrue;
   1.439 +			}
   1.440 +		else if (aStartQuad==2 && aEndQuad==1)
   1.441 +			aQuads[4]=ETrue;
   1.442 +		else if (aStartQuad==3 && aEndQuad==0)
   1.443 +			aQuads[2]=ETrue;
   1.444 +		else if (aStartQuad==3 && aEndQuad==2)
   1.445 +			{
   1.446 +			aQuads[1]=ETrue;
   1.447 +			aQuads[2]=ETrue;
   1.448 +			}
   1.449 +		}
   1.450 +	return EFalse;
   1.451 +	}
   1.452 +
   1.453 +/**
   1.454 +Draws the outline of a pie or arc.
   1.455 +
   1.456 +@param aRect  The bounding rectangle. 
   1.457 +@param aStart The arc start point.
   1.458 +@param aEnd	  The arc end point.
   1.459 +@param aPie If this is the outline for a pie ETrue, else EFalse
   1.460 +*/
   1.461 +void CSwDirectGdiEngine::PieArcOutline(const TRect& aRect,const TPoint& aStart,
   1.462 +							  const TPoint& aEnd,TBool aPie)
   1.463 +	{
   1.464 +	// arc runs counterclockwise, from startradius-center/ellipse intersect to endradius-center/ellipse intersect
   1.465 +	TInt dotparam=iDotParam;
   1.466 +	TRect rcpy(aRect);
   1.467 +	TPoint pt[4];
   1.468 +	TInt halfpenwidth=iPenSize.iWidth>>1;
   1.469 +	TInt halfpenheight=iPenSize.iHeight>>1;
   1.470 +	TInt otherhalfwidth=(iPenSize.iWidth+1)>>1;
   1.471 +	TInt otherhalfheight=(iPenSize.iHeight+1)>>1;
   1.472 +	rcpy.iTl.iX-=halfpenwidth;
   1.473 +	rcpy.iTl.iY-=halfpenheight;
   1.474 +	rcpy.iBr.iX+=otherhalfwidth;
   1.475 +	rcpy.iBr.iY+=otherhalfheight;
   1.476 +	TRect clipRect(0,0,0,0);
   1.477 +	for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
   1.478 +		{
   1.479 +		clipRect=(*iDefaultRegionPtr)[count];
   1.480 +		if (!clipRect.Intersects(rcpy))
   1.481 +			continue;
   1.482 +		clipRect.Intersection(rcpy);
   1.483 +		TSwDirectGdiArc arc;
   1.484 +		arc.Construct(aRect,aStart,aEnd);
   1.485 +		iDotParam=Max(iPenSize.iWidth>>1,iPenSize.iHeight>>1);
   1.486 +		TBool dotl,dotr,dobl,dobr;
   1.487 +		while(!arc.SingleStep(pt[0],dotl,pt[1],dotr,pt[2],dobl,pt[3],dobr))
   1.488 +			{
   1.489 +			if (dotl) PenDrawClipped(pt[0], clipRect);
   1.490 +			if (dotr) PenDrawClipped(pt[1], clipRect);
   1.491 +			if (dobl) PenDrawClipped(pt[2], clipRect);
   1.492 +			if (dobr) PenDrawClipped(pt[3], clipRect);
   1.493 +			iDotParam+=iDotDirection;
   1.494 +			}
   1.495 +		if (pt[0].iY==pt[2].iY)
   1.496 +			{
   1.497 +			if (dotl) PenDrawClipped(pt[0], clipRect);
   1.498 +			if (dotr) PenDrawClipped(pt[1], clipRect);
   1.499 +			}
   1.500 +		if (aPie)
   1.501 +			{
   1.502 +			TPoint temp;
   1.503 +			const TPoint center = aRect.Center();
   1.504 +			TLinearDDA line;
   1.505 +			line.Construct(arc.iStart,center);
   1.506 +			line.SingleStep(temp);
   1.507 +			while(!line.SingleStep(temp))
   1.508 +				{
   1.509 +				PenDrawClipped(temp, clipRect);
   1.510 +				iDotParam+=iDotDirection;
   1.511 +				}
   1.512 +			line.Construct(arc.iEnd,center);
   1.513 +			line.SingleStep(temp);
   1.514 +			while(!line.SingleStep(temp))
   1.515 +				{
   1.516 +				PenDrawClipped(temp, clipRect);
   1.517 +				iDotParam+=iDotDirection;
   1.518 +				}
   1.519 +			PenDrawClipped(center, clipRect);
   1.520 +			}
   1.521 +		iDrawDevice->UpdateRegion(clipRect);
   1.522 +		}
   1.523 +	iDotParam=dotparam;
   1.524 +	}
   1.525 +
   1.526 +/**
   1.527 +Fills a pie.
   1.528 +
   1.529 +@param aRect      The bounding rectangle. 
   1.530 +@param aStart     The arc start point.
   1.531 +@param aEnd	      The arc end point.
   1.532 +@param aStartQuad The quadrant which contains aStart. 
   1.533 +@param aEndQuad   The quadrant which contains aEnd.
   1.534 +@param aQuads     An array of full quadrants to fill.
   1.535 +@see CSwDirectGdiEngine::DrawPie
   1.536 +@see CSwDirectGdiEngine::AnalyseEllipse 
   1.537 +*/
   1.538 +void CSwDirectGdiEngine::PieFill(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd,
   1.539 +						TInt aStartQuad, TInt aEndQuad, const TBool* aQuads)
   1.540 +	{
   1.541 +	// arc runs counterclockwise, from startradius-center/ellipse intersect to endradius-center/ellipse intersect
   1.542 +	const TInt limit = iDefaultRegionPtr->Count();
   1.543 +	TRect clipRect(0,0,0,0);
   1.544 +	for(TInt count=0;count<limit;count++)
   1.545 +		{
   1.546 +		clipRect=(*iDefaultRegionPtr)[count];
   1.547 +		if (!clipRect.Intersects(aRect))
   1.548 +			{
   1.549 +			continue;
   1.550 +			}
   1.551 +		clipRect.Intersection(aRect);
   1.552 +		if (!aQuads[0])
   1.553 +			{
   1.554 +			PieShell(aRect, aStart, aEnd, aQuads, aStartQuad, aEndQuad, clipRect);
   1.555 +			}
   1.556 +		else
   1.557 +			{
   1.558 +			PieSliver(aRect, aStart, aEnd, aStartQuad, clipRect);
   1.559 +			}
   1.560 +		iDrawDevice->UpdateRegion(clipRect);
   1.561 +		}
   1.562 +	}
   1.563 +
   1.564 +/**
   1.565 +Draws a pie spanning one or more quadrants.
   1.566 +
   1.567 +@param aRect      The bounding rectangle. 
   1.568 +@param aStart     The arc start point.
   1.569 +@param aEnd	      The arc end point.
   1.570 +@param aQuads     Array of full quadrants to fill.
   1.571 +@param aStartQuad The quadrant which contains aStart. 
   1.572 +@param aEndQuad   The quadrant which contains aEnd.
   1.573 +@param aClipRect  The rectangle to which the pie is clipped.
   1.574 +*/
   1.575 +void CSwDirectGdiEngine::PieShell(const TRect& aRect,const TPoint& aStart,
   1.576 +						 const TPoint& aEnd, const TBool* aQuads, TInt aStartQuad, 
   1.577 +						 TInt aEndQuad, TRect aClipRect)
   1.578 +	{
   1.579 +	TSwDirectGdiEllipse ellipse;
   1.580 +	ellipse.Construct(aRect);
   1.581 +	TInt c=aRect.Center().iX;
   1.582 +	TPoint pt[4];
   1.583 +	TPoint tl,tr,bl,br;
   1.584 +	TBool donestart=EFalse;
   1.585 +	TBool doneend=EFalse;
   1.586 +	TBool todostart=EFalse;
   1.587 +	TBool todoend=EFalse;
   1.588 +	while(!ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]))
   1.589 +		{
   1.590 +		if (pt[aStartQuad].iY==aStart.iY)
   1.591 +			todostart=ETrue;
   1.592 +		if (pt[aEndQuad].iY==aEnd.iY)
   1.593 +			todoend=ETrue;
   1.594 +		pt[0].iX++;
   1.595 +		pt[1].iX--;
   1.596 +		pt[2].iX++;
   1.597 +		pt[3].iX--;
   1.598 +		tl.iY=pt[0].iY;
   1.599 +		tr.iY=pt[1].iY;
   1.600 +		bl.iY=pt[2].iY;
   1.601 +		br.iY=pt[3].iY;
   1.602 +		if (aQuads[1] || (aEndQuad==0 && !doneend)) // tl quadrant, half top end chord
   1.603 +			tl.iX=pt[0].iX;
   1.604 +		else tl.iX=c+1;
   1.605 +		if (aQuads[2] || (aStartQuad==1 && !donestart)) // tr quadrant, half top start chord
   1.606 +			tr.iX=pt[1].iX;
   1.607 +		else tr.iX=c;
   1.608 +		if (aQuads[3] || (aStartQuad==2 && !donestart)) // bl quadrant, half top start chord
   1.609 +			bl.iX=pt[2].iX;
   1.610 +		else bl.iX=c+1;
   1.611 +		if (aQuads[4] || (aEndQuad==3 && !doneend)) // br quadrant, half top end chord
   1.612 +			br.iX=pt[3].iX;
   1.613 +		else br.iX=c;
   1.614 +		ClipFillLine(tl,tr,aClipRect);
   1.615 +		ClipFillLine(bl,br,aClipRect);
   1.616 +		// do partial quadrants
   1.617 +		if (todostart)
   1.618 +			{
   1.619 +			if (aStartQuad==0)
   1.620 +				{
   1.621 +				tl.iX=pt[0].iX;
   1.622 +				tr.iX=aStart.iX;
   1.623 +				ClipFillLine(tl,tr,aClipRect);
   1.624 +				}
   1.625 +			else if (aStartQuad==3)
   1.626 +				{
   1.627 +				bl.iX=aStart.iX;
   1.628 +				br.iX=pt[3].iX;
   1.629 +				ClipFillLine(bl,br,aClipRect);
   1.630 +				}
   1.631 +			}
   1.632 +		if (todoend)
   1.633 +			{
   1.634 +			if (aEndQuad==2)
   1.635 +				{
   1.636 +				bl.iX=pt[2].iX;
   1.637 +				br.iX=aEnd.iX;
   1.638 +				ClipFillLine(bl,br,aClipRect);
   1.639 +				}
   1.640 +			else if (aEndQuad==1)
   1.641 +				{
   1.642 +				tl.iX=aEnd.iX;
   1.643 +				tr.iX=pt[1].iX;
   1.644 +				ClipFillLine(tl,tr,aClipRect);
   1.645 +				}
   1.646 +			}
   1.647 +		donestart=todostart;
   1.648 +		doneend=todoend;
   1.649 +		}
   1.650 +	tl.iX=c+1;
   1.651 +	tr.iX=c;
   1.652 +	if (pt[0].iY==pt[2].iY) // congruent mid lines
   1.653 +		{
   1.654 +		if (pt[aStartQuad].iY==aStart.iY)
   1.655 +			todostart=ETrue;
   1.656 +		if (pt[aEndQuad].iY==aEnd.iY)
   1.657 +			todoend=ETrue;
   1.658 +		pt[0].iX++;
   1.659 +		pt[1].iX--;
   1.660 +		tl.iY=pt[0].iY;
   1.661 +		tr.iY=tl.iY;
   1.662 +		TBool leftflag=EFalse;
   1.663 +		TBool rightflag=EFalse;
   1.664 +		if (aQuads[1] || (aEndQuad==0 && !doneend) ||
   1.665 +			aQuads[3] || (aStartQuad==2 && !donestart) ||
   1.666 +			(todostart && aStartQuad==0) || (todoend && aEndQuad==2))
   1.667 +			leftflag=ETrue;
   1.668 +		if (aQuads[2] || (aStartQuad==1 && !donestart) ||
   1.669 +			aQuads[4] || (aEndQuad==3 && !doneend) ||
   1.670 +			(todostart && aStartQuad==3) || (todoend && aEndQuad==1))
   1.671 +			rightflag=ETrue;
   1.672 +		if (leftflag) tl.iX=pt[0].iX;
   1.673 +		if (rightflag) tr.iX=pt[1].iX;
   1.674 +		ClipFillLine(tl,tr,aClipRect);
   1.675 +		}
   1.676 +	else
   1.677 +		{
   1.678 +		tl.iY=aRect.Center().iY;
   1.679 +		tr.iY=tl.iY;
   1.680 +		if (aStartQuad==3) tr.iX=aStart.iX-1;
   1.681 +		if (aEndQuad==2) tl.iX=aEnd.iX+1;
   1.682 +		ClipFillLine(tl,tr,aClipRect);
   1.683 +		}
   1.684 +	PieTriangles(aStartQuad==1 || aStartQuad==2,aStart,aRect.Center(), aClipRect);
   1.685 +	PieTriangles(aEndQuad==0 || aEndQuad==3,aEnd,aRect.Center(), aClipRect);
   1.686 +	}
   1.687 +
   1.688 +/**
   1.689 +Draws a filled triangle which forms part of a partially filled quadrant.
   1.690 +
   1.691 +@param aInside A boolean value indicating which side of the line to fill.
   1.692 +@param aStart The start of the line which forms the hypotenuse of the triangle.
   1.693 +@param aEnd The end of the line which forms the hypotenuse of the triangle.
   1.694 +@param aClipRect The rectangle to which the pie is clipped.
   1.695 +@see CSwDirectGdiEngine::PieShell 
   1.696 +*/
   1.697 +void CSwDirectGdiEngine::PieTriangles(TBool aInside,const TPoint& aStart,const TPoint& aEnd, TRect aClipRect)
   1.698 +	{
   1.699 +	TInt x=aInside?aEnd.iX:aStart.iX;
   1.700 +	if (aStart.iX>aEnd.iX)
   1.701 +		{
   1.702 +		if (aInside)
   1.703 +			{
   1.704 +			x++;
   1.705 +			}
   1.706 +		else
   1.707 +			{
   1.708 +			x--;
   1.709 +			}
   1.710 +		}
   1.711 +	else
   1.712 +		{
   1.713 +		if (!aInside)
   1.714 +			{
   1.715 +			x++;
   1.716 +			}
   1.717 +		}
   1.718 +	TLinearDDA line;
   1.719 +	TPoint pt,left,right;
   1.720 +	line.Construct(aStart,aEnd);
   1.721 +	line.NextStep(pt);
   1.722 +	while(!line.NextStep(pt))
   1.723 +		{
   1.724 +		if (pt.iY==aEnd.iY) break;
   1.725 +		left.iX=Min(pt.iX,x);
   1.726 +		right.iX=Max(pt.iX,x);
   1.727 +		left.iY=right.iY=pt.iY;
   1.728 +		ClipFillLine(left,right,aClipRect);
   1.729 +		}
   1.730 +	}
   1.731 +
   1.732 +/**
   1.733 +Draws a pie entirely contained in one quadrant.
   1.734 +
   1.735 +@param aRect The rectangle in which to draw the ellipse. 
   1.736 +@param aStart The arc start point.
   1.737 +@param aEnd	The arc end point.
   1.738 +@param aQuad The quadrant containing the pie.
   1.739 +@param aClipRect The rectangle to which the pie is clipped.
   1.740 +*/
   1.741 +void CSwDirectGdiEngine::PieSliver(const TRect& aRect,const TPoint& aStart,
   1.742 +						  const TPoint& aEnd, TInt aQuad, TRect aClipRect)
   1.743 +	{
   1.744 +	TPoint center=aRect.Center(),left,right;
   1.745 +	TPoint nearinter(aStart),farinter(aEnd);
   1.746 +	if (Abs(nearinter.iY-center.iY)>Abs(farinter.iY-center.iY))
   1.747 +		{
   1.748 +		nearinter=aEnd;
   1.749 +		farinter=aStart;
   1.750 +		}
   1.751 +	TBool ellipseComplete = EFalse;
   1.752 +	TPoint pt[4];
   1.753 +	TSwDirectGdiEllipse ellipse;
   1.754 +	ellipse.Construct(aRect);
   1.755 +	TLinearDDA mainline;
   1.756 +	mainline.Construct(farinter,center);
   1.757 +	ellipseComplete = ellipse.SingleStep(pt[0],pt[1],pt[2],pt[3]);
   1.758 +	mainline.SingleStep(right);
   1.759 +	do	{
   1.760 +		while(!ellipseComplete && pt[aQuad].iY!=right.iY)
   1.761 +			ellipseComplete = ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]);
   1.762 +		left=pt[aQuad];
   1.763 +		while(!ellipseComplete && pt[aQuad].iY==right.iY)
   1.764 +			{
   1.765 +			left=pt[aQuad];
   1.766 +			ellipseComplete = ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]);
   1.767 +			}
   1.768 +		if (right.iY==nearinter.iY || (ellipseComplete && (pt[0].iY != pt[2].iY)))
   1.769 +			break;
   1.770 +		if (left.iX>right.iX)
   1.771 +			{
   1.772 +			TInt temp=left.iX;
   1.773 +			left.iX=right.iX;
   1.774 +			right.iX=temp;
   1.775 +			}
   1.776 +		if(right==farinter && left.iX<=right.iX)
   1.777 +			{
   1.778 +			continue;
   1.779 +			}
   1.780 +		left.iX++;
   1.781 +		right.iX--;
   1.782 +		if (left.iX<=right.iX)
   1.783 +			ClipFillLine(left,right,aClipRect);
   1.784 +		}
   1.785 +	while(!mainline.NextStep(right));
   1.786 +	TPoint temppt;
   1.787 +	TLinearDDA line;
   1.788 +	line.Construct(nearinter,center);
   1.789 +	TBool linestat=EFalse;
   1.790 +	do
   1.791 +		linestat=line.SingleStep(temppt);
   1.792 +	while(temppt.iY!=right.iY && !linestat);
   1.793 +	do	{
   1.794 +		do	{
   1.795 +			left=temppt;
   1.796 +			linestat=line.SingleStep(temppt);
   1.797 +			}
   1.798 +		while(temppt.iY==right.iY && !linestat);
   1.799 +		if (ellipseComplete)
   1.800 +			break;
   1.801 +		if (left.iX>right.iX)
   1.802 +			{
   1.803 +			TInt temp=left.iX;
   1.804 +			left.iX=right.iX;
   1.805 +			right.iX=temp;
   1.806 +			}
   1.807 +		if(right==farinter && left.iX<=right.iX)
   1.808 +			{
   1.809 +			continue;
   1.810 +			}
   1.811 +		left.iX++;
   1.812 +		right.iX--;
   1.813 +		if (left.iX<=right.iX)
   1.814 +			ClipFillLine(left,right,aClipRect);
   1.815 +		}
   1.816 +	while(!mainline.NextStep(right));
   1.817 +	}
   1.818 +