os/graphics/graphicsdeviceinterface/bitgdi/sbit/LINE.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) 1997-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 <bitstd.h>
sl@0
    17
#include <bitdev.h>
sl@0
    18
#include "BITPANIC.H"
sl@0
    19
#include <bitdraw.h>
sl@0
    20
#include <graphics/fbsrasterizer.h>
sl@0
    21
#include "bitgcextradata.h"
sl@0
    22
sl@0
    23
sl@0
    24
/**  Draws a straight line between two points.
sl@0
    25
sl@0
    26
The function provides a concrete implementation of the pure virtual
sl@0
    27
function CGraphicsContext::DrawLine(). The function
sl@0
    28
behaviour is the same as documented in that class. */	
sl@0
    29
EXPORT_C void CFbsBitGc::DrawLine(const TPoint& aPt1,const TPoint& aPt2)
sl@0
    30
    {
sl@0
    31
	CheckDevice();
sl@0
    32
sl@0
    33
	TRect lineBoundingRect(aPt1,aPt2);
sl@0
    34
	lineBoundingRect.Normalize();
sl@0
    35
	lineBoundingRect.Move(iOrigin);
sl@0
    36
	lineBoundingRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1);
sl@0
    37
	if(!lineBoundingRect.Intersects(iUserClipRect))
sl@0
    38
		{
sl@0
    39
		iLinePosition = aPt2;// if DrawLine returns due to aPt2 being outside of the clipping rect then subsequent line are drawn from correct point.
sl@0
    40
		return;
sl@0
    41
		}
sl@0
    42
sl@0
    43
	SetupDevice();
sl@0
    44
	iDevice->DrawingBegin();
sl@0
    45
	DoDrawLine(aPt1,aPt2,ETrue);
sl@0
    46
	iDevice->DrawingEnd();
sl@0
    47
	}
sl@0
    48
sl@0
    49
/** Draws a straight line from the current drawing point to a specified
sl@0
    50
point.
sl@0
    51
sl@0
    52
The function provides a concrete implementation of the pure virtual
sl@0
    53
function CGraphicsContext::DrawLineTo(). The function
sl@0
    54
behaviour is the same as documented in that class. */
sl@0
    55
EXPORT_C void CFbsBitGc::DrawLineTo(const TPoint& aPoint)
sl@0
    56
	{
sl@0
    57
	DrawLine(iLinePosition,aPoint);
sl@0
    58
	}
sl@0
    59
sl@0
    60
sl@0
    61
/** Draws a straight line relative to the current drawing point, using a
sl@0
    62
vector.
sl@0
    63
sl@0
    64
The function provides a concrete implementation of the pure virtual
sl@0
    65
function CGraphicsContext::DrawLineBy(). The function
sl@0
    66
behaviour is the same as documented in that class. */	
sl@0
    67
EXPORT_C void CFbsBitGc::DrawLineBy(const TPoint& aVector)
sl@0
    68
    {
sl@0
    69
	DrawLine(iLinePosition,iLinePosition + aVector);
sl@0
    70
	}
sl@0
    71
sl@0
    72
/** Draws a polyline from a set of points specified in a list.
sl@0
    73
sl@0
    74
The functions provides a concrete implementation of the pure virtual
sl@0
    75
functions CGraphicsContext::DrawPolyLine(). The function
sl@0
    76
behaviour is the same as documented in that class. */
sl@0
    77
EXPORT_C void CFbsBitGc::DrawPolyLine(const CArrayFix<TPoint>* aPointList)
sl@0
    78
	{
sl@0
    79
	if(!aPointList || iPenSize.iWidth < 1 || iPenSize.iHeight < 1)
sl@0
    80
		return;
sl@0
    81
sl@0
    82
	const TInt vertexes = aPointList->Count()-1;
sl@0
    83
sl@0
    84
	for (TInt count = 0; count < vertexes; count++)
sl@0
    85
		DrawLine((*aPointList)[count],(*aPointList)[count + 1]);
sl@0
    86
sl@0
    87
	if (iPenStyle == CGraphicsContext::ESolidPen && vertexes >= 0)
sl@0
    88
		Plot((*aPointList)[vertexes]);
sl@0
    89
	}
sl@0
    90
sl@0
    91
/** Draws a polyline from a set of points specified in an array, but does not draw 
sl@0
    92
the final point of the last line.
sl@0
    93
sl@0
    94
@param aPointList An array containing the points on the polyline. */
sl@0
    95
EXPORT_C void CFbsBitGc::DrawPolyLineNoEndPoint(const CArrayFix<TPoint>* aPointList)
sl@0
    96
	{
sl@0
    97
	if(!aPointList || iPenSize.iWidth < 1 || iPenSize.iHeight < 1)
sl@0
    98
		return;
sl@0
    99
sl@0
   100
	const TInt vertexes = aPointList->Count() - 1;
sl@0
   101
sl@0
   102
	for (TInt count = 0; count < vertexes; count++)
sl@0
   103
		DrawLine((*aPointList)[count],(*aPointList)[count + 1]);
sl@0
   104
	}
