diff -r 000000000000 -r d46562c3d99d svgtopt/gfx2d/src/GfxRenderer/GfxEdgeListP.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svgtopt/gfx2d/src/GfxRenderer/GfxEdgeListP.cpp Thu Jan 07 16:19:02 2010 +0200 @@ -0,0 +1,848 @@ +/* +* Copyright (c) 2002 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: Graphics Extension Library source file +* +*/ + + +#include "GfxRendererInfoP.h" + +#define EInitialised 0 +#define ECurrent 1 +#define EComplete 2 + + +// --------------------------------------------------------------------------- +// Create a new instance and push it onto the cleanup stack. +// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- +// CGfxEdgeListP* CGfxEdgeListP::NewLC( TGfxRendererInfoP* aRenderInfo ) +// --------------------------------------------------------------------------- +CGfxEdgeListP* CGfxEdgeListP::NewLC( TGfxRendererInfoP* aRenderInfo ) + { + CGfxEdgeListP* self = new ( ELeave ) CGfxEdgeListP( aRenderInfo ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// Create a new instance. +// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- +// CGfxEdgeListP* CGfxEdgeListP::NewL( TGfxRendererInfoP* aRenderInfo ) +// --------------------------------------------------------------------------- +CGfxEdgeListP* CGfxEdgeListP::NewL( TGfxRendererInfoP* aRenderInfo ) + { + CGfxEdgeListP* self = NewLC( aRenderInfo ); + CleanupStack::Pop(); + return self; + } + +// --------------------------------------------------------------------------- +// Destructor. +// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- +// CGfxEdgeListP::~CGfxEdgeListP() +// --------------------------------------------------------------------------- +CGfxEdgeListP::~CGfxEdgeListP() + { + delete[] iPoints; + iPoints = NULL; + delete[] iSegset; + iSegset = NULL; + delete[] iEdges; + iEdges = NULL; + } + +// --------------------------------------------------------------------------- +// Constructor +// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- +// CGfxEdgeListP::CGfxEdgeListP( TGfxRendererInfoP* aRenderInfo ) : iWaitingSegList( NULL ), +// --------------------------------------------------------------------------- +CGfxEdgeListP::CGfxEdgeListP( TGfxRendererInfoP* aRenderInfo ) : iWaitingSegList( NULL ), + iActiveSegList( NULL ), + iPointsCount( 0 ), + iSegsetCount( 0 ), + iPointsCountMax( 20 ), + iSegsetCountMax( 10 ), + iEdgesCountMax( 10 ) + { + // From CGfxEdgeListP + iRenderInfo = aRenderInfo; + iMinX = KMAXFLOATFIX; + iMinY = KMAXFLOATFIX; + iMaxX = KMINFLOATFIX; + iMaxY = KMINFLOATFIX; + iEdgesCount = 0; + iLastSegLenSq = 0xffffffff; + } + +// --------------------------------------------------------------------------- +// Second phase in constructing this object. +// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::ConstructL() +// --------------------------------------------------------------------------- +void CGfxEdgeListP::ConstructL() + { + iPoints = new ( ELeave ) TPoint16[iPointsCountMax]; + iSegset = new ( ELeave ) TSegSet[iSegsetCountMax]; + iEdges = new ( ELeave ) TGfxSegEdge[iEdgesCountMax]; + } + + +// --------------------------------------------------------------------------- +// reset +// --------------------------------------------------------------------------- +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::Reset() +// --------------------------------------------------------------------------- +void CGfxEdgeListP::Reset() + { + // From CGfxEdgeListP + iEdgesCount = 0; + iLastSegLenSq = 0xffffffff; + iPolygonAreaSize = 0; + iMinX = KMAXFLOATFIX; + iMinY = KMAXFLOATFIX; + iMaxX = KMINFLOATFIX; + iMaxY = KMINFLOATFIX; + + iPointsCount = 0; + iSegsetCount = 0; + + iActiveSegList = 0; + iWaitingSegList = 0; + iSortedEdges = 0; + + iStartSeg = iSegset; + iIsNewOutlineStarted = EFalse; + iSubPathSegmentCount = 0; + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::AdjustShapeComplexityL( TInt32 aVertexSize ) +// --------------------------------------------------------------------------- +void CGfxEdgeListP::AdjustShapeComplexityL( TInt32 aVertexSize ) + { + if ( aVertexSize < iPointsCountMax ) + return; + // + delete[] iPoints; + delete[] iSegset; + delete[] iEdges; + iPoints = NULL; + iSegset = NULL; + iEdges = NULL; + iPointsCountMax = aVertexSize + 4; + iSegsetCountMax = aVertexSize; + iEdgesCountMax = aVertexSize; + iPoints = new ( ELeave ) TPoint16[iPointsCountMax]; + iSegset = new ( ELeave ) TSegSet[iSegsetCountMax]; + iEdges = new ( ELeave ) TGfxSegEdge[iEdgesCountMax]; + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::StartPoint( TFixPt& aX, TFixPt& aY ) +// --------------------------------------------------------------------------- +void CGfxEdgeListP::StartPoint( TFixPt& aX, TFixPt& aY ) + { + if ( iPointsCount >= iPointsCountMax - 1 ) // No more segments? + return; + + // New segment set. Add one point and set flag + TPoint16& p1 = iPoints[iPointsCount++]; + p1.iX = ( TInt16 ) ( TInt ) aX; + p1.iY = ( TInt16 ) ( TInt ) aY; + + // Min/Max update + if ( p1.iY < iMinY ) + iMinY = p1.iY; + else if ( p1.iY > iMaxY ) + iMaxY = p1.iY; + if ( p1.iX < iMinX ) + iMinX = p1.iX; + else if ( p1.iX > iMaxX ) + iMaxX = p1.iX; + + iIsNewOutlineStarted = ETrue; + iSubPathSegmentCount = 0; + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::AddPoint( TFixPt& aX, TFixPt& aY, TBool aFillOnly, TBool aClosePath ) +// --------------------------------------------------------------------------- +void CGfxEdgeListP::AddPoint( TFixPt& aX, TFixPt& aY, TBool aFillOnly, TBool aClosePath ) + { + if ( iPointsCount >= iPointsCountMax - 1 ) // No more segments? + return; + + TBool newSegsetFlag = EFalse; + TBool completeSubPathFlag = EFalse; + + if ( iIsNewOutlineStarted ) + { + CheckAndConnect(); + newSegsetFlag = ETrue; + } + else if ( aClosePath && ( iSubPathSegmentCount == 1 ) ) + { + completeSubPathFlag = ETrue; + newSegsetFlag = ETrue; + } + else + { + TInt x = ( TInt ) aX, y = ( TInt ) aY; + switch ( iSegset[iSegsetCount - 1].AddSegment( x, + y, + iLastSegLenSq, + aClosePath ) ) + { + case ESegAdd: + // Add point + iPointsCount++; + break; + case ESegMerge: + // Do nothing + break; + case ESegStartNew: + newSegsetFlag = ETrue; + break; + default: + return;// ESegIgnore - do nothing + } + } + + if ( newSegsetFlag && iSegsetCount < iSegsetCountMax ) + { + // New segment set. Add two points + TPoint16* p =& iPoints[iPointsCount++]; + p->iX = ( TInt16 ) ( TInt ) aX; + p->iY = ( TInt16 ) ( TInt ) aY; + + iSubPathSegmentCount++; + TSegSet& seg = iSegset[iSegsetCount++]; + seg.Construct( p - 1, p ); + + if ( iSegsetCount > 1 ) + iSegset[iSegsetCount - 2].iNext = &seg; + + if ( iIsNewOutlineStarted ) + iStartSeg = &seg; + + if ( completeSubPathFlag ) // (cdm) + { + iSegset[iSegsetCount - 1].iSign = -1; + iSegset[iSegsetCount - 2].iSign = 1; + iSegset[iSegsetCount - 1].iConnectFlag = EFalse; + iSegset[iSegsetCount - 2].iConnectFlag = EFalse; + } + } + + // Min/Max update + TPoint16& p = iPoints[iPointsCount - 1]; + if ( p.iY < iMinY ) + iMinY = p.iY; + else if ( p.iY > iMaxY ) + iMaxY = p.iY; + if ( p.iX < iMinX ) + iMinX = p.iX; + else if ( p.iX > iMaxX ) + iMaxX = p.iX; + + if ( aFillOnly ) + { + iSegset[iSegsetCount - 1].iFillOnlySeg = &iPoints[iPointsCount - 1]; + } + + iIsNewOutlineStarted = EFalse; + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::SetupEdgeList() +// --------------------------------------------------------------------------- +void CGfxEdgeListP::SetupEdgeList() + { + TInt i; + + // + CheckAndConnect(); + + // Sort waiting list + TSegSet* segset = iSegset; + for ( i = 0; i < iSegsetCount; i++ ) + { + if ( segset->iValid ) + { + InsertToList( ETrue, * segset ); + if ( segset->iActualBottomY < 0 ) + segset->iActualBottomY = segset->iBottomPoint->iY; + } + segset++; + } + + // Normalize x coordinates + for ( i = 0; i < iPointsCount; i++ ) + { + iPoints[i].iX = ( TInt16 ) ( iPoints[i].iX - iMinX ); + } + + // Setting up for simple polygon, if applicable + if ( iSegsetCount < 4 ) + { + TInt ix = 0; + segset = iWaitingSegList; + + iSegListForSimple[0] = iSegListForSimple[1] = NULL; // (cdm). + + while ( segset ) + { + if ( segset->iTopPoint->iY <= iMinY ) + { + iSegListForSimple[ix++] = segset; + segset->InitDDA(); + if ( ix > 2 ) + break; + } + segset = segset->iNext; + } + } + + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::UpdateActiveEdge( TInt aY ) +// --------------------------------------------------------------------------- +void CGfxEdgeListP::UpdateActiveEdge( TInt aY ) + { + // if number of segment is less than 4, it means the polygon is + // a simple polygon, which we can reduce some processing. + if ( iSegsetCount < 4 ) + { + UpdateActiveEdgeSimple( aY ); + return; + } + + // Remove from active segment list + while ( iActiveSegList ) + { + if ( aY <= iActiveSegList->iActualBottomY ) + break; + + + iActiveSegList = iActiveSegList->iNext; + } + + // Add newly activated segment to active segment list + while ( iWaitingSegList ) + { + if ( aY < iWaitingSegList->iTopPoint->iY ) + break; + TSegSet* seg = iWaitingSegList; + iWaitingSegList = iWaitingSegList->iNext; + + InsertToList( EFalse, * seg ); // add to active list + + seg->InitDDA(); + } + + // Add edges from active segements + TSegSet* asl = iActiveSegList; + TGfxSegEdge* edge; + TInt x1, x2; + TBool fillOnly; + + iSortedEdges = 0; + iEdgesCount = 0; + while ( asl ) + { + fillOnly = asl->GetEdge( x1, x2 ); + edge = AddEdge( x1, x2 ); + if ( !edge ) // no more edges can be added. + return; + edge->iSign = ( TInt16 ) asl->iSign; + edge->iOnlyForFill = ( TInt16 ) fillOnly; + + asl = asl->iNext; + } + } + +// -------------------------------------------------------------------------- +// TGfxSegEdge* CGfxEdgeListP::EdgeList() +// --------------------------------------------------------------------------- +TGfxSegEdge* CGfxEdgeListP::EdgeList() + { + return iSortedEdges; + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::UpdateActiveEdgeSimple( TInt aY ) // (cdm) +// --------------------------------------------------------------------------- +void CGfxEdgeListP::UpdateActiveEdgeSimple( TInt aY ) // (cdm) + { + // Add edges from active segments + TGfxSegEdge* edge; + TInt x01, x02, x11, x12; + TBool fillOnly0, fillOnly1; + iEdgesCount = 0; + + if ( iSegListForSimple[0] && iSegListForSimple[1] ) + { + + if ( aY > iSegListForSimple[0]->iActualBottomY ) // (cdm) + iSegListForSimple[0] = iSegListForSimple[0]->iNext; + + if ( aY > iSegListForSimple[1]->iActualBottomY ) + iSegListForSimple[1] = iSegListForSimple[1]->iNext; + + if ( !iSegListForSimple[0] || !iSegListForSimple[1] ) + return; + + iEdgesCount = 2; + fillOnly0 = iSegListForSimple[0]->GetEdge( x01, x02 ); + fillOnly1 = iSegListForSimple[1]->GetEdge( x11, x12 ); + + if ( x01 < x11 ) + { + // iSegListForSimple[0] is left + iSortedEdges = iEdges; + edge = iSortedEdges; + edge->iStart = ( TInt16 ) x01; + edge->iEnd = ( TInt16 ) x02; + edge->iSign = ( TInt16 ) iSegListForSimple[0]->iSign; + edge->iOnlyForFill = ( TInt16 ) fillOnly0; + edge->iNext = iEdges + 1; + + edge = edge->iNext; + edge->iStart = ( TInt16 ) x11; + edge->iEnd = ( TInt16 ) x12; + edge->iSign = ( TInt16 ) iSegListForSimple[1]->iSign; + edge->iOnlyForFill = ( TInt16 ) fillOnly1; + edge->iNext = NULL; + } + else + { + // iSegListForSimple[1] is left + iSortedEdges = iEdges; + edge = iSortedEdges; + edge->iStart = ( TInt16 ) x11; + edge->iEnd = ( TInt16 ) x12; + edge->iSign = ( TInt16 ) iSegListForSimple[1]->iSign; + edge->iOnlyForFill = ( TInt16 ) fillOnly1; + edge->iNext = iEdges + 1; + + edge = edge->iNext; + edge->iStart = ( TInt16 ) x01; + edge->iEnd = ( TInt16 ) x02; + edge->iSign = ( TInt16 ) iSegListForSimple[0]->iSign; + edge->iOnlyForFill = ( TInt16 ) fillOnly0; + edge->iNext = NULL; + } + } + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::InsertToList( TBool aWaitingList, TSegSet& aSegSet ) +// --------------------------------------------------------------------------- +void CGfxEdgeListP::InsertToList( TBool aWaitingList, TSegSet& aSegSet ) + { + TSegSet** next; + if ( aWaitingList ) + next = &iWaitingSegList; + else + next = &iActiveSegList; + if(aWaitingList) + { + while ( *next ) + { + if ( ( *next )->iTopPoint->iY >= aSegSet.iTopPoint->iY ) + break; + next = &( ( *next )->iNext ); + } + } + else + { + while( *next ) + { + if ( ( *next )->iActualBottomY >= aSegSet.iActualBottomY ) + break; + next = &( ( *next )->iNext ); + + } + } + // + aSegSet.iNext = *next; + *next = &aSegSet; + } + +// -------------------------------------------------------------------------- +// TGfxSegEdge* CGfxEdgeListP::AddEdge( TInt32 aSt, TInt32 aEd )//, TInt aSegSign) +// --------------------------------------------------------------------------- +TGfxSegEdge* CGfxEdgeListP::AddEdge( TInt32 aSt, TInt32 aEd )//, TInt aSegSign) +{ + if ( iEdgesCount >= iEdgesCountMax - 1 ) // No more edges? + return NULL; + + TGfxSegEdge& newEdge = iEdges[iEdgesCount++]; + newEdge.iStart = ( TInt16 ) aSt; + newEdge.iEnd = ( TInt16 ) aEd; + + // Insert this edge in sorted link list + TGfxSegEdge** next; + next = &iSortedEdges; + TInt16 lastEnd = KMINFLOATFIX; + while ( *next ) + { + if ( newEdge.iStart < ( *next )->iStart ) // (cdm). + break; + + lastEnd = ( *next )->iEnd; + next = &( ( *next )->iNext ); + } + // + newEdge.iNext = *next; + *next = &newEdge; + + return &newEdge; + } + +// -------------------------------------------------------------------------- +// void CGfxEdgeListP::CheckAndConnect() +// --------------------------------------------------------------------------- +void CGfxEdgeListP::CheckAndConnect() + { + if ( iSegsetCount < 3 ) // (cdm) + return; + + // Merge the first one and the last one if they have same sign + TSegSet* lastSegset =& iSegset[iSegsetCount - 1]; + TPoint16* ps1 = iStartSeg->iTopPoint; + TPoint16* ps2 = iStartSeg->iBottomPoint; + TPoint16* pl1 = lastSegset->iTopPoint; + TPoint16* pl2 = lastSegset->iBottomPoint; + + if ( iStartSeg->iPointAryInc == lastSegset->iPointAryInc && + iStartSeg->iConnectFlag && + ( ( ps1->iX == pl1->iX && ps1->iY == pl1->iY ) || + ( ps1->iX == pl2->iX && ps1->iY == pl2->iY ) || + ( ps2->iX == pl1->iX && ps2->iY == pl1->iY ) || + ( ps2->iX == pl2->iX && ps2->iY == pl2->iY ) ) ) + { + if ( iStartSeg->iPointAryInc == 1 ) + { + iStartSeg->iValid = EFalse; + lastSegset->iConnect = iStartSeg; + lastSegset->iActualBottomY = iStartSeg->iBottomPoint->iY; + } + else + { + lastSegset->iValid = EFalse; + iStartSeg->iConnect = lastSegset; + iStartSeg->iActualBottomY = lastSegset->iBottomPoint->iY; + } + } + } + +void TSegSet::Construct( TPoint16* aP1, TPoint16* aP2 ) + { + if ( aP1->iY < aP2->iY ) + { + iTopPoint = aP1; + iBottomPoint = aP2; + iSign = 1; + iPointAryInc = 1; + } + else if ( aP1->iY == aP2->iY ) + { + iTopPoint = aP1; + iBottomPoint = aP2; + iSign = 0; + iPointAryInc = 1; + } + else + { + iTopPoint = aP2; + iBottomPoint = aP1; + iSign = -1; + iPointAryInc = -1; + } + + iNext = NULL; + iConnect = NULL; + iValid = ETrue; + iActualBottomY = KMINFLOATFIX; + iFillOnlySeg = NULL; + iConnectFlag = ETrue; + } + +TAddSegStatus TSegSet::AddSegment( TInt aX, + TInt aY, + TUint& aLastSegLenSq, + TBool aClosePath ) + { + TPoint16* p; // the last vertex in the array of vertex + if ( iPointAryInc == 1 ) + p = iBottomPoint; + else + p = iTopPoint; + + // Check sign of y diff + TInt16 x3 = ( TInt16 ) aX, y3 = ( TInt16 ) aY; + + if ( p->iX == x3 && p->iY == y3 ) + return ESegIgnore; + + TInt sign; + if ( p->iY < y3 ) + sign = 1; + else if ( p->iY == y3 ) + sign = 0; + else + sign = -1; + if ( iSign == 0 ) + { + iSign = ( TInt16 ) sign; + if ( sign == -1 ) + { + // swap top point and bottom point + TPoint16* tmp = iTopPoint; + iTopPoint = iBottomPoint; + iBottomPoint = tmp; + iPointAryInc = -1; + } + } + else if ( sign != 0 && iSign != sign ) + return ESegStartNew; // sign is different. start new segment + + // Vertex merging + TUint lenSq = ( p->iX - x3 ) * ( p->iX - x3 ) + + ( p->iY - y3 ) * ( p->iY - y3 ); + if ( !aClosePath ) + { + if ( aLastSegLenSq < 9 && lenSq < 9 ) + { + p->iX = x3; + p->iY = y3; + TPoint16* pp = p + iPointAryInc; + aLastSegLenSq = ( p->iX - pp->iX ) * ( p->iX - pp->iX ) + + ( p->iY - pp->iY ) * ( p->iY - pp->iY ); + return ESegMerge; + } + } + aLastSegLenSq = lenSq; + + + // Add point + TPoint16* nextp; + if ( iPointAryInc == 1 ) + nextp = ++iBottomPoint; + else + nextp = ++iTopPoint; + nextp->iX = x3; + nextp->iY = y3; + + return ESegAdd; + } + +TBool TSegSet::GetEdge( TInt& aX1, TInt& aX2 ) + { + TPoint16 p1, p2; + TBool fillOnly; + TBool done = SingleScanline( p1, p2 ); + + if ( p1.iX < p2.iX ) + { + aX1 = p1.iX; + aX2 = p2.iX; + } + else + { + aX1 = p2.iX; + aX2 = p1.iX; + } + + if ( done ) // if done, construct new DDA with next segment + { + do + { + fillOnly = ( ( iTopPoint += iPointAryInc ) == iFillOnlySeg ); // (cdm) + + if ( iTopPoint == iBottomPoint ) + { + if ( iConnect ) + { + iTopPoint = iConnect->iTopPoint; + iBottomPoint = iConnect->iBottomPoint; + iFillOnlySeg = iConnect->iFillOnlySeg; + iConnect = NULL; + } + else + { + return fillOnly; + } + } + ConstructDDA( iTopPoint, iTopPoint + iPointAryInc ); + + done = SingleScanline( p1, p2 ); + + if ( p1.iX < p2.iX ) // update edge minX & maxX + { + if ( p1.iX < aX1 ) + aX1 = p1.iX; + if ( aX2 < p2.iX ) + aX2 = p2.iX; + } + else + { + if ( p2.iX < aX1 ) + aX1 = p2.iX; + if ( aX2 < p1.iX ) + aX2 = p1.iX; + } + } + while ( done ); + } + else + { + fillOnly = ( iTopPoint == iFillOnlySeg || iTopPoint + iPointAryInc == iFillOnlySeg ); + } + return fillOnly; + } + +void TSegSet::InitDDA() + { + ConstructDDA( iTopPoint, iTopPoint + iPointAryInc ); + } + +// --------------------------------------------------------------------------- +// DDA functions, which is mostly from Symbian's TLinearDDA +// --------------------------------------------------------------------------- +void TSegSet::ConstructDDA( TPoint16* aStart, TPoint16* aFinish ) + { + iStart = aStart; + iFinish = aFinish; + iDifference.iWidth = ( TInt16 ) Abs( iStart->iX - iFinish->iX ); + iDifference.iHeight = ( TInt16 ) Abs( iStart->iY - iFinish->iY ); + iInc.iX = ( TInt16 ) ( ( iStart->iX > iFinish->iX ) ? -1 : 1 ); + iInc.iY = ( TInt16 ) ( ( iStart->iY > iFinish->iY ) ? -1 : 1 ); + if ( iDifference.iWidth ) + { + iGradient = ( TInt16 ) + ( ( iFinish->iY - iStart->iY ) / + ( iFinish->iX - iStart->iX ) ); + } + else + { + iGradient = 0; // (cdm) + } + + iPos = *iStart; + if ( !iGradient ) + { + iCount = iDifference.iWidth; + } + else + { + iCount = iDifference.iHeight; + } + iCount >>= 1; + iStatus = EInitialised; + if ( aStart == aFinish ) + iStatus = EComplete; + } + +TBool TSegSet::SingleStep( TPoint16& aPosition ) + { + if ( iStatus == ECurrent ) + { + UpdatePosition(); + aPosition = iPos; + if ( iPos.iX == iFinish->iX && iPos.iY == iFinish->iY ) + { + iStatus = EComplete; + return( ETrue ); + } + return( EFalse ); + } + else if ( iStatus == EInitialised ) + { + aPosition = *iStart; + iStatus = ECurrent; + return( EFalse ); + } + else + { + aPosition = *iFinish; + return( ETrue ); + }; + } + +TBool TSegSet::SingleScanline( TPoint16& aStartPosition, + TPoint16& aEndPosition ) + { + TBool done = EFalse; + if ( iDifference.iHeight == 0 ) + { + aStartPosition = *iStart; + aEndPosition = *iFinish; + iStatus = EComplete; //KM + return( ETrue ); + } + if ( iDifference.iWidth == 0 || iGradient ) + { + done = SingleStep( aStartPosition ); + aEndPosition = aStartPosition; + return( done ); + } + done = SingleStep( aStartPosition ); + aEndPosition = aStartPosition; + while ( iCount - iDifference.iHeight >= 0 && !done ) + { + done = SingleStep( aEndPosition ); + } + return( done ); + } + +void TSegSet::UpdatePosition() + { + if ( iDifference.iHeight == 0 ) // horizontal line + iPos.iX = ( TInt16 ) ( iPos.iX + iInc.iX ); + else if ( iDifference.iWidth == 0 ) // vertical line + iPos.iY = ( TInt16 ) ( iPos.iY + iInc.iY ); + else + { + if ( !iGradient ) + { + iCount = ( TInt16 ) ( iCount - iDifference.iHeight ); + if ( iCount < 0 ) + { + iCount = ( TInt16 ) ( iCount + iDifference.iWidth ); + iPos.iY = ( TInt16 ) ( iPos.iY + iInc.iY ); + } + iPos.iX = ( TInt16 ) ( iPos.iX + iInc.iX ); + } + else + { + iCount = ( TInt16 ) ( iCount - iDifference.iWidth ); + if ( iCount < 0 ) + { + iCount = ( TInt16 ) ( iCount + iDifference.iHeight ); + iPos.iX = ( TInt16 ) ( iPos.iX + iInc.iX ); + } + iPos.iY = ( TInt16 ) ( iPos.iY + iInc.iY ); + } + } + }