os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdipiearc.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "swdirectgdiengine.h"
sl@0
    17
#include "swdirectgdiellipse.h"
sl@0
    18
sl@0
    19
sl@0
    20
/**
sl@0
    21
A utility class to efficiently draw arcs.
sl@0
    22
@see CSwDirectGdiEngine::PieArcOutline
sl@0
    23
sl@0
    24
@internalComponent
sl@0
    25
*/
sl@0
    26
class TSwDirectGdiArc : public TSwDirectGdiEllipse
sl@0
    27
	{
sl@0
    28
public:
sl@0
    29
	void Construct(const TRect& aRect,const TPoint& aStart,const TPoint& aEnd);
sl@0
    30
	TBool SingleStep(TPoint& aTl,TBool& aDoTl,TPoint& aTr,TBool& aDoTr,TPoint& aBl,TBool& aDoBl,TPoint& aBr,TBool& aDoBr);
sl@0
    31
	void Step(TPoint& aTl,TBool& aDoTl,TPoint& aTr,TBool& aDoTr,TPoint& aBl,TBool& aDoBl,TPoint& aBr,TBool& aDoBr);
sl@0
    32
public:
sl@0
    33
	TPoint iStart;
sl@0
    34
	TPoint iEnd;
sl@0
    35
private:
sl@0
    36
	TBool iTlquad;
sl@0
    37
	TBool iTrquad;
sl@0
    38
	TBool iBlquad;
sl@0
    39
	TBool iBrquad;
sl@0
    40
	TBool iStartquadenabled;
sl@0
    41
	TBool iEndquadenabled;
sl@0
    42
	TBool iStartquaddone;
sl@0
    43
	TBool iEndquaddone;
sl@0
    44
	TInt iStartquad;
sl@0
    45
	TInt iEndquad;
sl@0
    46
	TBool iSlice;
sl@0
    47
	};
sl@0
    48
sl@0
    49
/**
sl@0
    50
Constructs a TSwDirectGdiArc. 
sl@0
    51
@param aRect   The bounding rectangle. 
sl@0
    52
@param aStart  The arc start point.
sl@0
    53
@param aEnd	   The arc end point.
sl@0
    54
@see CSwDirectGdiEngine::PieArcOutline
sl@0
    55
*/
sl@0
    56
void TSwDirectGdiArc::Construct(const TRect& aRect,const TPoint& aStart,const TPoint& aEnd)
sl@0
    57
	{
sl@0
    58
	iStart=Intersection(aRect,aStart);
sl@0
    59
	iEnd=Intersection(aRect,aEnd);
sl@0
    60
	TSwDirectGdiEllipse::Construct(aRect);
sl@0
    61
	iTlquad=EFalse;
sl@0
    62
	iTrquad=EFalse;
sl@0
    63
	iBlquad=EFalse;
sl@0
    64
	iBrquad=EFalse;
sl@0
    65
	iStartquadenabled=EFalse;
sl@0
    66
	iEndquadenabled=EFalse;
sl@0
    67
	iSlice=EFalse;
sl@0
    68
	iStartquad=0;
sl@0
    69
	iEndquad=0;
sl@0
    70
	TPoint center=aRect.Center();
sl@0
    71
	if (iStart.iX>=center.iX) iStartquad=1;
sl@0
    72
	if (iStart.iY>=center.iY) iStartquad+=2;
sl@0
    73
	if (iEnd.iX>=center.iX) iEndquad=1;
sl@0
    74
	if (iEnd.iY>=center.iY) iEndquad+=2;
sl@0
    75
	if (iStartquad!=iEndquad)
sl@0
    76
		{
sl@0
    77
		if (iStartquad==0 && iEndquad==1)
sl@0
    78
			{
sl@0
    79
			iBlquad=ETrue;
sl@0
    80
			iBrquad=ETrue;
sl@0
    81
			}
sl@0
    82
		else if (iStartquad==0 && iEndquad==3)
sl@0
    83
			iBlquad=ETrue;
sl@0
    84
		else if (iStartquad==1 && iEndquad==2)
sl@0
    85
			iTlquad=ETrue;
sl@0
    86
		else if (iStartquad==1 && iEndquad==3)
sl@0
    87
			{
sl@0
    88
			iTlquad=ETrue;
sl@0
    89
			iBlquad=ETrue;
sl@0
    90
			}
sl@0
    91
		else if (iStartquad==2 && iEndquad==0)
sl@0
    92
			{
sl@0
    93
			iTrquad=ETrue;
sl@0
    94
			iBrquad=ETrue;
sl@0
    95
			}
sl@0
    96
		else if (iStartquad==2 && iEndquad==1)
sl@0
    97
			iBrquad=ETrue;
sl@0
    98
		else if (iStartquad==3 && iEndquad==0)
sl@0
    99
			iTrquad=ETrue;
sl@0
   100
		else if (iStartquad==3 && iEndquad==2)
sl@0
   101
			{
sl@0
   102
			iTlquad=ETrue;
sl@0
   103
			iTrquad=ETrue;
sl@0
   104
			}
sl@0
   105
		}
sl@0
   106
	else if (iStart==iEnd)
sl@0
   107
		{
sl@0
   108
		iTlquad=ETrue;
sl@0
   109
		iTrquad=ETrue;
sl@0
   110
		iBlquad=ETrue;
sl@0
   111
		iBrquad=ETrue;
sl@0
   112
		}
sl@0
   113
	else
sl@0
   114
		{
sl@0
   115
		iSlice=ETrue;
sl@0
   116
		if (iStartquad==0 && (iStart.iX<iEnd.iX || iStart.iY>iEnd.iY))
sl@0
   117
			{
sl@0
   118
			iTrquad=ETrue;
sl@0
   119
			iBlquad=ETrue;
sl@0
   120
			iBrquad=ETrue;
sl@0
   121
			iSlice=EFalse;
sl@0
   122
			}
sl@0
   123
		else if (iStartquad==1 && (iStart.iX<iEnd.iX || iStart.iY<iEnd.iY))
sl@0
   124
			{
sl@0
   125
			iTlquad=ETrue;
sl@0
   126
			iBlquad=ETrue;
sl@0
   127
			iBrquad=ETrue;
sl@0
   128
			iSlice=EFalse;
sl@0
   129
			}
sl@0
   130
		else if (iStartquad==2 && (iStart.iX>iEnd.iX || iStart.iY>iEnd.iY))
sl@0
   131
			{
sl@0
   132
			iTlquad=ETrue;
sl@0
   133
			iTrquad=ETrue;
sl@0
   134
			iBrquad=ETrue;
sl@0
   135
			iSlice=EFalse;
sl@0
   136
			}
sl@0
   137
		else if (iStartquad==3 && (iStart.iX>iEnd.iX || iStart.iY<iEnd.iY))
sl@0
   138
			{
sl@0
   139
			iTlquad=ETrue;
sl@0
   140
			iTrquad=ETrue;
sl@0
   141
			iBlquad=ETrue;
sl@0
   142
			iSlice=EFalse;
sl@0
   143
			}
sl@0
   144
		}
sl@0
   145
	if (iStartquad==1 || iStartquad==2)
sl@0
   146
		iStartquadenabled=ETrue;
sl@0
   147
	if (iEndquad==0 || iEndquad==3)
sl@0
   148
		iEndquadenabled=ETrue;
sl@0
   149
	iStartquaddone=EFalse;
sl@0
   150
	iEndquaddone=EFalse;
sl@0
   151
	}