sl@0
   105
sl@0
   106
/** Draws a polyline from a set of points specified in a list.
sl@0
   107
sl@0
   108
The functions provides a concrete implementation of the pure virtual
sl@0
   109
functions CGraphicsContext::DrawPolyLine(). The function
sl@0
   110
behaviour is the same as documented in that class. */
sl@0
   111
EXPORT_C void CFbsBitGc::DrawPolyLine(const TPoint* aPointList,TInt aNumPoints)
sl@0
   112
	{
sl@0
   113
    DrawPolyLineNoEndPoint(aPointList,aNumPoints);
sl@0
   114
sl@0
   115
	if (iPenStyle == CGraphicsContext::ESolidPen)
sl@0
   116
		Plot(aPointList[aNumPoints - 1]);
sl@0
   117
	}
sl@0
   118
sl@0
   119
/** Draws a polyline from a set of points specified in a list, but does not 
sl@0
   120
draw the final point of the last line.
sl@0
   121
sl@0
   122
@param aPointList Pointer to a set of points on the polyline. 
sl@0
   123
@param aNumPoints Number of points in the list. */
sl@0
   124
EXPORT_C void CFbsBitGc::DrawPolyLineNoEndPoint(const TPoint* aPointList,TInt aNumPoints)
sl@0
   125
	{
sl@0
   126
	if (!aPointList || iPenSize.iWidth < 1 || iPenSize.iHeight < 1)
sl@0
   127
		return;
sl@0
   128
sl@0
   129
	const TInt vertexes = aNumPoints - 1;
sl@0
   130
sl@0
   131
	for (TInt count = 0; count < vertexes; count++)
sl@0
   132
		DrawLine(aPointList[count],aPointList[count + 1]);
sl@0
   133
	}
sl@0
   134
sl@0
   135
/** Draws and fills a polygon defined using a list of points.
sl@0
   136
sl@0
   137
The function provides a concrete implementation of the pure virtual
sl@0
   138
function CGraphicsContext::DrawPolygon(). The function
sl@0
   139
behaviour is the same as documented in that class. */
sl@0
   140
EXPORT_C TInt CFbsBitGc::DrawPolygon(const CArrayFix<TPoint>* aPointList,TFillRule aFillRule)
sl@0
   141
	{
sl@0
   142
	CheckDevice();
sl@0
   143
sl@0
   144
	if (!aPointList)
sl@0
   145
		return KErrArgument;
sl@0
   146
sl@0
   147
	const TInt numpoints = aPointList->Count();
sl@0
   148
sl@0
   149
	if (numpoints == 0)
sl@0
   150
		return KErrNone; // Nothing to do!
sl@0
   151
	
sl@0
   152
	SetupDevice();
sl@0
   153
	iDevice->DrawingBegin(&iBrushBitmap);
sl@0
   154
	CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
sl@0
   155
sl@0
   156
	if (iBrushStyle != ENullBrush)
sl@0
   157
		{
sl@0
   158
		TRect pointrect(0,0,0,0);
sl@0
   159
		TRect truncrect(0,0,0,0);
sl@0
   160
		TBool largepolygon = EFalse;
sl@0
   161
sl@0
   162
		for (TInt count = 0; count < numpoints; count++)
sl@0
   163
			{
sl@0
   164
			pointrect.iTl = (*aPointList)[count] + iOrigin;
sl@0
   165
			truncrect.iTl = pointrect.iTl;
sl@0
   166
			iDevice->TruncateRect(truncrect);
sl@0
   167
sl@0
   168
			if (pointrect.iTl != truncrect.iTl)
sl@0
   169
				{
sl@0
   170
				largepolygon = ETrue;
sl@0
   171
				break;
sl@0
   172
				}
sl@0
   173
			}
sl@0
   174
sl@0
   175
		if (largepolygon)
sl@0
   176
			PolyFillLarge(aPointList,aFillRule);
sl@0
   177
		else
sl@0
   178
			PolyFill(aPointList,aFillRule);
sl@0
   179
		}
sl@0
   180
sl@0
   181
	if (iPenStyle != ENullPen)
sl@0
   182
		if (iPenSize.iWidth > 0 && iPenSize.iHeight > 0)
sl@0
   183
			PolyOutline(aPointList);
sl@0
   184
sl@0
   185
	if (brushRasterizer)
sl@0
   186
		{
sl@0
   187
		brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
sl@0
   188
		}
sl@0
   189
	iDevice->DrawingEnd(&iBrushBitmap);
sl@0
   190
sl@0
   191
	return KErrNone;
sl@0
   192
	}
