os/graphics/graphicsdeviceinterface/gdi/sgdi/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) 1998-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 <gdi.h>
sl@0
    17
sl@0
    18
#ifdef __ARMCC__
sl@0
    19
#pragma arm
sl@0
    20
#pragma O3
sl@0
    21
#pragma Otime
sl@0
    22
#endif
sl@0
    23
sl@0
    24
EXPORT_C TLinearDDA::TLinearDDA():
sl@0
    25
	iCount(0),
sl@0
    26
	iDifference(),
sl@0
    27
	iFinish(),
sl@0
    28
	iGradient(0),
sl@0
    29
	iInc(),
sl@0
    30
	iPos(),
sl@0
    31
	iStart(),
sl@0
    32
	iBoundingRect(),
sl@0
    33
	iBoundingRectSet(EFalse),
sl@0
    34
	iInsideX(EFalse),
sl@0
    35
	iInsideY(EFalse),
sl@0
    36
	iStatus(EComplete)
sl@0
    37
/** Constructs the default linear DDA.
sl@0
    38
sl@0
    39
No start or end point is defined for the line. */
sl@0
    40
	{}
sl@0
    41
sl@0
    42
 
sl@0
    43
EXPORT_C TLinearDDA::TLinearDDA(const TLinearDDA& aLine):
sl@0
    44
	iCount(aLine.iCount),
sl@0
    45
	iDifference(aLine.iDifference),
sl@0
    46
	iFinish(aLine.iFinish),
sl@0
    47
	iGradient(aLine.iGradient),
sl@0
    48
	iInc(aLine.iInc),
sl@0
    49
	iPos(aLine.iPos),
sl@0
    50
	iStart(aLine.iStart),
sl@0
    51
	iBoundingRect(aLine.iBoundingRect),
sl@0
    52
	iBoundingRectSet(aLine.iBoundingRectSet),
sl@0
    53
	iInsideX(aLine.iInsideX),
sl@0
    54
	iInsideY(aLine.iInsideY),
sl@0
    55
	iStatus(aLine.iStatus)
sl@0
    56
/** Copy constructs a linear DDA from the specified linear DDA.
sl@0
    57
sl@0
    58
@param aLine The linear DDA to be copied. */
sl@0
    59
	{}
sl@0
    60
sl@0
    61
 
sl@0
    62
EXPORT_C void TLinearDDA::Construct(const TPoint& aStart,const TPoint& aFinish,TLineMode aMode)
sl@0
    63
/** Constructs a linear DDA, setting the start and end points of the line.
sl@0
    64
sl@0
    65
@param aStart The start point of the line. 
sl@0
    66
@param aFinish The end point of the line. 
sl@0
    67
@param aMode The mode of the line; defaults to centred. */
sl@0
    68
	{
sl@0
    69
	iStart=aStart;
sl@0
    70
	iFinish=aFinish;
sl@0
    71
	iDifference=(iFinish-iStart).AsSize();
sl@0
    72
	iDifference.iWidth=Abs(iDifference.iWidth);
sl@0
    73
	iDifference.iHeight=Abs(iDifference.iHeight);
sl@0
    74
	iInc.iX=(iStart.iX>iFinish.iX)?-1:1;
sl@0
    75
	iInc.iY=(iStart.iY>iFinish.iY)?-1:1;
sl@0
    76
	if(iDifference.iWidth)
sl@0
    77
		iGradient=(iFinish.iY-iStart.iY)/(iFinish.iX-iStart.iX);
sl@0
    78
	iPos=iStart;
sl@0
    79
	if(!iGradient)
sl@0
    80
		iCount=iDifference.iWidth;
sl@0
    81
	else
sl@0
    82
		iCount=iDifference.iHeight;
sl@0
    83
	if(aMode==ECenter)
sl@0
    84
		iCount>>=1;
sl@0
    85
	else
sl@0
    86
		if(iCount)
sl@0
    87
			iCount--;
sl@0
    88
	iStatus=EInitialised;
sl@0
    89
	if(aStart==aFinish)
sl@0
    90
		iStatus=EComplete;
sl@0
    91
	iBoundingRectSet=EFalse;
sl@0
    92
	iInsideX = EFalse;
sl@0
    93
	iInsideY = EFalse;
sl@0
    94
	}