sl@0
   152
sl@0
   153
/**
sl@0
   154
Produces the next stage creating an arc, taking four points (the corners of 
sl@0
   155
the rectangle the arc should fill) as parameters.
sl@0
   156
sl@0
   157
@param aTopLeft Top left corner of rectangle.
sl@0
   158
@param aDoTl Span the top left quadrant.
sl@0
   159
@param aTopRight Top right corner of rectangle.
sl@0
   160
@param aDoTr Span the top right quadrant.
sl@0
   161
@param aBottomLeft Bottom left corner of rectangle.
sl@0
   162
@param aDoBl Span the bottom left quadrant.
sl@0
   163
@param aBottomRight Bottom right corner of rectangle.
sl@0
   164
@param aDoBr Span the bottom right quadrant.
sl@0
   165
@return TBool ETrue if step completed successfully.
sl@0
   166
@see TSwDirectGdiEllipse::SingleStep
sl@0
   167
*/
sl@0
   168
TBool TSwDirectGdiArc::SingleStep(TPoint& aTopLeft,TBool& aDoTl,TPoint& aTopRight,
sl@0
   169
					   TBool& aDoTr,TPoint& aBottomLeft,TBool& aDoBl,
sl@0
   170
					   TPoint& aBottomRight,TBool& aDoBr)
sl@0
   171
	{
sl@0
   172
	TBool finished=TSwDirectGdiEllipse::SingleStep(aTopLeft,aTopRight,aBottomLeft,aBottomRight);
sl@0
   173
	Step(aTopLeft,aDoTl,aTopRight,aDoTr,aBottomLeft,aDoBl,aBottomRight,aDoBr);
sl@0
   174
sl@0
   175
	return finished;
sl@0
   176
	}
sl@0
   177
sl@0
   178
/**
sl@0
   179
Determines how many quadrants are left to draw.
sl@0
   180
sl@0
   181
@param aTopLeft Top left corner of rectangle.
sl@0
   182
@param aDoTl Span the top left quadrant.
sl@0
   183
@param aTopRight Top right corner of rectangle.
sl@0
   184
@param aDoTr Span the top right quadrant.
sl@0
   185
@param aBottomLeft Bottom left corner of rectangle.
sl@0
   186
@param aDoBl Span the bottom left quadrant.
sl@0
   187
@param aBottomRight Bottom right corner of rectangle.
sl@0
   188
@param aDoBr Span the bottom right quadrant.
sl@0
   189
@see TSwDirectGdiArc::SingleStep
sl@0
   190
@see TSwDirectGdiArc::Construct
sl@0
   191
*/
sl@0
   192
void TSwDirectGdiArc::Step(TPoint& aTopLeft,TBool& aDoTl,TPoint& aTopRight,TBool& aDoTr,
sl@0
   193
				TPoint& aBottomLeft,TBool& aDoBl,TPoint& aBottomRight,TBool& aDoBr)
