os/graphics/graphicsdeviceinterface/directgdiadaptation/swsrc/swdirectgdiline.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
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 "swdirectgdipolygon.h"
sl@0
    18
sl@0
    19
/**
sl@0
    20
@see MDirectGdiEngine::DrawLine()
sl@0
    21
*/
sl@0
    22
void CSwDirectGdiEngine::DrawLine(const TPoint& aPt1,const TPoint& aPt2)
sl@0
    23
    {
sl@0
    24
	DoDrawLine(aPt1,aPt2,ETrue);
sl@0
    25
	}
sl@0
    26
sl@0
    27
/**
sl@0
    28
@see MDirectGdiEngine::DrawLineTo()
sl@0
    29
*/
sl@0
    30
void CSwDirectGdiEngine::DrawLineTo(const TPoint& aPoint)
sl@0
    31
	{
sl@0
    32
	DrawLine(iLinePosition,aPoint);
sl@0
    33
	}
sl@0
    34
sl@0
    35
sl@0
    36
/**
sl@0
    37
@see MDirectGdiEngine::DrawLineBy()
sl@0
    38
*/	
sl@0
    39
void CSwDirectGdiEngine::DrawLineBy(const TPoint& aVector)
sl@0
    40
    {
sl@0
    41
	DrawLine(iLinePosition,iLinePosition + aVector);
sl@0
    42
	}
sl@0
    43
sl@0
    44
/**
sl@0
    45
@see MDirectGdiEngine::DrawPolyLine()
sl@0
    46
sl@0
    47
@panic DGDIAdapter 27, if the passed point list has too few points (debug only).
sl@0
    48
*/
sl@0
    49
void CSwDirectGdiEngine::DrawPolyLine(const TArray<TPoint>& aPointList)
sl@0
    50
	{
sl@0
    51
	DrawPolyLineNoEndPoint(aPointList);
sl@0
    52
	
sl@0
    53
	if (iPenStyle == DirectGdi::ESolidPen)
sl@0
    54
		{
sl@0
    55
		Plot(aPointList[aPointList.Count()-1]);
sl@0
    56
		}
sl@0
    57
	}
sl@0
    58
sl@0
    59
/**
sl@0
    60
@see MDirectGdiEngine::DrawPolyLineNoEndPoint()
sl@0
    61
sl@0
    62
@panic DGDIAdapter 27, if the passed point list has too few points (debug only).
sl@0
    63
*/
sl@0
    64
void CSwDirectGdiEngine::DrawPolyLineNoEndPoint(const TArray<TPoint>& aPointList)
sl@0
    65
	{
sl@0
    66
	GRAPHICS_ASSERT_DEBUG(aPointList.Count() > 0, EDirectGdiPanicInvalidPointArray);
sl@0
    67
sl@0
    68
	const TInt vertexes = aPointList.Count()-1;
sl@0
    69
sl@0
    70
	for (TInt count = 0; count < vertexes; count++)
sl@0
    71
		{
sl@0
    72
		DrawLine(aPointList[count], aPointList[count + 1]);
sl@0
    73
		}
sl@0
    74
	}
sl@0
    75
sl@0
    76
/**
sl@0
    77
@see MDirectGdiEngine::DrawPolygon()
sl@0
    78
*/
sl@0
    79
void CSwDirectGdiEngine::DrawPolygon(const TArray<TPoint>& aPointList, DirectGdi::TFillRule aFillRule)
sl@0
    80
	{
sl@0
    81
	const TInt numpoints = aPointList.Count();
sl@0
    82
sl@0
    83
	if (iBrushStyle != DirectGdi::ENullBrush)
sl@0
    84
		{
sl@0
    85
		TRect pointrect(0,0,0,0);
sl@0
    86
		TRect truncrect(0,0,0,0);
sl@0
    87
		TBool largepolygon = EFalse;
sl@0
    88
sl@0
    89
		for (TInt count = 0; count < numpoints; count++)
sl@0
    90
			{
sl@0
    91
			pointrect.iTl = aPointList[count] + iOrigin;
sl@0
    92
			truncrect.iTl = pointrect.iTl;
sl@0
    93
			TruncateRect(truncrect);
sl@0
    94
sl@0
    95
			if (pointrect.iTl != truncrect.iTl)
sl@0
    96
				{
sl@0
    97
				largepolygon = ETrue;
sl@0
    98
				break;
sl@0
    99
				}
sl@0
   100
			}
sl@0
   101
sl@0
   102
		if (largepolygon)
sl@0
   103
			{
sl@0
   104
			PolyFillLarge(&aPointList, aFillRule);
sl@0
   105
			}
sl@0
   106
		else
sl@0
   107
			{
sl@0
   108
			PolyFill(&aPointList, aFillRule);
sl@0
   109
			}
sl@0
   110
		}
sl@0
   111
sl@0
   112
	if (iPenStyle != DirectGdi::ENullPen)
sl@0
   113
		{
sl@0
   114
		if (iPenSize.iWidth > 0 && iPenSize.iHeight > 0)
sl@0
   115
			{
sl@0
   116
			PolyOutline(&aPointList);
sl@0
   117
			}
sl@0
   118
		}
sl@0
   119
	}
