svgtopt/SVG/SVGImpl/src/SVGPointLexer.cpp
changeset 0 d46562c3d99d
equal deleted inserted replaced
-1:000000000000 0:d46562c3d99d
       
     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 "SVGPointLexer.h"
       
    20 
       
    21 #include "stdlib.h"
       
    22 #include "string.h"
       
    23 
       
    24 // Below define is used as a mask for getting LSB of 16bit number
       
    25 // for endian-agnostic progressing.
       
    26 #define KLSBMASK ( 0xFF )
       
    27 // ---------------------------------------------------------------------------
       
    28 //
       
    29 // ---------------------------------------------------------------------------
       
    30 TSvgPointLexer::TSvgPointLexer( const TDesC& aDes ) :
       
    31                 iLex( aDes ), iNegativeNumber( EFalse )
       
    32 {
       
    33     iDataCopy = NULL;
       
    34     iDataCopy = aDes.Alloc();
       
    35     if ( iDataCopy )
       
    36     {
       
    37         iData = (TUint16 *)iDataCopy->Ptr();
       
    38         iDataEnd = iData + iDataCopy->Length();
       
    39     }
       
    40 }
       
    41 
       
    42 void TSvgPointLexer::Cleanup()
       
    43 {
       
    44     if ( iDataCopy )
       
    45     {
       
    46         delete iDataCopy;
       
    47         iDataCopy = NULL;
       
    48     }
       
    49 }
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 //
       
    53 // ---------------------------------------------------------------------------
       
    54 TInt32 TSvgPointLexer::GetNext( TChar& aCommand, TFloatFixPt& aVal )
       
    55     {
       
    56     TReal32 realnum = 0.0;
       
    57 
       
    58     // Parse a command and minus symbol
       
    59     iNegativeNumber = EFalse;
       
    60     aCommand = SkipUntilNum();
       
    61     if ( iLex.Eos() && aCommand != 'z' )
       
    62         {
       
    63         return -1;
       
    64         }
       
    65     else if ( aCommand == 'z' )
       
    66         {
       
    67         // if 'z' was found return immediately
       
    68         // never parse for numbers
       
    69         return KErrNone;
       
    70         }
       
    71 
       
    72     // Parse a number with fraction
       
    73     iLex.Mark();
       
    74     if ( SkipToNumEnd() )
       
    75         {
       
    76          TInt result = TLex( iLex.MarkedToken() ).Val( realnum, '.' ) ;
       
    77 	     if (result != KErrNone)
       
    78 			{
       
    79 			realnum= 0.0;
       
    80 			return result;
       
    81 			}
       
    82         }
       
    83     else
       
    84         {
       
    85         realnum = 0.0;
       
    86         }
       
    87     if ( iNegativeNumber )
       
    88         realnum = -realnum;
       
    89     aVal = ( TFloatFixPt ) realnum;
       
    90 
       
    91     return KErrNone;
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 // ---------------------------------------------------------------------------
       
    97 
       
    98 TBool TSvgPointLexer::GetNextWithNumOfPoints( TFloatFixPt *aVal, TInt NoOfPoints)
       
    99     {
       
   100     TReal32 realnum = 0.0;
       
   101 	TUint8 tmpchar;
       
   102     TInt i=0;
       
   103 
       
   104 	for( i=0;i < NoOfPoints;i++ )
       
   105 		{
       
   106         // Since iData is a TUint16 pointer, and we need to 
       
   107         // operate with 8bit ASCII, mask LSB to obtain the same
       
   108 		tmpchar = *iData & KLSBMASK;
       
   109         // Traverse the string while character encountered is
       
   110         // ' ', LineFeed('\0xa'), ',', Carriage Return ('\0xd')
       
   111 		while( !(tmpchar^32) || !(tmpchar^10) || !(tmpchar^44) || !(tmpchar^13) )
       
   112 			{
       
   113 			iData++;
       
   114             if ( iData < iDataEnd )    
       
   115                 {
       
   116 		        tmpchar = *iData & KLSBMASK;
       
   117                 }
       
   118             else
       
   119                 {
       
   120                 // Exceeding buffer limits, return error
       
   121                 return EFalse;
       
   122                 }
       
   123 			}
       
   124 
       
   125         // Check if character encountered is '-' 
       
   126 		if( !(tmpchar^45) )
       
   127 			{
       
   128 			iData++;
       
   129 
       
   130             if ( iData < iDataEnd )
       
   131                 {
       
   132     			if(SkipToNumEndWithoutLex(realnum) )
       
   133     				{
       
   134     				realnum = -realnum;
       
   135     				}
       
   136     			else
       
   137     				{
       
   138     				return EFalse;
       
   139     				}
       
   140                 }
       
   141             else // if ( iData < iDataEnd )
       
   142                 {
       
   143                 // Exceeding buffer limits, return error
       
   144                 return EFalse;
       
   145                 }
       
   146 			}
       
   147 		else // Not a '-' char
       
   148 			{
       
   149 			    if( !(tmpchar^43) ) // to increment the data if '+' is given
       
   150 			        {
       
   151 			        iData++;    
       
   152 			        }
       
   153 			
       
   154 			if( !SkipToNumEndWithoutLex(realnum) )
       
   155 				{
       
   156 				return EFalse;
       
   157 				}
       
   158 			}
       
   159         // Save the converted number into float array 
       
   160         // provided by caller.
       
   161 		aVal[i] = ( TFloatFixPt )(realnum);
       
   162 		}
       
   163 
       
   164 	return ETrue;
       
   165     }
       
   166 
       
   167 
       
   168 //
       
   169 // ---------------------------------------------------------------------------
       
   170 //
       
   171 // ---------------------------------------------------------------------------
       
   172 TInt32 TSvgPointLexer::GetNextPoint( TChar& aCommand, TFloatFixPt& aX, TFloatFixPt& aY )
       
   173     {
       
   174     TReal32 realnum = 0.0;
       
   175 
       
   176     // Parse X value
       
   177     iNegativeNumber = EFalse;
       
   178     aCommand = SkipUntilNum();
       
   179     if ( iLex.Eos() )
       
   180         {
       
   181         return -1;
       
   182         }
       
   183     iLex.Mark();
       
   184     if ( SkipToNumEnd() )
       
   185         {
       
   186         TInt result = TLex( iLex.MarkedToken() ).Val( realnum, '.' ) ;
       
   187 		if (result != KErrNone)
       
   188 			{
       
   189 			realnum= 0.0;
       
   190 			return result;
       
   191 			}
       
   192         }
       
   193     else
       
   194         {
       
   195         realnum = 0.0;
       
   196         }
       
   197     if ( iNegativeNumber )
       
   198         realnum = -realnum;
       
   199     aX = realnum;
       
   200 
       
   201     // Parse Y value
       
   202     iNegativeNumber = EFalse;
       
   203     iLex.Mark();
       
   204     SkipUntilNum();
       
   205     if ( iLex.Eos() )
       
   206         {
       
   207         return -1;
       
   208         }
       
   209     iLex.Mark();
       
   210     if ( SkipToNumEnd() )
       
   211         {
       
   212        TInt result = TLex( iLex.MarkedToken() ).Val( realnum, '.') ;
       
   213 	   if (result != KErrNone)
       
   214 			{
       
   215 			realnum= 0.0;
       
   216 			return result;
       
   217 			}
       
   218         }
       
   219     else
       
   220         {
       
   221         realnum = 0.0;      // exponential description
       
   222         }
       
   223     if ( iNegativeNumber )
       
   224         realnum = -realnum;
       
   225     aY = realnum;
       
   226 
       
   227     return KErrNone;
       
   228     }
       
   229 
       
   230 //
       
   231 // ---------------------------------------------------------------------------
       
   232 //
       
   233 // ---------------------------------------------------------------------------
       
   234 TBool TSvgPointLexer::SkipToNumEnd()
       
   235     {
       
   236     TChar tmpchar = iLex.Peek();
       
   237     TBool tmpbool = ETrue;
       
   238     TBool acceptMinus = EFalse;
       
   239 
       
   240 	while ( tmpchar.IsDigit() ||
       
   241             !(tmpchar^46) ||
       
   242             ( !(tmpchar^45) && acceptMinus ) )
       
   243         {
       
   244         iLex.Inc();
       
   245         tmpchar = iLex.Peek();
       
   246         acceptMinus = EFalse;
       
   247 
       
   248 		if ( !(tmpchar^101) || !(tmpchar^69) )
       
   249             {
       
   250             // exponential value
       
   251             iLex.Inc();
       
   252             tmpchar = iLex.Peek();
       
   253             tmpbool = EFalse;
       
   254             acceptMinus = ETrue;
       
   255             }
       
   256         }
       
   257     return tmpbool;
       
   258     }
       
   259 
       
   260 //
       
   261 // ---------------------------------------------------------------------------
       
   262 // TBool TSvgPointLexer::SkipToNumEndWithoutLex(TReal32 &aNum)
       
   263 //   This function parses the number at the current position into aNum
       
   264 // ---------------------------------------------------------------------------
       
   265 TBool TSvgPointLexer::SkipToNumEndWithoutLex(TReal32 &aNum)
       
   266     {
       
   267     TBool numberFound = EFalse;
       
   268     TReal32 lNumber=0;
       
   269     // Since iData is a TUint16 pointer, and we need to 
       
   270     // operate with 8bit ASCII, mask LSB to obtain the same
       
   271     TUint8 tmpchar = *iData & KLSBMASK;
       
   272     TInt fractionPart=0;
       
   273 
       
   274     // Scan through the string while the character is 
       
   275     // between '0' and '9' 
       
   276     // or is '.'
       
   277     // and there are more characters in the string
       
   278     while ( (((tmpchar > 47) && (tmpchar < 58) )||
       
   279             !(tmpchar^46)) && iData < iDataEnd )
       
   280         {
       
   281         // If a '.' is not found
       
   282         if(tmpchar^46)
       
   283             {
       
   284             // This means that the char is between '0' and '9'
       
   285             numberFound = ETrue;
       
   286             // Append it to lNumber
       
   287             lNumber = 10*lNumber + (tmpchar -'0');
       
   288 
       
   289             if(fractionPart)
       
   290                 {
       
   291                 fractionPart++;
       
   292                 }
       
   293             }
       
   294         else // '.' is found
       
   295             {
       
   296             fractionPart++;
       
   297             }
       
   298         
       
   299         iData++;
       
   300         if ( iData < iDataEnd )
       
   301             {
       
   302             tmpchar = *iData & KLSBMASK;
       
   303             
       
   304             // Check if characted is 'e' or 'E'
       
   305             // for eg. -3.486e-007
       
   306             // This is for floating point representation and is
       
   307             // not supported currently. Such numbers are treated 
       
   308             // as 0.0. 
       
   309             // The number is skipped.
       
   310             if ( (!(tmpchar^101) || !(tmpchar^69)) )
       
   311                 {
       
   312                 iData++;
       
   313                 if ( iData < iDataEnd )
       
   314                     {
       
   315                     tmpchar = *iData & KLSBMASK;                    
       
   316                 
       
   317                     // Check if character is '-', if so 
       
   318                     // skip it 
       
   319                     if( !(tmpchar^45) )
       
   320                         {
       
   321                         iData++;
       
   322                         if ( iData < iDataEnd )
       
   323                             {
       
   324                             tmpchar = *iData & KLSBMASK;
       
   325                             }
       
   326                         }
       
   327                     // Skip the numbers and decimal point after 'e'
       
   328                     while ( ( ( ( tmpchar > 47 ) && ( tmpchar < 58 ) ) ||
       
   329                         !( tmpchar^46 ) ) && ( iData < iDataEnd ) )
       
   330                         {
       
   331                         iData++;
       
   332                         if ( iData < iDataEnd )
       
   333                             {
       
   334                             tmpchar = *iData & KLSBMASK;
       
   335                             }
       
   336                         }
       
   337                     }
       
   338                 aNum = 0.0;
       
   339                 return numberFound;
       
   340                } // if (exponential number)  
       
   341             } // if iData < iDataEnd
       
   342         } // end while 
       
   343     // Account for decimal point by performing following calculation
       
   344     // lNumber = lNumber / ( 10^ ( fractionPart - 1 ) )
       
   345     if(numberFound)
       
   346         {
       
   347         TInt l=0;
       
   348         TInt k=1;
       
   349         while(l<(fractionPart-1))
       
   350             {
       
   351             k=(k*10);
       
   352             l++;
       
   353             }
       
   354         lNumber = (lNumber/k);
       
   355         aNum = lNumber;
       
   356         }
       
   357 
       
   358     return numberFound;
       
   359     }
       
   360 
       
   361 
       
   362 
       
   363 
       
   364 //
       
   365 // ---------------------------------------------------------------------------
       
   366 //
       
   367 // ---------------------------------------------------------------------------
       
   368 TChar TSvgPointLexer::SkipUntilNum()
       
   369     {
       
   370     TChar ret = '\0';
       
   371     iLex.SkipSpace();
       
   372     TChar tmpchar = iLex.Peek();
       
   373     // skip until finding a digit or '.'
       
   374 
       
   375     while ( !( tmpchar.IsDigit() || tmpchar == '.' ) && !iLex.Eos() )
       
   376         {
       
   377         if ( tmpchar == '-' )
       
   378             {
       
   379             iNegativeNumber = ETrue;
       
   380             }
       
   381         else if ( tmpchar == 'Z' || tmpchar == 'z' )
       
   382             {
       
   383             // if 'Z' or 'z' was found, return imediately.
       
   384             iLex.Inc();
       
   385             return 'z';
       
   386             }
       
   387         else if ( tmpchar != ' ' && tmpchar != ',' && tmpchar != '\n' )
       
   388             // a better way may be for only selected characters to be recognized and not ignored.
       
   389         {
       
   390             ret = tmpchar;
       
   391             }
       
   392         iLex.Inc();
       
   393         tmpchar = iLex.Peek();
       
   394         }
       
   395 
       
   396     return ret;
       
   397     }
       
   398 
       
   399 
       
   400 //
       
   401 // ---------------------------------------------------------------------------
       
   402 //
       
   403 // ---------------------------------------------------------------------------
       
   404 TBool TSvgPointLexer::GetCommand(TUint8 &a)
       
   405 {
       
   406     a = '\0';
       
   407     TUint8 tmpchar;
       
   408     while (iData < iDataEnd )
       
   409         {
       
   410         tmpchar = *iData & KLSBMASK;
       
   411         // If character is a not between '0' and '9' and not '.' and '-'
       
   412         if (!((tmpchar > 47) && (tmpchar < 58)) && (tmpchar^46) && (tmpchar^45) )
       
   413              {
       
   414              // Check if character is an alphabet
       
   415              if((tmpchar >=65 && tmpchar <= 90) || (tmpchar >=97 && tmpchar <= 122) )
       
   416                 {
       
   417                 a = tmpchar;
       
   418                 iData++;
       
   419                 return ETrue;
       
   420                 }
       
   421             else
       
   422                 {
       
   423                 iData++;
       
   424                 }
       
   425              }
       
   426          else
       
   427              {
       
   428              return ETrue;
       
   429              }
       
   430 
       
   431         }
       
   432    return EFalse;
       
   433 
       
   434 }
       
   435