sl@0
   194
	{
sl@0
   195
	aDoTl=iTlquad;
sl@0
   196
	aDoTr=iTrquad;
sl@0
   197
	aDoBl=iBlquad;
sl@0
   198
	aDoBr=iBrquad;
sl@0
   199
	if (!iStartquaddone)
sl@0
   200
		{
sl@0
   201
		if (!iStartquadenabled)
sl@0
   202
			{
sl@0
   203
			if (iStartquad==0 && aTopLeft.iX<=iStart.iX && aTopLeft.iY>=iStart.iY)
sl@0
   204
				{
sl@0
   205
				iStartquadenabled=ETrue;
sl@0
   206
				iStartquaddone=ETrue;
sl@0
   207
				}
sl@0
   208
			if (iStartquad==3 && aBottomRight.iX>=iStart.iX && aBottomRight.iY<=iStart.iY)
sl@0
   209
				{
sl@0
   210
				iStartquadenabled=ETrue;
sl@0
   211
				iStartquaddone=ETrue;
sl@0
   212
				}
sl@0
   213
			}
sl@0
   214
		else
sl@0
   215
			{
sl@0
   216
			if (iStartquad==1 && (aTopRight.iX>iStart.iX || aTopRight.iY>iStart.iY))
sl@0
   217
				{
sl@0
   218
				iStartquadenabled=EFalse;
sl@0
   219
				iStartquaddone=ETrue;
sl@0
   220
				}
sl@0
   221
			if (iStartquad==2 && (aBottomLeft.iX<iStart.iX || aBottomLeft.iY<iStart.iY))
sl@0
   222
				{
sl@0
   223
				iStartquadenabled=EFalse;
sl@0
   224
				iStartquaddone=ETrue;
sl@0
   225
				}
sl@0
   226
			}
sl@0
   227
		}
sl@0
   228
	if (!iEndquaddone)
sl@0
   229
		{
sl@0
   230
		if (iEndquadenabled)
sl@0
   231
			{
sl@0
   232
			if (iEndquad==0 && (aTopLeft.iX<iEnd.iX || aTopLeft.iY>iEnd.iY))
sl@0
   233
				{
sl@0
   234
				iEndquadenabled=EFalse;
sl@0
   235
				iEndquaddone=ETrue;
sl@0
   236
				}
sl@0
   237
			if (iEndquad==3 && (aBottomRight.iX>iEnd.iX || aBottomRight.iY<iEnd.iY))
sl@0
   238
				{
sl@0
   239
				iEndquadenabled=EFalse;
sl@0
   240
				iEndquaddone=ETrue;
sl@0
   241
				}
sl@0
   242
			}
sl@0
   243
		else
sl@0
   244
			{
sl@0
   245
			if (iEndquad==1 && aTopRight.iX>=iEnd.iX && aTopRight.iY>=iEnd.iY)
sl@0
   246
				{
sl@0
   247
				iEndquadenabled=ETrue;
sl@0
   248
				iEndquaddone=ETrue;
sl@0
   249
				}
sl@0
   250
			if (iEndquad==2 && aBottomLeft.iX<=iEnd.iX && aBottomLeft.iY<=iEnd.iY)
sl@0
   251
				{
sl@0
   252
				iEndquadenabled=ETrue;
sl@0
   253
				iEndquaddone=ETrue;
sl@0
   254
				}
sl@0
   255
			}
sl@0
   256
		}
sl@0
   257
	if (iStartquad!=iEndquad)
sl@0
   258
		{
sl@0
   259
		if (iStartquadenabled)
sl@0
   260
			{
sl@0
   261
			if (iStartquad==0) aDoTl=ETrue;
sl@0
   262
			else if (iStartquad==1) aDoTr=ETrue;
sl@0
   263
			else if (iStartquad==2) aDoBl=ETrue;
sl@0
   264
			else if (iStartquad==3) aDoBr=ETrue;
sl@0
   265
			}
sl@0
   266
		if (iEndquadenabled)
sl@0
   267
			{
sl@0
   268
			if (iEndquad==0) aDoTl=ETrue;
sl@0
   269
			else if (iEndquad==1) aDoTr=ETrue;
sl@0
   270
			else if (iEndquad==2) aDoBl=ETrue;
sl@0
   271
			else if (iEndquad==3) aDoBr=ETrue;
sl@0
   272
			}
sl@0
   273
		}
sl@0
   274
	else
sl@0
   275
		{
sl@0
   276
		if (iSlice)
sl@0
   277
			{
sl@0
   278
			if (iStartquadenabled && iEndquadenabled)
sl@0
   279
				{
sl@0
   280
				if (iStartquad==0) aDoTl=ETrue;
sl@0
   281
				else if (iStartquad==1) aDoTr=ETrue;
sl@0
   282
				else if (iStartquad==2) aDoBl=ETrue;
sl@0
   283
				else if (iStartquad==3) aDoBr=ETrue;
sl@0
   284
				}
sl@0
   285
			}
sl@0
   286
		else
sl@0
   287
			{
sl@0
   288
			if (iStartquadenabled || iEndquadenabled)
sl@0
   289
				{
sl@0
   290
				if (iStartquad==0) aDoTl=ETrue;
sl@0
   291
				else if (iStartquad==1) aDoTr=ETrue;
sl@0
   292
				else if (iStartquad==2) aDoBl=ETrue;
sl@0
   293
				else if (iStartquad==3) aDoBr=ETrue;
sl@0
   294
				}
sl@0
   295
			}
sl@0
   296
		}
sl@0
   297
	if (aTopLeft.iX==aTopRight.iX)
sl@0
   298
		{
sl@0
   299
		if (aDoTl && aDoTr) aDoTr=EFalse;
sl@0
   300
		if (aDoBl && aDoBr) aDoBr=EFalse;
sl@0
   301
		}
sl@0
   302
	}
sl@0
   303
sl@0
   304
//
sl@0
   305
// Pie and Arc drawing functions
sl@0
   306
//
sl@0
   307
sl@0
   308
/**
sl@0
   309
@see MDirectGdiEngine::DrawArc()
sl@0
   310
*/
sl@0
   311
void CSwDirectGdiEngine::DrawArc(const TRect& aRect,const TPoint& aStart,
sl@0
   312
								 const TPoint& aEnd)
sl@0
   313
	{
sl@0
   314
	TRect rcpy(aRect);
sl@0
   315
	rcpy.Move(iOrigin);
sl@0
   316
	TruncateRect(rcpy);
sl@0
   317
	TRect targetRect(rcpy);
sl@0
   318
	targetRect.Grow((iPenSize.iWidth>>1)+1,(iPenSize.iHeight>>1)+1);
sl@0
   319
	PieArcOutline(rcpy,aStart+iOrigin,aEnd+iOrigin,EFalse);
sl@0
   320
	}
