svgtopt/SVG/SVGImpl/src/SVGAnimTimeController.cpp
changeset 46 88edb906c587
equal deleted inserted replaced
-1:000000000000 46:88edb906c587
       
     1 /*
       
     2 * Copyright (c) 2003 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:  SVG Implementation source file
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 #include "SVGAnimTimeController.h"
       
    20 #include "SVGAnimationBase.h"
       
    21 
       
    22 #include "GfxGeneralPath.h"
       
    23 #include "GfxFlatteningPathIterator.h"
       
    24 
       
    25 	#ifdef SVG_FLOAT_BUILD
       
    26 #define MULT255(x) (255*(x))
       
    27 	#else
       
    28 #define MULT255(x) (((x)<<8) - (x))
       
    29 	#endif
       
    30 
       
    31 _LIT( KEmptyString,"" );
       
    32 
       
    33 // ---------------------------------------------------------------------------
       
    34 // Two phase construction
       
    35 // ---------------------------------------------------------------------------
       
    36 CSvgAnimTimeController* CSvgAnimTimeController::NewL()
       
    37     {
       
    38     CSvgAnimTimeController* self = new ( ELeave ) CSvgAnimTimeController();
       
    39     CleanupStack::PushL( self );
       
    40     self->ConstructL();
       
    41     CleanupStack::Pop();
       
    42 
       
    43     return self;
       
    44     }
       
    45 
       
    46 
       
    47 // ---------------------------------------------------------------------------
       
    48 //
       
    49 // ---------------------------------------------------------------------------
       
    50 CSvgAnimTimeController::~CSvgAnimTimeController()
       
    51     {
       
    52 	if ( iKeyTime )
       
    53 		{
       
    54 		iKeyTime->Close();
       
    55 		delete iKeyTime;
       
    56 		iKeyTime = NULL;
       
    57 		}
       
    58 
       
    59     if ( iAnimTime )
       
    60 		{
       
    61 		iAnimTime->Close();
       
    62 		delete iAnimTime;
       
    63 		iAnimTime = NULL;
       
    64 		}
       
    65 
       
    66     if ( iBeginTimeList )
       
    67         {
       
    68         iBeginTimeList->Close();
       
    69         delete iBeginTimeList;
       
    70 		iBeginTimeList = NULL;
       
    71         }
       
    72     if ( iInitialBeginTimeList )
       
    73         {
       
    74         iInitialBeginTimeList->Close();
       
    75         delete iInitialBeginTimeList;
       
    76 		iInitialBeginTimeList = NULL;
       
    77         }
       
    78     if ( iEndTimeList )
       
    79         {
       
    80         iEndTimeList->Close();
       
    81         delete iEndTimeList;
       
    82 		iEndTimeList = NULL;
       
    83         }
       
    84     if ( iInitialEndTimeList )
       
    85         {
       
    86         iInitialEndTimeList->Close();
       
    87         delete iInitialEndTimeList;
       
    88 		iInitialEndTimeList = NULL;
       
    89         }
       
    90     delete iSplines;
       
    91     }
       
    92 
       
    93 // ---------------------------------------------------------------------------
       
    94 //
       
    95 // ---------------------------------------------------------------------------
       
    96 CSvgAnimTimeController::CSvgAnimTimeController() : iCalcMode( KAnimCalcModeLinear ),
       
    97                                                    iBeginTime( 0 ),
       
    98                                                    iInitialBeginTime(0),
       
    99                                                    iDurationTime( KTimeIndefinite ),
       
   100                                                    iEndTime( KTimeIndefinite ),
       
   101                                                    iInitialEndTime(KTimeIndefinite),
       
   102                                                    iRepeatDurationTime( KTimeIndefinite ),
       
   103                                                    iNewActiveDurationTime( 0 ),
       
   104                                                    iSplineIndex( 0 ),
       
   105 												   iModifiedEndTime( 0 ),
       
   106                                                    iIsSplineCalcMode( EFalse )
       
   107     {
       
   108     }
       
   109 
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 // ---------------------------------------------------------------------------
       
   113 void CSvgAnimTimeController::ConstructL()
       
   114     {
       
   115     iKeyTime = new ( ELeave ) RArray<TKeyTime>( 1 );
       
   116     iAnimTime = new ( ELeave ) RArray<TUint32>( 1 );
       
   117     for ( TInt32 i = 0; i < KTimeMax + 1; i++ )
       
   118         {
       
   119         iAnimTime->AppendL(0);
       
   120         }
       
   121     iBeginTimeList = new ( ELeave ) RArray<TInt32>( 1 );
       
   122     iInitialBeginTimeList = new ( ELeave ) RArray<TInt32>( 1 );
       
   123     iEndTimeList = new (ELeave) RArray<TInt32>(1);
       
   124     iInitialEndTimeList = new (ELeave) RArray<TInt32>(1);
       
   125     }
       
   126 
       
   127 
       
   128 // *******************************************************
       
   129 // ---------------------------------------------------------------------------
       
   130 //
       
   131 // ---------------------------------------------------------------------------
       
   132 void CSvgAnimTimeController::SetBeginTime( TInt32 aBeginTime )
       
   133     {
       
   134     iBeginTime = aBeginTime; // msec
       
   135     }
       
   136     
       
   137     
       
   138 
       
   139 void CSvgAnimTimeController::SetOrgDurationTime(TInt32 aValue)
       
   140 {
       
   141 	iOrgDurationTime = aValue;
       
   142 }
       
   143 
       
   144 
       
   145 
       
   146 
       
   147 // ---------------------------------------------------------------------------
       
   148 //
       
   149 // ---------------------------------------------------------------------------
       
   150 void CSvgAnimTimeController::AddBeginTime( TInt32 aBeginTime )
       
   151     {
       
   152        if ( aBeginTime < 0 )
       
   153         {
       
   154             aBeginTime = 0;     //Himanshu: to check the negative begin value
       
   155         }   
       
   156      iBeginTimeList->Append( aBeginTime );
       
   157      iBeginTimeList->SortSigned();
       
   158     }
       
   159 void CSvgAnimTimeController::AddEndTime( TInt32 aEndTime )
       
   160     {
       
   161      iEndTimeList->Append( aEndTime );
       
   162      iEndTimeList->SortSigned();
       
   163      iEndTime = iEndTimeList->operator[](0);
       
   164     }
       
   165 // ---------------------------------------------------------------------------
       
   166 //
       
   167 // ---------------------------------------------------------------------------
       
   168 TUint32 CSvgAnimTimeController::GetBeginTime( TInt32 aIndex )
       
   169     {
       
   170 
       
   171     if(aIndex >= 0 && aIndex < iBeginTimeList->Count())
       
   172 	    {
       
   173 
       
   174 		return (TUint32) (iBeginTimeList->operator[](aIndex));
       
   175     	}
       
   176 	else
       
   177 		{
       
   178 
       
   179 		return 0;
       
   180 
       
   181 	    }
       
   182     }
       
   183 
       
   184 
       
   185 // ---------------------------------------------------------------------------
       
   186 //
       
   187 // ---------------------------------------------------------------------------
       
   188 void CSvgAnimTimeController::ResetBeginTime( TInt32 aBeginTime )
       
   189     {
       
   190     iBeginTime = aBeginTime; // msec
       
   191     }
       
   192 
       
   193 // ---------------------------------------------------------------------------
       
   194 //
       
   195 // ---------------------------------------------------------------------------
       
   196 void CSvgAnimTimeController::SetDurationTime( TInt32 aDurationTime )
       
   197     {
       
   198     iDurationTime = aDurationTime; // msec
       
   199 
       
   200     }
       
   201 
       
   202 // ---------------------------------------------------------------------------
       
   203 //
       
   204 // ---------------------------------------------------------------------------
       
   205 TInt32 CSvgAnimTimeController::GetDurationTime()
       
   206     {
       
   207     return iDurationTime; // msec
       
   208 
       
   209     }
       
   210 
       
   211 // ---------------------------------------------------------------------------
       
   212 //
       
   213 // ---------------------------------------------------------------------------
       
   214 void CSvgAnimTimeController::SetEndTime( TInt32 aEndTime )
       
   215     {
       
   216     iEndTime = aEndTime; // msec
       
   217 	if (aEndTime != (TInt32)KTimeIndefinite)
       
   218 		iModifiedEndTime= aEndTime;
       
   219     }
       
   220 
       
   221 
       
   222 // ---------------------------------------------------------------------------
       
   223 //
       
   224 // ---------------------------------------------------------------------------
       
   225 TInt32 CSvgAnimTimeController::GetEndTime()
       
   226     {
       
   227     return iEndTime; // msec
       
   228 
       
   229     }
       
   230     
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 // ---------------------------------------------------------------------------
       
   234 void CSvgAnimTimeController::SetRepeatDurationTime( TUint32 aRepeatDurationTime )
       
   235     {
       
   236     iRepeatDurationTime = aRepeatDurationTime;
       
   237 
       
   238    }
       
   239 
       
   240 
       
   241 // ---------------------------------------------------------------------------
       
   242 //
       
   243 // ---------------------------------------------------------------------------
       
   244 void CSvgAnimTimeController::GetAnimTime( TInt32 aTimerTime,
       
   245                                           TInt32& aAnimTime,
       
   246                                           TInt32& aValueIndex,
       
   247                                           TInt32& aSubAnimTime )
       
   248     {
       
   249     if(iDurationTime == KTimeIndefinite || iDurationTime == 0)
       
   250         {
       
   251         aValueIndex = 0;
       
   252         aSubAnimTime= 0;
       
   253         aAnimTime=0;
       
   254         return;
       
   255         }
       
   256     TInt32 x = 0;
       
   257 
       
   258     if( iNewActiveDurationTime > 0 )//"repeatDur" <= "Dur"
       
   259 		{
       
   260        	x = MULT255( aTimerTime - iBeginTime ) / iNewActiveDurationTime;
       
   261 		}
       
   262     else
       
   263 		{
       
   264 
       
   265 		x = MULT255( aTimerTime - iBeginTime ) / iDurationTime;
       
   266 
       
   267 		}
       
   268 
       
   269     if ( x > KTimeMax )
       
   270 		{
       
   271         x = KTimeMax;
       
   272 		}
       
   273 	else
       
   274 		{
       
   275 		if ( x < 0 )
       
   276 			{
       
   277 			x = 0;
       
   278 			}
       
   279 		}
       
   280 
       
   281     TInt32 kcount = iKeyTime->Count();
       
   282 
       
   283     if ( kcount == 0 )// || iCalcMode == KAnimCalcModePaced)
       
   284 	    {
       
   285         aValueIndex = 0;
       
   286         aSubAnimTime = 0;
       
   287         aAnimTime = x; //
       
   288         // No keytimes or paced animation
       
   289         if ( iCalcMode == KAnimCalcModeDiscrete )
       
   290             {
       
   291          // From SMIL 2.1 Animation Modules
       
   292          // Normative: Normative: A from-to animation with a from value vf
       
   293          // and a to value vt is equivalent to the same animation with a 
       
   294          // values list with 2 values, vf and vt. 
       
   295  
       
   296             if ( x < KTimeMax / 2 )
       
   297 				{
       
   298                 aAnimTime = 0;
       
   299 				}
       
   300             else
       
   301 				{
       
   302                 aAnimTime = KTimeMax;
       
   303 				}
       
   304             }
       
   305         }
       
   306     else if ( iCalcMode == KAnimCalcModePaced )
       
   307         {
       
   308         aAnimTime = x;
       
   309         TInt32 i = 0;
       
   310         while ( i < kcount && ( *iKeyTime )[i].iY < aAnimTime )
       
   311             i++;
       
   312         if ( i > 0 )
       
   313             i--;
       
   314         aValueIndex = i;
       
   315         // to avoid crashing for the array index aValueIndex + 1
       
   316 		TBool IndexWasDecremented = EFalse;
       
   317         if(aValueIndex + 1 == kcount)
       
   318            	{
       
   319            	 aValueIndex--;
       
   320            	 IndexWasDecremented = ETrue;
       
   321            	}
       
   322         TInt32 dy = ( TInt32 )
       
   323                     ( ( *iKeyTime )[aValueIndex + 1].iY -
       
   324                       ( *iKeyTime )[aValueIndex].iY );
       
   325         if ( dy != 0 )
       
   326             aSubAnimTime = MULT255( aAnimTime - ( *iKeyTime )[aValueIndex].iY ) / dy;
       
   327         else
       
   328             aSubAnimTime = 0;
       
   329 
       
   330 		if(IndexWasDecremented)
       
   331            	{
       
   332            	aValueIndex++;
       
   333            	}
       
   334         }
       
   335     else
       
   336         {
       
   337         // find corresponding keytime index
       
   338         TInt32 i = 0;
       
   339         while ( i < kcount && ( *iKeyTime )[i].iX < x )
       
   340             i++;
       
   341         if ( i > 0 )
       
   342             i--;
       
   343 
       
   344 
       
   345         ///// EXPLICITLY INCREMENT THE aValueIndex TO THE LAST OF THE LIST.
       
   346 
       
   347         if(x == 255)
       
   348 	        {
       
   349 	        aValueIndex = kcount-1;
       
   350 	        }
       
   351 	    else
       
   352 	    	{
       
   353          	aValueIndex = i;
       
   354 	    	}
       
   355 
       
   356 
       
   357         ////////////// END OF ADDITION ///////////////
       
   358 
       
   359         if ( iCalcMode == KAnimCalcModeDiscrete )
       
   360             {
       
   361             if ( x == KTimeMax )
       
   362                 aValueIndex = iKeyTime->Count() - 1;
       
   363             aAnimTime = ( *iKeyTime )[aValueIndex].iY;
       
   364             aSubAnimTime = 0;
       
   365             }
       
   366         else
       
   367             {
       
   368             if ( iCalcMode == KAnimCalcModeLinear )
       
   369                 {
       
   370                 // calcMode:Linear
       
   371 
       
   372 
       
   373 				if(( *iKeyTime )[i].iX == ( *iKeyTime )[i+1].iX)
       
   374 					{
       
   375 					while((i<(kcount-1)) && ( *iKeyTime )[i + 1].iX == ( *iKeyTime )[i].iX )
       
   376 						{
       
   377 						// this will increment the index so that
       
   378 						// the interpolation would be done between the last
       
   379 						// values.
       
   380 						i++;
       
   381 						// count should be less than the total number of elements.
       
   382 						}
       
   383 
       
   384 
       
   385 					}
       
   386 
       
   387 				TInt32 alpha = MULT255( ( TInt32 )
       
   388                                         ( x - ( *iKeyTime )[i].iX ) ) /
       
   389                                ( TInt32 )
       
   390                                ( ( *iKeyTime )[i + 1].iX -
       
   391                                  ( *iKeyTime )[i].iX ) ;
       
   392 
       
   393                 if(x == 255)
       
   394                 	{
       
   395 	             	aAnimTime = 255; // THIS SPECIFIES THAT THE DUR IS COMPLETE.
       
   396 	               	}
       
   397 				else
       
   398 					{
       
   399 
       
   400 					aAnimTime = CSvgAnimationBase::BlendInt( alpha,
       
   401 	                                                         ( *iKeyTime )[i].iY,
       
   402 	                                                         ( *iKeyTime )[i + 1].iY );
       
   403 	                 }
       
   404                 aSubAnimTime = alpha;
       
   405 
       
   406                 }
       
   407             else
       
   408                 {
       
   409                 // calcMode:Spline
       
   410                 TBool IndexWasDecremented = EFalse;
       
   411 				if(aValueIndex + 1 == kcount)
       
   412 					 {
       
   413 					 aValueIndex--;
       
   414 					 IndexWasDecremented = ETrue;
       
   415 					 }
       
   416 				aAnimTime = ( *iAnimTime )[x];
       
   417                 TInt32 ydiff = ( TInt32 )
       
   418                                ( ( *iKeyTime )[aValueIndex + 1].iY -
       
   419                                  ( *iKeyTime )[aValueIndex].iY );
       
   420                 if ( ydiff != 0 )
       
   421 					{
       
   422                     aSubAnimTime = MULT255( aAnimTime -
       
   423                                             ( *iKeyTime )[aValueIndex].iY ) / ydiff;
       
   424 					}
       
   425                 else
       
   426 					 {
       
   427                     aSubAnimTime = 0;
       
   428                 }
       
   429 				// oops increment again if it was decremented.
       
   430 				if(IndexWasDecremented)
       
   431 					 {
       
   432 					 aValueIndex++;
       
   433 					 }
       
   434 
       
   435 
       
   436 
       
   437                 }
       
   438 
       
   439             if ( aAnimTime > KTimeMax )
       
   440 				{
       
   441                 aAnimTime = KTimeMax;
       
   442 				}
       
   443 			else
       
   444 				{
       
   445 				if ( aAnimTime < 0 )
       
   446 					{
       
   447 					aAnimTime = 0;
       
   448 					}
       
   449 				}
       
   450 
       
   451             }
       
   452         }
       
   453     }
       
   454 
       
   455 // *******************************************************
       
   456 // Create keytimes
       
   457 // default is equally deived time
       
   458 // ---------------------------------------------------------------------------
       
   459 //
       
   460 // ---------------------------------------------------------------------------
       
   461 
       
   462 void CSvgAnimTimeController::CreateKeyTime( TInt32 aKeyTimeCount )
       
   463     {
       
   464     // Create keyTime array if not available
       
   465 	TInt lDivider = aKeyTimeCount;
       
   466 	if ( iCalcMode != KAnimCalcModeDiscrete )
       
   467 		{
       
   468 		lDivider--;
       
   469 		}
       
   470 
       
   471     if ( iKeyTime->Count() == 0 && aKeyTimeCount > 0 && lDivider != 0 ) // check to avoid division by zero.
       
   472         {
       
   473         for ( TInt32 i = 0; i < aKeyTimeCount; i++ )
       
   474             {
       
   475 			AddKeyTime( TFloatFixPt( i ) / TFloatFixPt( lDivider ) );
       
   476             }
       
   477         }
       
   478     }
       
   479 
       
   480 void CSvgAnimTimeController::CreateKeyTimeForEnumeration( TInt32 aKeyTimeCount )
       
   481     {
       
   482     // Create keyTime array if not available
       
   483 	// ignore the calc mode specification.
       
   484 
       
   485 	TInt lDivider = aKeyTimeCount - 1;
       
   486     if ( iKeyTime->Count() == 0 && aKeyTimeCount > 0 && lDivider != 0 ) // check to avoid division by zero.
       
   487         {
       
   488         for ( TInt32 i = 0; i < aKeyTimeCount; i++ )
       
   489             {
       
   490 			AddKeyTime( TFloatFixPt( i ) / TFloatFixPt( lDivider ) );
       
   491             }
       
   492         }
       
   493     }
       
   494 
       
   495 // Preparing animation time
       
   496 // this should be called just before animation start
       
   497 // ---------------------------------------------------------------------------
       
   498 //
       
   499 // ---------------------------------------------------------------------------
       
   500 void CSvgAnimTimeController::PrepareTimeL( const RArray<TFloatFixPt>* aValues )
       
   501     {
       
   502     TInt32 i;
       
   503     // set y for each keytime
       
   504     TInt32 count = iKeyTime->Count();
       
   505 
       
   506 	// THIS IS MODIFIED FOR THE BUG FIX.
       
   507     if ( count <= 1)
       
   508 		{
       
   509         return;
       
   510 		}
       
   511 
       
   512     if ( iCalcMode == KAnimCalcModePaced )
       
   513         {
       
   514         if ( aValues == NULL )
       
   515 			{
       
   516             return;
       
   517 			}
       
   518 
       
   519         TInt32 valCount = aValues->Count();
       
   520         if ( valCount != count )
       
   521 			{
       
   522             return; // No animation if values and keytimes has different number of items
       
   523 			}
       
   524 
       
   525         // 'Paced' animation needs unique animation time from
       
   526         //  value difference
       
   527         RArray<TFloatFixPt>* yary = new ( ELeave ) RArray<TFloatFixPt>( 1 ); // SSB was 10
       
   528         CleanupStack::PushL( yary );
       
   529 	
       
   530 				#ifdef SVG_FLOAT_BUILD
       
   531         yary->AppendL( TFloatFixPt( 0.0f ) );
       
   532         TFloatFixPt sum( 0.0f );
       
   533         #else
       
   534         yary->AppendL( TFloatFixPt( 0, ETrue ) );
       
   535         TFloatFixPt sum( 0, ETrue );
       
   536         #endif
       
   537         
       
   538         for ( i = 1; i < valCount; i++ )
       
   539             {
       
   540             TFloatFixPt value = ( *aValues )[i] - ( *aValues )[i - 1];
       
   541             if ( value < TFloatFixPt( 0 ) )
       
   542             	{
       
   543             	value = TFloatFixPt(0) - value;
       
   544             	}
       
   545             yary->AppendL( value );
       
   546             sum += ( *yary )[i];
       
   547             }
       
   548         TFloatFixPt tmax( ( TInt32 ) KTimeMax );
       
   549         ( *iKeyTime )[0].iY = 0;
       
   550 
       
   551 
       
   552 		for ( i = 1; i < valCount; i++ )
       
   553 			{
       
   554 			if( (TReal32)sum != 0) // check to avoid division by zero.
       
   555 				{
       
   556 				( *yary )[i] = ( ( *yary )[i] / sum ) * tmax; // need to make sure value does not exceed 0x7fff
       
   557 				}
       
   558 			else
       
   559 				{
       
   560 				( *yary )[i] = (TFloatFixPt) (0);
       
   561 				}
       
   562 
       
   563 			( *iKeyTime )[i].iY = ( TUint16 )
       
   564 								  ( ( *iKeyTime )[i - 1].iY +
       
   565 									( TUint16 ) ( TInt32 ) ( *yary )[i] );
       
   566 			}
       
   567 		( *iKeyTime )[count - 1].iY = KTimeMax;
       
   568 
       
   569         yary->Close();
       
   570         CleanupStack::PopAndDestroy( 1 ); // yary
       
   571         }
       
   572     else
       
   573 		{
       
   574         for ( i = 0; i < count; i++ )
       
   575             {
       
   576             ( *iKeyTime )[i].iY = ( TUint16 ) ( i * KTimeMax / ( count -1  ) );
       
   577             }
       
   578 		}
       
   579     // interpolate animation time (keySplines)
       
   580     for ( i = 1; i < KTimeMax; i++ )
       
   581         {
       
   582         if ( ( *iAnimTime )[i] == 0 )
       
   583             ( *iAnimTime )[i] = ( *iAnimTime )[i - 1];
       
   584         }
       
   585     }
       
   586 
       
   587 //
       
   588 // ---------------------------------------------------------------------------
       
   589 //
       
   590 // ---------------------------------------------------------------------------
       
   591 void CSvgAnimTimeController::AddKeyTime( TFloatFixPt aTimerTime )
       
   592     {
       
   593     TKeyTime newKeytime;
       
   594     newKeytime.iX = ( TUint16 )
       
   595                     ( ( TInt32 ) ( aTimerTime * TFloatFixPt( KTimeMax ) ) );
       
   596     newKeytime.iY = 0;
       
   597     iKeyTime->Append( newKeytime );
       
   598     }
       
   599 
       
   600 //
       
   601 // This needs 'L' postfix or TRAP
       
   602 // ---------------------------------------------------------------------------
       
   603 //
       
   604 // ---------------------------------------------------------------------------
       
   605 void CSvgAnimTimeController::AddKeySplineL( TFloatFixPt aX1,
       
   606                                             TFloatFixPt aY1,
       
   607                                             TFloatFixPt aX2,
       
   608                                             TFloatFixPt aY2 )
       
   609     {
       
   610     // keySplines must be keyTime-1
       
   611     if ( iSplineIndex >= iKeyTime->Count() - 1 )
       
   612 		{
       
   613         return;
       
   614 		}
       
   615 
       
   616     // Keytime must be set before adding keyspline
       
   617     CGfxGeneralPath* path = CGfxGeneralPath::NewLC();
       
   618 
       
   619     TFloatFixPt x0, y0, x3, y3;
       
   620     x0 = ( TInt32 ) ( *iKeyTime )[iSplineIndex].iX;
       
   621     y0 = ( TInt32 ) ( *iKeyTime )[iSplineIndex].iY;
       
   622     x3 = ( TInt32 )
       
   623          ( ( *iKeyTime )[iSplineIndex + 1].iX -
       
   624            ( *iKeyTime )[iSplineIndex].iX );
       
   625     y3 = ( TInt32 )
       
   626          ( ( *iKeyTime )[iSplineIndex + 1].iY -
       
   627            ( *iKeyTime )[iSplineIndex].iY );
       
   628     aX1 *= x3;
       
   629     aY1 *= y3;
       
   630     aX2 *= x3;
       
   631     aY2 *= y3;
       
   632 
       
   633     path->MoveToL( x0, y0, ETrue );
       
   634     path->CubicToL( aX1, aY1, aX2, aY2, x3, y3, EFalse );
       
   635     TGfxAffineTransform ident;
       
   636 
       
   637     CGfxFlatteningPathIterator* itr = CGfxFlatteningPathIterator::NewL( path,
       
   638                                                                         &ident,
       
   639                                                                         3 );
       
   640 
       
   641     CleanupStack::PushL( itr );
       
   642     TFloatFixPt tmpcoords[6];
       
   643     while ( !itr->IsDone() )
       
   644         {
       
   645         itr->CurrentSegment( tmpcoords );
       
   646         TInt32 x = tmpcoords[0];
       
   647         if ( 0 <= x && x <= 255 )
       
   648             {
       
   649             ( *iAnimTime )[x] = ( TUint8 ) ( TInt32 ) tmpcoords[1];
       
   650             }
       
   651         itr->NextL();
       
   652         }
       
   653 
       
   654     iSplineIndex++;
       
   655     CleanupStack::PopAndDestroy( 2 ); // path, itr
       
   656     }
       
   657 
       
   658 
       
   659 
       
   660 // ---------------------------------------------------------------------------
       
   661 // Functions used by Decoder
       
   662 // ---------------------------------------------------------------------------
       
   663 
       
   664 TInt CSvgAnimTimeController::BeginTimesCount()
       
   665 	{
       
   666 	return iBeginTimeList->Count();
       
   667 	}
       
   668 // ---------------------------------------------------------------------------
       
   669 //
       
   670 // ---------------------------------------------------------------------------
       
   671 void CSvgAnimTimeController::SetBeginTimeList(RArray<TInt32>*& aList)
       
   672 	{
       
   673 	if (iBeginTimeList)
       
   674 		{
       
   675 		iBeginTimeList->Reset();
       
   676 		delete iBeginTimeList;
       
   677 		iBeginTimeList= NULL;
       
   678 		}
       
   679 
       
   680 	iBeginTimeList= aList;
       
   681 	}
       
   682 // ---------------------------------------------------------------------------
       
   683 //
       
   684 // ---------------------------------------------------------------------------
       
   685 void CSvgAnimTimeController::SetKeyTimeArray(RArray<TKeyTime>*& aArray)
       
   686 	{
       
   687 	if (iKeyTime)
       
   688 		{
       
   689 		iKeyTime->Close();
       
   690 		delete iKeyTime;
       
   691 		iKeyTime= NULL;
       
   692 		}
       
   693 
       
   694 	iKeyTime= aArray;
       
   695 	}
       
   696 // ---------------------------------------------------------------------------
       
   697 //
       
   698 // ---------------------------------------------------------------------------
       
   699 void CSvgAnimTimeController::  SetAnimTimeArray(RArray<TUint32>*& aArray)
       
   700 	{
       
   701 	if (iAnimTime)
       
   702 		{
       
   703 		iAnimTime->Close();
       
   704 		delete iAnimTime;
       
   705 		iAnimTime= NULL;
       
   706 		}
       
   707 
       
   708 	iAnimTime= aArray;
       
   709 	}
       
   710 
       
   711 
       
   712 // ---------------------------------------------------------------------------
       
   713 //
       
   714 // ---------------------------------------------------------------------------
       
   715 void CSvgAnimTimeController:: CalculateAnimTimes()
       
   716     {
       
   717     if(iRepeatDurationTime <= iDurationTime   )
       
   718 	    {
       
   719         iNewActiveDurationTime = iDurationTime;
       
   720         iDurationTime = iRepeatDurationTime;
       
   721 
       
   722 	    }
       
   723 	if( iBeginTime == KTimeIndefinite || iRepeatDurationTime == KTimeIndefinite )
       
   724 		{
       
   725 		iEndTime = KTimeIndefinite;
       
   726 		}
       
   727 
       
   728 	}
       
   729 
       
   730 void CSvgAnimTimeController:: SetOriginalValues_DOMReuse()
       
   731     {
       
   732     iOrgEndTime = iEndTime;
       
   733 	iModifiedEndTime= iEndTime;
       
   734     iOrgDurationTime = iDurationTime;
       
   735 	}
       
   736 TUint32 CSvgAnimTimeController::GetOriginalEndTime()
       
   737 {
       
   738 return iOrgEndTime;
       
   739 }
       
   740 void CSvgAnimTimeController:: ReInitialize()
       
   741     {
       
   742      iEndTime = iOrgEndTime;
       
   743 	 iDurationTime = iOrgDurationTime;
       
   744 	}
       
   745 void CSvgAnimTimeController::AddToInitialList(TInt aBeginTime)
       
   746     {
       
   747         if ( aBeginTime < 0 )
       
   748             {
       
   749             aBeginTime = 0;     
       
   750             }   
       
   751      iInitialBeginTimeList->Append( aBeginTime );
       
   752      iInitialBeginTimeList->SortSigned();
       
   753      
       
   754     }
       
   755 void CSvgAnimTimeController:: ReInitializeForSeek()
       
   756     {
       
   757 /*	if (iOrgEndTime == KTimeIndefinite)
       
   758 		{
       
   759 		if( iEndTime == KTimeIndefinite)
       
   760 			{
       
   761             iEndTime= iModifiedEndTime;
       
   762 			}
       
   763 		}
       
   764 	else
       
   765 		{
       
   766 		iEndTime = iOrgEndTime;
       
   767 		}
       
   768 */
       
   769 	iEndTime = iModifiedEndTime;
       
   770 	 iDurationTime = iOrgDurationTime;
       
   771 	}
       
   772 
       
   773 // ---------------------------------------------------------------------------
       
   774 // CSvgAnimTimeController::SetIsSplineCalcMode
       
   775 //  Sets the calc mode to spline mode
       
   776 // ---------------------------------------------------------------------------
       
   777 void CSvgAnimTimeController::SetIsSplineCalcMode( 
       
   778         const TBool aIsSplineCalcMode ) // Boolean indicating calcMode
       
   779     {
       
   780     iIsSplineCalcMode = aIsSplineCalcMode;
       
   781     }
       
   782 
       
   783 
       
   784 // ---------------------------------------------------------------------------
       
   785 // CSvgAnimTimeController::IsSplineCalcMode
       
   786 //  Returns ETrue if the calc mode is in spline mode
       
   787 // ---------------------------------------------------------------------------
       
   788 TBool CSvgAnimTimeController::IsSplineCalcMode() const
       
   789     {
       
   790     return iIsSplineCalcMode;
       
   791     }
       
   792 
       
   793 // ---------------------------------------------------------------------------
       
   794 // CSvgAnimTimeController::SetSplineValueL
       
   795 // Sets the spline parameter string for later processing when calc mode is set
       
   796 // ---------------------------------------------------------------------------
       
   797 void CSvgAnimTimeController::SetSplineValueL( const TDesC& aSplineValue )
       
   798     {
       
   799     iSplines = aSplineValue.AllocL();
       
   800     }
       
   801 
       
   802 // ---------------------------------------------------------------------------
       
   803 // CSvgAnimTimeController::SplineValue
       
   804 //  Returns the string corresponding to the Spline parameters.
       
   805 // ---------------------------------------------------------------------------
       
   806 TPtrC CSvgAnimTimeController::SplineValue() const
       
   807     {
       
   808     if ( iSplines )
       
   809         {
       
   810         return iSplines->Des();
       
   811         }
       
   812     else
       
   813         {
       
   814         TPtrC lRetVal;
       
   815         lRetVal.Set( KEmptyString );
       
   816         return lRetVal;
       
   817         }
       
   818     }
       
   819 
       
   820 void CSvgAnimTimeController::GetAnimTimeForEnumeration( TInt32 aTimerTime,
       
   821                                           TInt32& aAnimTime,
       
   822                                           TInt32& aValueIndex,
       
   823                                           TBool aKeyTimesPresent
       
   824                                            )
       
   825     {
       
   826 
       
   827 	// This function is specifically for enumerations. i.e. "strings"
       
   828 	// remember that these attributes  {"strings"} can not be interpolated
       
   829 	// linearly so the calc mode for these should be
       
   830 	// discrete irrespective of what is specified in the .svg file.
       
   831 
       
   832 
       
   833 	// THE following code supports only "discrete" calc mode.
       
   834 
       
   835 	if(  iDurationTime == KTimeIndefinite || iDurationTime == 0)
       
   836         {
       
   837         aValueIndex = 0;
       
   838         aAnimTime=0;
       
   839         return;
       
   840         }
       
   841     TInt32 x;
       
   842 
       
   843     if( iNewActiveDurationTime > 0 )//"repeatDur" <= "Dur"
       
   844 		{
       
   845        	x = MULT255( aTimerTime - iBeginTime ) / iNewActiveDurationTime;
       
   846 		}
       
   847     else
       
   848 		{
       
   849 
       
   850 	   	x = MULT255( aTimerTime - iBeginTime ) / iDurationTime;
       
   851 
       
   852 		}
       
   853 
       
   854     if ( x > KTimeMax )
       
   855 		{
       
   856         x = KTimeMax;
       
   857 		}
       
   858 	else
       
   859 		{
       
   860 		if ( x < 0 )
       
   861 			{
       
   862 			x = 0;
       
   863 			}
       
   864 		}
       
   865 
       
   866     TInt32 kcount = iKeyTime->Count();
       
   867 
       
   868     if ( kcount == 0 )
       
   869 	    {
       
   870         aValueIndex = 0;
       
   871         aAnimTime = x; //
       
   872         // No keytimes or paced animation
       
   873            if ( x < KTimeMax / 2 )
       
   874 				{
       
   875                 aAnimTime = 0;
       
   876 				}
       
   877             else
       
   878 				{
       
   879                 aAnimTime = KTimeMax;
       
   880 				}
       
   881 
       
   882         }
       
   883      else
       
   884         {
       
   885         // find corresponding keytime index
       
   886         TInt32 i = 0;
       
   887 		// earlier the last one was getting missed. this is specifically for
       
   888 		// "string" data types.
       
   889         while ( i < kcount && ( *iKeyTime )[i].iX <= x )
       
   890 			{
       
   891             i++;
       
   892 			}
       
   893         if ( i > 0 )
       
   894 			{
       
   895 			i--;
       
   896 			}
       
   897 
       
   898 			/// PROPAGATE THE CHANGES TO THIS PLACE ALSO.
       
   899         if(x == 255)
       
   900 	        {
       
   901 	        aValueIndex = kcount-1;
       
   902 	        }
       
   903 	    else
       
   904 	    	{
       
   905          	aValueIndex = i;
       
   906 	    	}
       
   907 	    	////// END OF ADDITION.
       
   908 
       
   909 		if(i == (kcount-1))
       
   910 			{
       
   911 			i--;
       
   912 			}
       
   913 		// do not go down if "keyTimes" is specified in the file.
       
   914 
       
   915         if(aKeyTimesPresent)
       
   916 	        {
       
   917 	        return;
       
   918 	        }
       
   919 
       
   920 		///come to this place if keyTimes is not present.
       
   921 		TInt32 alpha  = MULT255( ( TInt32 )
       
   922 	                                        ( x - ( *iKeyTime )[i].iX ) ) /
       
   923 	                               ( TInt32 )
       
   924 	                               ( ( *iKeyTime )[i + 1].iX -
       
   925 	                                 ( *iKeyTime )[i].iX ) ;
       
   926 
       
   927 
       
   928 
       
   929 		// gives you AnimTime between 0-255 , this is used when KeyTimes is not
       
   930 		// explicitly specified in the .svg file.
       
   931 		aAnimTime = CSvgAnimationBase::BlendInt( alpha,
       
   932                                                          ( *iKeyTime )[i].iY,
       
   933                                                          ( *iKeyTime )[i + 1].iY );
       
   934 
       
   935 
       
   936 		if(aAnimTime > KTimeMax)
       
   937 			aAnimTime = KTimeMax;
       
   938         if(aAnimTime < 0)
       
   939 			aAnimTime = 0;
       
   940 
       
   941         }
       
   942     }
       
   943 
       
   944 //////////////////////////////////////
       
   945 void CSvgAnimTimeController::CopyL(CSvgAnimTimeController* newElement)
       
   946 {
       
   947 	if(newElement)
       
   948 		{
       
   949 		newElement->iCalcMode = iCalcMode;
       
   950 		newElement->iBeginTime = iBeginTime;
       
   951 		newElement->iDurationTime = iDurationTime;
       
   952 		newElement->iOrgDurationTime = iOrgDurationTime;
       
   953 		newElement->iEndTime = iEndTime;
       
   954 		newElement->iOrgEndTime = iOrgEndTime;
       
   955 		newElement->iRepeatDurationTime = iRepeatDurationTime;
       
   956 		newElement->iNewActiveDurationTime = iNewActiveDurationTime;
       
   957 		newElement->iSplineIndex = iSplineIndex;
       
   958 		newElement->iModifiedEndTime = iModifiedEndTime;
       
   959         newElement->iIsSplineCalcMode = EFalse;
       
   960         newElement->iSplines = NULL; // There is no parsing later
       
   961 		TInt Count= iKeyTime->Count();
       
   962 		newElement->iKeyTime->Reset();
       
   963 		for(TInt i=0; i<Count; i++)
       
   964             {
       
   965             newElement->iKeyTime->AppendL(this->iKeyTime->operator[](i));
       
   966             }
       
   967         TInt Count2= iAnimTime->Count();
       
   968         newElement->iAnimTime->Reset();
       
   969         for(TInt i2=0; i2<Count2; i2++)
       
   970             {
       
   971             newElement->iAnimTime->AppendL(this->iAnimTime->operator[](i2));
       
   972             }
       
   973         TInt Count3= iBeginTimeList->Count();
       
   974         newElement->iBeginTimeList->Reset();
       
   975         for(TInt i3=0; i3<Count3; i3++)
       
   976             {
       
   977             newElement->iBeginTimeList->AppendL(this->iBeginTimeList->operator[](i3));
       
   978             }
       
   979 		}
       
   980 
       
   981 }
       
   982 void CSvgAnimTimeController:: SetModifiedEndTime(TUint32 aTime)
       
   983     {
       
   984 	if(aTime >= iBeginTime)
       
   985 	    iModifiedEndTime = aTime;
       
   986 	else
       
   987 	    iModifiedEndTime = iBeginTime;
       
   988 
       
   989 	}
       
   990 
       
   991 void CSvgAnimTimeController:: Reset()
       
   992     {
       
   993    // iEndTime = iModifiedEndTime;
       
   994 
       
   995    if(iOrgEndTime == KTimeIndefinite)
       
   996 		{
       
   997 		iEndTime = iModifiedEndTime;
       
   998 		}
       
   999 	else
       
  1000 		{
       
  1001 		iEndTime= iOrgEndTime;
       
  1002 		}
       
  1003 	 iDurationTime = iOrgDurationTime ;
       
  1004 
       
  1005 
       
  1006 	}
       
  1007 void CSvgAnimTimeController:: SetEndTimesIndefinite()
       
  1008     {
       
  1009 	iModifiedEndTime = KTimeIndefinite;
       
  1010 	iEndTime = KTimeIndefinite;
       
  1011 	}
       
  1012 void CSvgAnimTimeController::GetNextEndTime(TInt32 aBeginTime)
       
  1013     {
       
  1014     // this is similar to adobe.
       
  1015 	TInt lCount = iEndTimeList->Count();
       
  1016 	for(TInt i=0; i<lCount; i++)
       
  1017 		{
       
  1018 		if(iEndTimeList->operator[](i) >= aBeginTime)
       
  1019 			{
       
  1020 		 	iEndTime = iEndTimeList->operator[](i);
       
  1021 		 	return;
       
  1022 			}
       
  1023 		}
       
  1024 	iEndTime = KTimeIndefinite;
       
  1025 	}
       
  1026 void CSvgAnimTimeController::SetNextBeginTime(TInt32 aCurTime)
       
  1027     {
       
  1028     // Initially begintime is indefinite
       
  1029     // checking beginlist
       
  1030     if( aCurTime == KTimeIndefinite && iBeginTimeList->Count() > 0)
       
  1031         {
       
  1032         iBeginTime = iBeginTimeList->operator[](0);
       
  1033         }
       
  1034     // pick the begin time that is greater than the time passed
       
  1035     else
       
  1036         {
       
  1037         TInt lCount = iBeginTimeList->Count();
       
  1038     	for(TInt i=0; i<lCount; i++)
       
  1039     		{
       
  1040     		if(iBeginTimeList->operator[](i) >= aCurTime)
       
  1041     			{
       
  1042     		 	iBeginTime = iBeginTimeList->operator[](i);
       
  1043     		 	return;
       
  1044     			}
       
  1045     		}
       
  1046     	
       
  1047     	iBeginTime = KTimeIndefinite;
       
  1048 	    }
       
  1049 	}
       
  1050 	
       
  1051 void CSvgAnimTimeController::SaveEndTime()	
       
  1052     {
       
  1053     iInitialEndTime = iEndTime;
       
  1054     iInitialEndTimeList->Reset();
       
  1055     for(TInt i=0; i<iEndTimeList->Count(); i++)
       
  1056         {
       
  1057         iInitialEndTimeList->Append(iEndTimeList->operator[](i));
       
  1058         }
       
  1059     }
       
  1060 void CSvgAnimTimeController::SaveBeginTime()
       
  1061     {
       
  1062     iInitialBeginTime = iBeginTime;
       
  1063     iInitialBeginTimeList->Reset();
       
  1064     for(TInt i =0; i<iBeginTimeList->Count(); i++)
       
  1065         {
       
  1066         iInitialBeginTimeList->Append(iBeginTimeList->operator[](i));
       
  1067         }
       
  1068     }
       
  1069 void CSvgAnimTimeController::ResetEndTime()
       
  1070     {
       
  1071 
       
  1072     iEndTime = iInitialEndTime;
       
  1073     iModifiedEndTime = iInitialEndTime;
       
  1074     
       
  1075     iEndTimeList->Reset();
       
  1076     
       
  1077     for(TInt i=0; i<iInitialEndTimeList->Count();i++)
       
  1078         {
       
  1079         iEndTimeList->Append(iInitialEndTimeList->operator[](i));
       
  1080         }
       
  1081     }
       
  1082 void CSvgAnimTimeController::ResetBeginTime()
       
  1083     {
       
  1084     iBeginTime = iInitialBeginTime;
       
  1085     iBeginTimeList->Reset();
       
  1086     for(TInt i=0; i<iInitialBeginTimeList->Count();i++)
       
  1087         {
       
  1088         iBeginTimeList->Append(iInitialBeginTimeList->operator[](i));
       
  1089         }
       
  1090     }
       
  1091 TInt32 CSvgAnimTimeController::LastEndTime()
       
  1092     {
       
  1093     if(iEndTimeList)
       
  1094         {
       
  1095         if(iEndTimeList->Count())
       
  1096             {
       
  1097             return iEndTimeList->operator[](iEndTimeList->Count() - 1);
       
  1098             }
       
  1099         else
       
  1100             {
       
  1101             return KTimeIndefinite;
       
  1102             }    
       
  1103         }
       
  1104     else
       
  1105         {
       
  1106         return KTimeIndefinite;
       
  1107         }
       
  1108     }
       
  1109 TInt32 CSvgAnimTimeController::LastBeginTime()
       
  1110     {
       
  1111     if(iBeginTimeList)
       
  1112         {
       
  1113         if(iBeginTimeList->Count())
       
  1114             {
       
  1115             return iBeginTimeList->operator[](iBeginTimeList->Count() - 1);
       
  1116             }
       
  1117         else
       
  1118             {
       
  1119             return KTimeIndefinite;
       
  1120             } 
       
  1121         }
       
  1122     else
       
  1123         {
       
  1124         return KTimeIndefinite;
       
  1125         }
       
  1126     }
       
  1127