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