sl@0
   321
sl@0
   322
/**
sl@0
   323
@see MDirectGdiEngine::DrawPie()
sl@0
   324
*/
sl@0
   325
void CSwDirectGdiEngine::DrawPie(const TRect& aRect,const TPoint& aStart,
sl@0
   326
								 const TPoint& aEnd)
sl@0
   327
	{
sl@0
   328
	TRect rcpy(aRect);
sl@0
   329
	rcpy.Move(iOrigin);
sl@0
   330
	TruncateRect(rcpy);
sl@0
   331
	TPoint startIntersect = aStart + iOrigin, endIntersect = aEnd + iOrigin;
sl@0
   332
	TInt startQuadrant, endQuadrant;
sl@0
   333
	TBool quadrants[5];
sl@0
   334
	const TBool isEllipse = AnalyseEllipse(
sl@0
   335
		rcpy, startIntersect, endIntersect, startQuadrant, endQuadrant, quadrants);
sl@0
   336
sl@0
   337
	if (iBrushStyle!=DirectGdi::ENullBrush)
sl@0
   338
		{
sl@0
   339
		if (isEllipse)
sl@0
   340
			EllipseFill(rcpy);
sl@0
   341
		else
sl@0
   342
			PieFill(rcpy, startIntersect, endIntersect, startQuadrant, endQuadrant, quadrants);
sl@0
   343
		}
sl@0
   344
	if ((iPenStyle!=DirectGdi::ENullPen) && (iPenSize.iWidth>0) && (iPenSize.iHeight>0))
sl@0
   345
		PieArcOutline(rcpy,aStart+iOrigin,aEnd+iOrigin,ETrue);
sl@0
   346
	}
sl@0
   347
sl@0
   348
/**
sl@0
   349
Calculates which quadrants are completely filled and which quadrants contain the 
sl@0
   350
start and end points.
sl@0
   351
sl@0
   352
@param aRect      The bounding rectangle. 
sl@0
   353
@param aStart     The arc start point.
sl@0
   354
@param aEnd	      The arc end point.
sl@0
   355
@param aStartQuad On return, contains the quadrant which contains aStart. 
sl@0
   356
@param aEndQuad   On return, contains the quadrant which contains aEnd.
sl@0
   357
@param aQuads     On return, populates an array of full quadrants to fill.
sl@0
   358
@pre Input params aRect, aStart, aEnd are to be given.
sl@0
   359
@post Output params aStart, aEnd, aStartQuad, aEndQuad, aQuads will be populated.
sl@0
   360
@return ETrue if the pie is an ellipse, otherwise EFalse.
sl@0
   361
*/
sl@0
   362
TBool CSwDirectGdiEngine::AnalyseEllipse(const TRect& aRect,TPoint& aStart,TPoint& aEnd,
sl@0
   363
							   TInt& aStartQuad,TInt& aEndQuad,TBool* aQuads)
sl@0
   364
	{
sl@0
   365
	aStartQuad=0;
sl@0
   366
	aEndQuad=0;
sl@0
   367
	const TPoint center = aRect.Center();
sl@0
   368
	TSwDirectGdiEllipse ellipse;
sl@0
   369
	aStart=ellipse.Intersection(aRect,aStart);
sl@0
   370
	aEnd=ellipse.Intersection(aRect,aEnd);
sl@0
   371
	if (aStart==aEnd)
sl@0
   372
		{
sl@0
   373
		aQuads[0]=EFalse;
sl@0
   374
		aQuads[1]=ETrue;
sl@0
   375
		aQuads[2]=ETrue;
sl@0
   376
		aQuads[3]=ETrue;
sl@0
   377
		aQuads[4]=ETrue;
sl@0
   378
		return ETrue;
sl@0
   379
		}
sl@0
   380
	const TInt startx = aStart.iX - center.iX, starty = aStart.iY - center.iY;
sl@0
   381
	const TInt endx = aEnd.iX - center.iX, endy = aEnd.iY - center.iY;
sl@0
   382
	if (startx>=0) aStartQuad=1;
sl@0
   383
	if (starty>=0) aStartQuad+=2;
sl@0
   384
	if (endx>=0) aEndQuad=1;
sl@0
   385
	if (endy>=0) aEndQuad+=2;
sl@0
   386
	aQuads[1]=EFalse,aQuads[2]=EFalse,aQuads[3]=EFalse,aQuads[4]=EFalse; // complete quadrants to draw
sl@0
   387
	aQuads[0]=EFalse; // ellipse is a sliver completely within a quadrant
sl@0
   388
	if (aStartQuad==aEndQuad)
sl@0
   389
		{
sl@0
   390
		if (aStartQuad==0 && (startx<endx || starty>endy))
sl@0
   391
			{
sl@0
   392
			aQuads[2]=ETrue;
sl@0
   393
			aQuads[3]=ETrue;
sl@0
   394
			aQuads[4]=ETrue;
sl@0
   395
			}
sl@0
   396
		else if (aStartQuad==1 && (startx<endx || starty<endy))
sl@0
   397
			{
sl@0
   398
			aQuads[1]=ETrue;
sl@0
   399
			aQuads[3]=ETrue;
sl@0
   400
			aQuads[4]=ETrue;
sl@0
   401
			}
sl@0
   402
		else if (aStartQuad==2 && (startx>endx || starty>endy))
sl@0
   403
			{
sl@0
   404
			aQuads[1]=ETrue;
sl@0
   405
			aQuads[2]=ETrue;
sl@0
   406
			aQuads[4]=ETrue;
sl@0
   407
			}
sl@0
   408
		else if (aStartQuad==3 && (startx>endx || starty<endy))
sl@0
   409
			{
sl@0
   410
			aQuads[1]=ETrue;
sl@0
   411
			aQuads[2]=ETrue;
sl@0
   412
			aQuads[3]=ETrue;
sl@0
   413
			}
sl@0
   414
		else aQuads[0]=ETrue; // "slice"
sl@0
   415
		}
sl@0
   416
	else
sl@0
   417
		{
sl@0
   418
		if (aStartQuad==0 && aEndQuad==1)
sl@0
   419
			{
sl@0
   420
			aQuads[3]=ETrue;
sl@0
   421
			aQuads[4]=ETrue;
sl@0
   422
			}
sl@0
   423
		else if (aStartQuad==0 && aEndQuad==3)
sl@0
   424
			aQuads[3]=ETrue;
sl@0
   425
		else if (aStartQuad==1 && aEndQuad==2)
sl@0
   426
			aQuads[1]=ETrue;
sl@0
   427
		else if (aStartQuad==1 && aEndQuad==3)
sl@0
   428
			{
sl@0
   429
			aQuads[1]=ETrue;
sl@0
   430
			aQuads[3]=ETrue;
sl@0
   431
			}
sl@0
   432
		else if (aStartQuad==2 && aEndQuad==0)
sl@0
   433
			{
sl@0
   434
			aQuads[2]=ETrue;
sl@0
   435
			aQuads[4]=ETrue;
sl@0
   436
			}
sl@0
   437
		else if (aStartQuad==2 && aEndQuad==1)
sl@0
   438
			aQuads[4]=ETrue;
sl@0
   439
		else if (aStartQuad==3 && aEndQuad==0)
sl@0
   440
			aQuads[2]=ETrue;
sl@0
   441
		else if (aStartQuad==3 && aEndQuad==2)
sl@0
   442
			{
sl@0
   443
			aQuads[1]=ETrue;
sl@0
   444
			aQuads[2]=ETrue;
sl@0
   445
			}
sl@0
   446
		}
sl@0
   447
	return EFalse;
sl@0
   448
	}
