skins/AknSkins/polysrc/AknsAlPolyLine.cpp
changeset 0 05e9090e2422
equal deleted inserted replaced
-1:000000000000 0:05e9090e2422
       
     1 /*
       
     2 * Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Poly line class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "AknsAlPolyLine.h"
       
    20 
       
    21 // -----------------------------------------------------------------------------
       
    22 // C++ constructor.
       
    23 // -----------------------------------------------------------------------------
       
    24 //
       
    25 CAknsAlPolyLine::CAknsAlPolyLine()
       
    26     {
       
    27     }
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // Destructor.
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 CAknsAlPolyLine::~CAknsAlPolyLine()
       
    34     {
       
    35     delete [] iSegmentLengths;
       
    36     iSegmentLengths = NULL;
       
    37     }
       
    38 
       
    39 // -----------------------------------------------------------------------------
       
    40 // Symbian 1st phase constructor.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 CAknsAlPolyLine* CAknsAlPolyLine::NewL()
       
    44     { // static
       
    45     CAknsAlPolyLine* self=new(ELeave) CAknsAlPolyLine();
       
    46     return self;
       
    47     }
       
    48 
       
    49 // -----------------------------------------------------------------------------
       
    50 // Gets poly point.
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 TPoint CAknsAlPolyLine::GetPolyPoint( const TUint32 aPosition )
       
    54     {
       
    55     // aPosition is 32 bit integer representing range 0...1
       
    56 #if (defined(__SERIES60_26__) || defined(__SERIES60_27__) || defined(__SERIES60_28__))
       
    57     TInt64 aa;
       
    58     aa.Set(0,aPosition);
       
    59     TInt64 bb;
       
    60     bb.Set(0,iSegmentLengths[iPointCount-2]);
       
    61     TInt64 pos64 = aa*bb;
       
    62     TUint32 pos = (TUint32)pos64.High(); // same as pos64 >> 32
       
    63 #else // 3.0 or newer
       
    64     TUint64 pos64 = TUint64(aPosition) * TUint64(iSegmentLengths[iPointCount-2]);
       
    65     TUint32 pos = pos64 >> 32;
       
    66 #endif
       
    67     // because of possible rounding errors, first check for last pixel
       
    68     if (pos >= iSegmentLengths[iPointCount-2])
       
    69         {
       
    70         return TPoint(iPoints[iPointCount-1].iX,
       
    71                       iPoints[iPointCount-1].iY);
       
    72         }
       
    73 
       
    74     // find the segment, where pos is pointing
       
    75     TInt i = 0; // first index
       
    76     TInt j = iPointCount-2; // last index
       
    77     TInt k;
       
    78     while ( i < j )
       
    79         {
       
    80         k = (i + j)/2;
       
    81         if ( pos < iSegmentLengths[k] )
       
    82             {
       
    83             j = k;
       
    84             }
       
    85         else
       
    86             {
       
    87             i = k + 1;
       
    88             }
       
    89         }
       
    90     // i = j = wanted index
       
    91 
       
    92     TUint32 segLength; // real segment length (not cumulative)
       
    93     if (i > 0)
       
    94         {
       
    95         pos -= iSegmentLengths[i-1]; // position between 0...segment length
       
    96         segLength = iSegmentLengths[i]-iSegmentLengths[i-1];
       
    97         }
       
    98     else
       
    99         {
       
   100         segLength =  iSegmentLengths[0]; // we are in first segment
       
   101         }
       
   102 
       
   103     TUint32 deltaX, deltaY;
       
   104     // must handle negative values differently
       
   105     TBool xnegative = EFalse;
       
   106     TBool ynegative = EFalse;
       
   107 
       
   108     if ( (iPoints[i+1].iX - iPoints[i].iX) < 0)
       
   109         {
       
   110         deltaX = iPoints[i].iX - iPoints[i+1].iX; // max 16 bits
       
   111         xnegative = ETrue;
       
   112         }
       
   113     else
       
   114         {
       
   115         deltaX = iPoints[i+1].iX - iPoints[i].iX; // max 16 bits
       
   116         }
       
   117 
       
   118     if ( (iPoints[i+1].iY - iPoints[i].iY) < 0)
       
   119         {
       
   120         deltaY = iPoints[i].iY - iPoints[i+1].iY; // max 16 bits
       
   121         ynegative = ETrue;
       
   122         }
       
   123     else
       
   124         {
       
   125         deltaY = iPoints[i+1].iY - iPoints[i].iY; // max 16 bits
       
   126         }
       
   127 
       
   128     TUint32 deltaXpos = ((pos * deltaX) / segLength);
       
   129     TUint32 deltaYpos = ((pos * deltaY) / segLength);
       
   130 
       
   131     if (xnegative)
       
   132         {
       
   133         deltaXpos = iPoints[i].iX - deltaXpos;
       
   134         }
       
   135     else
       
   136         {
       
   137         deltaXpos = iPoints[i].iX + deltaXpos;
       
   138         }
       
   139 
       
   140     if (ynegative)
       
   141         {
       
   142         deltaYpos = iPoints[i].iY - deltaYpos;
       
   143         }
       
   144     else
       
   145         {
       
   146         deltaYpos = iPoints[i].iY + deltaYpos;
       
   147         }
       
   148 
       
   149     return CalculateScaledPoint(TPoint(deltaXpos,deltaYpos));
       
   150     }
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // Calculates lengths.
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 void CAknsAlPolyLine::CalculateLengthsL()
       
   157     {
       
   158     // won't get here if not at least 2 points are already set
       
   159     delete [] iSegmentLengths;
       
   160     iSegmentLengths = NULL;
       
   161 
       
   162     iSegmentLengths = new (ELeave) TUint32[iPointCount-1];
       
   163 
       
   164     TInt32 diffX, diffY;
       
   165 
       
   166     TUint32 length = 0; // for holding the cumulative length
       
   167 
       
   168     for (TInt i = 0; i < (iPointCount-1); i++)
       
   169         {
       
   170         // Points have their x and y coordinates in form 0.16 (e.g. only decimal
       
   171         // part is set), so there won't be overflow when multiplying. But after
       
   172         // multiply the results can't be added together without a possibility
       
   173         // for overflow. That's why the coordinates are first divided by 2.
       
   174         diffX = (iPoints[i+1].iX - iPoints[i].iX) >> 1; // result can be negative!
       
   175         diffY = (iPoints[i+1].iY - iPoints[i].iY) >> 1; // result can be negative!
       
   176 
       
   177         // this is not the actual length, but length/2
       
   178         // length might overflow if the poly has over 60000 segments...
       
   179         length += Sqrt( diffX*diffX + diffY*diffY );
       
   180         iSegmentLengths[i] = length;
       
   181         }
       
   182     }
       
   183 
       
   184 // End of file