sl@0
   120
sl@0
   121
/**
sl@0
   122
Draws a straight line from the start to the end position using current pen size, colour and style.
sl@0
   123
sl@0
   124
@param	aPt1 Start position.
sl@0
   125
@param	aPt2 End position.
sl@0
   126
@param	aDrawStartPoint	If ETrue, draws the first pixel of the line.
sl@0
   127
sl@0
   128
@post   The internal drawing position is set to the line's endpoint.
sl@0
   129
@see CSwDirectGdiEngine::DrawLine()
sl@0
   130
*/
sl@0
   131
void CSwDirectGdiEngine::DoDrawLine(TPoint aPt1, TPoint aPt2, TBool aDrawStartPoint)
sl@0
   132
	{
sl@0
   133
	iLinePosition = aPt2;
sl@0
   134
sl@0
   135
	if ((aPt1 == aPt2))
sl@0
   136
		{
sl@0
   137
		return;
sl@0
   138
		}
sl@0
   139
sl@0
   140
	aPt1 += iOrigin;
sl@0
   141
	aPt2 += iOrigin;
sl@0
   142
sl@0
   143
	TRect temp(aPt1,aPt2);
sl@0
   144
	temp.Normalize();
sl@0
   145
	temp.Grow(iPenSize.iWidth, iPenSize.iHeight);
sl@0
   146
sl@0
   147
	TRect screenRect;
sl@0
   148
	iDrawDevice->GetDrawRect(screenRect);
sl@0
   149
	screenRect.Grow(iPenSize.iWidth, iPenSize.iHeight);
sl@0
   150
sl@0
   151
	const TInt dotParam = iDotParam;
sl@0
   152
	TPoint plotpt(0,0);
sl@0
   153
	const CGraphicsContext::TDrawMode drawMode = GcDrawMode(iDrawMode);
sl@0
   154
sl@0
   155
	TRect clipRect(0,0,0,0);
sl@0
   156
	for (TInt count = 0; count < iDefaultRegionPtr->Count(); count++)
sl@0
   157
		{
sl@0
   158
		iDotParam = dotParam;
sl@0
   159
		clipRect = (*iDefaultRegionPtr)[count];
sl@0
   160
sl@0
   161
		if (!clipRect.Intersects(temp))
sl@0
   162
			{
sl@0
   163
			TLinearDDA line;
sl@0
   164
			line.Construct(aPt1,aPt2);
sl@0
   165
			line.JumpToRect(screenRect);
sl@0
   166
			if (iPenStyle != DirectGdi::ESolidPen)
sl@0
   167
				{
sl@0
   168
				while (!line.SingleStep(plotpt))
sl@0
   169
					{
sl@0
   170
					iDotParam += iDotDirection;
sl@0
   171
					}
sl@0
   172
				}
sl@0
   173
			continue;
sl@0
   174
			}
sl@0
   175
sl@0
   176
		clipRect.Intersection(temp);
sl@0
   177
sl@0
   178
		if ((iPenSize.iWidth > 1 || iPenSize.iHeight > 1) && (iPenStyle == DirectGdi::ESolidPen)) // wide solid line
sl@0
   179
			{
sl@0
   180
			DoDrawSolidWideLine(aPt1, aPt2, aDrawStartPoint, screenRect, clipRect);
sl@0
   181
			}
sl@0
   182
		else if (iPenSize.iWidth > 1 || iPenSize.iHeight > 1) // dotted line
sl@0
   183
			{
sl@0
   184
			DoDrawDottedWideLine(aPt1, aPt2, aDrawStartPoint, screenRect, clipRect);
sl@0
   185
			}
sl@0
   186
		else if (iPenStyle != DirectGdi::ESolidPen) // single pixel dotted line
sl@0
   187
			{
sl@0
   188
			TLinearDDA line;
sl@0
   189
			line.Construct(aPt1,aPt2);
sl@0
   190
			line.JumpToRect(screenRect);
sl@0
   191
sl@0
   192
			iDotParam = dotParam;
sl@0
   193
			if (!aDrawStartPoint)
sl@0
   194
				{
sl@0
   195
				line.SingleStep(plotpt);
sl@0
   196
				iDotParam += iDotDirection;
sl@0
   197
				}
sl@0
   198
sl@0
   199
			while (!line.SingleStep(plotpt))
sl@0
   200
				{
sl@0
   201
				PenDrawClipped(plotpt, clipRect);
sl@0
   202
				iDotParam += iDotDirection;
sl@0
   203
				}
sl@0
   204
			}
sl@0
   205
		else if (aPt1.iY == aPt2.iY && 
sl@0
   206
				(aPt1.iY >= clipRect.iTl.iY && 
sl@0
   207
				 aPt1.iY < clipRect.iBr.iY))
sl@0
   208
			{ // single pixel solid horizontal line
sl@0
   209
			TInt start = Min(aPt1.iX,aPt2.iX + 1);
sl@0
   210
			TInt length = Abs(aPt2.iX - aPt1.iX);
sl@0
   211
sl@0
   212
			if (!aDrawStartPoint)
sl@0
   213
				{
sl@0
   214
				if (aPt1.iX < aPt2.iX)
sl@0
   215
					{
sl@0
   216
					start++;
sl@0
   217
					}
sl@0
   218
				else
sl@0
   219
					{
sl@0
   220
					length--;
sl@0
   221
					}
sl@0
   222
				}
sl@0
   223
			if (start < clipRect.iTl.iX)
sl@0
   224
				{
sl@0
   225
				length += start - clipRect.iTl.iX;
sl@0
   226
				start = clipRect.iTl.iX;
sl@0
   227
				}
sl@0
   228
			if ( (start + length) > clipRect.iBr.iX)
sl@0
   229
				{
sl@0
   230
				length = clipRect.iBr.iX - start;
sl@0
   231
				}
sl@0
   232
sl@0
   233
			if (length > 0)
sl@0
   234
				{
sl@0
   235
				iDrawDevice->WriteRgbMulti(start, aPt1.iY, length, 1, iPenColor, drawMode);
sl@0
   236
				}
sl@0
   237
			}
sl@0
   238
		else if (aPt1.iX == aPt2.iX && (aPt1.iX >= clipRect.iTl.iX && aPt1.iX < clipRect.iBr.iX))
sl@0
   239
			{ // single pixel solid vertical line
sl@0
   240
			TInt start = Min(aPt1.iY,aPt2.iY + 1);
sl@0
   241
			TInt length = Abs(aPt2.iY - aPt1.iY);
sl@0
   242
sl@0
   243
			if (!aDrawStartPoint)
sl@0
   244
				{
sl@0
   245
				if (aPt1.iY < aPt2.iY)
sl@0
   246
					{
sl@0
   247
					start++;
sl@0
   248
					}
sl@0
   249
				else
sl@0
   250
					{
sl@0
   251
					length--;
sl@0
   252
					}
sl@0
   253
				}
sl@0
   254
sl@0
   255
			if (start < clipRect.iTl.iY)
sl@0
   256
				{
sl@0
   257
				length += start - clipRect.iTl.iY;
sl@0
   258
				start = clipRect.iTl.iY;
sl@0
   259
				}
sl@0
   260
			if (start + length > clipRect.iBr.iY)
sl@0
   261
				{
sl@0
   262
				length = clipRect.iBr.iY - start;
sl@0
   263
				}
sl@0
   264
sl@0
   265
			if (length > 0)
sl@0
   266
				{			
sl@0
   267
				iDrawDevice->WriteRgbMulti(aPt1.iX,start,1,length,iPenColor, drawMode);
sl@0
   268
				}
sl@0
   269
			}
sl@0
   270
		else
sl@0
   271
			{ // single pixel solid diagonal line
sl@0
   272
			TLinearDDA line;
sl@0
   273
			line.Construct(aPt1,aPt2);
sl@0
   274
sl@0
   275
			line.JumpToRect(screenRect);
sl@0
   276
sl@0
   277
			if (!aDrawStartPoint)
sl@0
   278
				{
sl@0
   279
				line.SingleStep(plotpt);
sl@0
   280
				}
sl@0
   281
sl@0
   282
			while (!line.SingleStep(plotpt))
sl@0
   283
				{
sl@0
   284
				if (clipRect.Contains(plotpt))
sl@0
   285
					{
sl@0
   286
					iDrawDevice->WriteRgb(plotpt.iX, plotpt.iY, iPenColor, drawMode);
sl@0
   287
					}
sl@0
   288
				}
sl@0
   289
			}
sl@0
   290
sl@0
   291
		iDrawDevice->UpdateRegion(clipRect);
sl@0
   292
		}
sl@0
   293
	}