sl@0
    95
sl@0
    96
 
sl@0
    97
EXPORT_C TBool TLinearDDA::SingleStep(TPoint& aPosition)
sl@0
    98
/** Gets the pixel co-ordinates of the next pixel on the pixel line.
sl@0
    99
sl@0
   100
The function is called repeatedly until the whole line has been traversed or, 
sl@0
   101
if JumpToRect() has been called, until the part of the line inside the rectangle 
sl@0
   102
has been traversed. Note that, for performance reasons, JumpToRect() may fail 
sl@0
   103
to detect the intersection of the line with the rectangle accurately and 
sl@0
   104
SingleStep() may return more points than strictly necessary.
sl@0
   105
sl@0
   106
@param aPosition On entry to the first call, this can be a reference to any 
sl@0
   107
point. On return from the first call, this is the position of the first pixel 
sl@0
   108
in the line, as specified during construction of this object. On return from 
sl@0
   109
subsequent calls, this is the position of subsequent pixels in the line, as 
sl@0
   110
calculated by the function. On return from the final call, this is the position 
sl@0
   111
of the last pixel in the line, as specified during construction of this object.
sl@0
   112
@return ETrue, when the position of the last pixel is returned; EFalse, 
sl@0
   113
otherwise. */
sl@0
   114
    {
sl@0
   115
    switch (iStatus)
sl@0
   116
        {
sl@0
   117
        case EInitialised:
sl@0
   118
            aPosition = iStart;
sl@0
   119
            iStatus = ECurrent;
sl@0
   120
            return EFalse;
sl@0
   121
        case ECurrent:
sl@0
   122
            if (iDifference.iHeight == 0) // horizontal line
sl@0
   123
                {
sl@0
   124
                iPos.iX += iInc.iX;
sl@0
   125
                if (iPos.iX == iFinish.iX)
sl@0
   126
                    {
sl@0
   127
                    iStatus = EComplete;
sl@0
   128
                    }
sl@0
   129
                }
sl@0
   130
            else if (iDifference.iWidth == 0) // vertical line
sl@0
   131
                {
sl@0
   132
                iPos.iY += iInc.iY;
sl@0
   133
                if (iPos.iY == iFinish.iY)
sl@0
   134
                    {
sl@0
   135
                    iStatus = EComplete;
sl@0
   136
                    }
sl@0
   137
                }
sl@0
   138
            else // diagonal stripes
sl@0
   139
                {
sl@0
   140
                if (!iGradient)
sl@0
   141
                    {
sl@0
   142
                    iCount -= iDifference.iHeight;
sl@0
   143
                    iPos.iX += iInc.iX;
sl@0
   144
                    if (iCount < 0)
sl@0
   145
                        {
sl@0
   146
                        iCount += iDifference.iWidth;
sl@0
   147
                        iPos.iY += iInc.iY;
sl@0
   148
                        }
sl@0
   149
                    }
sl@0
   150
                else
sl@0
   151
                    {
sl@0
   152
                    iCount -= iDifference.iWidth;
sl@0
   153
                    iPos.iY += iInc.iY;
sl@0
   154
                    if (iCount < 0)
sl@0
   155
                        {
sl@0
   156
                        iCount += iDifference.iHeight;
sl@0
   157
                        iPos.iX += iInc.iX;
sl@0
   158
                        }
sl@0
   159
                    }
sl@0
   160
                if ((iPos.iX == iFinish.iX) && (iPos.iY == iFinish.iY))
sl@0
   161
                    {
sl@0
   162
                    iStatus = EComplete;
sl@0
   163
                    }
sl@0
   164
                }
sl@0
   165
            // common
sl@0
   166
            aPosition = iPos;
sl@0
   167
            if (iStatus == EComplete)
sl@0
   168
                {
sl@0
   169
                return ETrue;
sl@0
   170
                }
sl@0
   171
            if(iBoundingRectSet)
sl@0
   172
                {
sl@0
   173
                if (iPos.iX >= iBoundingRect.iTl.iX && iPos.iX < iBoundingRect.iBr.iX)
sl@0
   174
                    iInsideX = ETrue;
sl@0
   175
                else
sl@0
   176
                    if (iInsideX)
sl@0
   177
                        {
sl@0
   178
                        iStatus=EComplete;
sl@0
   179
                        return(ETrue);
sl@0
   180
                        }
sl@0
   181
                if (iPos.iY >= iBoundingRect.iTl.iY && iPos.iY < iBoundingRect.iBr.iY)
sl@0
   182
                    iInsideY = ETrue;
sl@0
   183
                else
sl@0
   184
                    if (iInsideY)
sl@0
   185
                        {
sl@0
   186
                        iStatus=EComplete;
sl@0
   187
                        return(ETrue);
sl@0
   188
                        }
sl@0
   189
                }
sl@0
   190
            return EFalse;
sl@0
   191
        default:
sl@0
   192
            aPosition = iFinish;
sl@0
   193
            return ETrue;
sl@0
   194
        }
sl@0
   195
    }