sl@0
   449
sl@0
   450
/**
sl@0
   451
Draws the outline of a pie or arc.
sl@0
   452
sl@0
   453
@param aRect  The bounding rectangle. 
sl@0
   454
@param aStart The arc start point.
sl@0
   455
@param aEnd	  The arc end point.
sl@0
   456
@param aPie If this is the outline for a pie ETrue, else EFalse
sl@0
   457
*/
sl@0
   458
void CSwDirectGdiEngine::PieArcOutline(const TRect& aRect,const TPoint& aStart,
sl@0
   459
							  const TPoint& aEnd,TBool aPie)
sl@0
   460
	{
sl@0
   461
	// arc runs counterclockwise, from startradius-center/ellipse intersect to endradius-center/ellipse intersect
sl@0
   462
	TInt dotparam=iDotParam;
sl@0
   463
	TRect rcpy(aRect);
sl@0
   464
	TPoint pt[4];
sl@0
   465
	TInt halfpenwidth=iPenSize.iWidth>>1;
sl@0
   466
	TInt halfpenheight=iPenSize.iHeight>>1;
sl@0
   467
	TInt otherhalfwidth=(iPenSize.iWidth+1)>>1;
sl@0
   468
	TInt otherhalfheight=(iPenSize.iHeight+1)>>1;
sl@0
   469
	rcpy.iTl.iX-=halfpenwidth;
sl@0
   470
	rcpy.iTl.iY-=halfpenheight;
sl@0
   471
	rcpy.iBr.iX+=otherhalfwidth;
sl@0
   472
	rcpy.iBr.iY+=otherhalfheight;
sl@0
   473
	TRect clipRect(0,0,0,0);
sl@0
   474
	for(TInt count=0;count<iDefaultRegionPtr->Count();count++)
sl@0
   475
		{
sl@0
   476
		clipRect=(*iDefaultRegionPtr)[count];
sl@0
   477
		if (!clipRect.Intersects(rcpy))
sl@0
   478
			continue;
sl@0
   479
		clipRect.Intersection(rcpy);
sl@0
   480
		TSwDirectGdiArc arc;
sl@0
   481
		arc.Construct(aRect,aStart,aEnd);
sl@0
   482
		iDotParam=Max(iPenSize.iWidth>>1,iPenSize.iHeight>>1);
sl@0
   483
		TBool dotl,dotr,dobl,dobr;
sl@0
   484
		while(!arc.SingleStep(pt[0],dotl,pt[1],dotr,pt[2],dobl,pt[3],dobr))
sl@0
   485
			{
sl@0
   486
			if (dotl) PenDrawClipped(pt[0], clipRect);
sl@0
   487
			if (dotr) PenDrawClipped(pt[1], clipRect);
sl@0
   488
			if (dobl) PenDrawClipped(pt[2], clipRect);
sl@0
   489
			if (dobr) PenDrawClipped(pt[3], clipRect);
sl@0
   490
			iDotParam+=iDotDirection;
sl@0
   491
			}
sl@0
   492
		if (pt[0].iY==pt[2].iY)
sl@0
   493
			{
sl@0
   494
			if (dotl) PenDrawClipped(pt[0], clipRect);
sl@0
   495
			if (dotr) PenDrawClipped(pt[1], clipRect);
sl@0
   496
			}
sl@0
   497
		if (aPie)
sl@0
   498
			{
sl@0
   499
			TPoint temp;
sl@0
   500
			const TPoint center = aRect.Center();
sl@0
   501
			TLinearDDA line;
sl@0
   502
			line.Construct(arc.iStart,center);
sl@0
   503
			line.SingleStep(temp);
sl@0
   504
			while(!line.SingleStep(temp))
sl@0
   505
				{
sl@0
   506
				PenDrawClipped(temp, clipRect);
sl@0
   507
				iDotParam+=iDotDirection;
sl@0
   508
				}
sl@0
   509
			line.Construct(arc.iEnd,center);
sl@0
   510
			line.SingleStep(temp);
sl@0
   511
			while(!line.SingleStep(temp))
sl@0
   512
				{
sl@0
   513
				PenDrawClipped(temp, clipRect);
sl@0
   514
				iDotParam+=iDotDirection;
sl@0
   515
				}
sl@0
   516
			PenDrawClipped(center, clipRect);
sl@0
   517
			}
sl@0
   518
		iDrawDevice->UpdateRegion(clipRect);
sl@0
   519
		}
sl@0
   520
	iDotParam=dotparam;
sl@0
   521
	}