sl@0
   193
sl@0
   194
sl@0
   195
/** Draws and fills a polygon defined using a list of points.
sl@0
   196
sl@0
   197
The function provides a concrete implementation of the pure virtual
sl@0
   198
function CGraphicsContext::DrawPolygon(). The function
sl@0
   199
behaviour is the same as documented in that class. */	
sl@0
   200
EXPORT_C TInt CFbsBitGc::DrawPolygon(const TPoint* aPointList,
sl@0
   201
									 TInt aNumPoints,
sl@0
   202
									 CGraphicsContext::TFillRule aFillRule)
sl@0
   203
    {
sl@0
   204
	CheckDevice();
sl@0
   205
sl@0
   206
	if (!aPointList || aNumPoints < 0)
sl@0
   207
		return KErrArgument;
sl@0
   208
sl@0
   209
	if (aNumPoints == 0)
sl@0
   210
		return KErrNone; // Nothing to do!
sl@0
   211
sl@0
   212
	SetupDevice();
sl@0
   213
	iDevice->DrawingBegin(&iBrushBitmap);
sl@0
   214
	CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap);
sl@0
   215
sl@0
   216
	if (iBrushStyle != ENullBrush)
sl@0
   217
		{
sl@0
   218
		TRect pointrect(0,0,0,0);
sl@0
   219
		TRect truncrect(0,0,0,0);
sl@0
   220
		TBool largepolygon = EFalse;
sl@0
   221
sl@0
   222
		for (TInt count = 0; count < aNumPoints; count++)
sl@0
   223
			{
sl@0
   224
			pointrect.iTl = aPointList[count] + iOrigin;
sl@0
   225
			truncrect.iTl = pointrect.iTl;
sl@0
   226
			iDevice->TruncateRect(truncrect);
sl@0
   227
sl@0
   228
			if (pointrect.iTl != truncrect.iTl)
sl@0
   229
				{
sl@0
   230
				largepolygon = ETrue;
sl@0
   231
				break;
sl@0
   232
				}
sl@0
   233
			}
sl@0
   234
sl@0
   235
		if (largepolygon)
sl@0
   236
			PolyFillLarge(aPointList,aNumPoints,aFillRule);
sl@0
   237
		else
sl@0
   238
			PolyFill(aPointList,aNumPoints,aFillRule);
sl@0
   239
		}
sl@0
   240
sl@0
   241
	if (iPenStyle != ENullPen && iPenSize.iWidth > 0 && iPenSize.iHeight > 0)
sl@0
   242
		PolyOutline(aPointList,aNumPoints);
sl@0
   243
sl@0
   244
	if (brushRasterizer)
sl@0
   245
		{
sl@0
   246
		brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber());
sl@0
   247
		}
sl@0
   248
	iDevice->DrawingEnd(&iBrushBitmap);
sl@0
   249
sl@0
   250
	return KErrNone;
sl@0
   251
	}
sl@0
   252
sl@0
   253
