--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/skins/AknSkins/polysrc/AknsAlPolyLine.cpp Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,184 @@
+/*
+* Copyright (c) 2004-2008 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: Poly line class.
+*
+*/
+
+
+#include "AknsAlPolyLine.h"
+
+// -----------------------------------------------------------------------------
+// C++ constructor.
+// -----------------------------------------------------------------------------
+//
+CAknsAlPolyLine::CAknsAlPolyLine()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CAknsAlPolyLine::~CAknsAlPolyLine()
+ {
+ delete [] iSegmentLengths;
+ iSegmentLengths = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// Symbian 1st phase constructor.
+// -----------------------------------------------------------------------------
+//
+CAknsAlPolyLine* CAknsAlPolyLine::NewL()
+ { // static
+ CAknsAlPolyLine* self=new(ELeave) CAknsAlPolyLine();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// Gets poly point.
+// -----------------------------------------------------------------------------
+//
+TPoint CAknsAlPolyLine::GetPolyPoint( const TUint32 aPosition )
+ {
+ // aPosition is 32 bit integer representing range 0...1
+#if (defined(__SERIES60_26__) || defined(__SERIES60_27__) || defined(__SERIES60_28__))
+ TInt64 aa;
+ aa.Set(0,aPosition);
+ TInt64 bb;
+ bb.Set(0,iSegmentLengths[iPointCount-2]);
+ TInt64 pos64 = aa*bb;
+ TUint32 pos = (TUint32)pos64.High(); // same as pos64 >> 32
+#else // 3.0 or newer
+ TUint64 pos64 = TUint64(aPosition) * TUint64(iSegmentLengths[iPointCount-2]);
+ TUint32 pos = pos64 >> 32;
+#endif
+ // because of possible rounding errors, first check for last pixel
+ if (pos >= iSegmentLengths[iPointCount-2])
+ {
+ return TPoint(iPoints[iPointCount-1].iX,
+ iPoints[iPointCount-1].iY);
+ }
+
+ // find the segment, where pos is pointing
+ TInt i = 0; // first index
+ TInt j = iPointCount-2; // last index
+ TInt k;
+ while ( i < j )
+ {
+ k = (i + j)/2;
+ if ( pos < iSegmentLengths[k] )
+ {
+ j = k;
+ }
+ else
+ {
+ i = k + 1;
+ }
+ }
+ // i = j = wanted index
+
+ TUint32 segLength; // real segment length (not cumulative)
+ if (i > 0)
+ {
+ pos -= iSegmentLengths[i-1]; // position between 0...segment length
+ segLength = iSegmentLengths[i]-iSegmentLengths[i-1];
+ }
+ else
+ {
+ segLength = iSegmentLengths[0]; // we are in first segment
+ }
+
+ TUint32 deltaX, deltaY;
+ // must handle negative values differently
+ TBool xnegative = EFalse;
+ TBool ynegative = EFalse;
+
+ if ( (iPoints[i+1].iX - iPoints[i].iX) < 0)
+ {
+ deltaX = iPoints[i].iX - iPoints[i+1].iX; // max 16 bits
+ xnegative = ETrue;
+ }
+ else
+ {
+ deltaX = iPoints[i+1].iX - iPoints[i].iX; // max 16 bits
+ }
+
+ if ( (iPoints[i+1].iY - iPoints[i].iY) < 0)
+ {
+ deltaY = iPoints[i].iY - iPoints[i+1].iY; // max 16 bits
+ ynegative = ETrue;
+ }
+ else
+ {
+ deltaY = iPoints[i+1].iY - iPoints[i].iY; // max 16 bits
+ }
+
+ TUint32 deltaXpos = ((pos * deltaX) / segLength);
+ TUint32 deltaYpos = ((pos * deltaY) / segLength);
+
+ if (xnegative)
+ {
+ deltaXpos = iPoints[i].iX - deltaXpos;
+ }
+ else
+ {
+ deltaXpos = iPoints[i].iX + deltaXpos;
+ }
+
+ if (ynegative)
+ {
+ deltaYpos = iPoints[i].iY - deltaYpos;
+ }
+ else
+ {
+ deltaYpos = iPoints[i].iY + deltaYpos;
+ }
+
+ return CalculateScaledPoint(TPoint(deltaXpos,deltaYpos));
+ }
+
+// -----------------------------------------------------------------------------
+// Calculates lengths.
+// -----------------------------------------------------------------------------
+//
+void CAknsAlPolyLine::CalculateLengthsL()
+ {
+ // won't get here if not at least 2 points are already set
+ delete [] iSegmentLengths;
+ iSegmentLengths = NULL;
+
+ iSegmentLengths = new (ELeave) TUint32[iPointCount-1];
+
+ TInt32 diffX, diffY;
+
+ TUint32 length = 0; // for holding the cumulative length
+
+ for (TInt i = 0; i < (iPointCount-1); i++)
+ {
+ // Points have their x and y coordinates in form 0.16 (e.g. only decimal
+ // part is set), so there won't be overflow when multiplying. But after
+ // multiply the results can't be added together without a possibility
+ // for overflow. That's why the coordinates are first divided by 2.
+ diffX = (iPoints[i+1].iX - iPoints[i].iX) >> 1; // result can be negative!
+ diffY = (iPoints[i+1].iY - iPoints[i].iY) >> 1; // result can be negative!
+
+ // this is not the actual length, but length/2
+ // length might overflow if the poly has over 60000 segments...
+ length += Sqrt( diffX*diffX + diffY*diffY );
+ iSegmentLengths[i] = length;
+ }
+ }
+
+// End of file