sl@0
   196
 
sl@0
   197
EXPORT_C TBool TLinearDDA::NextStep(TPoint& aPosition)
sl@0
   198
/** Gets the pixel co-ordinates of the start of the next scan line.
sl@0
   199
sl@0
   200
The best line that joins the start and end points is formed from all the scan 
sl@0
   201
lines returned by this function.
sl@0
   202
sl@0
   203
The function is called repeatedly until the start position of all scanlines 
sl@0
   204
has been returned.
sl@0
   205
sl@0
   206
The start and end points passed to the constructor of this object define the 
sl@0
   207
boundaries of the line. Successive scan lines move from the start point to 
sl@0
   208
the end point.
sl@0
   209
sl@0
   210
@param aPosition On entry to the first call, this can be a reference to any 
sl@0
   211
point. On return from the first call, this is the position of the pixel that 
sl@0
   212
defines the leftmost position of the first scan line. On return from subsequent 
sl@0
   213
calls, this is the position of the pixel that defines the leftmost position 
sl@0
   214
of the next scan line. On return from the final call, this is the position 
sl@0
   215
of the last pixel in the line, as specified during construction. 
sl@0
   216
@return ETrue, when the position of the last pixel is returned; EFalse, 
sl@0
   217
otherwise. */
sl@0
   218
    {
sl@0
   219
    if (!iDifference.iHeight) // horizontal line
sl@0
   220
        {
sl@0
   221
        iPos = iFinish;
sl@0
   222
        iStatus = EComplete;
sl@0
   223
        aPosition = iFinish;
sl@0
   224
        return ETrue;
sl@0
   225
        }
sl@0
   226
    if (!iDifference.iWidth || iGradient || (iStatus != ECurrent))
sl@0
   227
        {
sl@0
   228
        return SingleStep(aPosition);
sl@0
   229
        }
sl@0
   230
    // !iGradient && (iStatus != EInitialised)
sl@0
   231
    if(iBoundingRectSet)
sl@0
   232
        { // slower version
sl@0
   233
        while ((iCount - iDifference.iHeight) >= 0)
sl@0
   234
            {
sl@0
   235
            if (SingleStep(aPosition))
sl@0
   236
                return ETrue;
sl@0
   237
            }
sl@0
   238
        return SingleStep(aPosition);
sl@0
   239
        }
sl@0
   240
    // faster version avoids function calls
sl@0
   241
    TBool lastLoop = EFalse;
sl@0
   242
    do {
sl@0
   243
        if ((iCount - iDifference.iHeight) < 0)
sl@0
   244
            {
sl@0
   245
            lastLoop = ETrue;
sl@0
   246
            }
sl@0
   247
        iCount -= iDifference.iHeight;
sl@0
   248
        iPos.iX += iInc.iX;
sl@0
   249
        if (iCount < 0)
sl@0
   250
            {
sl@0
   251
            iCount += iDifference.iWidth;
sl@0
   252
            iPos.iY += iInc.iY;
sl@0
   253
            }
sl@0
   254
sl@0
   255
        if ((iPos.iX == iFinish.iX) && (iPos.iY == iFinish.iY))
sl@0
   256
            {
sl@0
   257
            aPosition = iFinish;
sl@0
   258
            iStatus = EComplete;
sl@0
   259
            return ETrue;
sl@0
   260
            }
sl@0
   261
        }
sl@0
   262
        while (!lastLoop);
sl@0
   263
    aPosition = iPos;
sl@0
   264
    return EFalse;
sl@0
   265
    }