sl@0
   294
sl@0
   295
/**
sl@0
   296
Draws a straight line from the start to the end position using pen sizes larger than 1x1 pixel. 
sl@0
   297
sl@0
   298
@param	aPt1 Start position.
sl@0
   299
@param	aPt2 End position.
sl@0
   300
@param	aDrawStartPoint	If ETrue, draws the first pixel of the line.
sl@0
   301
@param  aScreenRect Rectangle representing the screen boundary.
sl@0
   302
@param aClipRect The rectangle to which the line is clipped.
sl@0
   303
@see CSwDirectGdiEngine::DrawLine()
sl@0
   304
*/
sl@0
   305
void CSwDirectGdiEngine::DoDrawSolidWideLine(const TPoint& aPt1,
sl@0
   306
									const TPoint& aPt2,
sl@0
   307
									TBool aDrawStartPoint,
sl@0
   308
									const TRect& aScreenRect,
sl@0
   309
									TRect aClipRect)
sl@0
   310
	{
sl@0
   311
	CFbsDrawDevice* drawDevice = iDrawDevice;
sl@0
   312
sl@0
   313
	TLinearDDA line;
sl@0
   314
	line.Construct(aPt1,aPt2);
sl@0
   315
sl@0
   316
	TPoint plotpt(aPt1);
sl@0
   317
	line.JumpToRect(aScreenRect);
sl@0
   318
	if (!aDrawStartPoint)
sl@0
   319
		line.SingleStep(plotpt);
sl@0
   320
sl@0
   321
	TInt* deferred = NULL;
sl@0
   322
	const TInt doubleheight = iPenSize.iHeight << 1;
sl@0
   323
sl@0
   324
	if (iPenArray)
sl@0
   325
		{
sl@0
   326
		deferred = new TInt[doubleheight];
sl@0
   327
		}
sl@0
   328
sl@0
   329
	if (!iPenArray || !deferred)
sl@0
   330
		{
sl@0
   331
		while (!line.SingleStep(plotpt))
sl@0
   332
			PenDrawClipped(plotpt, aClipRect);
sl@0
   333
		}
sl@0
   334
	else
sl@0
   335
		{
sl@0
   336
		const TBool down = (aPt2.iY >= aPt1.iY);
sl@0
   337
sl@0
   338
		for (TInt fillcount = 0; fillcount < doubleheight; )
sl@0
   339
			{
sl@0
   340
			deferred[fillcount++] = KMaxTInt;
sl@0
   341
			deferred[fillcount++] = KMinTInt;
sl@0
   342
			}
sl@0
   343
sl@0
   344
		TInt nextline = 0;
sl@0
   345
		TInt nexty = plotpt.iY;
sl@0
   346
		if (down)
sl@0
   347
			{
sl@0
   348
			nexty -= ((iPenSize.iHeight - 1) >> 1);
sl@0
   349
			}
sl@0
   350
		else
sl@0
   351
			{
sl@0
   352
			nexty += (iPenSize.iHeight >> 1);
sl@0
   353
			}
sl@0
   354
sl@0
   355
		TInt lasty = plotpt.iY;
sl@0
   356
sl@0
   357
		while (!line.SingleStep(plotpt))
sl@0
   358
			{
sl@0
   359
			if (plotpt.iY != lasty)
sl@0
   360
				{
sl@0
   361
				if (nexty >= aClipRect.iTl.iY && nexty < aClipRect.iBr.iY)
sl@0
   362
					{
sl@0
   363
					TInt left = deferred[nextline];
sl@0
   364
					TInt right = deferred[nextline + 1];
sl@0
   365
					if (left < aClipRect.iTl.iX)
sl@0
   366
						{
sl@0
   367
						left = aClipRect.iTl.iX;
sl@0
   368
						}
sl@0
   369
					if (right >= aClipRect.iBr.iX)
sl@0
   370
						{
sl@0
   371
						right = aClipRect.iBr.iX - 1;
sl@0
   372
						}
sl@0
   373
sl@0
   374
					if (left <= right)
sl@0
   375
						{
sl@0
   376
						drawDevice->WriteRgbMulti(left,nexty,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
sl@0
   377
						}
sl@0
   378
					}
sl@0
   379
sl@0
   380
				if (down)
sl@0
   381
					{
sl@0
   382
					nexty++;
sl@0
   383
					}
sl@0
   384
				else
sl@0
   385
					{
sl@0
   386
					nexty--;
sl@0
   387
					}
sl@0
   388
				
sl@0
   389
				lasty = plotpt.iY;
sl@0
   390
				deferred[nextline++] = KMaxTInt;
sl@0
   391
				deferred[nextline++] = KMinTInt;
sl@0
   392
				if (nextline == doubleheight)
sl@0
   393
					{
sl@0
   394
					nextline = 0;
sl@0
   395
					}
sl@0
   396
				}
sl@0
   397
sl@0
   398
			PenDrawDeferred(plotpt,deferred,nextline);
sl@0
   399
			}
sl@0
   400
sl@0
   401
		for (TInt restofline = 0; restofline < doubleheight; restofline += 2,nextline += 2)
sl@0
   402
			{
sl@0
   403
			if (nextline == doubleheight)
sl@0
   404
				nextline = 0;
sl@0
   405
sl@0
   406
			if (nexty >= aClipRect.iTl.iY && nexty < aClipRect.iBr.iY)
sl@0
   407
				{
sl@0
   408
				TInt left = deferred[nextline];
sl@0
   409
				TInt right = deferred[nextline+1];
sl@0
   410
				if (left < aClipRect.iTl.iX)
sl@0
   411
					{
sl@0
   412
					left = aClipRect.iTl.iX;
sl@0
   413
					}
sl@0
   414
				if (right >= aClipRect.iBr.iX)
sl@0
   415
					{
sl@0
   416
					right = aClipRect.iBr.iX-1;
sl@0
   417
					}
sl@0
   418
sl@0
   419
				if (left <= right)
sl@0
   420
					{
sl@0
   421
					drawDevice->WriteRgbMulti(left,nexty,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
sl@0
   422
					}
sl@0
   423
				}
sl@0
   424
sl@0
   425
			if (down)
sl@0
   426
				{
sl@0
   427
				nexty++;
sl@0
   428
				}
sl@0
   429
			else
sl@0
   430
				{
sl@0
   431
				nexty--;
sl@0
   432
				}
sl@0
   433
			}
sl@0
   434
sl@0
   435
		delete[] deferred;
sl@0
   436
		}
sl@0
   437
	}
sl@0
   438
sl@0
   439
/**
sl@0
   440
Draws a dotted straight line from the start to the end position using pen sizes larger than 1x1 pixel.
sl@0
   441
sl@0
   442
@param	aPt1 Start position.
sl@0
   443
@param	aPt2 End position.
sl@0
   444
@param	aDrawStartPoint	If ETrue, draws the first pixel of the line.
sl@0
   445
@param  aScreenRect Rectangle representing the screen boundary.
sl@0
   446
@param	aClipRect The rectangle to which the line is clipped.
sl@0
   447
@see CSwDirectGdiEngine::DrawLine()
sl@0
   448
*/
sl@0
   449
void CSwDirectGdiEngine::DoDrawDottedWideLine(const TPoint& aPt1,
sl@0
   450
									 const TPoint& aPt2,
sl@0
   451
									 TBool aDrawStartPoint,
sl@0
   452
									 const TRect& aScreenRect,
sl@0
   453
									 TRect aClipRect)
sl@0
   454
	{
sl@0
   455
	TLinearDDA line;
sl@0
   456
	line.Construct(aPt1,aPt2);
sl@0
   457
sl@0
   458
	TPoint plotpt(aPt1);
sl@0
   459
	line.JumpToRect(aScreenRect);
sl@0
   460
	if (!aDrawStartPoint)
sl@0
   461
		{
sl@0
   462
		line.SingleStep(plotpt);
sl@0
   463
		iDotParam += iDotDirection;
sl@0
   464
		}
sl@0
   465
	
sl@0
   466
	const TInt maxdim = Max(iPenSize.iWidth, iPenSize.iHeight);
sl@0
   467
sl@0
   468
	TBool done = EFalse;
sl@0
   469
	while (!done)
sl@0
   470
		{
sl@0
   471
		while (!done && !(iDotMask & (1 << ((iDotParam / maxdim) % iDotLength))))
sl@0
   472
			{
sl@0
   473
			done = line.SingleStep(plotpt);
sl@0
   474
			iDotParam += iDotDirection;
sl@0
   475
			}
sl@0
   476
sl@0
   477
		TPoint startdash(plotpt);
sl@0
   478
		TPoint enddash(plotpt);
sl@0
   479
sl@0
   480
		while (!done && (iDotMask & (1 << ((iDotParam / maxdim) % iDotLength))))
sl@0
   481
			{
sl@0
   482
			enddash = plotpt;
sl@0
   483
			done = line.SingleStep(plotpt);
sl@0
   484
			iDotParam += iDotDirection;
sl@0
   485
			}
sl@0
   486
sl@0
   487
		DoDrawSolidWideLine(startdash,enddash,ETrue,aScreenRect,aClipRect);
sl@0
   488
		}
sl@0
   489
	}
sl@0
   490
sl@0
   491
/**
sl@0
   492
Fills a polygon defined using an array of points. The first point in the array defines the 
sl@0
   493
start of the first side of the polygon. The final side of the polygon is drawn using the last point 
sl@0
   494
from the array. The area is filled with the current brush settings. 
sl@0
   495
sl@0
   496
Self-crossing polygons are filled according to the specified fill rule.
sl@0
   497
sl@0
   498
@param	aPointList	Array of points specifying the vertices of the polygon.
sl@0
   499
@param	aFillRule	Polygon filling rule.
sl@0
   500
*/
sl@0
   501
void CSwDirectGdiEngine::PolyFill(const TArray<TPoint>* aPointList, DirectGdi::TFillRule aFillRule)
sl@0
   502
	{
sl@0
   503
	TBool exists;
sl@0
   504
	TInt scanline;
sl@0
   505
	TInt pixelRunStart;
sl@0
   506
	TInt pixelRunEnd;
sl@0
   507
sl@0
   508
	TRect clipRect(0,0,0,0);
sl@0
   509
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   510
	for (TInt count = 0; count < limit; count++)
sl@0
   511
		{
sl@0
   512
		clipRect = (*iDefaultRegionPtr)[count];
sl@0
   513
		CSwDirectGdiPolygonFiller polyfill;
sl@0
   514
		polyfill.Construct(aPointList,aFillRule);
sl@0
   515
sl@0
   516
		for(polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd);exists;
sl@0
   517
						polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd))
sl@0
   518
			{
sl@0
   519
			TPoint start(pixelRunStart, scanline);
sl@0
   520
			TPoint end(pixelRunEnd, scanline);
sl@0
   521
			start += iOrigin;
sl@0
   522
			end += iOrigin;
sl@0
   523
			ClipFillLine(start,end,clipRect);
sl@0
   524
			}
sl@0
   525
sl@0
   526
		polyfill.Reset();
sl@0
   527
		iDrawDevice->UpdateRegion(clipRect);
sl@0
   528
		}
sl@0
   529
	}