void CFbsBitGc::DoDrawLine(TPoint aPt1,TPoint aPt2,TBool aDrawStartPoint)
sl@0
   254
	{
sl@0
   255
	iLinePosition = aPt2;
sl@0
   256
sl@0
   257
	if (aPt1 == aPt2 || iPenStyle == ENullPen || !iPenSize.iWidth || !iPenSize.iHeight)
sl@0
   258
		return;
sl@0
   259
sl@0
   260
	aPt1 += iOrigin;
sl@0
   261
	aPt2 += iOrigin;
sl@0
   262
sl@0
   263
	TRect temp(aPt1,aPt2);
sl@0
   264
	temp.Normalize();
sl@0
   265
	temp.Grow(iPenSize.iWidth,iPenSize.iHeight);
sl@0
   266
	AddRect(temp);
sl@0
   267
	if (UserClipRect(temp))
sl@0
   268
		return;
sl@0
   269
sl@0
   270
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   271
sl@0
   272
	TRect screenRect;
sl@0
   273
	drawDevice->GetDrawRect(screenRect);
sl@0
   274
	screenRect.Grow(iPenSize.iWidth,iPenSize.iHeight);
sl@0
   275
sl@0
   276
	const TInt dotParam = iDotParam;
sl@0
   277
	TPoint plotpt(0,0);
sl@0
   278
sl@0
   279
	for (TInt count = 0; count < iDefaultRegionPtr->Count(); count++)
sl@0
   280
		{
sl@0
   281
		iDotParam = dotParam;
sl@0
   282
		iClipRect = (*iDefaultRegionPtr)[count];
sl@0
   283
sl@0
   284
		if (!iClipRect.Intersects(temp))
sl@0
   285
			{
sl@0
   286
			TLinearDDA line;
sl@0
   287
			line.Construct(aPt1,aPt2);
sl@0
   288
			line.JumpToRect(screenRect);
sl@0
   289
			if (iPenStyle != ESolidPen)
sl@0
   290
				while (!line.SingleStep(plotpt))
sl@0
   291
					iDotParam += iDotDirection;
sl@0
   292
			continue;
sl@0
   293
			}
sl@0
   294
sl@0
   295
		iClipRect.Intersection(temp);
sl@0
   296
sl@0
   297
		if ((iPenSize.iWidth > 1 || iPenSize.iHeight > 1) && iPenStyle == ESolidPen) // wide solid line
sl@0
   298
			DoDrawSolidWideLine(aPt1,aPt2,aDrawStartPoint,screenRect);
sl@0
   299
		else if (iPenSize.iWidth > 1 || iPenSize.iHeight > 1) // dotted line
sl@0
   300
			DoDrawDottedWideLine(aPt1,aPt2,aDrawStartPoint,screenRect);
sl@0
   301
		else if (iPenStyle != ESolidPen) // single pixel dotted line
sl@0
   302
			{
sl@0
   303
			TLinearDDA line;
sl@0
   304
			line.Construct(aPt1,aPt2);
sl@0
   305
			line.JumpToRect(screenRect);
sl@0
   306
sl@0
   307
			iDotParam = dotParam;
sl@0
   308
			if (!aDrawStartPoint)
sl@0
   309
				{
sl@0
   310
				line.SingleStep(plotpt);
sl@0
   311
				iDotParam += iDotDirection;
sl@0
   312
				}
sl@0
   313
sl@0
   314
			while (!line.SingleStep(plotpt))
sl@0
   315
				{
sl@0
   316
				PenDrawClipped(plotpt);
sl@0
   317
				iDotParam += iDotDirection;
sl@0
   318
				}
sl@0
   319
			}
sl@0
   320
		else if (aPt1.iY == aPt2.iY && 
sl@0
   321
				 (aPt1.iY >= iClipRect.iTl.iY && aPt1.iY < iClipRect.iBr.iY))
sl@0
   322
			{ // single pixel solid horizontal line
sl@0
   323
			TInt start = Min(aPt1.iX,aPt2.iX + 1);
sl@0
   324
			TInt length = Abs(aPt2.iX - aPt1.iX);
sl@0
   325
sl@0
   326
			if (!aDrawStartPoint)
sl@0
   327
				if (aPt1.iX < aPt2.iX)
sl@0
   328
					start++;
sl@0
   329
				else
sl@0
   330
					length--;
sl@0
   331
			if (start < iClipRect.iTl.iX)
sl@0
   332
				{
sl@0
   333
				length += start - iClipRect.iTl.iX;
sl@0
   334
				start = iClipRect.iTl.iX;
sl@0
   335
				}
sl@0
   336
			if (start + length > iClipRect.iBr.iX)
sl@0
   337
				length = iClipRect.iBr.iX - start;
sl@0
   338
sl@0
   339
			if (length > 0)
sl@0
   340
				{
sl@0
   341
				BG_ASSERT_DEBUG(start >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds);
sl@0
   342
				BG_ASSERT_DEBUG(aPt1.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds);
sl@0
   343
				BG_ASSERT_DEBUG(start + length <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds);
sl@0
   344
				BG_ASSERT_DEBUG(aPt1.iY < iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds);
sl@0
   345
sl@0
   346
				drawDevice->WriteRgbMulti(start,aPt1.iY,length,1,iPenColor,iDrawMode);
sl@0
   347
				}
sl@0
   348
			}
sl@0
   349
		else if (aPt1.iX == aPt2.iX && (aPt1.iX >= iClipRect.iTl.iX && aPt1.iX < iClipRect.iBr.iX))
sl@0
   350
			{ // single pixel solid vertical line
sl@0
   351
			TInt start = Min(aPt1.iY,aPt2.iY + 1);
sl@0
   352
			TInt length = Abs(aPt2.iY - aPt1.iY);
sl@0
   353
sl@0
   354
			if (!aDrawStartPoint)
sl@0
   355
				if (aPt1.iY < aPt2.iY)
sl@0
   356
					start++;
sl@0
   357
				else
sl@0
   358
					length--;
sl@0
   359
sl@0
   360
			if (start < iClipRect.iTl.iY)
sl@0
   361
				{
sl@0
   362
				length += start - iClipRect.iTl.iY;
sl@0
   363
				start = iClipRect.iTl.iY;
sl@0
   364
				}
sl@0
   365
			if (start + length > iClipRect.iBr.iY)
sl@0
   366
				length = iClipRect.iBr.iY - start;
sl@0
   367
sl@0
   368
			if (length > 0)
sl@0
   369
				{
sl@0
   370
				BG_ASSERT_DEBUG(aPt1.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds);
sl@0
   371
				BG_ASSERT_DEBUG(start >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds);
sl@0
   372
				BG_ASSERT_DEBUG(aPt1.iX < iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds);
sl@0
   373
				BG_ASSERT_DEBUG(start + length <= iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds);
sl@0
   374
sl@0
   375
				drawDevice->WriteRgbMulti(aPt1.iX,start,1,length,iPenColor,iDrawMode);
sl@0
   376
				}
sl@0
   377
			}
sl@0
   378
		else
sl@0
   379
			{ // single pixel solid diagonal line
sl@0
   380
			TLinearDDA line;
sl@0
   381
			line.Construct(aPt1,aPt2);
sl@0
   382
sl@0
   383
			line.JumpToRect(screenRect);
sl@0
   384
sl@0
   385
			if (!aDrawStartPoint)
sl@0
   386
				line.SingleStep(plotpt);
sl@0
   387
sl@0
   388
			while (!line.SingleStep(plotpt))
sl@0
   389
				{
sl@0
   390
				if (iClipRect.Contains(plotpt))
sl@0
   391
					{
sl@0
   392
					BG_ASSERT_DEBUG(plotpt.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds);
sl@0
   393
					BG_ASSERT_DEBUG(plotpt.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds);
sl@0
   394
					BG_ASSERT_DEBUG(plotpt.iX < iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds);
sl@0
   395
					BG_ASSERT_DEBUG(plotpt.iY < iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds);
sl@0
   396
sl@0
   397
					drawDevice->WriteRgb(plotpt.iX,plotpt.iY,iPenColor,iDrawMode);
sl@0
   398
					}
sl@0
   399
				}
sl@0
   400
			}
sl@0
   401
sl@0
   402
		drawDevice->UpdateRegion(iClipRect);
sl@0
   403
		}
sl@0
   404
	}