sl@0
   522
sl@0
   523
/**
sl@0
   524
Fills a pie.
sl@0
   525
sl@0
   526
@param aRect      The bounding rectangle. 
sl@0
   527
@param aStart     The arc start point.
sl@0
   528
@param aEnd	      The arc end point.
sl@0
   529
@param aStartQuad The quadrant which contains aStart. 
sl@0
   530
@param aEndQuad   The quadrant which contains aEnd.
sl@0
   531
@param aQuads     An array of full quadrants to fill.
sl@0
   532
@see CSwDirectGdiEngine::DrawPie
sl@0
   533
@see CSwDirectGdiEngine::AnalyseEllipse 
sl@0
   534
*/
sl@0
   535
void CSwDirectGdiEngine::PieFill(const TRect& aRect, const TPoint& aStart, const TPoint& aEnd,
sl@0
   536
						TInt aStartQuad, TInt aEndQuad, const TBool* aQuads)
sl@0
   537
	{
sl@0
   538
	// arc runs counterclockwise, from startradius-center/ellipse intersect to endradius-center/ellipse intersect
sl@0
   539
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   540
	TRect clipRect(0,0,0,0);
sl@0
   541
	for(TInt count=0;count<limit;count++)
sl@0
   542
		{
sl@0
   543
		clipRect=(*iDefaultRegionPtr)[count];
sl@0
   544
		if (!clipRect.Intersects(aRect))
sl@0
   545
			{
sl@0
   546
			continue;
sl@0
   547
			}
sl@0
   548
		clipRect.Intersection(aRect);
sl@0
   549
		if (!aQuads[0])
sl@0
   550
			{
sl@0
   551
			PieShell(aRect, aStart, aEnd, aQuads, aStartQuad, aEndQuad, clipRect);
sl@0
   552
			}
sl@0
   553
		else
sl@0
   554
			{
sl@0
   555
			PieSliver(aRect, aStart, aEnd, aStartQuad, clipRect);
sl@0
   556
			}
sl@0
   557
		iDrawDevice->UpdateRegion(clipRect);
sl@0
   558
		}
sl@0
   559
	}
sl@0
   560
sl@0
   561
/**
sl@0
   562
Draws a pie spanning one or more quadrants.
sl@0
   563
sl@0
   564
@param aRect      The bounding rectangle. 
sl@0
   565
@param aStart     The arc start point.
sl@0
   566
@param aEnd	      The arc end point.
sl@0
   567
@param aQuads     Array of full quadrants to fill.
sl@0
   568
@param aStartQuad The quadrant which contains aStart. 
sl@0
   569
@param aEndQuad   The quadrant which contains aEnd.
sl@0
   570
@param aClipRect  The rectangle to which the pie is clipped.
sl@0
   571
*/
sl@0
   572
void CSwDirectGdiEngine::PieShell(const TRect& aRect,const TPoint& aStart,
sl@0
   573
						 const TPoint& aEnd, const TBool* aQuads, TInt aStartQuad, 
sl@0
   574
						 TInt aEndQuad, TRect aClipRect)
sl@0
   575
	{
sl@0
   576
	TSwDirectGdiEllipse ellipse;
sl@0
   577
	ellipse.Construct(aRect);
sl@0
   578
	TInt c=aRect.Center().iX;
sl@0
   579
	TPoint pt[4];
sl@0
   580
	TPoint tl,tr,bl,br;
sl@0
   581
	TBool donestart=EFalse;
sl@0
   582
	TBool doneend=EFalse;
sl@0
   583
	TBool todostart=EFalse;
sl@0
   584
	TBool todoend=EFalse;
sl@0
   585
	while(!ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]))