sl@0
   530
sl@0
   531
sl@0
   532
/**
sl@0
   533
Fills a polygon defined using an array of points. The first point in the array defines the 
sl@0
   534
start of the first side of the polygon. The final side of the polygon is drawn using the last point 
sl@0
   535
from the array. The area is filled with the current brush settings. Optimized for polygons that are
sl@0
   536
much larger than the screen.
sl@0
   537
sl@0
   538
Self-crossing polygons are filled according to the specified fill rule.
sl@0
   539
sl@0
   540
@param	aPointList	Array of points specifying the vertices of the polygon.
sl@0
   541
@param	aFillRule	Polygon filling rule.
sl@0
   542
*/
sl@0
   543
void CSwDirectGdiEngine::PolyFillLarge(const TArray<TPoint>* aPointList, DirectGdi::TFillRule aFillRule)
sl@0
   544
	{
sl@0
   545
	TBool exists;
sl@0
   546
	TInt pixelRunStart;
sl@0
   547
	TInt pixelRunEnd;
sl@0
   548
	
sl@0
   549
	TRect clipRect(0,0,0,0);
sl@0
   550
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   551
	for (TInt count = 0; count < limit; count++)
sl@0
   552
		{
sl@0
   553
		clipRect = (*iDefaultRegionPtr)[count];
sl@0
   554
		CSwDirectGdiPolygonFiller polyfill;
sl@0
   555
		polyfill.Construct(aPointList,aFillRule,CSwDirectGdiPolygonFiller::EGetPixelRunsSequentiallyForSpecifiedScanLines);
sl@0
   556
		TInt clipRectOffsetStart = clipRect.iTl.iY - iOrigin.iY;
sl@0
   557
		TInt clipRectOffsetEnd = clipRect.iBr.iY - iOrigin.iY;
sl@0
   558
sl@0
   559
		for (TInt scanline = clipRectOffsetStart; scanline < clipRectOffsetEnd; scanline++)
sl@0
   560
			{
sl@0
   561
			polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd);
sl@0
   562
			while (exists)
sl@0
   563
				{
sl@0
   564
				TPoint start(pixelRunStart,scanline);
sl@0
   565
				TPoint end(pixelRunEnd,scanline);
sl@0
   566
				start += iOrigin;
sl@0
   567
				end += iOrigin;
sl@0
   568
				ClipFillLine(start,end,clipRect);
sl@0
   569
				polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd);
sl@0
   570
				}
sl@0
   571
			}