sl@0
   405
sl@0
   406
void CFbsBitGc::DoDrawSolidWideLine(const TPoint& aPt1,
sl@0
   407
									const TPoint& aPt2,
sl@0
   408
									TBool aDrawStartPoint,
sl@0
   409
									const TRect& aScreenRect)
sl@0
   410
	{
sl@0
   411
	CFbsDrawDevice* drawDevice = iDevice->iDrawDevice;
sl@0
   412
sl@0
   413
	TLinearDDA line;
sl@0
   414
	line.Construct(aPt1,aPt2);
sl@0
   415
sl@0
   416
	TPoint plotpt(aPt1);
sl@0
   417
	line.JumpToRect(aScreenRect);
sl@0
   418
	if (!aScreenRect.Contains(plotpt) || !aDrawStartPoint)
sl@0
   419
		line.SingleStep(plotpt);
sl@0
   420
sl@0
   421
	TInt* deferred = NULL;
sl@0
   422
	const TInt doubleheight = iPenSize.iHeight << 1;
sl@0
   423
sl@0
   424
	if (iFbsBitGcExtraData->PenArray())
sl@0
   425
		deferred = new TInt[doubleheight];
sl@0
   426
sl@0
   427
	if (!iFbsBitGcExtraData->PenArray() || !deferred)
sl@0
   428
		{
sl@0
   429
		while (!line.SingleStep(plotpt))
sl@0
   430
			PenDrawClipped(plotpt);
sl@0
   431
		}
sl@0
   432
	else
sl@0
   433
		{
sl@0
   434
		const TBool down = (aPt2.iY >= aPt1.iY);
sl@0
   435
sl@0
   436
		for (TInt fillcount = 0; fillcount < doubleheight; )
sl@0
   437
			{
sl@0
   438
			deferred[fillcount++] = KMaxTInt;
sl@0
   439
			deferred[fillcount++] = KMinTInt;
sl@0
   440
			}
sl@0
   441
sl@0
   442
		TInt nextline = 0;
sl@0
   443
		TInt nexty = plotpt.iY;
sl@0
   444
		if (down)
sl@0
   445
			nexty -= ((iPenSize.iHeight - 1) >> 1);
sl@0
   446
		else
sl@0
   447
			nexty += (iPenSize.iHeight >> 1);
sl@0
   448
sl@0
   449
		TInt lasty = plotpt.iY;
sl@0
   450
sl@0
   451
		while (!line.SingleStep(plotpt))
sl@0
   452
			{
sl@0
   453
			if (plotpt.iY != lasty)
sl@0
   454
				{
sl@0
   455
				if (nexty >= iClipRect.iTl.iY && nexty < iClipRect.iBr.iY)
sl@0
   456
					{
sl@0
   457
					TInt left = deferred[nextline];
sl@0
   458
					TInt right = deferred[nextline + 1];
sl@0
   459
					if (left < iClipRect.iTl.iX)
sl@0
   460
						left = iClipRect.iTl.iX;
sl@0
   461
					if (right >= iClipRect.iBr.iX)
sl@0
   462
						right = iClipRect.iBr.iX - 1;
sl@0
   463
sl@0
   464
					if (left <= right)
sl@0
   465
						drawDevice->WriteRgbMulti(left,nexty,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
sl@0
   466
					}
sl@0
   467
sl@0
   468
				if (down)
sl@0
   469
					nexty++;
sl@0
   470
				else
sl@0
   471
					nexty--;
sl@0
   472
				lasty = plotpt.iY;
sl@0
   473
				deferred[nextline++] = KMaxTInt;
sl@0
   474
				deferred[nextline++] = KMinTInt;
sl@0
   475
				if (nextline == doubleheight)
sl@0
   476
					nextline = 0;
sl@0
   477
				}
sl@0
   478
sl@0
   479
			PenDrawDeferred(plotpt,deferred,nextline);
sl@0
   480
			}
sl@0
   481
sl@0
   482
		for (TInt restofline = 0; restofline < doubleheight; restofline += 2,nextline += 2)
sl@0
   483
			{
sl@0
   484
			if (nextline == doubleheight)
sl@0
   485
				nextline = 0;
sl@0
   486
sl@0
   487
			if (nexty >= iClipRect.iTl.iY && nexty < iClipRect.iBr.iY)
sl@0
   488
				{
sl@0
   489
				TInt left = deferred[nextline];
sl@0
   490
				TInt right = deferred[nextline+1];
sl@0
   491
				if (left < iClipRect.iTl.iX)
sl@0
   492
					left = iClipRect.iTl.iX;
sl@0
   493
				if (right >= iClipRect.iBr.iX)
sl@0
   494
					right = iClipRect.iBr.iX-1;
sl@0
   495
sl@0
   496
				if (left <= right)
sl@0
   497
					drawDevice->WriteRgbMulti(left,nexty,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN);
sl@0
   498
				}
sl@0
   499
sl@0
   500
			if (down)
sl@0
   501
				nexty++;
sl@0
   502
			else
sl@0
   503
				nexty--;
sl@0
   504
			}
sl@0
   505
sl@0
   506
		delete[] deferred;
sl@0
   507
		}
sl@0
   508
	}
sl@0
   509
sl@0
   510
sl@0
   511
void CFbsBitGc::DoDrawDottedWideLine(const TPoint& aPt1,
sl@0
   512
									 const TPoint& aPt2,
sl@0
   513
									 TBool aDrawStartPoint,
sl@0
   514
									 const TRect& aScreenRect)
sl@0
   515
	{
sl@0
   516
	TLinearDDA line;
sl@0
   517
	line.Construct(aPt1,aPt2);
sl@0
   518
sl@0
   519
	TPoint plotpt(aPt1);
sl@0
   520
	line.JumpToRect(aScreenRect);
sl@0
   521
	if (!aDrawStartPoint)
sl@0
   522
		{
sl@0
   523
		line.SingleStep(plotpt);
sl@0
   524
		iDotParam += iDotDirection;
sl@0
   525
		}
sl@0
   526
sl@0
   527
	const TInt maxdim = Max(iPenSize.iWidth,iPenSize.iHeight);
sl@0
   528
sl@0
   529
	TBool done = EFalse;
sl@0
   530
	while (!done)
sl@0
   531
		{
sl@0
   532
		while (!done && !(iDotMask & (1 << ((iDotParam / maxdim) % iDotLength))))
sl@0
   533
			{
sl@0
   534
			done = line.SingleStep(plotpt);
sl@0
   535
			iDotParam += iDotDirection;
sl@0
   536
			}
sl@0
   537
sl@0
   538
		TPoint startdash(plotpt);
sl@0
   539
		TPoint enddash(plotpt);
sl@0
   540
sl@0
   541
		while (!done && (iDotMask & (1 << ((iDotParam / maxdim) % iDotLength))))
sl@0
   542
			{
sl@0
   543
			enddash = plotpt;
sl@0
   544
			done = line.SingleStep(plotpt);
sl@0
   545
			iDotParam += iDotDirection;
sl@0
   546
			}
sl@0
   547
sl@0
   548
		DoDrawSolidWideLine(startdash,enddash,ETrue,aScreenRect);
sl@0
   549
		}
sl@0
   550
	}
sl@0
   551
sl@0
   552
// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
sl@0
   553
void CFbsBitGc::PolyFill(const CArrayFix<TPoint>* aPointList,TFillRule aFillRule)
sl@0
   554
	{
sl@0
   555
	TBool exists;
sl@0
   556
	TInt scanline;
sl@0
   557
	TInt pixelRunStart;
sl@0
   558
	TInt pixelRunEnd;
sl@0
   559
sl@0
   560
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   561
	for (TInt count = 0; count < limit; count++)
sl@0
   562
		{
sl@0
   563
		iClipRect = (*iDefaultRegionPtr)[count];
sl@0
   564
		AddRect(iClipRect);
sl@0
   565
		if (UserClipRect(iClipRect))
sl@0
   566
			continue;
sl@0
   567
sl@0
   568
		CPolygonFiller polyfill;
sl@0
   569
		polyfill.Construct(aPointList,aFillRule);
sl@0
   570
sl@0
   571
		for(polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd);exists;
sl@0
   572
						polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd))
sl@0
   573
			{
sl@0
   574
			TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline);
sl@0
   575
			start += iOrigin;
sl@0
   576
			end += iOrigin;
sl@0
   577
			ClipFillLine(start,end);
sl@0
   578
			}