sl@0
   266
 
sl@0
   267
EXPORT_C TBool TLinearDDA::SingleScanline(TPoint& aStartPosition,TPoint& aEndPosition)
sl@0
   268
/** Gets the start and end pixel co-ordinates that define the next scan line.
sl@0
   269
sl@0
   270
The best line that joins the start and end points is formed from all the scan 
sl@0
   271
lines returned by this function.
sl@0
   272
sl@0
   273
The function is called repeatedly until the position of all scanlines has 
sl@0
   274
been returned.
sl@0
   275
sl@0
   276
The start and end points passed to the constructor of this object define the 
sl@0
   277
boundaries of the line. Successive scan lines move from the start point to 
sl@0
   278
the end point.
sl@0
   279
sl@0
   280
@param aStartPosition On entry to the first call, this can be a reference 
sl@0
   281
to any point. On return from the first call, this is the position of the pixel 
sl@0
   282
that defines the leftmost position of the first scan line. On return from 
sl@0
   283
subsequent calls, this is the position of the pixel that defines the leftmost 
sl@0
   284
position of the next scan line. On return from the final call, either this 
sl@0
   285
or aEndPosition is set to the end point, as specified during construction.
sl@0
   286
@param aEndPosition On entry to the first call, this can be a reference to 
sl@0
   287
any point. On return from the first call, this is the position of the pixel 
sl@0
   288
that defines the rightmost position of the first scan line. On return from 
sl@0
   289
subsequent calls, this is the position of the pixel that defines the rightmost 
sl@0
   290
position of the next scan line. On return from the final call, either this 
sl@0
   291
or aStartPosition is set to the end point, as specified during construction.
sl@0
   292
@return ETrue, when the position of the last scan line includes the end point; 
sl@0
   293
EFalse, otherwise. */
sl@0
   294
    {
sl@0
   295
    TBool done=EFalse;
sl@0
   296
    if(iDifference.iHeight==0)
sl@0
   297
        {
sl@0
   298
        aStartPosition=iStart;
sl@0
   299
        aEndPosition=iFinish;
sl@0
   300
        return(ETrue);
sl@0
   301
        }
sl@0
   302
    if(iDifference.iWidth==0 || iGradient)
sl@0
   303
        {
sl@0
   304
        done=SingleStep(aStartPosition);
sl@0
   305
        aEndPosition=aStartPosition;
sl@0
   306
        return(done);
sl@0
   307
        }
sl@0
   308
    // !iGradient
sl@0
   309
    done=SingleStep(aStartPosition);
sl@0
   310
    aEndPosition=aStartPosition;
sl@0
   311
    while(iCount-iDifference.iHeight>=0 && !done)
sl@0
   312
        {
sl@0
   313
        iCount -= iDifference.iHeight;
sl@0
   314
        iPos.iX += iInc.iX;
sl@0
   315
        if (iCount < 0)
sl@0
   316
            {
sl@0
   317
            iCount += iDifference.iWidth;
sl@0
   318
            iPos.iY += iInc.iY;
sl@0
   319
            }
sl@0
   320
sl@0
   321
        if ((iPos.iX == iFinish.iX) && (iPos.iY == iFinish.iY))
sl@0
   322
            {
sl@0
   323
            iStatus = EComplete;
sl@0
   324
            done = ETrue;
sl@0
   325
            }
sl@0
   326
        }
sl@0
   327
    aEndPosition = iPos;
sl@0
   328
    return done;
sl@0
   329
    }