sl@0
   572
sl@0
   573
		polyfill.Reset();
sl@0
   574
		iDrawDevice->UpdateRegion(clipRect);
sl@0
   575
		}
sl@0
   576
	}
sl@0
   577
sl@0
   578
/**
sl@0
   579
Draws a polygon defined by an array of points using the current pen settings. The first point in the array defines the 
sl@0
   580
start of the first side of the polygon. The final side of the polygon is drawn using the last point 
sl@0
   581
from the array, and the line is drawn to the start point of the first side.
sl@0
   582
sl@0
   583
@param	aPointList List of points specifying the vertices of the polygon.
sl@0
   584
*/	
sl@0
   585
void CSwDirectGdiEngine::PolyOutline(const TArray<TPoint>* aPointList)
sl@0
   586
	{
sl@0
   587
	const TInt vertexes = aPointList->Count();
sl@0
   588
	
sl@0
   589
	for (TInt count = 0; count < vertexes; count++)
sl@0
   590
		{
sl@0
   591
		TPoint point1((*aPointList)[count]);
sl@0
   592
		TPoint point2((*aPointList)[(count + 1) % vertexes]);
sl@0
   593
sl@0
   594
		if (point1.iY < point2.iY)
sl@0
   595
			{
sl@0
   596
			DoDrawLine(point1,point2,ETrue);
sl@0
   597
			}
sl@0
   598
		else
sl@0
   599
			{
sl@0
   600
			iDotDirection = -1;
sl@0
   601
			iDotParam += Max(Abs(point2.iX - point1.iX),Abs(point2.iY - point1.iY));
sl@0
   602
			const TInt dotParam = iDotParam;
sl@0
   603
			DoDrawLine(point2,point1,EFalse);
sl@0
   604
sl@0
   605
			if (Abs(point2.iX - point1.iX) > Abs(point2.iY - point1.iY))
sl@0
   606
				{
sl@0
   607
				if (iPenStyle == DirectGdi::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iWidth) % iDotLength))))
sl@0
   608
					DoPlot((*aPointList)[count]);
sl@0
   609
				}
sl@0
   610
			else
sl@0
   611
				{
sl@0
   612
				if (iPenStyle == DirectGdi::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iHeight) % iDotLength))))
sl@0
   613
					DoPlot((*aPointList)[count]);
sl@0
   614
				}
sl@0
   615
sl@0
   616
			iDotDirection = 1;
sl@0
   617
			iDotParam = dotParam;
sl@0
   618
			}
sl@0
   619
		}
sl@0
   620
	}