sl@0
   579
sl@0
   580
		polyfill.Reset();
sl@0
   581
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   582
		}
sl@0
   583
	}
sl@0
   584
sl@0
   585
// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
sl@0
   586
void CFbsBitGc::PolyFillLarge(const CArrayFix<TPoint>* aPointList,TFillRule aFillRule)
sl@0
   587
	{
sl@0
   588
	TBool exists;
sl@0
   589
	TInt pixelRunStart;
sl@0
   590
	TInt pixelRunEnd;
sl@0
   591
sl@0
   592
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   593
	for (TInt count = 0; count < limit; count++)
sl@0
   594
		{
sl@0
   595
		iClipRect = (*iDefaultRegionPtr)[count];
sl@0
   596
		AddRect(iClipRect);
sl@0
   597
		if (UserClipRect(iClipRect))
sl@0
   598
			continue;
sl@0
   599
sl@0
   600
		CPolygonFiller polyfill;
sl@0
   601
		polyfill.Construct(aPointList,aFillRule,CPolygonFiller::EGetPixelRunsSequentiallyForSpecifiedScanLines);
sl@0
   602
		TInt clipRectOffsetStart = iClipRect.iTl.iY - iOrigin.iY;
sl@0
   603
		TInt clipRectOffsetEnd = iClipRect.iBr.iY - iOrigin.iY;
sl@0
   604
sl@0
   605
		for (TInt scanline = clipRectOffsetStart; scanline < clipRectOffsetEnd; scanline++)
sl@0
   606
			{
sl@0
   607
			polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd);
sl@0
   608
			while (exists)
sl@0
   609
				{
sl@0
   610
				TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline);
sl@0
   611
				start += iOrigin;
sl@0
   612
				end += iOrigin;
sl@0
   613
				ClipFillLine(start,end);
sl@0
   614
				polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd);
sl@0
   615
				}