sl@0
   330
 
sl@0
   331
EXPORT_C void TLinearDDA::JumpToRect(const TRect& aRect)
sl@0
   332
/** Jumps to start of a clipping rectangle.
sl@0
   333
sl@0
   334
This will accelerate the linear DDA to the vicinity of the specified rectangle. 
sl@0
   335
It is NOT guaranteed to reach the rectangle, but will reduce co-ordinates 
sl@0
   336
that are 1000's out to co-ordinates that are 10's out. Because of this, failure 
sl@0
   337
to intersect the rectangle may not be detected. If it is, or the line has 
sl@0
   338
not been constructed or has been run to completion, then a subsequent call 
sl@0
   339
to the stepping functions returns ETrue.
sl@0
   340
sl@0
   341
@param aRect The rectangle to be jumped to. */
sl@0
   342
	{
sl@0
   343
	if(aRect.IsEmpty() || iStatus!=EInitialised) return;
sl@0
   344
	iBoundingRect=aRect;
sl@0
   345
	iBoundingRectSet=ETrue;
sl@0
   346
sl@0
   347
	TInt nearestx = 0;
sl@0
   348
	if (iStart.iX < aRect.iTl.iX)
sl@0
   349
		nearestx = aRect.iTl.iX;
sl@0
   350
	else if (iStart.iX >= aRect.iBr.iX)
sl@0
   351
		nearestx = aRect.iBr.iX;
sl@0
   352
	else
sl@0
   353
		iInsideX = ETrue;
sl@0
   354
	TInt nearesty = 0;
sl@0
   355
	if (iStart.iY < aRect.iTl.iY)
sl@0
   356
		nearesty = aRect.iTl.iY;
sl@0
   357
	else if (iStart.iY >= aRect.iBr.iY)
sl@0
   358
		nearesty = aRect.iBr.iY;
sl@0
   359
	else
sl@0
   360
		iInsideY = ETrue;
sl@0
   361
	if (iInsideX && iInsideY)
sl@0
   362
		return;
sl@0
   363
sl@0
   364
	TInt dummy;
sl@0
   365
	if(!iGradient)
sl@0
   366
		{
sl@0
   367
		if (iInsideX)
sl@0
   368
			return;
sl@0
   369
		JumpToXCoord(nearestx,dummy);
sl@0
   370
		}
sl@0
   371
	else
sl@0
   372
		{
sl@0
   373
		if (iInsideY)
sl@0
   374
			return;
sl@0
   375
		JumpToYCoord(dummy,nearesty);
sl@0
   376
		}
sl@0
   377
	}
sl@0
   378
sl@0
   379
 
sl@0
   380
EXPORT_C void TLinearDDA::JumpToXCoord(const TInt aXCoord,TInt& aYCoord)
sl@0
   381