sl@0
   586
		{
sl@0
   587
		if (pt[aStartQuad].iY==aStart.iY)
sl@0
   588
			todostart=ETrue;
sl@0
   589
		if (pt[aEndQuad].iY==aEnd.iY)
sl@0
   590
			todoend=ETrue;
sl@0
   591
		pt[0].iX++;
sl@0
   592
		pt[1].iX--;
sl@0
   593
		pt[2].iX++;
sl@0
   594
		pt[3].iX--;
sl@0
   595
		tl.iY=pt[0].iY;
sl@0
   596
		tr.iY=pt[1].iY;
sl@0
   597
		bl.iY=pt[2].iY;
sl@0
   598
		br.iY=pt[3].iY;
sl@0
   599
		if (aQuads[1] || (aEndQuad==0 && !doneend)) // tl quadrant, half top end chord
sl@0
   600
			tl.iX=pt[0].iX;
sl@0
   601
		else tl.iX=c+1;
sl@0
   602
		if (aQuads[2] || (aStartQuad==1 && !donestart)) // tr quadrant, half top start chord
sl@0
   603
			tr.iX=pt[1].iX;
sl@0
   604
		else tr.iX=c;
sl@0
   605
		if (aQuads[3] || (aStartQuad==2 && !donestart)) // bl quadrant, half top start chord
sl@0
   606
			bl.iX=pt[2].iX;
sl@0
   607
		else bl.iX=c+1;
sl@0
   608
		if (aQuads[4] || (aEndQuad==3 && !doneend)) // br quadrant, half top end chord
sl@0
   609
			br.iX=pt[3].iX;
sl@0
   610
		else br.iX=c;
sl@0
   611
		ClipFillLine(tl,tr,aClipRect);
sl@0
   612
		ClipFillLine(bl,br,aClipRect);
sl@0
   613
		// do partial quadrants
sl@0
   614
		if (todostart)
sl@0
   615
			{
sl@0
   616
			if (aStartQuad==0)
sl@0
   617
				{
sl@0
   618
				tl.iX=pt[0].iX;
sl@0
   619
				tr.iX=aStart.iX;
sl@0
   620
				ClipFillLine(tl,tr,aClipRect);
sl@0
   621
				}
sl@0
   622
			else if (aStartQuad==3)
sl@0
   623
				{
sl@0
   624
				bl.iX=aStart.iX;
sl@0
   625
				br.iX=pt[3].iX;
sl@0
   626
				ClipFillLine(bl,br,aClipRect);
sl@0
   627
				}
sl@0
   628
			}
sl@0
   629
		if (todoend)
sl@0
   630
			{
sl@0
   631
			if (aEndQuad==2)
sl@0
   632
				{
sl@0
   633
				bl.iX=pt[2].iX;
sl@0
   634
				br.iX=aEnd.iX;
sl@0
   635
				ClipFillLine(bl,br,aClipRect);
sl@0
   636
				}
sl@0
   637
			else if (aEndQuad==1)
sl@0
   638
				{
sl@0
   639
				tl.iX=aEnd.iX;
sl@0
   640
				tr.iX=pt[1].iX;
sl@0
   641
				ClipFillLine(tl,tr,aClipRect);
sl@0
   642
				}
sl@0
   643
			}
sl@0
   644
		donestart=todostart;
sl@0
   645
		doneend=todoend;
sl@0
   646
		}
sl@0
   647
	tl.iX=c+1;
sl@0
   648
	tr.iX=c;
sl@0
   649
	if (pt[0].iY==pt[2].iY) // congruent mid lines
sl@0
   650
		{
sl@0
   651
		if (pt[aStartQuad].iY==aStart.iY)
sl@0
   652
			todostart=ETrue;
sl@0
   653
		if (pt[aEndQuad].iY==aEnd.iY)
sl@0
   654
			todoend=ETrue;
sl@0
   655
		pt[0].iX++;
sl@0
   656
		pt[1].iX--;
sl@0
   657
		tl.iY=pt[0].iY;
sl@0
   658
		tr.iY=tl.iY;
sl@0
   659
		TBool leftflag=EFalse;
sl@0
   660
		TBool rightflag=EFalse;
sl@0
   661
		if (aQuads[1] || (aEndQuad==0 && !doneend) ||
sl@0
   662
			aQuads[3] || (aStartQuad==2 && !donestart) ||
sl@0
   663
			(todostart && aStartQuad==0) || (todoend && aEndQuad==2))
sl@0
   664
			leftflag=ETrue;
sl@0
   665
		if (aQuads[2] || (aStartQuad==1 && !donestart) ||
sl@0
   666
			aQuads[4] || (aEndQuad==3 && !doneend) ||
sl@0
   667
			(todostart && aStartQuad==3) || (todoend && aEndQuad==1))
sl@0
   668
			rightflag=ETrue;
sl@0
   669
		if (leftflag) tl.iX=pt[0].iX;
sl@0
   670
		if (rightflag) tr.iX=pt[1].iX;
sl@0
   671
		ClipFillLine(tl,tr,aClipRect);
sl@0
   672
		}
sl@0
   673
	else
sl@0
   674
		{
sl@0
   675
		tl.iY=aRect.Center().iY;
sl@0
   676
		tr.iY=tl.iY;
sl@0
   677
		if (aStartQuad==3) tr.iX=aStart.iX-1;
sl@0
   678
		if (aEndQuad==2) tl.iX=aEnd.iX+1;
sl@0
   679
		ClipFillLine(tl,tr,aClipRect);
sl@0
   680
		}
sl@0
   681
	PieTriangles(aStartQuad==1 || aStartQuad==2,aStart,aRect.Center(), aClipRect);
sl@0
   682
	PieTriangles(aEndQuad==0 || aEndQuad==3,aEnd,aRect.Center(), aClipRect);
sl@0
   683
	}
sl@0
   684
sl@0
   685
/**
sl@0
   686
Draws a filled triangle which forms part of a partially filled quadrant.
sl@0
   687
sl@0
   688
@param aInside A boolean value indicating which side of the line to fill.
sl@0
   689
@param aStart The start of the line which forms the hypotenuse of the triangle.
sl@0
   690
@param aEnd The end of the line which forms the hypotenuse of the triangle.
sl@0
   691
@param aClipRect The rectangle to which the pie is clipped.
sl@0
   692
@see CSwDirectGdiEngine::PieShell 
sl@0
   693
*/
sl@0
   694