sl@0
   616
			}
sl@0
   617
sl@0
   618
		polyfill.Reset();
sl@0
   619
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   620
		}
sl@0
   621
	}
sl@0
   622
sl@0
   623
void CFbsBitGc::PolyOutline(const CArrayFix<TPoint>* aPointList)
sl@0
   624
	{
sl@0
   625
	const TInt vertexes = aPointList->Count();
sl@0
   626
sl@0
   627
	for (TInt count = 0; count < vertexes; count++)
sl@0
   628
		{
sl@0
   629
		TPoint point1((*aPointList)[count]);
sl@0
   630
		TPoint point2((*aPointList)[(count + 1) % vertexes]);
sl@0
   631
sl@0
   632
		if (point1.iY < point2.iY)
sl@0
   633
			DoDrawLine(point1,point2,ETrue);
sl@0
   634
		else
sl@0
   635
			{
sl@0
   636
			iDotDirection = -1;
sl@0
   637
			iDotParam += Max(Abs(point2.iX - point1.iX),Abs(point2.iY - point1.iY));
sl@0
   638
			const TInt dotParam = iDotParam;
sl@0
   639
			DoDrawLine(point2,point1,EFalse);
sl@0
   640
sl@0
   641
			if (Abs(point2.iX - point1.iX) > Abs(point2.iY - point1.iY))
sl@0
   642
				{
sl@0
   643
				if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iWidth) % iDotLength))))
sl@0
   644
					DoPlot((*aPointList)[count]);
sl@0
   645
				}
sl@0
   646
			else
sl@0
   647
				{
sl@0
   648
				if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iHeight) % iDotLength))))
sl@0
   649
					DoPlot((*aPointList)[count]);
sl@0
   650
				}
sl@0
   651
sl@0
   652
			iDotDirection = 1;
sl@0
   653
			iDotParam = dotParam;
sl@0
   654
			}
sl@0
   655
		}
sl@0
   656
	}
sl@0
   657
sl@0
   658
// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
sl@0
   659
