diff -r 000000000000 -r 5d03bc08d59c graphicsdeviceinterface/bitgdi/sbit/LINE.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsdeviceinterface/bitgdi/sbit/LINE.CPP Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,763 @@ +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include "BITPANIC.H" +#include +#include +#include "bitgcextradata.h" + + +/** Draws a straight line between two points. + +The function provides a concrete implementation of the pure virtual +function CGraphicsContext::DrawLine(). The function +behaviour is the same as documented in that class. */ +EXPORT_C void CFbsBitGc::DrawLine(const TPoint& aPt1,const TPoint& aPt2) + { + CheckDevice(); + + TRect lineBoundingRect(aPt1,aPt2); + lineBoundingRect.Normalize(); + lineBoundingRect.Move(iOrigin); + lineBoundingRect.Grow((iPenSize.iWidth >> 1) + 1,(iPenSize.iHeight >> 1) + 1); + if(!lineBoundingRect.Intersects(iUserClipRect)) + { + iLinePosition = aPt2;// if DrawLine returns due to aPt2 being outside of the clipping rect then subsequent line are drawn from correct point. + return; + } + + SetupDevice(); + iDevice->DrawingBegin(); + DoDrawLine(aPt1,aPt2,ETrue); + iDevice->DrawingEnd(); + } + +/** Draws a straight line from the current drawing point to a specified +point. + +The function provides a concrete implementation of the pure virtual +function CGraphicsContext::DrawLineTo(). The function +behaviour is the same as documented in that class. */ +EXPORT_C void CFbsBitGc::DrawLineTo(const TPoint& aPoint) + { + DrawLine(iLinePosition,aPoint); + } + + +/** Draws a straight line relative to the current drawing point, using a +vector. + +The function provides a concrete implementation of the pure virtual +function CGraphicsContext::DrawLineBy(). The function +behaviour is the same as documented in that class. */ +EXPORT_C void CFbsBitGc::DrawLineBy(const TPoint& aVector) + { + DrawLine(iLinePosition,iLinePosition + aVector); + } + +/** Draws a polyline from a set of points specified in a list. + +The functions provides a concrete implementation of the pure virtual +functions CGraphicsContext::DrawPolyLine(). The function +behaviour is the same as documented in that class. */ +EXPORT_C void CFbsBitGc::DrawPolyLine(const CArrayFix* aPointList) + { + if(!aPointList || iPenSize.iWidth < 1 || iPenSize.iHeight < 1) + return; + + const TInt vertexes = aPointList->Count()-1; + + for (TInt count = 0; count < vertexes; count++) + DrawLine((*aPointList)[count],(*aPointList)[count + 1]); + + if (iPenStyle == CGraphicsContext::ESolidPen && vertexes >= 0) + Plot((*aPointList)[vertexes]); + } + +/** Draws a polyline from a set of points specified in an array, but does not draw +the final point of the last line. + +@param aPointList An array containing the points on the polyline. */ +EXPORT_C void CFbsBitGc::DrawPolyLineNoEndPoint(const CArrayFix* aPointList) + { + if(!aPointList || iPenSize.iWidth < 1 || iPenSize.iHeight < 1) + return; + + const TInt vertexes = aPointList->Count() - 1; + + for (TInt count = 0; count < vertexes; count++) + DrawLine((*aPointList)[count],(*aPointList)[count + 1]); + } + +/** Draws a polyline from a set of points specified in a list. + +The functions provides a concrete implementation of the pure virtual +functions CGraphicsContext::DrawPolyLine(). The function +behaviour is the same as documented in that class. */ +EXPORT_C void CFbsBitGc::DrawPolyLine(const TPoint* aPointList,TInt aNumPoints) + { + DrawPolyLineNoEndPoint(aPointList,aNumPoints); + + if (iPenStyle == CGraphicsContext::ESolidPen) + Plot(aPointList[aNumPoints - 1]); + } + +/** Draws a polyline from a set of points specified in a list, but does not +draw the final point of the last line. + +@param aPointList Pointer to a set of points on the polyline. +@param aNumPoints Number of points in the list. */ +EXPORT_C void CFbsBitGc::DrawPolyLineNoEndPoint(const TPoint* aPointList,TInt aNumPoints) + { + if (!aPointList || iPenSize.iWidth < 1 || iPenSize.iHeight < 1) + return; + + const TInt vertexes = aNumPoints - 1; + + for (TInt count = 0; count < vertexes; count++) + DrawLine(aPointList[count],aPointList[count + 1]); + } + +/** Draws and fills a polygon defined using a list of points. + +The function provides a concrete implementation of the pure virtual +function CGraphicsContext::DrawPolygon(). The function +behaviour is the same as documented in that class. */ +EXPORT_C TInt CFbsBitGc::DrawPolygon(const CArrayFix* aPointList,TFillRule aFillRule) + { + CheckDevice(); + + if (!aPointList) + return KErrArgument; + + const TInt numpoints = aPointList->Count(); + + if (numpoints == 0) + return KErrNone; // Nothing to do! + + SetupDevice(); + iDevice->DrawingBegin(&iBrushBitmap); + CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap); + + if (iBrushStyle != ENullBrush) + { + TRect pointrect(0,0,0,0); + TRect truncrect(0,0,0,0); + TBool largepolygon = EFalse; + + for (TInt count = 0; count < numpoints; count++) + { + pointrect.iTl = (*aPointList)[count] + iOrigin; + truncrect.iTl = pointrect.iTl; + iDevice->TruncateRect(truncrect); + + if (pointrect.iTl != truncrect.iTl) + { + largepolygon = ETrue; + break; + } + } + + if (largepolygon) + PolyFillLarge(aPointList,aFillRule); + else + PolyFill(aPointList,aFillRule); + } + + if (iPenStyle != ENullPen) + if (iPenSize.iWidth > 0 && iPenSize.iHeight > 0) + PolyOutline(aPointList); + + if (brushRasterizer) + { + brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber()); + } + iDevice->DrawingEnd(&iBrushBitmap); + + return KErrNone; + } + + +/** Draws and fills a polygon defined using a list of points. + +The function provides a concrete implementation of the pure virtual +function CGraphicsContext::DrawPolygon(). The function +behaviour is the same as documented in that class. */ +EXPORT_C TInt CFbsBitGc::DrawPolygon(const TPoint* aPointList, + TInt aNumPoints, + CGraphicsContext::TFillRule aFillRule) + { + CheckDevice(); + + if (!aPointList || aNumPoints < 0) + return KErrArgument; + + if (aNumPoints == 0) + return KErrNone; // Nothing to do! + + SetupDevice(); + iDevice->DrawingBegin(&iBrushBitmap); + CFbsRasterizer* brushRasterizer = PrepareRasterizerForExtendedBitmap(iBrushBitmap); + + if (iBrushStyle != ENullBrush) + { + TRect pointrect(0,0,0,0); + TRect truncrect(0,0,0,0); + TBool largepolygon = EFalse; + + for (TInt count = 0; count < aNumPoints; count++) + { + pointrect.iTl = aPointList[count] + iOrigin; + truncrect.iTl = pointrect.iTl; + iDevice->TruncateRect(truncrect); + + if (pointrect.iTl != truncrect.iTl) + { + largepolygon = ETrue; + break; + } + } + + if (largepolygon) + PolyFillLarge(aPointList,aNumPoints,aFillRule); + else + PolyFill(aPointList,aNumPoints,aFillRule); + } + + if (iPenStyle != ENullPen && iPenSize.iWidth > 0 && iPenSize.iHeight > 0) + PolyOutline(aPointList,aNumPoints); + + if (brushRasterizer) + { + brushRasterizer->EndBitmap(iBrushBitmap.SerialNumber()); + } + iDevice->DrawingEnd(&iBrushBitmap); + + return KErrNone; + } + +void CFbsBitGc::DoDrawLine(TPoint aPt1,TPoint aPt2,TBool aDrawStartPoint) + { + iLinePosition = aPt2; + + if (aPt1 == aPt2 || iPenStyle == ENullPen || !iPenSize.iWidth || !iPenSize.iHeight) + return; + + aPt1 += iOrigin; + aPt2 += iOrigin; + + TRect temp(aPt1,aPt2); + temp.Normalize(); + temp.Grow(iPenSize.iWidth,iPenSize.iHeight); + AddRect(temp); + if (UserClipRect(temp)) + return; + + CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; + + TRect screenRect; + drawDevice->GetDrawRect(screenRect); + screenRect.Grow(iPenSize.iWidth,iPenSize.iHeight); + + const TInt dotParam = iDotParam; + TPoint plotpt(0,0); + + for (TInt count = 0; count < iDefaultRegionPtr->Count(); count++) + { + iDotParam = dotParam; + iClipRect = (*iDefaultRegionPtr)[count]; + + if (!iClipRect.Intersects(temp)) + { + TLinearDDA line; + line.Construct(aPt1,aPt2); + line.JumpToRect(screenRect); + if (iPenStyle != ESolidPen) + while (!line.SingleStep(plotpt)) + iDotParam += iDotDirection; + continue; + } + + iClipRect.Intersection(temp); + + if ((iPenSize.iWidth > 1 || iPenSize.iHeight > 1) && iPenStyle == ESolidPen) // wide solid line + DoDrawSolidWideLine(aPt1,aPt2,aDrawStartPoint,screenRect); + else if (iPenSize.iWidth > 1 || iPenSize.iHeight > 1) // dotted line + DoDrawDottedWideLine(aPt1,aPt2,aDrawStartPoint,screenRect); + else if (iPenStyle != ESolidPen) // single pixel dotted line + { + TLinearDDA line; + line.Construct(aPt1,aPt2); + line.JumpToRect(screenRect); + + iDotParam = dotParam; + if (!aDrawStartPoint) + { + line.SingleStep(plotpt); + iDotParam += iDotDirection; + } + + while (!line.SingleStep(plotpt)) + { + PenDrawClipped(plotpt); + iDotParam += iDotDirection; + } + } + else if (aPt1.iY == aPt2.iY && + (aPt1.iY >= iClipRect.iTl.iY && aPt1.iY < iClipRect.iBr.iY)) + { // single pixel solid horizontal line + TInt start = Min(aPt1.iX,aPt2.iX + 1); + TInt length = Abs(aPt2.iX - aPt1.iX); + + if (!aDrawStartPoint) + if (aPt1.iX < aPt2.iX) + start++; + else + length--; + if (start < iClipRect.iTl.iX) + { + length += start - iClipRect.iTl.iX; + start = iClipRect.iTl.iX; + } + if (start + length > iClipRect.iBr.iX) + length = iClipRect.iBr.iX - start; + + if (length > 0) + { + BG_ASSERT_DEBUG(start >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(aPt1.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(start + length <= iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(aPt1.iY < iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds); + + drawDevice->WriteRgbMulti(start,aPt1.iY,length,1,iPenColor,iDrawMode); + } + } + else if (aPt1.iX == aPt2.iX && (aPt1.iX >= iClipRect.iTl.iX && aPt1.iX < iClipRect.iBr.iX)) + { // single pixel solid vertical line + TInt start = Min(aPt1.iY,aPt2.iY + 1); + TInt length = Abs(aPt2.iY - aPt1.iY); + + if (!aDrawStartPoint) + if (aPt1.iY < aPt2.iY) + start++; + else + length--; + + if (start < iClipRect.iTl.iY) + { + length += start - iClipRect.iTl.iY; + start = iClipRect.iTl.iY; + } + if (start + length > iClipRect.iBr.iY) + length = iClipRect.iBr.iY - start; + + if (length > 0) + { + BG_ASSERT_DEBUG(aPt1.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(start >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(aPt1.iX < iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(start + length <= iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds); + + drawDevice->WriteRgbMulti(aPt1.iX,start,1,length,iPenColor,iDrawMode); + } + } + else + { // single pixel solid diagonal line + TLinearDDA line; + line.Construct(aPt1,aPt2); + + line.JumpToRect(screenRect); + + if (!aDrawStartPoint) + line.SingleStep(plotpt); + + while (!line.SingleStep(plotpt)) + { + if (iClipRect.Contains(plotpt)) + { + BG_ASSERT_DEBUG(plotpt.iX >= iUserClipRect.iTl.iX,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(plotpt.iY >= iUserClipRect.iTl.iY,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(plotpt.iX < iUserClipRect.iBr.iX,EBitgdiPanicOutOfBounds); + BG_ASSERT_DEBUG(plotpt.iY < iUserClipRect.iBr.iY,EBitgdiPanicOutOfBounds); + + drawDevice->WriteRgb(plotpt.iX,plotpt.iY,iPenColor,iDrawMode); + } + } + } + + drawDevice->UpdateRegion(iClipRect); + } + } + +void CFbsBitGc::DoDrawSolidWideLine(const TPoint& aPt1, + const TPoint& aPt2, + TBool aDrawStartPoint, + const TRect& aScreenRect) + { + CFbsDrawDevice* drawDevice = iDevice->iDrawDevice; + + TLinearDDA line; + line.Construct(aPt1,aPt2); + + TPoint plotpt(aPt1); + line.JumpToRect(aScreenRect); + if (!aScreenRect.Contains(plotpt) || !aDrawStartPoint) + line.SingleStep(plotpt); + + TInt* deferred = NULL; + const TInt doubleheight = iPenSize.iHeight << 1; + + if (iFbsBitGcExtraData->PenArray()) + deferred = new TInt[doubleheight]; + + if (!iFbsBitGcExtraData->PenArray() || !deferred) + { + while (!line.SingleStep(plotpt)) + PenDrawClipped(plotpt); + } + else + { + const TBool down = (aPt2.iY >= aPt1.iY); + + for (TInt fillcount = 0; fillcount < doubleheight; ) + { + deferred[fillcount++] = KMaxTInt; + deferred[fillcount++] = KMinTInt; + } + + TInt nextline = 0; + TInt nexty = plotpt.iY; + if (down) + nexty -= ((iPenSize.iHeight - 1) >> 1); + else + nexty += (iPenSize.iHeight >> 1); + + TInt lasty = plotpt.iY; + + while (!line.SingleStep(plotpt)) + { + if (plotpt.iY != lasty) + { + if (nexty >= iClipRect.iTl.iY && nexty < iClipRect.iBr.iY) + { + TInt left = deferred[nextline]; + TInt right = deferred[nextline + 1]; + if (left < iClipRect.iTl.iX) + left = iClipRect.iTl.iX; + if (right >= iClipRect.iBr.iX) + right = iClipRect.iBr.iX - 1; + + if (left <= right) + drawDevice->WriteRgbMulti(left,nexty,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN); + } + + if (down) + nexty++; + else + nexty--; + lasty = plotpt.iY; + deferred[nextline++] = KMaxTInt; + deferred[nextline++] = KMinTInt; + if (nextline == doubleheight) + nextline = 0; + } + + PenDrawDeferred(plotpt,deferred,nextline); + } + + for (TInt restofline = 0; restofline < doubleheight; restofline += 2,nextline += 2) + { + if (nextline == doubleheight) + nextline = 0; + + if (nexty >= iClipRect.iTl.iY && nexty < iClipRect.iBr.iY) + { + TInt left = deferred[nextline]; + TInt right = deferred[nextline+1]; + if (left < iClipRect.iTl.iX) + left = iClipRect.iTl.iX; + if (right >= iClipRect.iBr.iX) + right = iClipRect.iBr.iX-1; + + if (left <= right) + drawDevice->WriteRgbMulti(left,nexty,right - left + 1,1,iPenColor,CGraphicsContext::EDrawModePEN); + } + + if (down) + nexty++; + else + nexty--; + } + + delete[] deferred; + } + } + + +void CFbsBitGc::DoDrawDottedWideLine(const TPoint& aPt1, + const TPoint& aPt2, + TBool aDrawStartPoint, + const TRect& aScreenRect) + { + TLinearDDA line; + line.Construct(aPt1,aPt2); + + TPoint plotpt(aPt1); + line.JumpToRect(aScreenRect); + if (!aDrawStartPoint) + { + line.SingleStep(plotpt); + iDotParam += iDotDirection; + } + + const TInt maxdim = Max(iPenSize.iWidth,iPenSize.iHeight); + + TBool done = EFalse; + while (!done) + { + while (!done && !(iDotMask & (1 << ((iDotParam / maxdim) % iDotLength)))) + { + done = line.SingleStep(plotpt); + iDotParam += iDotDirection; + } + + TPoint startdash(plotpt); + TPoint enddash(plotpt); + + while (!done && (iDotMask & (1 << ((iDotParam / maxdim) % iDotLength)))) + { + enddash = plotpt; + done = line.SingleStep(plotpt); + iDotParam += iDotDirection; + } + + DoDrawSolidWideLine(startdash,enddash,ETrue,aScreenRect); + } + } + +// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method +void CFbsBitGc::PolyFill(const CArrayFix* aPointList,TFillRule aFillRule) + { + TBool exists; + TInt scanline; + TInt pixelRunStart; + TInt pixelRunEnd; + + const TInt limit = iDefaultRegionPtr->Count(); + for (TInt count = 0; count < limit; count++) + { + iClipRect = (*iDefaultRegionPtr)[count]; + AddRect(iClipRect); + if (UserClipRect(iClipRect)) + continue; + + CPolygonFiller polyfill; + polyfill.Construct(aPointList,aFillRule); + + for(polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd);exists; + polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd)) + { + TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline); + start += iOrigin; + end += iOrigin; + ClipFillLine(start,end); + } + + polyfill.Reset(); + iDevice->iDrawDevice->UpdateRegion(iClipRect); + } + } + +// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method +void CFbsBitGc::PolyFillLarge(const CArrayFix* aPointList,TFillRule aFillRule) + { + TBool exists; + TInt pixelRunStart; + TInt pixelRunEnd; + + const TInt limit = iDefaultRegionPtr->Count(); + for (TInt count = 0; count < limit; count++) + { + iClipRect = (*iDefaultRegionPtr)[count]; + AddRect(iClipRect); + if (UserClipRect(iClipRect)) + continue; + + CPolygonFiller polyfill; + polyfill.Construct(aPointList,aFillRule,CPolygonFiller::EGetPixelRunsSequentiallyForSpecifiedScanLines); + TInt clipRectOffsetStart = iClipRect.iTl.iY - iOrigin.iY; + TInt clipRectOffsetEnd = iClipRect.iBr.iY - iOrigin.iY; + + for (TInt scanline = clipRectOffsetStart; scanline < clipRectOffsetEnd; scanline++) + { + polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd); + while (exists) + { + TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline); + start += iOrigin; + end += iOrigin; + ClipFillLine(start,end); + polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd); + } + } + + polyfill.Reset(); + iDevice->iDrawDevice->UpdateRegion(iClipRect); + } + } + +void CFbsBitGc::PolyOutline(const CArrayFix* aPointList) + { + const TInt vertexes = aPointList->Count(); + + for (TInt count = 0; count < vertexes; count++) + { + TPoint point1((*aPointList)[count]); + TPoint point2((*aPointList)[(count + 1) % vertexes]); + + if (point1.iY < point2.iY) + DoDrawLine(point1,point2,ETrue); + else + { + iDotDirection = -1; + iDotParam += Max(Abs(point2.iX - point1.iX),Abs(point2.iY - point1.iY)); + const TInt dotParam = iDotParam; + DoDrawLine(point2,point1,EFalse); + + if (Abs(point2.iX - point1.iX) > Abs(point2.iY - point1.iY)) + { + if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iWidth) % iDotLength)))) + DoPlot((*aPointList)[count]); + } + else + { + if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iHeight) % iDotLength)))) + DoPlot((*aPointList)[count]); + } + + iDotDirection = 1; + iDotParam = dotParam; + } + } + } + +// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method +void CFbsBitGc::PolyFill(const TPoint* aPointList,TInt aNumPoints,TFillRule aFillRule) + { + TBool exists; + TInt scanline; + TInt pixelRunStart; + TInt pixelRunEnd; + + const TInt limit = iDefaultRegionPtr->Count(); + for (TInt count = 0; count < limit; count++) + { + iClipRect = (*iDefaultRegionPtr)[count]; + AddRect(iClipRect); + if (UserClipRect(iClipRect)) + continue; + + CPolygonFiller polyfill; + polyfill.Construct(aPointList,aNumPoints,aFillRule); + + for (polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd);exists; + polyfill.GetNextPixelRun(exists,scanline,pixelRunStart,pixelRunEnd)) + { + TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline); + start += iOrigin; + end += iOrigin; + ClipFillLine(start,end); + } + + polyfill.Reset(); + iDevice->iDrawDevice->UpdateRegion(iClipRect); + } + } + +// if iBrushBitmap is an extended bitmap, PrepareRasterizerForExtendedBitmap() must have been called before this method +void CFbsBitGc::PolyFillLarge(const TPoint* aPointList,TInt aNumPoints,TFillRule aFillRule) + { + TBool exists; + TInt pixelRunStart; + TInt pixelRunEnd; + + const TInt limit = iDefaultRegionPtr->Count(); + for (TInt count = 0; count < limit; count++) + { + iClipRect = (*iDefaultRegionPtr)[count]; + AddRect(iClipRect); + if (UserClipRect(iClipRect)) + continue; + + CPolygonFiller polyfill; + polyfill.Construct(aPointList,aNumPoints,aFillRule,CPolygonFiller::EGetPixelRunsSequentiallyForSpecifiedScanLines); + TInt clipRectOffsetStart = iClipRect.iTl.iY - iOrigin.iY; + TInt clipRectOffsetEnd = iClipRect.iBr.iY - iOrigin.iY; + + for (TInt scanline = clipRectOffsetStart; scanline < clipRectOffsetEnd; scanline++) + { + polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd); + while (exists) + { + TPoint start(pixelRunStart,scanline),end(pixelRunEnd,scanline); + start += iOrigin; + end += iOrigin; + ClipFillLine(start,end); + + polyfill.GetNextPixelRunOnSpecifiedScanLine(exists,scanline,pixelRunStart,pixelRunEnd); + } + } + + polyfill.Reset(); + iDevice->iDrawDevice->UpdateRegion(iClipRect); + } + } + +void CFbsBitGc::PolyOutline(const TPoint* aPointList,TInt aNumPoints) + { + for (TInt count = 0; count < aNumPoints; count++) + { + TPoint point1(aPointList[count]); + TPoint point2(aPointList[(count + 1) % aNumPoints]); + + if (point1.iY < point2.iY) + DoDrawLine(point1,point2,ETrue); + else + { + iDotDirection = -1; + iDotParam += Max(Abs(point2.iX - point1.iX),Abs(point2.iY - point1.iY)); + const TInt dotParam = iDotParam; + + DoDrawLine(point2,point1,EFalse); + + if (Abs(point2.iX - point1.iX) > Abs(point2.iY - point1.iY)) + { + if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iWidth) % iDotLength)))) + DoPlot(aPointList[count]); + } + else + { + if (iPenStyle == CGraphicsContext::ESolidPen || (iDotMask & (1 << ((iDotParam / iPenSize.iHeight) % iDotLength)))) + DoPlot(aPointList[count]); + } + + iDotDirection = 1; + iDotParam = dotParam; + } + } + } +