void CSwDirectGdiEngine::PieTriangles(TBool aInside,const TPoint& aStart,const TPoint& aEnd, TRect aClipRect)
sl@0
   695
	{
sl@0
   696
	TInt x=aInside?aEnd.iX:aStart.iX;
sl@0
   697
	if (aStart.iX>aEnd.iX)
sl@0
   698
		{
sl@0
   699
		if (aInside)
sl@0
   700
			{
sl@0
   701
			x++;
sl@0
   702
			}
sl@0
   703
		else
sl@0
   704
			{
sl@0
   705
			x--;
sl@0
   706
			}
sl@0
   707
		}
sl@0
   708
	else
sl@0
   709
		{
sl@0
   710
		if (!aInside)
sl@0
   711
			{
sl@0
   712
			x++;
sl@0
   713
			}
sl@0
   714
		}
sl@0
   715
	TLinearDDA line;
sl@0
   716
	TPoint pt,left,right;
sl@0
   717
	line.Construct(aStart,aEnd);
sl@0
   718
	line.NextStep(pt);
sl@0
   719
	while(!line.NextStep(pt))
sl@0
   720
		{
sl@0
   721
		if (pt.iY==aEnd.iY) break;
sl@0
   722
		left.iX=Min(pt.iX,x);
sl@0
   723
		right.iX=Max(pt.iX,x);
sl@0
   724
		left.iY=right.iY=pt.iY;
sl@0
   725
		ClipFillLine(left,right,aClipRect);
sl@0
   726
		}
sl@0
   727
	}
sl@0
   728
sl@0
   729
/**
sl@0
   730
Draws a pie entirely contained in one quadrant.
sl@0
   731
sl@0
   732
@param aRect The rectangle in which to draw the ellipse. 
sl@0
   733
@param aStart The arc start point.
sl@0
   734
@param aEnd	The arc end point.
sl@0
   735
@param aQuad The quadrant containing the pie.
sl@0
   736
@param aClipRect The rectangle to which the pie is clipped.
sl@0
   737
*/
sl@0
   738
void CSwDirectGdiEngine::PieSliver(const TRect& aRect,const TPoint& aStart,
sl@0
   739
						  const TPoint& aEnd, TInt aQuad, TRect aClipRect)
sl@0
   740
	{
sl@0
   741
	TPoint center=aRect.Center(),left,right;
sl@0
   742
	TPoint nearinter(aStart),farinter(aEnd);
sl@0
   743
	if (Abs(nearinter.iY-center.iY)>Abs(farinter.iY-center.iY))
sl@0
   744
		{
sl@0
   745
		nearinter=aEnd;
sl@0
   746
		farinter=aStart;
sl@0
   747
		}
sl@0
   748
	TBool ellipseComplete = EFalse;
sl@0
   749
	TPoint pt[4];
sl@0
   750
	TSwDirectGdiEllipse ellipse;
sl@0
   751
	ellipse.Construct(aRect);
sl@0
   752
	TLinearDDA mainline;
sl@0
   753
	mainline.Construct(farinter,center);
sl@0
   754
	ellipseComplete = ellipse.SingleStep(pt[0],pt[1],pt[2],pt[3]);
sl@0
   755
	mainline.SingleStep(right);
sl@0
   756
	do	{
sl@0
   757
		while(!ellipseComplete && pt[aQuad].iY!=right.iY)
sl@0
   758
			ellipseComplete = ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]);
sl@0
   759
		left=pt[aQuad];
sl@0
   760
		while(!ellipseComplete && pt[aQuad].iY==right.iY)
sl@0
   761
			{
sl@0
   762
			left=pt[aQuad];
sl@0
   763
			ellipseComplete = ellipse.NextStep(pt[0],pt[1],pt[2],pt[3]);
sl@0
   764
			}
sl@0
   765
		if (right.iY==nearinter.iY || (ellipseComplete && (pt[0].iY != pt[2].iY)))
sl@0
   766
			break;
sl@0
   767
		if (left.iX>right.iX)
sl@0
   768
			{
sl@0
   769
			TInt temp=left.iX;
sl@0
   770
			left.iX=right.iX;
sl@0
   771
			right.iX=temp;
sl@0
   772
			}
sl@0
   773
		if(right==farinter && left.iX<=right.iX)
sl@0
   774
			{
sl@0
   775
			continue;
sl@0
   776
			}
sl@0
   777
		left.iX++;
sl@0
   778
		right.iX--;
sl@0
   779
		if (left.iX<=right.iX)
sl@0
   780
			ClipFillLine(left,right,aClipRect);
sl@0
   781
		}
sl@0
   782
	while(!mainline.NextStep(right));
sl@0
   783
	TPoint temppt;
sl@0
   784
	TLinearDDA line;
sl@0
   785
	line.Construct(nearinter,center);
sl@0
   786
	TBool linestat=EFalse;
sl@0
   787
	do
sl@0
   788
		linestat=line.SingleStep(temppt);
sl@0
   789
	while(temppt.iY!=right.iY && !linestat);
sl@0
   790
	do	{
sl@0
   791
		do	{
sl@0
   792
			left=temppt;
sl@0
   793
			linestat=line.SingleStep(temppt);
sl@0
   794
			}
sl@0
   795
		while(temppt.iY==right.iY && !linestat);
sl@0
   796
		if (ellipseComplete)
sl@0
   797
			break;
sl@0
   798
		if (left.iX>right.iX)
sl@0
   799
			{
sl@0
   800
			TInt temp=left.iX;
sl@0
   801
			left.iX=right.iX;
sl@0
   802
			right.iX=temp;
sl@0
   803
			}
sl@0
   804
		if(right==farinter && left.iX<=right.iX)
sl@0
   805
			{
sl@0
   806
			continue;
sl@0
   807
			}
sl@0
   808
		left.iX++;
sl@0
   809
		right.iX--;
sl@0
   810
		if (left.iX<=right.iX)
sl@0
   811
			ClipFillLine(left,right,aClipRect);
sl@0
   812
		}
sl@0
   813
	while(!mainline.NextStep(right));
sl@0
   814
	}
sl@0
   815