svgtopt/SVG/SVGImpl/src/SVGAnimTimingParser.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 <e32svr.h>
       
    20 
       
    21 #include "SVGAnimTimingParser.h"
       
    22 #include "SVGStringTokenizer.h"
       
    23 #include "SVGAnimationBase.h"
       
    24 
       
    25 #include "SVGTokenizer.h"
       
    26 _LIT( KTextRepeat, "repeat" );
       
    27 
       
    28 // ---------------------------------------------------------------------------
       
    29 // Two phase construction
       
    30 // ---------------------------------------------------------------------------
       
    31 CSvgAnimTimingParser* CSvgAnimTimingParser::NewL( const TDesC& aTimingDes, CSvgElementImpl* aElement )
       
    32     {
       
    33     CSvgAnimTimingParser* self = NewLC( aTimingDes, aElement );
       
    34     CleanupStack::Pop();
       
    35     return self;
       
    36     }
       
    37 //
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 // ---------------------------------------------------------------------------
       
    41 CSvgAnimTimingParser* CSvgAnimTimingParser::NewLC( const TDesC& aTimingDes, CSvgElementImpl* aElement )
       
    42     {
       
    43     CSvgAnimTimingParser* self = new ( ELeave ) CSvgAnimTimingParser();
       
    44     CleanupStack::PushL( self );
       
    45     self->ConstructL( aTimingDes, aElement );
       
    46     return self;
       
    47     }
       
    48 
       
    49 //
       
    50 // ---------------------------------------------------------------------------
       
    51 //
       
    52 // ---------------------------------------------------------------------------
       
    53 CSvgAnimTimingParser::CSvgAnimTimingParser() : iTimingDes( NULL, 0 )
       
    54     {
       
    55 
       
    56     }
       
    57 
       
    58 //
       
    59 // ---------------------------------------------------------------------------
       
    60 //
       
    61 // ---------------------------------------------------------------------------
       
    62 void CSvgAnimTimingParser::ConstructL( const TDesC& aTimingDes, CSvgElementImpl* aElement )
       
    63     {
       
    64     // Copy Timing descriptor and trim all spaces
       
    65     iBuf = HBufC::NewL( aTimingDes.Length() );
       
    66     *iBuf = aTimingDes; // copy data
       
    67     iTimingDes.Set( iBuf->Des() );
       
    68     iTimingDes.TrimAll();
       
    69     iElement = aElement;
       
    70     }
       
    71 
       
    72 // ---------------------------------------------------------------------------
       
    73 //
       
    74 // ---------------------------------------------------------------------------
       
    75 CSvgAnimTimingParser::~CSvgAnimTimingParser()
       
    76     {
       
    77     delete iBuf;
       
    78     iBuf = NULL;
       
    79     }
       
    80 
       
    81 
       
    82 //***************************************************************
       
    83 // 'begin' and 'end' attribute parser
       
    84 // ---------------------------------------------------------------------------
       
    85 //
       
    86 // ---------------------------------------------------------------------------
       
    87 void CSvgAnimTimingParser::Parse( TDes& aIdValue,
       
    88                                   TSvgEvent& aEvent,
       
    89                                   TInt32& aClockValue,
       
    90                                   TReal32& aRepeatValue,
       
    91                                   TBool aBeginAttribute )
       
    92     {
       
    93     // Init value
       
    94     aEvent = ESvgEventNone;
       
    95     aClockValue = 0;
       
    96     aRepeatValue = 0;
       
    97 
       
    98     TLex lex( iTimingDes );
       
    99     
       
   100     lex.SkipSpace();
       
   101     
       
   102     // Check if Offset-value only
       
   103     if ( lex.Peek() == '+' || lex.Peek() == '-' || lex.Peek().IsDigit() || lex.Peek() == '.' )
       
   104         {
       
   105         lex.SkipSpace();
       
   106         ParseClockValue( lex, aClockValue );
       
   107         aEvent = ESvgEventNone;
       
   108         return;
       
   109         }
       
   110 
       
   111     // Parse first token
       
   112     lex.Mark();
       
   113     SkipAlphaNumeric( lex );
       
   114     TPtrC firstToken = lex.MarkedToken();
       
   115     // Checks if the first part of the begin attribute is an event
       
   116     TSvgEvent event = DesToEventId( firstToken );
       
   117 
       
   118     if ( event == ESvgEventNone )
       
   119         {
       
   120         if ( firstToken == _L( "accessKey" ) )
       
   121             {
       
   122             // accessKey(x)
       
   123             aEvent = ESvgEventKey;
       
   124             //Skip any spaces between "Access Key" and opening Brace "("
       
   125             lex.SkipSpace();
       
   126             //Get automatically moves the pointer to the next character
       
   127             TChar openBraces = lex.Get();
       
   128             //If the next character is opening brace then continue
       
   129             if(openBraces == '(')
       
   130                 {
       
   131                     TChar curValue = 0;
       
   132                     TInt inc=0;
       
   133                     
       
   134                     //inc checks how many chars are there between opening and closing braces
       
   135                     // it is needed to ensure only one char is there between "(" and ")"
       
   136                     do
       
   137                     {
       
   138                         inc++;
       
   139                         //If there are more than one char between "(" and ")" exit
       
   140                         if(inc >1)
       
   141                             break;
       
   142                         //Move to the next char
       
   143                         curValue = lex.Peek();
       
   144                         lex.Inc();
       
   145                     }while(lex.Peek() != ')');
       
   146                     
       
   147                     //assign cur value to access key if no of chars between "(" and ")" is 1 
       
   148                     if(inc == 1)
       
   149                     {
       
   150                         iAccessKeyValue = curValue;    
       
   151                     }
       
   152                     
       
   153                    if ( lex.Peek() == ')' ) 
       
   154                     {
       
   155                     lex.Inc();
       
   156                     }
       
   157                    // if some offset value is given with accesskey then parse it. 
       
   158                    ParseClockValue( lex, aClockValue ); 
       
   159                     
       
   160                 }
       
   161             }
       
   162         else if ( firstToken == KTextRepeat )
       
   163             {
       
   164             // repeat(x) without Id-value
       
   165             // Not yet supported
       
   166             aEvent = ESvgEventRepeatEvent;
       
   167             }
       
   168         else if ( firstToken == _L( "wallclock" ) )
       
   169             {
       
   170             // wallclock(....)
       
   171             // Not yet supported
       
   172             aEvent = ESvgEventWallClock;
       
   173             }
       
   174         else //
       
   175             {
       
   176                 // The first token was 'id'. Parse next token as event
       
   177             if ( lex.Peek() != '.')
       
   178 				{
       
   179 				// This is not a valid begin value
       
   180 				aEvent = ESvgEventNone;
       
   181 				aIdValue = _L("");
       
   182 				aClockValue= KTimeIndefinite; // same as KTimeIndefinite
       
   183 				return;
       
   184 				}
       
   185             lex.Inc();      // skip '.': no space allowed between id, '.', and event
       
   186 			lex.Mark();
       
   187             aIdValue = firstToken;      // copy token string
       
   188 
       
   189             SkipAlphaNumeric( lex );
       
   190             TPtrC secondToken = lex.MarkedToken();
       
   191 
       
   192             // What if the event is not clearly mentioned
       
   193             aEvent = DesToEventId( secondToken );
       
   194             if(aEvent != ESvgEventNone)
       
   195             	{
       
   196 			if ( secondToken == KTextRepeat )
       
   197                 {
       
   198                 // repeat(x) with Id-value
       
   199 
       
   200              	((CSvgAnimationBase*)iElement)->StoreRepeatId(firstToken, aBeginAttribute);
       
   201 
       
   202                 aEvent = ESvgEventRepeatEvent;
       
   203 				// TChar tmpchar = lex.Peek();
       
   204                 if ( lex.Peek() == '(' )
       
   205                     {
       
   206                     lex.Inc();
       
   207                     if (lex.Val(aRepeatValue, '.' )!= KErrNone)
       
   208 						{
       
   209 						    if(lex.Val(aRepeatValue) != KErrNone )
       
   210 						aRepeatValue=1;
       
   211 						}
       
   212                         lex.Inc();
       
   213                     }
       
   214 
       
   215                 }
       
   216                 ParseClockValue( lex, aClockValue );
       
   217             }
       
   218 	         else
       
   219 	         	{
       
   220 	         	// this is not a valid begin value;
       
   221 	         	aEvent = ESvgEventNone;
       
   222 				aIdValue = _L("");
       
   223 				aClockValue= KTimeIndefinite; // same as KTimeIndefinite
       
   224 				return;
       
   225 	         	}
       
   226 
       
   227             }
       
   228         }
       
   229     else
       
   230         {
       
   231         // Event without id
       
   232         aEvent = event;
       
   233 //        TPtrC tempToken = lex.MarkedToken();
       
   234         ParseClockValue( lex, aClockValue );
       
   235 //        aClockValue = 0;
       
   236         }
       
   237     }
       
   238 
       
   239 //***************************************************************
       
   240 // Private methods
       
   241 
       
   242 // ---------------------------------------------------------------------------
       
   243 // Parse clock value
       
   244 // ---------------------------------------------------------------------------
       
   245 void CSvgAnimTimingParser::ParseClockValue( TLex& aLex, TInt32& aClockValue )
       
   246     {
       
   247     TReal32 value = 0;
       
   248 
       
   249 	aLex.SkipSpaceAndMark();
       
   250 	
       
   251 	TBool wasAddition = ETrue;
       
   252 	
       
   253 	if (aLex.Peek() == '+')
       
   254 	{
       
   255 		aLex.Inc();
       
   256 		aLex.Mark();
       
   257 		aLex.SkipSpaceAndMark();	
       
   258 	}
       
   259 	else if (aLex.Peek() == '-')
       
   260 	{
       
   261 		wasAddition = EFalse;
       
   262 		aLex.Inc();
       
   263 		aLex.Mark();
       
   264 		aLex.SkipSpaceAndMark();
       
   265 	}
       
   266 	
       
   267 	TTokenizer tokenizer( aLex.Remainder() );
       
   268 	
       
   269     // blank, setting to zero
       
   270     if ( tokenizer.IsAtEnd() )
       
   271         {
       
   272         aClockValue = 0;
       
   273         }
       
   274     else if ( tokenizer.SkipDecimal() )
       
   275         {
       
   276         // Decimal number , extract it
       
   277         TPtrC decimalString = tokenizer.SkippedString();
       
   278         TLex lex( decimalString );
       
   279         // Specify the decimal seperator, instead of using
       
   280         // locale specific seperator.        
       
   281         lex.Val( value, '.' );
       
   282         
       
   283         tokenizer.SkipWhiteSpace();
       
   284         // Get the units
       
   285         TPtrC remainder = tokenizer.Remainder();
       
   286         // millseconds
       
   287         if ( remainder == _L( "ms" ) )
       
   288             {
       
   289             aClockValue = value;
       
   290             
       
   291             if (!wasAddition)
       
   292             aClockValue = 0 - aClockValue;
       
   293             }
       
   294         // seconds: implied or 's'
       
   295         else if ( remainder.Length() == 0 || remainder == _L( "s" ) )
       
   296             {
       
   297             aClockValue = value * 1000;
       
   298             
       
   299             if (!wasAddition)
       
   300             aClockValue = 0 - aClockValue;
       
   301             }
       
   302         // anything else is invalid
       
   303         else
       
   304             {
       
   305             aClockValue = KTimeIndefinite;
       
   306             }
       
   307         }
       
   308     // invalid
       
   309     else
       
   310         {
       
   311         aClockValue = KTimeIndefinite;
       
   312         }
       
   313     }
       
   314 
       
   315 //
       
   316 // ---------------------------------------------------------------------------
       
   317 //
       
   318 // ---------------------------------------------------------------------------
       
   319 void CSvgAnimTimingParser::SkipUntilNumEnd( TLex& aLex )
       
   320     {
       
   321     TChar tmpchar = aLex.Peek();
       
   322     while ( tmpchar.IsDigit() || tmpchar == '.' )
       
   323 		{
       
   324         tmpchar = aLex.Get();
       
   325 		}
       
   326 
       
   327     if ( !aLex.Eos() && (aLex.Offset() > 0) )
       
   328 		{
       
   329         aLex.UnGet();
       
   330 		}
       
   331     }
       
   332 
       
   333 // ---------------------------------------------------------------------------
       
   334 //
       
   335 // ---------------------------------------------------------------------------
       
   336 void CSvgAnimTimingParser::SkipAlphaNumeric( TLex& aLex )
       
   337     {
       
   338     TChar tmpchar = aLex.Peek();
       
   339     while ( tmpchar.IsAlphaDigit() || tmpchar == '_' || tmpchar == '-' )
       
   340 		{
       
   341         tmpchar = aLex.Get();
       
   342 		}
       
   343     if ( !aLex.Eos() && (aLex.Offset() > 0) )
       
   344 		{
       
   345         aLex.UnGet();
       
   346 		}
       
   347     }
       
   348 
       
   349 // ---------------------------------------------------------------------------
       
   350 //
       
   351 // ---------------------------------------------------------------------------
       
   352 TSvgEvent CSvgAnimTimingParser::DesToEventId( const TDesC& aEventDes )
       
   353     {
       
   354     // 'begin' matches with 'begineEvent' and 'end' matches with 'endEvent'
       
   355 
       
   356     if ( aEventDes == _L("begin") )
       
   357 		{
       
   358 		return ESvgEventBeginEvent;
       
   359 		}
       
   360 	else if ( aEventDes == _L("end") )
       
   361 		{
       
   362 		return ESvgEventEndEvent;
       
   363 		}
       
   364 	else if ( aEventDes == _L("repeat") )
       
   365 		{
       
   366 		return ESvgEventRepeatEvent;
       
   367 		}
       
   368 	else if ( aEventDes == _L("focusin") )
       
   369 		{
       
   370 		return ESvgEventFocusin;
       
   371 		}
       
   372 	else if ( aEventDes == _L("focusout") )
       
   373 		{
       
   374 		return ESvgEventFocusout;
       
   375 		}
       
   376 	else if ( aEventDes == _L("activate") )
       
   377 		{
       
   378 		return ESvgEventActivate;
       
   379 		}
       
   380 	else if ( aEventDes == _L("click") )
       
   381 		{
       
   382 		return ESvgEventClick;
       
   383 		}
       
   384 	else if ( aEventDes == _L("mousedown") )
       
   385 		{
       
   386 		return ESvgEventMousedown;
       
   387 		}
       
   388 	else if ( aEventDes == _L("mouseup") )
       
   389 		{
       
   390 		return ESvgEventMouseup;
       
   391 		}
       
   392 	else if ( aEventDes == _L("mouseover") )
       
   393 		{
       
   394 		return ESvgEventMouseover;
       
   395 		}
       
   396 	else if ( aEventDes == _L("mousemove") )
       
   397 		{
       
   398 		return ESvgEventMousemove;
       
   399 		}
       
   400 	else if ( aEventDes == _L("mouseout") )
       
   401 		{
       
   402 		return ESvgEventMouseout;
       
   403 		}
       
   404 	else if ( aEventDes == _L("DOMSubtreeModified") )
       
   405 		{
       
   406 		return ESvgEventDOMSubtreeModified;
       
   407 		}
       
   408 	else if ( aEventDes == _L("DOMNodeInserted") )
       
   409 		{
       
   410 		return ESvgEventDOMNodeInserted;
       
   411 		}
       
   412 	else if ( aEventDes == _L("DOMNodeRemoved") )
       
   413 		{
       
   414 		return ESvgEventDOMNodeRemoved;
       
   415 		}
       
   416 	else if ( aEventDes == _L("DOMNodeRemovedFromDocument") )
       
   417 		{
       
   418 		return ESvgEventDOMNodeRemovedFromDocument;
       
   419 		}
       
   420 	else if ( aEventDes == _L("DOMNodeInsertedIntoDocument") )
       
   421 		{
       
   422 		return ESvgEventDOMNodeInsertedIntoDocument;
       
   423 		}
       
   424 	else if ( aEventDes == _L("DOMAttrModified") )
       
   425 		{
       
   426 		return ESvgEventDOMAttrModified;
       
   427 		}
       
   428 	else if ( aEventDes == _L("DOMCharacterDataModified") )
       
   429 		{
       
   430 		return ESvgEventDOMCharacterDataModified;
       
   431 		}
       
   432 	else if ( aEventDes == _L("SVGLoad") )
       
   433 		{
       
   434 		return ESvgEventSVGLoad;
       
   435 		}
       
   436 	else if ( aEventDes == _L("SVGUnload") )
       
   437 		{
       
   438 		return ESvgEventSVGUnload;
       
   439 		}
       
   440 	else if ( aEventDes == _L("SVGAbort") )
       
   441 		{
       
   442 		return ESvgEventSVGAbort;
       
   443 		}
       
   444 	else if ( aEventDes == _L("SVGError") )
       
   445 		{
       
   446 		return ESvgEventSVGError;
       
   447 		}
       
   448 	else if ( aEventDes == _L("SVGResize") )
       
   449 		{
       
   450 		return ESvgEventSVGResize;
       
   451 		}
       
   452 	else if ( aEventDes == _L("SVGScroll") )
       
   453 		{
       
   454 		return ESvgEventSVGScroll;
       
   455 		}
       
   456 	else if ( aEventDes == _L("SVGZoom") )
       
   457 		{
       
   458 		return ESvgEventSVGZoom;
       
   459 		}
       
   460 
       
   461 	else
       
   462 		{
       
   463         return ESvgEventNone;
       
   464     }
       
   465 
       
   466     }