/** Jumps to x co-ordinate.
sl@0
   382
sl@0
   383
The other co-ordinate of the intersection is returned through a reference 
sl@0
   384
argument. After a jump call, the line is ready to continue through calls to 
sl@0
   385
the stepping functions.
sl@0
   386
sl@0
   387
This function accelerates the Linear DDA stepping functions (e.g. SingleStep()) 
sl@0
   388
making them return EFalse when they reach the specified co-ordinate. If the 
sl@0
   389
line does not cross the co-ordinate, has not been constructed, has been run 
sl@0
   390
to completion or the intersection is the end point of the line then the stepping 
sl@0
   391
functions will return ETrue.
sl@0
   392
sl@0
   393
@param aXCoord x co-ordinate to jump to 
sl@0
   394
@param aYCoord On return, this parameter holds the y co-ordinate which corresponds 
sl@0
   395
to the specified x co-ordinate */
sl@0
   396
	{
sl@0
   397
	if(iStatus==EComplete) return; // not constructed
sl@0
   398
	if((iStart.iX<aXCoord && iFinish.iX<aXCoord) || (iStart.iX>aXCoord && iFinish.iX>aXCoord))
sl@0
   399
		return; // no intersection
sl@0
   400
	aYCoord=iStart.iY;
sl@0
   401
	if(iStart.iX==aXCoord) return; // trivial first intersection
sl@0
   402
	iStatus=ECurrent;
sl@0
   403
	if(iDifference.iHeight==0) // horizontal line
sl@0
   404
		iPos.iX=aXCoord;
sl@0
   405
	else
sl@0
   406
		{
sl@0
   407
		if(!iGradient)
sl@0
   408
			{
sl@0
   409
			TInt64 numsteps=Abs(aXCoord-iPos.iX);
sl@0
   410
			TInt64 tempcount=TInt64(iCount)-(TInt64(iDifference.iHeight)*numsteps);
sl@0
   411
			numsteps=Abs(tempcount/iDifference.iWidth);
sl@0
   412
			tempcount+=numsteps*iDifference.iWidth;
sl@0
   413
			while(tempcount<0)
sl@0
   414
				{
sl@0
   415
				tempcount+=iDifference.iWidth;
sl@0
   416
				numsteps++;
sl@0
   417
				}
sl@0
   418
			iCount = I64INT(tempcount);
sl@0
   419
			iPos.iY += (iInc.iY * I64INT(numsteps));
sl@0
   420
			iPos.iX=aXCoord;
sl@0
   421
			aYCoord=iPos.iY;
sl@0
   422
			}
sl@0
   423
		else
sl@0
   424
			{
sl@0
   425
			while(iPos.iX!=aXCoord)
sl@0
   426
				{
sl@0
   427
				iCount-=iDifference.iWidth;
sl@0
   428
				if(iCount<0)
sl@0
   429
					{
sl@0
   430
					iCount+=iDifference.iHeight;
sl@0
   431
					iPos.iX+=iInc.iX;
sl@0
   432
					}
sl@0
   433
				iPos.iY+=iInc.iY;
sl@0
   434
				}
sl@0
   435
			aYCoord=iPos.iY;
sl@0
   436
			}
sl@0
   437
		}
sl@0
   438
    if ((iPos.iX == iFinish.iX) && (iPos.iY == iFinish.iY))
sl@0
   439
        {
sl@0
   440
        iStatus=EComplete;
sl@0
   441
        }
sl@0
   442
	}
sl@0
   443
sl@0
   444
 
sl@0
   445
EXPORT_C void TLinearDDA::JumpToYCoord(TInt& aXCoord,const TInt aYCoord)
sl@0
   446