void CFbsBitGc::PolyFill(const TPoint* aPointList,TInt aNumPoints,TFillRule aFillRule)
sl@0
   660
	{
sl@0
   661
	TBool exists;
sl@0
   662
	TInt scanline;
sl@0
   663
	TInt pixelRunStart;
sl@0
   664
	TInt pixelRunEnd;
sl@0
   665
sl@0
   666
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   667
	for (TInt count = 0; count < limit; count++)
sl@0
   668
		{
sl@0
   669
		iClipRect = (*iDefaultRegionPtr)[count];
sl@0
   670
		AddRect(iClipRect);
sl@0
   671
		if (UserClipRect(iClipRect))
sl@0
   672
			continue;
sl@0
   673
sl@0
   674
		CPolygonFiller polyfill;
sl@0
   675
		polyfill.Construct(aPointList,aNumPoints,aFillRule);
sl@0
   676
sl@0
   677
		for (polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd);exists;
sl@0
   678
						polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd))
sl@0
   679
			{
sl@0
   680
			TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline);
sl@0
   681
			start += iOrigin;
sl@0
   682
			end += iOrigin;
sl@0
   683
			ClipFillLine(start,end);
sl@0
   684
			}
sl@0
   685
sl@0
   686
		polyfill.Reset();
sl@0
   687
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   688
		}
sl@0
   689
	}
sl@0
   690
sl@0
   691
// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method
sl@0
   692
void CFbsBitGc::PolyFillLarge(const TPoint* aPointList,TInt aNumPoints,TFillRule aFillRule)
sl@0
   693
	{
sl@0
   694
	TBool exists;
sl@0
   695
	TInt pixelRunStart;
sl@0
   696
	TInt pixelRunEnd;
sl@0
   697
sl@0
   698
	const TInt limit = iDefaultRegionPtr->Count();
sl@0
   699
	for (TInt count = 0; count < limit; count++)
sl@0
   700
		{
sl@0
   701
		iClipRect = (*iDefaultRegionPtr)[count];
sl@0
   702
		AddRect(iClipRect);
sl@0
   703
		if (UserClipRect(iClipRect))
sl@0
   704
			continue;
sl@0
   705
sl@0
   706
		CPolygonFiller polyfill;
sl@0
   707
		polyfill.Construct(aPointList,aNumPoints,aFillRule,CPolygonFiller::EGetPixelRunsSequentiallyForSpecifiedScanLines);
sl@0
   708
		TInt clipRectOffsetStart = iClipRect.iTl.iY - iOrigin.iY;
sl@0
   709
		TInt clipRectOffsetEnd = iClipRect.iBr.iY - iOrigin.iY;
sl@0
   710
sl@0
   711
		for (TInt scanline = clipRectOffsetStart; scanline < clipRectOffsetEnd; scanline++)
sl@0
   712
			{
sl@0
   713
			polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd);
sl@0
   714
			while (exists)
sl@0
   715
				{
sl@0
   716
				TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline);
sl@0
   717
				start += iOrigin;
sl@0
   718
				end += iOrigin;
sl@0
   719
				ClipFillLine(start,end);
sl@0
   720
sl@0
   721
				polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd);
sl@0
   722
				}
sl@0
   723
			}
sl@0
   724
sl@0
   725
		polyfill.Reset();
sl@0
   726
		iDevice->iDrawDevice->UpdateRegion(iClipRect);
sl@0
   727
		}
sl@0
   728
	}
sl@0
   729
sl@0
   730
void CFbsBitGc::PolyOutline(const TPoint* aPointList,TInt aNumPoints)
sl@0
   731
	{
sl@0
   732
	for (TInt count = 0; count < aNumPoints; count++)
sl@0
   733
		{
sl@0
   734
		TPoint point1(aPointList[count]);
sl@0
   735
		TPoint point2(aPointList[(count + 1) % aNumPoints]);
sl@0
   736
sl@0
   737
		if (point1.iY < point2.iY)
sl@0
   738
			DoDrawLine(point1,point2,ETrue);
sl@0
   739
		else
sl@0
   740
			{
sl@0
   741
			iDotDirection = -1;
sl@0
   742
			iDotParam += Max(Abs(point2.iX - point1.iX),Abs(point2.iY - point1.iY));
sl@0
   743
			const TInt dotParam = iDotParam;
sl@0
   744
sl@0
   745
			DoDrawLine(point2,point1,EFalse);
sl@0
   746
sl@0
   747
			if (Abs(point2.iX - point1.iX) > Abs(point2.iY - point1.iY))
sl@0
   748
				{
sl@0
   749
				if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iWidth) % iDotLength))))
sl@0
   750
					DoPlot(aPointList[count]);
sl@0
   751
				}
sl@0
   752
			else
sl@0
   753
				{
sl@0
   754
				if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iHeight) % iDotLength))))
sl@0
   755
					DoPlot(aPointList[count]);
sl@0
   756
				}
sl@0
   757
sl@0
   758
			iDotDirection = 1;
sl@0
   759
			iDotParam = dotParam;
sl@0
   760
			}
sl@0
   761
		}
sl@0
   762
	}
sl@0
   763