/** Jumps to a y co-ordinate.
sl@0
   447
sl@0
   448
The other co-ordinate of the intersection is returned through a reference 
sl@0
   449
argument. After a jump call, the line is ready to continue through calls to 
sl@0
   450
the stepping functions.
sl@0
   451
sl@0
   452
This function accelerates the Linear DDA stepping functions (e.g. SingleStep()) 
sl@0
   453
making them return EFalse when they reach the specified co-ordinate. If the 
sl@0
   454
line does not cross the co-ordinate, has not been constructed, has been run 
sl@0
   455
to completion or the intersection is the end point of the line then they will 
sl@0
   456
return ETrue. 
sl@0
   457
sl@0
   458
@param aXCoord On return, this parameter holds the x co-ordinate which corresponds 
sl@0
   459
to the specified y co-ordinate. 
sl@0
   460
@param aYCoord y co-ordinate to jump to */
sl@0
   461
	{
sl@0
   462
	if(iStatus==EComplete) return; // not constructed
sl@0
   463
	if((iStart.iY<aYCoord && iFinish.iY<aYCoord) || (iStart.iY>aYCoord && iFinish.iY>aYCoord))
sl@0
   464
		return; // no intersection
sl@0
   465
	aXCoord=iStart.iX;
sl@0
   466
	if(iStart.iY==aYCoord) return; // trivial first intersection
sl@0
   467
	iStatus=ECurrent;
sl@0
   468
	if(iDifference.iWidth==0) // vertical line
sl@0
   469
		iPos.iY=aYCoord;
sl@0
   470
	else
sl@0
   471
		{
sl@0
   472
		if(!iGradient)
sl@0
   473
			{
sl@0
   474
			while(iPos.iY!=aYCoord)
sl@0
   475
				{
sl@0
   476
				iCount-=iDifference.iHeight;
sl@0
   477
				if(iCount<0)
sl@0
   478
					{
sl@0
   479
					iCount+=iDifference.iWidth;
sl@0
   480
					iPos.iY+=iInc.iY;
sl@0
   481
					}
sl@0
   482
				iPos.iX+=iInc.iX;
sl@0
   483
				}
sl@0
   484
			aXCoord=iPos.iX;
sl@0
   485
			}
sl@0
   486
		else
sl@0
   487
			{
sl@0
   488
			TInt64 numsteps=Abs(aYCoord-iPos.iY);
sl@0
   489
			TInt64 tempcount=TInt64(iCount)-(TInt64(iDifference.iWidth)*numsteps);
sl@0
   490
			numsteps=Abs(tempcount/iDifference.iHeight);
sl@0
   491
			tempcount+=numsteps*iDifference.iHeight;
sl@0
   492
			while (tempcount<0)
sl@0
   493
				{
sl@0
   494
				tempcount+=iDifference.iHeight;
sl@0
   495
				numsteps++;
sl@0
   496
				}
sl@0
   497
			iCount = I64INT(tempcount);
sl@0
   498
			iPos.iX += (iInc.iX * I64INT(numsteps));
sl@0
   499
			iPos.iY=aYCoord;
sl@0
   500
			aXCoord=iPos.iX;
sl@0
   501
			}
sl@0
   502
		}
sl@0
   503
    if ((iPos.iX == iFinish.iX) && (iPos.iY == iFinish.iY))
sl@0
   504
        {
sl@0
   505
        iStatus=EComplete;
sl@0
   506
        }
sl@0
   507
	}
sl@0
   508
sl@0
   509
void TLinearDDA::UpdatePosition()
sl@0
   510
	{
sl@0
   511
	}
sl@0
   512
sl@0
   513
EXPORT_C void TLinearDDA::JumpToXCoord2(TInt aXCoord,TInt& aYCoord)
sl@0
   514
/**
sl@0
   515
Jumps to x co-ordinate.
sl@0
   516
sl@0
   517
This works in the same way as TLinearDDA::JumpToXCoord except that it make sure
sl@0
   518
that using the NextStep function does not return the same value twice.
sl@0
   519
sl@0
   520
@param aXCoord x co-ordinate to jump to
sl@0
   521
@param aYCoord On return, this parameter holds the y co-ordinate which corresponds
sl@0
   522
to the specified x co-ordinate
sl@0
   523
@see TLinearDDA::JumpToXCoord(TInt, TInt&)
sl@0
   524
*/
sl@0
   525
	{
sl@0
   526
	JumpToXCoord(aXCoord,aYCoord);
sl@0
   527
	iStatus=ECurrent;
sl@0
   528
	}
sl@0
   529
sl@0
   530
EXPORT_C void TLinearDDA::JumpToYCoord2(TInt& aXCoord,TInt aYCoord)
sl@0
   531
/**
sl@0
   532
Jumps to a y co-ordinate.
sl@0
   533
sl@0
   534
This works in the same way as TLinearDDA::JumpToYCoord except that it make sure
sl@0
   535
that using the NextStep function does not return the same value twice.
sl@0
   536
sl@0
   537
@param aXCoord On return, this parameter holds the x co-ordinate which corresponds
sl@0
   538
to the specified y co-ordinate.
sl@0
   539
@param aYCoord y co-ordinate to jump to
sl@0
   540
@see TLinearDDA::JumpToYCoord(TInt&, TInt)
sl@0
   541
*/ 
sl@0
   542
	{
sl@0
   543
	JumpToYCoord(aXCoord,aYCoord);
sl@0
   544
	iStatus=ECurrent;
sl@0
   545
	}