svgtopt/SVG/SVGImpl/src/SVGTextElementImpl.cpp
changeset 46 88edb906c587
child 19 df65ec4f2d28
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 #if !defined(__E32BASE_H__)
       
    20 #include <e32base.h>
       
    21 #endif
       
    22 #include "SVGTextElementImpl.h"
       
    23 #include "SVGDocumentImpl.h"
       
    24 #include "SVGEngineImpl.h"
       
    25 #include "SVGSchemaData.h"
       
    26 #include "SVGFloatCssValueImpl.h"
       
    27 #include "SVGStrCssValueImpl.h"
       
    28 #include "SVGIntCssValueImpl.h"
       
    29 #include "SVGPaintCssValueImpl.h"
       
    30 
       
    31 #include "GfxLine2D.h"
       
    32 #include "GfxStroke.h"
       
    33 #include "GfxColor.h"
       
    34 
       
    35 #include "GfxAffineTransform.h"
       
    36 
       
    37 
       
    38 #include "SVGStringTokenizer.h"
       
    39 #include "GfxGeneralPath.h"
       
    40 
       
    41 #include "SVGGlyphElementImpl.h"
       
    42 //#include "SvgDefaultFont.h"
       
    43 #include "SVGErrorImpl.h"
       
    44 #include "SVGFourPointRect.h"
       
    45 
       
    46 #include "hal.h"
       
    47 #include "hal_data.h"
       
    48 
       
    49 #define KDefaultFontSize 10
       
    50 #define KOne 1
       
    51 #define KDefaultUnitsPerEm 1000
       
    52 
       
    53 _LIT( KGlyphNameNone, "GlyphNameNone");
       
    54 _LIT( KDefaultFont, "serif" ); // Similar changes should be applied to Gfx2dGcOpenVg.cpp file
       
    55 
       
    56 // ---------------------------------------------------------------------------
       
    57 // Two phase construction
       
    58 // ---------------------------------------------------------------------------
       
    59 
       
    60 CSvgTextElementImpl* CSvgTextElementImpl::NewL(  const TUint8 aElemID,
       
    61                                                 CSvgDocumentImpl* aDoc )
       
    62 
       
    63     {
       
    64     CSvgTextElementImpl*self    = new ( ELeave ) CSvgTextElementImpl( aDoc );
       
    65     CleanupStack::PushL( self );
       
    66 
       
    67 
       
    68     self->ConstructL(  aElemID );
       
    69     CleanupStack::Pop();
       
    70 
       
    71     return self;
       
    72     }
       
    73 
       
    74 // ---------------------------------------------------------------------------
       
    75 //
       
    76 // ---------------------------------------------------------------------------
       
    77 
       
    78 
       
    79 CSvgTextElementImpl* CSvgTextElementImpl::NewLC(  const TUint8 aElemID,
       
    80                                                 CSvgDocumentImpl* aDoc )
       
    81     {
       
    82     CSvgTextElementImpl*self    = new ( ELeave ) CSvgTextElementImpl( aDoc );
       
    83     CleanupStack::PushL( self );
       
    84     self->ConstructL( aElemID );
       
    85 
       
    86     return self;
       
    87     }
       
    88 
       
    89 
       
    90 // ---------------------------------------------------------------------------
       
    91 //
       
    92 // ---------------------------------------------------------------------------
       
    93 CSvgTextElementImpl::CSvgTextElementImpl( CSvgDocumentImpl* aDoc ): iOffset(0)
       
    94     {
       
    95     SetOwnerDocument(aDoc);
       
    96 
       
    97     }
       
    98 
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 //
       
   102 // ---------------------------------------------------------------------------
       
   103 
       
   104 void CSvgTextElementImpl::ConstructL(  const TUint8 aElemID )
       
   105     {
       
   106     CSvgElementImpl::InitializeL(  aElemID );
       
   107 
       
   108 
       
   109     iArrayX = new ( ELeave ) CArrayFixFlat<TFloatFixPt>( 1 );
       
   110     iArrayY = new ( ELeave ) CArrayFixFlat<TFloatFixPt>( 1 );
       
   111 
       
   112 	#ifdef SVG_FLOAT_BUILD
       
   113     iArrayX->AppendL( TFloatFixPt(0) );
       
   114     iArrayY->AppendL( TFloatFixPt(0) );
       
   115 
       
   116     iPoint.iX = TFloatFixPt( 0 );
       
   117     iPoint.iY = TFloatFixPt( 0 );
       
   118 	#else
       
   119     iArrayX->AppendL( TFloatFixPt( 0 , ETrue) );
       
   120     iArrayY->AppendL( TFloatFixPt( 0 , ETrue) );
       
   121 
       
   122 
       
   123     iPoint.iX = TFloatFixPt( 0 ,ETrue);
       
   124     iPoint.iY = TFloatFixPt( 0 ,ETrue);
       
   125 	#endif
       
   126 
       
   127     iText = HBufC::NewL( 2 );
       
   128    // *iText = _L( " " );
       
   129 
       
   130     iG1 = HBufC::NewL( 0 );
       
   131     iG2 = HBufC::NewL( 0 );
       
   132 
       
   133     iU1 = HBufC::NewL( 0 );
       
   134     iU2 = HBufC::NewL( 0 );
       
   135 
       
   136     iSvgStyleProperties = new(ELeave) RPointerArray<CCssValue>(KCSS_MAX_ATTR);
       
   137      User::LeaveIfError( iSvgStyleProperties->Append( NULL ) );
       
   138 	iSvgStyleProperties->Remove( 0 );
       
   139 
       
   140 	iTriedLoadingSVGFonts = EFalse;
       
   141 	iNeedToCacheGlyphs = EFalse;
       
   142 
       
   143     iSvgTransformable = CSvgTransformableImpl::NewL();
       
   144 
       
   145 	//set in the default font...just in case
       
   146 	SetFontFamilyL(KDefaultFont ); //_L("DefaultFont"));
       
   147 
       
   148 	iEditable = EFalse;
       
   149 
       
   150 	if (OwnerDocument())
       
   151 	{
       
   152 	((CSvgDocumentImpl*)OwnerDocument())->AddInternalMouseListener( this );
       
   153 	}
       
   154 
       
   155 	//gets the default font that the graphics context holds at the start
       
   156 	//should be whatever the client side specified as the initial fontspec
       
   157 	//GetCurrentFontScaled(iBitmapFont, iBitmapFontSpec);
       
   158 
       
   159     }
       
   160 
       
   161 
       
   162 // ---------------------------------------------------------------------------
       
   163 //
       
   164 // ---------------------------------------------------------------------------
       
   165 CSvgTextElementImpl::~CSvgTextElementImpl()
       
   166     {
       
   167 
       
   168     iGlyphElements.Close();
       
   169 
       
   170     if ( iFamilies )
       
   171         {
       
   172         iFamilies->Reset();
       
   173         delete iFamilies;
       
   174         iFamilies = NULL;
       
   175         }
       
   176     if ( iArrayX )
       
   177         {
       
   178         iArrayX->Reset();
       
   179         delete iArrayX;
       
   180         iArrayX = NULL;
       
   181         }
       
   182     if ( iArrayY )
       
   183         {
       
   184         iArrayY->Reset();
       
   185         delete iArrayY;
       
   186         iArrayY = NULL;
       
   187         }
       
   188     if ( iArrayRotate )
       
   189         {
       
   190         iArrayRotate->Reset();
       
   191         delete iArrayRotate;
       
   192         iArrayRotate = NULL;
       
   193         }
       
   194 
       
   195     if ( iText )
       
   196         {
       
   197         delete iText;
       
   198         iText = NULL;
       
   199         }
       
   200 
       
   201     if ( iG1 )
       
   202         {
       
   203         delete iG1;
       
   204         iG1 = NULL;
       
   205         }
       
   206 
       
   207     if ( iG2 )
       
   208         {
       
   209         delete iG2;
       
   210         iG2 = NULL;
       
   211         }
       
   212 
       
   213     if ( iU1)
       
   214         {
       
   215         delete iU1;
       
   216         iU1 = NULL;
       
   217         }
       
   218 
       
   219     if ( iU2 )
       
   220         {
       
   221         delete iU2;
       
   222         iU2 = NULL;
       
   223         }
       
   224 
       
   225         ((CSvgDocumentImpl*)OwnerDocument())->RemoveInternalMouseListener( this );
       
   226     // The Font is owned by TextElement
       
   227     // now as each text element may have its own specific font
       
   228     // and keeping one copy at Gc level will not work.
       
   229     // Gc is just refering to the Font from Textelement, so
       
   230     // need to free it here. Note the iWsSceenDevice initialisation
       
   231     // was done in draw as it needs to happens in main thread in case
       
   232     // of progressive rendering.
       
   233     //
       
   234     if (iBitmapFont)
       
   235     {
       
   236     	 CSvgBitmapFontProvider *tempBitmapFontProvider = ((CSvgDocumentImpl*)iOwnerDocument)->GetBitmapFontProvider();
       
   237     	 tempBitmapFontProvider->ReleaseFont(iBitmapFont);
       
   238     	 iBitmapFont = NULL;
       
   239     	
       
   240 	}
       
   241 
       
   242     if ( iSvgStyleProperties )
       
   243         {
       
   244         iSvgStyleProperties->Close();
       
   245         delete iSvgStyleProperties;
       
   246         iSvgStyleProperties = NULL;
       
   247         }
       
   248 
       
   249     }
       
   250 
       
   251 
       
   252 // *******************************************************
       
   253 // From SVG DOM
       
   254 // ---------------------------------------------------------------------------
       
   255 //
       
   256 // ---------------------------------------------------------------------------
       
   257 TInt32 CSvgTextElementImpl::NumberOfChars()
       
   258     {
       
   259     return iText->Length();
       
   260     }
       
   261 
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 // ---------------------------------------------------------------------------
       
   265 void CSvgTextElementImpl::GetX( CArrayFix<TFloatFixPt>* aX )
       
   266     {
       
   267     	if (aX->Count() > 0)
       
   268     	{
       
   269     aX->At( 0 ) = iPoint.iX;
       
   270     	}
       
   271     }
       
   272 
       
   273 // ---------------------------------------------------------------------------
       
   274 //
       
   275 // ---------------------------------------------------------------------------
       
   276 void CSvgTextElementImpl::GetY( CArrayFix<TFloatFixPt>* aY )
       
   277     {
       
   278     	if (aY->Count() > 0 )
       
   279     	{
       
   280     aY->At( 0 ) = iPoint.iY;
       
   281     	}
       
   282     }
       
   283 
       
   284 // *******************************************************
       
   285 // SVG Implementation
       
   286 
       
   287 TBool CSvgTextElementImpl::IsNumberAttributeValid( const TDesC& aValue )
       
   288 
       
   289     {
       
   290         TBool lValidAttr = EFalse;
       
   291 
       
   292         if ( aValue.Length() > 0 )
       
   293         {
       
   294 
       
   295         TLex    lInput ( aValue );
       
   296 
       
   297         TChar tmpchar;
       
   298         while ( lInput.Peek() != 0 )
       
   299         {
       
   300         tmpchar = lInput.Get();
       
   301         if( !(tmpchar.IsDigit()) && !(tmpchar == '.') && !(tmpchar == '-') && !(tmpchar == ' ') )
       
   302             {
       
   303             lValidAttr = EFalse;
       
   304             break;
       
   305             }
       
   306             lValidAttr = ETrue;
       
   307         }
       
   308 
       
   309         }
       
   310 
       
   311         return lValidAttr;
       
   312 }
       
   313 
       
   314 // ---------------------------------------------------------------------------
       
   315 // xml:space is an inheritable attribute which can have one of two values:
       
   316 //
       
   317 // default (the initial/default value for xml:space) - When xml:space="default":
       
   318 //      - Remove all newline characters.
       
   319 //      - Convert all tab characters into space characters.
       
   320 //      - Strip off all leading and trailing space characters.
       
   321 //      - All contiguous space characters will be consolidated.
       
   322 //
       
   323 // preserve - When xml:space="preserve" :
       
   324 //      - Convert all newline and tab characters into space characters.
       
   325 // ---------------------------------------------------------------------------
       
   326 void CSvgTextElementImpl::SetTextL( const TDesC& aText )
       
   327     {
       
   328     _LIT( KPreserve, "preserve" );
       
   329     _LIT( KDefault, "default");
       
   330     if ( iText )
       
   331         {
       
   332         delete iText;
       
   333         iText = NULL;
       
   334         }
       
   335 
       
   336     iText = aText.AllocL();
       
   337     TPtr textDes = iText->Des();
       
   338     TBool def = ETrue;
       
   339     
       
   340     // Get the xml:space value.
       
   341     TBuf<20> lXmlspace;    
       
   342    
       
   343     if(XMLSpace() == KPreserve)
       
   344     	{
       
   345     	lXmlspace=KPreserve;
       
   346     	def=EFalse;
       
   347     	}
       
   348     else if(XMLSpace() == KDefault)
       
   349     	{
       
   350     	lXmlspace=KDefault;
       
   351     	}
       
   352     // xml:space is inherited if not specified
       
   353     if ( lXmlspace!= KPreserve && lXmlspace != KDefault) 
       
   354         {
       
   355 		// Traverse to the nearest parent element which has the xml:space 
       
   356 		// If no xml:space then render using xml:space="default"
       
   357 	    CSvgElementImpl *lRoot=(CSvgElementImpl *)this->ParentNode();
       
   358 	 	while(lRoot)
       
   359 	 		{
       
   360 	 		if ((lRoot->XMLSpace() == KPreserve))
       
   361 	    		{
       
   362 	    		def = EFalse;
       
   363 	    		break;
       
   364 	        	}
       
   365 	        else if(lRoot->XMLSpace()==KDefault)
       
   366 	        	{
       
   367 	        	break;	
       
   368 	        	}
       
   369 	        lRoot=(CSvgElementImpl *)lRoot->ParentNode();
       
   370 	 		}
       
   371     
       
   372         }
       
   373     
       
   374     _LIT(KSpace, " ");
       
   375     // default    
       
   376     if ( def && lXmlspace != KPreserve )
       
   377         {
       
   378         
       
   379         // Remove leading, trailing and contiguous spaces
       
   380         textDes.TrimAll();
       
   381         
       
   382         for (TInt i = textDes.Length() - 1; i >= 0; i--)
       
   383         	{
       
   384                 	
       
   385         	// Remove new line character
       
   386         	if (textDes[i] == '\n' ||
       
   387         	    textDes[i] == '\r') 
       
   388        			{
       
   389           		textDes.Delete(i,1);
       
   390        			}
       
   391           	
       
   392           	// Tab to be replaced with space.
       
   393           	if(textDes[i] == '\t')
       
   394           		{
       
   395           		textDes.Replace(i,1,KSpace);
       
   396           		}           	
       
   397         	}
       
   398         }
       
   399     // preserve
       
   400     else
       
   401         {
       
   402        
       
   403         for ( TInt i = 0; i < textDes.Length(); i++ )
       
   404             {
       
   405             // ms-dos carriage return contains two characters: 13, 10
       
   406            	const TInt KCarriageReturn1 = 13;
       
   407            	const TInt KCarriageReturn2 = 10;
       
   408            	
       
   409            	if ( i + 1 < textDes.Length() &&
       
   410            	 	(TInt)textDes[i] == KCarriageReturn1 && 
       
   411            	 	(TInt)textDes[i+1] == KCarriageReturn2 )
       
   412               	{
       
   413                 textDes[i] = ' ';
       
   414                 textDes.Delete( i+1, 1 );
       
   415        		    }
       
   416 			
       
   417 			// New line and tab should be replaced by space character.         
       
   418            	if (textDes[i] == '\n' ||textDes[i] == '\t')
       
   419               	{
       
   420                 textDes.Replace(i,1, KSpace);
       
   421                	}
       
   422             }
       
   423         }
       
   424 
       
   425         iUseDefaultSVGFont = IsMostBasicLatin();
       
   426         iNeedToCacheGlyphs = ETrue;
       
   427     }
       
   428 
       
   429 void CSvgTextElementImpl::CacheGlyphsForText()
       
   430 {
       
   431 	if (!iNeedToCacheGlyphs || iText == NULL || iText->Length() == 0 || iSVGFont == NULL)
       
   432 	{
       
   433 		return;
       
   434 	}
       
   435     // Reset the cache first
       
   436     iGlyphElements.Reset();
       
   437 	//initialize the glyph elements cache array...this seems expensive any other way to do this
       
   438 	TInt textLength = iText->Length();
       
   439 	for (TInt j = 0; j < textLength; j++)
       
   440 	{
       
   441 		//it might actually be better to put a ptr to missing glyph in here instead of null
       
   442 		iGlyphElements.Append(NULL);
       
   443 	}
       
   444 
       
   445 	//we have an svg font...
       
   446     if ( iSVGFont->HasChildNodes() )
       
   447     {
       
   448     	/*******************************/
       
   449     	/* Text Caching functionality, */
       
   450     	/*******************************/
       
   451 
       
   452         CSvgElementImpl* lFirstChild = ( CSvgElementImpl * ) iSVGFont->FirstChild();
       
   453 
       
   454         while ( lFirstChild != NULL )
       
   455         {
       
   456         	/***********************/
       
   457     		/*CACHING HKERN ELEMENT*/
       
   458     		/***********************/
       
   459             if( lFirstChild->ElemID() == KSvgHkernElement)
       
   460             {
       
   461             	//1 per font
       
   462             	iHkernElement = lFirstChild;
       
   463             }
       
   464 
       
   465     		/******************************/
       
   466     		/*CACHING MISSINGGLYPH ELEMENT*/
       
   467     		/******************************/
       
   468 
       
   469             if ( lFirstChild->ElemID() == KSvgMissingglyphElement)
       
   470             {
       
   471             	//1 per font
       
   472               	iMissingGlyphElement = lFirstChild;
       
   473             }
       
   474 
       
   475     		/***********************/
       
   476     		/* FONTFACE ELEMENT    */
       
   477     		/***********************/
       
   478 
       
   479             if ( lFirstChild->ElemID() == KSvgFontfaceElement )
       
   480             {
       
   481             	//1 per font
       
   482 				iFontFaceElement = lFirstChild;
       
   483             }
       
   484 
       
   485             /***********************/
       
   486             /* CACHE GLYPH ELEMENT */
       
   487             /***********************/
       
   488 
       
   489         	if ( lFirstChild->ElemID() == KSvgGlyphElement)
       
   490                 {
       
   491                 TPtrC16 lUnicode;
       
   492                 lFirstChild->GetAttributeDes( KAtrUnicode, lUnicode );
       
   493 
       
   494                 TPtr textDes = iText->Des();
       
   495 
       
   496                 TPtrC  lLangCode;
       
   497                 TInt    langCodeFound = 0;
       
   498 
       
   499                 TInt checkErrorLangCode = lFirstChild->GetAttributeDes( KAtrLang, lLangCode);
       
   500                 
       
   501                 if (checkErrorLangCode !=  KErrNoAttribute)
       
   502                     {
       
   503                     TPtrC lXmlLangAttr(this->XMLLang());
       
   504                     langCodeFound = lLangCode.CompareF( lXmlLangAttr );
       
   505                     }
       
   506                     
       
   507                 TInt textLength = iText->Length();
       
   508                 for (TInt i=0; i < textLength; i++)
       
   509                     {
       
   510                     	//this probably isnt right i think one of these is a string that needs to be an int
       
   511                     if ( textDes[i] == lUnicode[0] && langCodeFound == 0)
       
   512                     	{
       
   513                     		//then this text string uses this glyph and we need to cache it in each spot it is used
       
   514                     		iGlyphElements[i] = lFirstChild;
       
   515                     	}
       
   516                     }
       
   517                 }
       
   518 
       
   519       		lFirstChild = ( CSvgElementImpl* ) lFirstChild->NextSibling();
       
   520     	}
       
   521     }
       
   522 
       
   523     iNeedToCacheGlyphs = EFalse;
       
   524 }
       
   525 
       
   526 TBool CSvgTextElementImpl::IsMostBasicLatin()
       
   527 {
       
   528 	//check to see if all basic latin characters
       
   529 	if (iText == NULL || iText->Length() == 0)
       
   530 	{
       
   531 		return EFalse;
       
   532 	}
       
   533 
       
   534 	TPtr textDes = iText->Des();
       
   535 
       
   536     TInt lOutOfLatinCount = 0;
       
   537 
       
   538 	TInt textDesLength = textDes.Length();
       
   539     for (TInt i=0; i< textDesLength; i++)
       
   540     {
       
   541       	if (!((TInt)textDes[i] <= 0x007F))
       
   542        	{
       
   543        		lOutOfLatinCount++;
       
   544        		break;
       
   545       	}
       
   546     }
       
   547 
       
   548     //make sure that at least half arent outside of basic latin characters
       
   549     if (lOutOfLatinCount > (textDes.Length() / 2) )
       
   550     {
       
   551       	return EFalse;
       
   552     }
       
   553 
       
   554     return ETrue;
       
   555 }
       
   556 
       
   557 TDesC& CSvgTextElementImpl::GetText()
       
   558 {
       
   559     return *iText;
       
   560 }
       
   561 
       
   562 void CSvgTextElementImpl::SetFont(CFont* aBitmapFont, CSvgElementImpl* aSVGFont)
       
   563 {
       
   564 	if (aBitmapFont != NULL)
       
   565 	{
       
   566 		iBitmapFont = aBitmapFont;
       
   567 	}
       
   568 	if (aSVGFont != NULL)
       
   569 	{
       
   570 		iSVGFont = aSVGFont;
       
   571 	}
       
   572 }
       
   573 
       
   574 TBool CSvgTextElementImpl::HasFont()
       
   575 {
       
   576 	if (iBitmapFont || iSVGFont)
       
   577 	{
       
   578 		return ETrue;
       
   579 	}
       
   580 	else
       
   581 	{
       
   582 		return EFalse;
       
   583 	}
       
   584 }
       
   585 
       
   586 
       
   587 void CSvgTextElementImpl::FreeFontData()
       
   588 {
       
   589 	
       
   590 	if (iBitmapFont)
       
   591     {
       
   592     	 CSvgBitmapFontProvider *tempBitmapFontProvider = ((CSvgDocumentImpl*)iOwnerDocument)->GetBitmapFontProvider();
       
   593     	 tempBitmapFontProvider->ReleaseFont(iBitmapFont);
       
   594     	 iBitmapFont = NULL;
       
   595     	
       
   596 	}
       
   597 	
       
   598 }
       
   599 
       
   600 
       
   601 // ---------------------------------------------------------------------------
       
   602 //
       
   603 // ---------------------------------------------------------------------------
       
   604 void CSvgTextElementImpl::SetFontFamilyL( const TDesC& aValue )
       
   605     {
       
   606 		//May not need to be called every frame, the CSS value is stored on the element level
       
   607 
       
   608     TInt    pos;
       
   609     if ( iFamilies )
       
   610         {
       
   611         iFamilies->Reset();
       
   612         delete iFamilies;
       
   613         iFamilies = NULL;
       
   614         }
       
   615     iFamilies = new ( ELeave ) CDesCArrayFlat( 1 );
       
   616     TStringTokenizer    tkn ( aValue, _L( "," ) );
       
   617 
       
   618     _LIT( KQuote, "'" );
       
   619     while ( tkn.HasMoreTokens() )
       
   620         {
       
   621         TPtrC lToken = tkn.NextToken();
       
   622         pos = lToken.Find( KQuote );
       
   623         TLex lStr( lToken );
       
   624 
       
   625         const TChar KQuoteChar( '\'' );
       
   626         if ( pos == KErrNotFound )
       
   627             {
       
   628             lStr.SkipSpaceAndMark(); //Skip whitespaces at beginning of font-family value
       
   629             while (lStr.Get()) //get the remaining string from Mark
       
   630             {
       
   631             }
       
   632             lStr.UnGet(); //"back" up one character
       
   633 
       
   634             const TChar KWhiteSpaceChar( ' ' );
       
   635 
       
   636             while (lStr.Peek() == KWhiteSpaceChar) //for multi white spaces at the end
       
   637             {
       
   638             	lStr.UnGet();
       
   639             }
       
   640                         //Token length = iNext pos - iMark pos
       
   641             lStr.Inc(); //Increment iNext position by 1 to "include" iNext
       
   642 
       
   643             }
       
   644         else
       
   645             {
       
   646             pos++;
       
   647             lStr.SkipAndMark( pos );
       
   648             lStr.Inc( pos );
       
   649             while ( lStr.Get() != KQuoteChar )
       
   650                 {
       
   651                 }
       
   652             lStr.UnGet();
       
   653             }
       
   654         TPtrC   lFontFamily = lStr.MarkedToken();
       
   655         iFamilies->AppendL( lFontFamily );
       
   656         }
       
   657 
       
   658         //default font added to end here...
       
   659         iFamilies->AppendL( KDefaultFont ); // _L("DefaultFont"));
       
   660     }
       
   661 
       
   662 // ---------------------------------------------------------------------------
       
   663 //
       
   664 // ---------------------------------------------------------------------------
       
   665 void CSvgTextElementImpl::SetRotateL( const TDesC& aValue )
       
   666     {
       
   667     iArrayRotate = new ( ELeave ) CArrayFixFlat<TReal32>( 1 );
       
   668     TStringTokenizer    tkn ( aValue, _L( ", " ) );
       
   669 
       
   670     TInt lCount = 0;
       
   671 
       
   672     while ( tkn.HasMoreTokens() )
       
   673         {
       
   674         TPtrC   lToken  = tkn.NextToken();
       
   675         TLex    lString ( lToken );
       
   676         TReal32 val;
       
   677         if (lString.Val( val, '.' ) == KErrNone)
       
   678             {
       
   679             iArrayRotate->AppendL( val );
       
   680             lCount++;
       
   681             }
       
   682         }
       
   683 
       
   684     if( lCount == 0)
       
   685         {
       
   686         if ( iArrayRotate )
       
   687             {
       
   688             iArrayRotate->Reset();
       
   689             delete iArrayRotate;
       
   690             iArrayRotate = NULL;
       
   691             }
       
   692         }
       
   693 
       
   694     }
       
   695 
       
   696 // ---------------------------------------------------------------------------
       
   697 //AA: Generic function to parse the "x" or "y" coordinate values
       
   698 // ---------------------------------------------------------------------------
       
   699 void CSvgTextElementImpl::SetArrayL( const TDesC& aValue , const TBool aIsX)
       
   700     {
       
   701 
       
   702     CArrayFixFlat<TFloatFixPt>* lArray;
       
   703     TFloatFixPt lPt;
       
   704     // the flag is used to determine which coodinate needs to be processed
       
   705     if(aIsX)
       
   706         {
       
   707         lArray=iArrayX;
       
   708         lPt=iPoint.iX;
       
   709 
       
   710         }
       
   711     else
       
   712         {
       
   713         lArray=iArrayY;
       
   714         lPt=iPoint.iY;
       
   715         }
       
   716 
       
   717     if ( lArray )
       
   718         {
       
   719         lArray->Reset();
       
   720         delete lArray;
       
   721         lArray = NULL;
       
   722         }
       
   723 
       
   724     lArray = new ( ELeave ) CArrayFixFlat<TFloatFixPt>( 1 );
       
   725 CleanupStack::PushL(lArray);
       
   726 
       
   727     if( (aValue.Length() > 0 ) && ( IsNumberAttributeValid(aValue) ) )
       
   728     {
       
   729         TStringTokenizer    tkn     ( aValue, _L( ", " ) );
       
   730 
       
   731         TInt                lFirstXY = 0;
       
   732 
       
   733         TInt lCount = 0;
       
   734 
       
   735         while ( tkn.HasMoreTokens() )
       
   736         {
       
   737         TPtrC   lToken  = tkn.NextToken();
       
   738         TLex    lString ( lToken );
       
   739         TReal32 val;
       
   740         if (lString.Val( val, '.' ) == KErrNone)
       
   741             {
       
   742         if( val < -32765 )
       
   743             val = -32765;
       
   744         if( val > 32765 )
       
   745             val = 32765;
       
   746 
       
   747         if ( lFirstXY == 0 )
       
   748             {
       
   749             lPt = val;
       
   750             lFirstXY = 1;
       
   751             }
       
   752 
       
   753         lArray->AppendL( ( TFloatFixPt ) val );
       
   754         lCount++;
       
   755             }
       
   756         }
       
   757 
       
   758         if( lCount == 0)
       
   759         {
       
   760         lPt = TFloatFixPt( 0 );
       
   761         lArray->AppendL( ( TFloatFixPt ) 0 );
       
   762         }
       
   763     }
       
   764     else
       
   765     {
       
   766         lPt = TFloatFixPt( 0 );
       
   767         lArray->AppendL( ( TFloatFixPt ) 0 );
       
   768 
       
   769     }
       
   770 CleanupStack::Pop(lArray);
       
   771 
       
   772     if(aIsX)
       
   773         {
       
   774         iPoint.iX = lPt;
       
   775         iArrayX = lArray;
       
   776         }
       
   777     else
       
   778         {
       
   779         iPoint.iY = lPt;
       
   780         iArrayY = lArray;
       
   781         }
       
   782 	// In case of fewer x and more y and 
       
   783 	// fewer y and more x, we need to append the last value of the 
       
   784 	// coordinate to the corresponding array to be used for all the 
       
   785 	// remaining characters.
       
   786 	if ( iArrayY && iArrayX )   
       
   787 		{
       
   788 		
       
   789 		TInt xCount=iArrayX->Count();
       
   790 		TInt yCount=iArrayY->Count();
       
   791 		TInt charCount=iText->Length();
       
   792 		
       
   793 		// Either x or y should be having valid values.
       
   794 		if(xCount>0 || yCount>0)
       
   795    			{
       
   796    			// Text has more characters than the x or y values.
       
   797    			if(charCount>xCount||charCount>yCount)
       
   798    			
       
   799    				{
       
   800    				// More y than x and More characters than x append last
       
   801    				// value of the x coordinate.
       
   802    				if((yCount>=xCount) && (charCount>xCount))
       
   803 	   				{
       
   804 	   				iArrayX->AppendL(iArrayX->At(xCount-1), (charCount-xCount));
       
   805 	   				}
       
   806    				// More x than y and More characters than y append last
       
   807    				// value of the y coordinate.
       
   808    				if((yCount<=xCount) && (charCount>yCount))
       
   809 	   				{
       
   810 	   				iArrayY->AppendL(iArrayY->At(yCount-1), (charCount-yCount));
       
   811 	   				}
       
   812    				}
       
   813    			
       
   814    			}
       
   815 		}
       
   816         
       
   817        }
       
   818 
       
   819 // ---------------------------------------------------------------------------
       
   820 //
       
   821 // ---------------------------------------------------------------------------
       
   822 void CSvgTextElementImpl::SetX( CArrayFix<TFloatFixPt>* aX )
       
   823     {
       
   824     	if (aX->Count() > 0)
       
   825     	{
       
   826     iPoint.iX = aX->At( 0 );
       
   827     	}
       
   828     }
       
   829 
       
   830 // ---------------------------------------------------------------------------
       
   831 //
       
   832 // ---------------------------------------------------------------------------
       
   833 void CSvgTextElementImpl::SetY( CArrayFix<TFloatFixPt>* aY )
       
   834     {
       
   835     	if (aY->Count() > 0)
       
   836     	{
       
   837     iPoint.iY = aY->At( 0 );
       
   838     	}
       
   839     }
       
   840 
       
   841 // *******************************************************
       
   842 // From MXmlElement
       
   843 
       
   844 // ---------------------------------------------------------------------------
       
   845 //
       
   846 // ---------------------------------------------------------------------------
       
   847 TInt CSvgTextElementImpl::SetAttributeL( const TDesC& aName,
       
   848                                          const TDesC& aValue )
       
   849     {
       
   850     CSvgElementImpl::SetAttributeL(aName,aValue);
       
   851     return KErrNone;
       
   852     }
       
   853 
       
   854 
       
   855 // *******************************************************
       
   856 // From MXmlElementOpt
       
   857 
       
   858 // ---------------------------------------------------------------------------
       
   859 //
       
   860 // ---------------------------------------------------------------------------
       
   861 TInt CSvgTextElementImpl::GetAttributeFloat( const TInt aNameId,
       
   862                                              TFloatFixPt& aValue )
       
   863     {
       
   864     switch ( aNameId )
       
   865         {
       
   866         case KAtrX:
       
   867         case KAtrRefX:
       
   868         aValue = iPoint.iX;
       
   869         break;
       
   870         case KAtrY:
       
   871         case KAtrRefY:
       
   872         aValue = iPoint.iY;
       
   873         break;
       
   874         default:
       
   875         return CSvgElementImpl::GetAttributeFloat( aNameId, aValue );
       
   876         }
       
   877     return KErrNone;
       
   878     }
       
   879 // ---------------------------------------------------------------------------
       
   880 //
       
   881 // ---------------------------------------------------------------------------
       
   882 TInt CSvgTextElementImpl::SetAttributeFloatL( const TInt aNameId,
       
   883                                               const TFloatFixPt aValue )
       
   884     {
       
   885     switch ( aNameId )
       
   886         {
       
   887         case KAtrX:
       
   888 			{
       
   889 			iPoint.iX = aValue;
       
   890 			if(!iArrayX)
       
   891 				{
       
   892 				iArrayX= new ( ELeave ) CArrayFixFlat<TFloatFixPt>( 1 );
       
   893 				}
       
   894 
       
   895             iArrayX->Reset();
       
   896 			iArrayX->AppendL((TFloatFixPt)aValue);
       
   897 			}
       
   898         break;
       
   899         case KAtrY:
       
   900 			{
       
   901 			iPoint.iY = aValue;
       
   902 			if(!iArrayY)
       
   903 				{
       
   904 				iArrayY= new ( ELeave ) CArrayFixFlat<TFloatFixPt>( 1 );
       
   905 				}
       
   906 
       
   907             iArrayY->Reset();
       
   908 			iArrayY->AppendL((TFloatFixPt)aValue);
       
   909 			}
       
   910         break;
       
   911 
       
   912 
       
   913         default:
       
   914         return CSvgElementImpl::SetAttributeFloatL( aNameId, aValue );
       
   915         }
       
   916     return KErrNone;
       
   917     }
       
   918 
       
   919 // ---------------------------------------------------------------------------
       
   920 //
       
   921 // ---------------------------------------------------------------------------
       
   922 TInt CSvgTextElementImpl::GetAttributeDes( const TInt aNameId, TPtrC16& aValue )
       
   923     {
       
   924     switch ( aNameId )
       
   925         {
       
   926         case KAtrCdata:
       
   927         aValue.Set(*iText);
       
   928         break;
       
   929         default:
       
   930         return CSvgElementImpl::GetAttributeDes( aNameId, aValue );
       
   931         }
       
   932     return KErrNone;
       
   933     }
       
   934 // ---------------------------------------------------------------------------
       
   935 //
       
   936 // ---------------------------------------------------------------------------
       
   937 TInt CSvgTextElementImpl::SetAttributeDesL( const TInt aNameId,
       
   938                                             const TDesC& aValue )
       
   939     {
       
   940     switch ( aNameId )
       
   941         {
       
   942         case KAtrCdata:
       
   943         SetTextL( aValue );
       
   944         break;
       
   945 
       
   946         case KAtrX:
       
   947         SetArrayL(aValue, ETrue);
       
   948         break;
       
   949 
       
   950         case KAtrY:
       
   951         SetArrayL(aValue, EFalse);
       
   952         break;
       
   953 
       
   954         case KAtrRotate:
       
   955         SetRotateL( aValue );
       
   956         break;
       
   957 
       
   958         default:
       
   959         return CSvgElementImpl::SetAttributeDesL( aNameId, aValue );
       
   960         }
       
   961 
       
   962     // check first character is number or '.'
       
   963     if ( aNameId == KAtrX || aNameId == KAtrY )
       
   964         {
       
   965         if ( aValue.Length() == 0 ||
       
   966              ( !TChar( aValue[0] ).IsDigit() && aValue[0] != '.' && aValue[0] != '-') )
       
   967             {
       
   968             if ( iOwnerDocument )
       
   969                 {
       
   970                _LIT( KMsg, "Invalid value-string for number attribute: " );
       
   971                 ((CSvgDocumentImpl*)iOwnerDocument)->SetError( KErrNotFound, KMsg, aValue );
       
   972                 }
       
   973             }
       
   974         }
       
   975     return KErrNone;
       
   976     }
       
   977 
       
   978 
       
   979 // ---------------------------------------------------------------------------
       
   980 // This is a Local Function.
       
   981 // Checks to see if the given character is within the SVG Font's Unicode Range.*
       
   982 // Only the following formats are allowed for "unicode-range" attribute
       
   983 // Single numbers: U+20A7 | U+215? | U+00?? | U+E??
       
   984 // Pair of numbers: U+AC00-D7FF | U+F9000-FAFF
       
   985 // ---------------------------------------------------------------------------
       
   986 TBool CSvgTextElementImpl::IsWithinUnicodeRange( const TDesC& aUnicodeRange,
       
   987                                                  const TDesC& aCharacter )
       
   988     {
       
   989     _LIT( KQQ, "??" );
       
   990     _LIT( KQ, "?" );
       
   991     _LIT( KF, "F" );
       
   992     _LIT( KFF, "FF" );
       
   993     _LIT( KLitZero, "0" );
       
   994     _LIT( KZZero, "00" );
       
   995     _LIT( KHyph, "-" );
       
   996     _LIT( KUni, "U+" );
       
   997 
       
   998     TUint32     lStartRange = 0;
       
   999     TUint32     lEndRange = 65536;
       
  1000 
       
  1001     TUint32     lCharacter      = ( TUint32 ) aCharacter.operator[]( 0 );
       
  1002 
       
  1003     TBuf<11>    lUnicodeRange;
       
  1004 
       
  1005     if(aUnicodeRange.Length() <= 11)
       
  1006         lUnicodeRange   = aUnicodeRange; //Max.Length "U+00AB-00AF"
       
  1007     else
       
  1008         return EFalse; //Length is greater than 11.
       
  1009 
       
  1010     TInt        pos;
       
  1011 
       
  1012 
       
  1013     //Removing "U+"
       
  1014     pos = lUnicodeRange.Find( KUni );
       
  1015     if ( pos != KErrNotFound )
       
  1016         lUnicodeRange.Delete( pos, 2 );
       
  1017     else
       
  1018         return EFalse; // Not a valid unicode range, i.e. not "U+" element
       
  1019 
       
  1020     //Finding "-", if yes, then pair found.
       
  1021     pos = lUnicodeRange.Find( KHyph );
       
  1022     if ( pos != KErrNotFound )//found
       
  1023     {
       
  1024         TPtrC   lStartString    = lUnicodeRange.Left( pos );
       
  1025         TLex    lStart          ( lStartString );
       
  1026         if (lStart.Val( lStartRange, EHex ) != KErrNone)
       
  1027             lStartRange=0;
       
  1028 
       
  1029         TPtrC   lEndString  = lUnicodeRange.Right( lUnicodeRange.Length() -
       
  1030                                                    pos -
       
  1031                                                    1 );
       
  1032         TLex    lEnd        ( lEndString );
       
  1033         if (lEnd.Val( lEndRange, EHex ) != KErrNone)
       
  1034              lEndRange= 65536;
       
  1035         }
       
  1036     else //single number
       
  1037     {
       
  1038         pos = lUnicodeRange.Find( KQQ );
       
  1039         if ( pos != KErrNotFound )
       
  1040             {
       
  1041             lUnicodeRange.Replace( pos, 2, KZZero );
       
  1042             TPtrC   lStartString    = lUnicodeRange.Left( pos + 2 );
       
  1043             TLex    lStart          ( lStartString );
       
  1044             if (lStart.Val( lStartRange, EHex ) != KErrNone)
       
  1045                 lStartRange=0;
       
  1046 
       
  1047             lUnicodeRange.Replace( pos, 2, KFF );
       
  1048             TPtrC   lEndString  = lUnicodeRange.Left( pos + 2 );
       
  1049             TLex    lEnd        ( lEndString );
       
  1050             if (lEnd.Val( lEndRange, EHex ) != KErrNone)
       
  1051                 lEndRange= 65536;
       
  1052             }
       
  1053 
       
  1054         else if ( (pos = lUnicodeRange.Find( KQ ) ) != KErrNotFound )
       
  1055             {
       
  1056             lUnicodeRange.Replace( pos, 1, KLitZero );
       
  1057             TPtrC   lStartString    = lUnicodeRange.Left( pos + 1 );
       
  1058             TLex    lStart          ( lStartString );
       
  1059             if (lStart.Val( lStartRange, EHex ) != KErrNone)
       
  1060                 lStartRange=0;
       
  1061 
       
  1062             lUnicodeRange.Replace( pos, 1, KF );
       
  1063             TPtrC   lEndString  = lUnicodeRange.Left( pos + 1 );
       
  1064             TLex    lEnd        ( lEndString );
       
  1065             if (lEnd.Val( lEndRange, EHex ) != KErrNone)
       
  1066                 lEndRange= 65536;
       
  1067             }
       
  1068         else
       
  1069             {
       
  1070             TLex    lEnd    ( lUnicodeRange );
       
  1071             if (lEnd.Val( lEndRange, EHex ) != KErrNone)
       
  1072                 lEndRange= 65536;
       
  1073             lStartRange = lEndRange;
       
  1074             }
       
  1075         }
       
  1076 
       
  1077     if ( ( lCharacter >= lStartRange ) && ( lCharacter <= lEndRange ) )
       
  1078         return ETrue;
       
  1079     else
       
  1080         return EFalse;
       
  1081     }
       
  1082 
       
  1083 //Method to set kerning pairs u1 and u2.
       
  1084 // ---------------------------------------------------------------------------
       
  1085 //
       
  1086 // ---------------------------------------------------------------------------
       
  1087 void CSvgTextElementImpl::SetUKernPairsL( const TDesC& aU1, const TDesC& aU2 )
       
  1088    {
       
  1089     if(iU1)
       
  1090     	{
       
  1091 	    delete iU1;
       
  1092 	    iU1 = NULL;
       
  1093     	}
       
  1094     iU1 = aU1.AllocL();
       
  1095 	if(iU2)
       
  1096 		{
       
  1097 		delete iU2;
       
  1098 	    iU2 = NULL;
       
  1099 		}
       
  1100      iU2 = aU2.AllocL();
       
  1101 
       
  1102    }
       
  1103 
       
  1104 
       
  1105 //Method to set kerning pairs g1 and g2.
       
  1106 // ---------------------------------------------------------------------------
       
  1107 //
       
  1108 // ---------------------------------------------------------------------------
       
  1109 void CSvgTextElementImpl::SetGKernPairsL( const TDesC& aG1, const TDesC& aG2 )
       
  1110    {
       
  1111 
       
  1112    if(iG1)
       
  1113 		{
       
  1114 		delete iG1;
       
  1115 		iG1 = NULL;
       
  1116 		}
       
  1117     iG1 = aG1.AllocL();
       
  1118 
       
  1119 	if(iG2)
       
  1120 		{
       
  1121 		delete iG2;
       
  1122 		iG2 = NULL;
       
  1123 		}
       
  1124     iG2 = aG2.AllocL();
       
  1125 
       
  1126    }
       
  1127 
       
  1128 
       
  1129 // ---------------------------------------------------------------------------
       
  1130 // This method checks to see whether kerning is required.
       
  1131 // ---------------------------------------------------------------------------
       
  1132 TBool CSvgTextElementImpl::IsKerningRequired( const TDesC& aPrevGlyphName,
       
  1133                                               const TDesC& aCurrGlyphName,
       
  1134                                               const TDesC& aPrevUnicode,
       
  1135                                               const TDesC& aCurrUnicode )
       
  1136    {
       
  1137     _LIT( KGlyphNameNone, "GlyphNameNone");
       
  1138     TBool lFoundG1(EFalse);
       
  1139     TBool lFoundG2(EFalse);
       
  1140     TBool lFoundU1(EFalse);
       
  1141     TBool lFoundU2(EFalse);
       
  1142 
       
  1143     //Finding G1
       
  1144     if( aPrevGlyphName != KGlyphNameNone)
       
  1145     {
       
  1146     TStringTokenizer    tkn1 ( iG1->Des(), _L( "," ) );
       
  1147     while ( tkn1.HasMoreTokens() )
       
  1148     {
       
  1149         TPtrC   lToken  = tkn1.NextToken();
       
  1150         if( (lToken.Compare(aPrevGlyphName)) == 0 )
       
  1151         {
       
  1152             lFoundG1 = ETrue;
       
  1153                 break;
       
  1154         }
       
  1155     }
       
  1156     }
       
  1157     //Finding G2
       
  1158     if( aCurrGlyphName != KGlyphNameNone)
       
  1159     {
       
  1160     TStringTokenizer    tkn2 ( iG2->Des(), _L( "," ) );
       
  1161     while ( tkn2.HasMoreTokens() )
       
  1162     {
       
  1163         TPtrC   lToken  = tkn2.NextToken();
       
  1164         if( (lToken.Compare(aCurrGlyphName)) == 0 )
       
  1165         {
       
  1166             lFoundG2 = ETrue;
       
  1167                 break;
       
  1168         }
       
  1169     }
       
  1170     }
       
  1171     //Finding U1
       
  1172     TStringTokenizer    tkn3 ( iU1->Des(), _L( "," ) );
       
  1173     while ( tkn3.HasMoreTokens() )
       
  1174     {
       
  1175 
       
  1176         TPtrC   lToken  = tkn3.NextToken();
       
  1177 
       
  1178         if( lToken.Length() == 1) //Unicode character
       
  1179         {
       
  1180             if( (lToken.Compare(aPrevUnicode.Right(1))) == 0 )
       
  1181             {
       
  1182                 lFoundU1 = ETrue;
       
  1183                 break;
       
  1184             }
       
  1185 
       
  1186         }
       
  1187         else // Unicode Range
       
  1188         {
       
  1189             if(IsWithinUnicodeRange( lToken, aPrevUnicode ))
       
  1190                 lFoundU1 = ETrue;
       
  1191                 break;
       
  1192         }
       
  1193 
       
  1194     }
       
  1195 
       
  1196     //Finding U2
       
  1197     TStringTokenizer    tkn4 ( iU2->Des(), _L( "," ) );
       
  1198     while ( tkn4.HasMoreTokens() )
       
  1199     {
       
  1200 
       
  1201         TPtrC   lToken  = tkn4.NextToken();
       
  1202 
       
  1203         if( lToken.Length() == 1) //Unicode character
       
  1204         {
       
  1205             if( (lToken.Compare(aCurrUnicode.Left(1))) == 0 )
       
  1206             {
       
  1207                 lFoundU2 = ETrue;
       
  1208                 break;
       
  1209             }
       
  1210 
       
  1211         }
       
  1212         else // Unicode Range
       
  1213         {
       
  1214             if(IsWithinUnicodeRange( lToken, aCurrUnicode ))
       
  1215             {
       
  1216                 lFoundU2 = ETrue;
       
  1217                 break;
       
  1218             }
       
  1219         }
       
  1220 
       
  1221     }
       
  1222 
       
  1223     if ( (lFoundG1 || lFoundU1) && (lFoundG2 || lFoundU2) )
       
  1224         return ETrue;
       
  1225     else
       
  1226         return EFalse;
       
  1227    }
       
  1228 
       
  1229 
       
  1230 // *******************************************************
       
  1231 // From CSvgElementImpl
       
  1232 
       
  1233 // perform a deep clone of this object
       
  1234 // ---------------------------------------------------------------------------
       
  1235 //
       
  1236 // ---------------------------------------------------------------------------
       
  1237 MXmlElement* CSvgTextElementImpl::CloneL(MXmlElement* aParentElement)
       
  1238     {
       
  1239 
       
  1240 	CSvgTextElementImpl* newElement = CSvgTextElementImpl::NewL(  this->ElemID(), ((CSvgDocumentImpl*)iOwnerDocument) );
       
  1241 
       
  1242 		CleanupStack::PushL(newElement);
       
  1243 	newElement->iParentNode = aParentElement;
       
  1244     // copy everything over
       
  1245     this->CopyL(newElement);
       
  1246 	CleanupStack::Pop();
       
  1247     return newElement;
       
  1248     }
       
  1249 
       
  1250 // ---------------------------------------------------------------------------
       
  1251 // perform a deep copy of this object
       
  1252 // ---------------------------------------------------------------------------
       
  1253 void CSvgTextElementImpl::CopyL( CSvgTextElementImpl* aDestElement )
       
  1254     {
       
  1255     if(aDestElement)
       
  1256     {
       
  1257 
       
  1258     // copy stuff from superclass
       
  1259     this->CSvgElementImpl::CopyL(aDestElement);
       
  1260 
       
  1261 	if(this->iText)
       
  1262 		{
       
  1263          delete aDestElement->iText;
       
  1264 		 aDestElement->iText= NULL;
       
  1265 		 aDestElement->iText= (this->iText)->AllocL();
       
  1266 		}
       
  1267     aDestElement->iPoint.iX= this->iPoint.iX;
       
  1268 	aDestElement->iPoint.iY= this->iPoint.iY;
       
  1269 
       
  1270 	aDestElement->iLetterSpacing= this->iLetterSpacing;
       
  1271 	aDestElement->iWordSpacing= this->iWordSpacing;
       
  1272 	aDestElement->iRotate= this->iRotate;
       
  1273 
       
  1274 	//iFamilies
       
  1275 	if(this->iFamilies)
       
  1276 		{
       
  1277 		TInt lCount= (this->iFamilies)->Count();
       
  1278 		if(lCount)
       
  1279 			{
       
  1280             if(aDestElement->iFamilies)
       
  1281 				{
       
  1282 				aDestElement->iFamilies->Reset();
       
  1283 			    delete aDestElement->iFamilies;
       
  1284 			    aDestElement->iFamilies = NULL;
       
  1285 			    }
       
  1286 			aDestElement->iFamilies = new ( ELeave ) CDesCArrayFlat( 1 );
       
  1287 			for(TInt i=0; i<lCount; i++)
       
  1288 				{
       
  1289 				TPtrC lPtr= (this->iFamilies)->operator[](i);
       
  1290 				aDestElement->iFamilies->AppendL(lPtr);
       
  1291 				}
       
  1292 			}
       
  1293 		}
       
  1294 
       
  1295     //iArraX
       
  1296 	if(this->iArrayX)
       
  1297 		{
       
  1298 		TInt lCount= (this->iArrayX)->Count();
       
  1299 		if(lCount)
       
  1300 			{
       
  1301             if(aDestElement->iArrayX)
       
  1302 				{
       
  1303 				aDestElement->iArrayX->Reset();
       
  1304 			    delete aDestElement->iArrayX;
       
  1305 			    aDestElement->iArrayX = NULL;
       
  1306 			    }
       
  1307 			aDestElement->iArrayX = new ( ELeave ) CArrayFixFlat<TFloatFixPt>( 1 );
       
  1308 			for(TInt i=0; i<lCount; i++)
       
  1309 				{
       
  1310 				TFloatFixPt lFix= (this->iArrayX)->operator[](i);
       
  1311 				aDestElement->iArrayX->AppendL(lFix);
       
  1312 				}
       
  1313 			}
       
  1314 		}
       
  1315 
       
  1316     //iArrayY
       
  1317 	if(this->iArrayY)
       
  1318 		{
       
  1319 		TInt lCount= (this->iArrayY)->Count();
       
  1320 		if(lCount)
       
  1321 			{
       
  1322             if(aDestElement->iArrayY)
       
  1323 				{
       
  1324 				aDestElement->iArrayY->Reset();
       
  1325 			    delete aDestElement->iArrayY;
       
  1326 			    aDestElement->iArrayY = NULL;
       
  1327 			    }
       
  1328 			aDestElement->iArrayY = new ( ELeave ) CArrayFixFlat<TFloatFixPt>( 1 );
       
  1329 			for(TInt i=0; i<lCount; i++)
       
  1330 				{
       
  1331 				TFloatFixPt lFix= (this->iArrayY)->operator[](i);
       
  1332 				aDestElement->iArrayY->AppendL(lFix);
       
  1333 				}
       
  1334 			}
       
  1335 		}
       
  1336 
       
  1337   // iArrayRotate
       
  1338 	if(this->iArrayRotate)
       
  1339 		{
       
  1340 		TInt lCount= (this->iArrayRotate)->Count();
       
  1341 		if(lCount)
       
  1342 			{
       
  1343             if(aDestElement->iArrayRotate)
       
  1344 				{
       
  1345 				aDestElement->iArrayRotate->Reset();
       
  1346 			    delete aDestElement->iArrayRotate;
       
  1347 			    aDestElement->iArrayRotate = NULL;
       
  1348 			    }
       
  1349 			aDestElement->iArrayRotate = new ( ELeave ) CArrayFixFlat<TReal32>( 1 );
       
  1350 			for(TInt i=0; i<lCount; i++)
       
  1351 				{
       
  1352 				TReal32 lFix= (this->iArrayRotate)->operator[](i);
       
  1353 				aDestElement->iArrayRotate->AppendL(lFix);
       
  1354 				}
       
  1355 			}
       
  1356 		}
       
  1357 
       
  1358 ///////////////////Cloning the glyph elements///////////////////////
       
  1359 		TInt lCount= (this->iGlyphElements).Count();
       
  1360 		if(lCount)
       
  1361 			{
       
  1362             for(TInt i=0; i<lCount; i++)
       
  1363 				{
       
  1364 				CSvgElementImpl* element = (this->iGlyphElements).operator[](i);
       
  1365 				aDestElement->iGlyphElements.AppendL(element);
       
  1366 				}
       
  1367 			}
       
  1368 
       
  1369 
       
  1370         aDestElement->iNeedToCacheGlyphs = this->iNeedToCacheGlyphs;
       
  1371 
       
  1372 //////////////////////////////////////////////////////////////////////
       
  1373 	aDestElement->iTextAnchor= this->iTextAnchor;
       
  1374 	aDestElement->iTextDecoration= this->iTextDecoration;
       
  1375 
       
  1376 	if(this->iG1)
       
  1377 		{
       
  1378          delete aDestElement->iG1;
       
  1379 		 aDestElement->iG1= NULL;
       
  1380 		 aDestElement->iG1= (this->iG1)->AllocL();
       
  1381 		}
       
  1382 
       
  1383 	if(this->iG2)
       
  1384 		{
       
  1385          delete aDestElement->iG2;
       
  1386 		 aDestElement->iG2= NULL;
       
  1387 		 aDestElement->iG2= (this->iG2)->AllocL();
       
  1388 		}
       
  1389 
       
  1390 	if(this->iU1)
       
  1391 		{
       
  1392          delete aDestElement->iU1;
       
  1393 		 aDestElement->iU1= NULL;
       
  1394 		 aDestElement->iU1= (this->iU1)->AllocL();
       
  1395 		}
       
  1396 
       
  1397 	if(this->iU2)
       
  1398 		{
       
  1399          delete aDestElement->iU2;
       
  1400 		 aDestElement->iU2= NULL;
       
  1401 		 aDestElement->iU2= (this->iU2)->AllocL();
       
  1402 		}
       
  1403 
       
  1404 	//Note that copying iBitmapFont from one text element to
       
  1405 	//another, there is danger of double free. Let new element
       
  1406 	//get its own Font pointer. Anyway it just updates the
       
  1407 	//access count on the server side if two fonts are same.
       
  1408 	//aDestElement->iBitmapFont= this->iBitmapFont;
       
  1409 	aDestElement->iBitmapFont= NULL;
       
  1410 
       
  1411 
       
  1412     // copy the reference to idoc (CSvgDocumentImpl)
       
  1413     aDestElement->iOwnerDocument = this->iOwnerDocument;
       
  1414     }
       
  1415 
       
  1416     }
       
  1417 
       
  1418 // ---------------------------------------------------------------------------
       
  1419 // This Method is used to draw the TEXT described within the <text> element.
       
  1420 // There are 2 types of Fonts used to render the text. First, the family-name
       
  1421 // is checked to see if there exists a SVG FONT defined within the SVG File.
       
  1422 // If there is one, then text is rendered using this font, else the text is
       
  1423 // rendered using the Bitmap system fonts using the Drawstring() in Gfx2D.
       
  1424 // ---------------------------------------------------------------------------
       
  1425 TBool CSvgTextElementImpl::DrawL( CGfx2dGc* aGc, CSvgElementImpl* aElement )
       
  1426 {
       
  1427     if (iText->Length() == 0)
       
  1428        {
       
  1429        	return EFalse;
       
  1430        }
       
  1431 
       
  1432     // Reset and set GC
       
  1433     this->DrawShapeL( aGc, aElement );
       
  1434     //if ( !aGc->RenderingHints()->Visibility() )
       
  1435       //  return EFalse;  // Do nothing if visibility is False.
       
  1436 
       
  1437 
       
  1438     TInt8   lTextDecoration = (TInt8)
       
  1439     (((CIntCssValueImpl *)(iSvgStyleProperties->operator[](KCSS_ATTR_TEXTDECORATION)))->Value());
       
  1440 
       
  1441     TInt8   lTextAnchor =(TInt8)(
       
  1442     ((CIntCssValueImpl *)(iSvgStyleProperties->operator[](KCSS_ATTR_TEXTANCHOR)))->Value());
       
  1443 
       
  1444 /**********************************************************/
       
  1445 /* ROM Configuration Flag whether to include SVG FONTS    */
       
  1446 /**********************************************************/
       
  1447 
       
  1448 	//get the scaling factor currently in the graphics library.
       
  1449 
       
  1450     TFloatFixPt KZero;
       
  1451 
       
  1452     //CSvgElementImpl* lFirstChild = NULL;
       
  1453     CGfxGeneralPath* lShape = NULL;
       
  1454     CGfxGeneralPath* lShapeMG = NULL;
       
  1455     TFloatFixPt origX ( iPoint.iX );
       
  1456     TFloatFixPt currentPosOrigX( iPoint.iX );
       
  1457     /*iSVGBbox.iX = iPoint.iX;
       
  1458     iSVGBbox.iY = iPoint.iY;
       
  1459     iSVGBbox.iWidth = 0;*/
       
  1460     TFloatFixPt currentPosOrigY( iPoint.iY );
       
  1461     TFloatFixPt lUnitsPerEm( 1000 );
       
  1462     TFloatFixPt lAlphabetic( 0 );
       
  1463     TFloatFixPt lFontHorzOrgX( 0 );
       
  1464     TFloatFixPt lFontHorzAdvX( 0 );
       
  1465     TFloatFixPt lMissingGlyphHorzAdvX( 0 );
       
  1466     TFloatFixPt lFontSize( 10 );
       
  1467     TPtrC lFontFamily;
       
  1468     TPtrC16 lUnicode;
       
  1469     TPtrC16 lPrevUnicode;
       
  1470     TPtrC16 lUnicodeRange; //Max.Length "U+00AB-00AF"
       
  1471     TPtrC16 lLangCode; //ex: en-US or en-GB or ja-JP or zh-CN or en....
       
  1472     TPtrC16 lG1;
       
  1473     TPtrC16 lG2;
       
  1474     TPtrC16 lU1;
       
  1475     TPtrC16 lU2;
       
  1476     TPtrC16 lPrevGlyphName;
       
  1477     TPtrC16 lCurrGlyphName;
       
  1478     TFloatFixPt lK; //kerning purpose....
       
  1479 
       
  1480     TFloatFixPt lAscent( KZero );
       
  1481     TFloatFixPt lDescent( KZero );
       
  1482     TFloatFixPt lUnderlinePosition( KZero );
       
  1483     TFloatFixPt lUnderlineThickness( KZero );
       
  1484     TFloatFixPt lOverlinePosition( KZero );
       
  1485     TFloatFixPt lOverlineThickness( KZero );
       
  1486     TFloatFixPt lStrikethroughPosition( KZero );
       
  1487     TFloatFixPt lStrikethroughThickness( KZero );
       
  1488     TFloatFixPt lTotalTextAdvance ( KZero );
       
  1489 
       
  1490     //Getting font-size property
       
  1491 
       
  1492     CCssValue* lCssValue = NULL;
       
  1493     this->FindProperty( KCSS_ATTR_FONTSIZE, lCssValue, aElement );
       
  1494     if ( lCssValue )
       
  1495         {
       
  1496         lFontSize = (( CFloatCssValueImpl * ) lCssValue )->Value();
       
  1497         if(lFontSize <= KZero )
       
  1498             lFontSize = TFloatFixPt ( 10 );
       
  1499         }
       
  1500 
       
  1501     //Getting font-family property
       
  1502     this->FindProperty( KCSS_ATTR_FONTFAMILY, lCssValue, aElement );
       
  1503     if ( lCssValue && ((( CStrCssValueImpl * ) lCssValue )->Value()).Length() != 0)
       
  1504         {
       
  1505         lFontFamily.Set( ( ( CStrCssValueImpl * ) lCssValue )->Value() );
       
  1506         SetFontFamilyL( lFontFamily );
       
  1507         }
       
  1508 
       
  1509 	
       
  1510 		//attempt to load svg font files of same font family name
       
  1511 		//this boolean will be a problem if we want to be able to swap
       
  1512 		//font-family names on the fly and use svg fonts.
       
  1513     	if (!iTriedLoadingSVGFonts)
       
  1514     	{
       
  1515     		LoadExternalSVGFontL(lFontFamily);
       
  1516     		iTriedLoadingSVGFonts = ETrue;
       
  1517     	}
       
  1518 
       
  1519     //Retrieving Font Element Pointer from the Font Table
       
  1520     //if font in svg document
       
  1521     iSVGFont = NULL;
       
  1522     if ( iFamilies != NULL )
       
  1523     {
       
  1524     	TInt familiesCnt = iFamilies->Count();
       
  1525     	for (int i=0; i< familiesCnt; i++)
       
  1526     	{
       
  1527         	iSVGFont = ( CSvgElementImpl * )
       
  1528                 ((CSvgDocumentImpl*)iOwnerDocument)->Engine()->iFontHashMap->GetFontPtr(iFamilies->operator[]( i ));
       
  1529 
       
  1530 			if (iSVGFont == NULL)
       
  1531 			{
       
  1532 				iSVGFont = ( CSvgElementImpl * )
       
  1533                 ((CSvgDocumentImpl*)iOwnerDocument)->iFontHashMap->GetFontPtr( iFamilies->operator[]( i ) );
       
  1534 			}
       
  1535 
       
  1536         	if (iSVGFont != NULL)
       
  1537         	{
       
  1538         		//found a font with that family name...continue
       
  1539         		break;
       
  1540         	}
       
  1541     	}
       
  1542     }
       
  1543 
       
  1544 /**********************************************************/
       
  1545 /* Checking for pre-defined SVG Fonts through the         */
       
  1546 /* retrieved pointer from the Font Table.                 */
       
  1547 /* IF the Font is found (ptr!=NULL), SVG Fonts are used   */
       
  1548 /* ELSE Bitmap Font is used through DrawString() method   */
       
  1549 /**********************************************************/
       
  1550 
       
  1551     if ( iSVGFont != NULL && iSVGFont->HasChildNodes())
       
  1552     {
       
  1553        	TGfxAffineTransform currentTM;
       
  1554        	//we found an svg font and are using it...
       
  1555 
       
  1556        	iSVGFont->GetAttributeFloat( KAtrHorizOriginX, lFontHorzOrgX );
       
  1557        	iSVGFont->GetAttributeFloat( KAtrHorizAdvX, lFontHorzAdvX );
       
  1558        	lMissingGlyphHorzAdvX = lFontHorzAdvX; //Default Value
       
  1559        	TInt checkErrShapeMG = -1;//To keep a value other than KErrNone. Should this be replaced
       
  1560 
       
  1561        	if (iNeedToCacheGlyphs)
       
  1562        	{
       
  1563        		CacheGlyphsForText();
       
  1564        	}
       
  1565 
       
  1566         TFloatFixPt lUnitsPerEmInverse;
       
  1567         TFloatFixPt minusOne( -1 );
       
  1568 
       
  1569 		/***********************/
       
  1570     	/* HKERN ELEMENT       */
       
  1571     	/***********************/
       
  1572         if (iHkernElement != NULL)
       
  1573         {
       
  1574        		iHkernElement->GetAttributeFloat( KAtrK, lK );
       
  1575 
       
  1576           	TInt checkErrorG1 = iHkernElement->GetAttributeDes( KAtrG1, lG1);
       
  1577           	TInt checkErrorG2 = iHkernElement->GetAttributeDes( KAtrG2, lG2);
       
  1578            	TInt checkErrorU1 = iHkernElement->GetAttributeDes( KAtrU1, lU1);
       
  1579            	TInt checkErrorU2 = iHkernElement->GetAttributeDes( KAtrU2, lU2);
       
  1580 
       
  1581        		if( (checkErrorG1 != KErrNoAttribute) && (checkErrorG2 != KErrNoAttribute) )
       
  1582       		{
       
  1583         		  SetGKernPairsL( lG1, lG2);
       
  1584        		}
       
  1585 
       
  1586        		if( (checkErrorU1 != KErrNoAttribute) && (checkErrorU2 != KErrNoAttribute) )
       
  1587           	{
       
  1588           		SetUKernPairsL( lU1, lU2);
       
  1589           	}
       
  1590         }
       
  1591 
       
  1592     	/********************************/
       
  1593     	/* Text Rendering functionality */
       
  1594     	/*******************************/
       
  1595 
       
  1596     	/***********************/
       
  1597     	/* MISSINGGLYPH ELEMENT*/
       
  1598     	/***********************/
       
  1599         if (iMissingGlyphElement != NULL)
       
  1600         {
       
  1601            	iMissingGlyphElement->GetAttributeFloat( KAtrHorizAdvX,
       
  1602                                                     lMissingGlyphHorzAdvX );
       
  1603 
       
  1604            	if ( lMissingGlyphHorzAdvX == TFloatFixPt( 0 ) )
       
  1605            	{
       
  1606            		lMissingGlyphHorzAdvX = lFontHorzAdvX;
       
  1607            	}
       
  1608 
       
  1609            	checkErrShapeMG = iMissingGlyphElement->GetAttributePath( KAtrData,
       
  1610                                                                     lShapeMG );
       
  1611          }
       
  1612 
       
  1613    		/***********************/
       
  1614    		/* FONTFACE ELEMENT    */
       
  1615    		/***********************/
       
  1616 
       
  1617 		if (iFontFaceElement != NULL)
       
  1618 		{
       
  1619            	iFontFaceElement->GetAttributeFloat( KAtrUnitsPerEm,
       
  1620                                                     lUnitsPerEm );
       
  1621 
       
  1622 	#ifdef SVG_FLOAT_BUILD
       
  1623 	       	if ( lUnitsPerEm <= TFloatFixPt( 0 ) )
       
  1624         	{
       
  1625               	lUnitsPerEm = TFloatFixPt( 1000 );
       
  1626             }
       
  1627 	#else
       
  1628 	       	if ( lUnitsPerEm <= TFloatFixPt( 0,ETrue ) )
       
  1629         	{
       
  1630               	lUnitsPerEm = TFloatFixPt( 1000 );
       
  1631             }
       
  1632 	#endif
       
  1633             lUnitsPerEmInverse = TFloatFixPt( 1 ) / lUnitsPerEm;
       
  1634 
       
  1635             iFontFaceElement->GetAttributeFloat( KAtrAscent,
       
  1636                                                     lAscent );
       
  1637 
       
  1638             iFontFaceElement->GetAttributeFloat( KAtrDescent,
       
  1639                                                     lDescent );
       
  1640 
       
  1641             iFontFaceElement->GetAttributeFloat( KAtrUnderlinePosition,
       
  1642                                                     lUnderlinePosition );
       
  1643 
       
  1644             iFontFaceElement->GetAttributeFloat( KAtrUnderlineThickness,
       
  1645                                                     lUnderlineThickness );
       
  1646 
       
  1647             iFontFaceElement->GetAttributeFloat( KAtrOverlinePosition,
       
  1648                                                     lOverlinePosition );
       
  1649 
       
  1650             iFontFaceElement->GetAttributeFloat( KAtrOverlineThickness,
       
  1651                                                     lOverlineThickness );
       
  1652 
       
  1653          	iFontFaceElement->GetAttributeFloat( KAtrStrikethroughPosition,
       
  1654                                                     lStrikethroughPosition );
       
  1655 
       
  1656             iFontFaceElement->GetAttributeFloat( KAtrStrikethroughThickness,
       
  1657                                                     lStrikethroughThickness );
       
  1658 
       
  1659             iFontFaceElement->GetAttributeFloat( KAtrAlphabetic,
       
  1660                                                     lAlphabetic );
       
  1661         }
       
  1662 
       
  1663         //Checking valid UnicodeRange of FontFace Element this is trying to limit the number that we have to search through
       
  1664         //but why do we need this in here
       
  1665 
       
  1666         /*TInt checkErrorUnicodeRange = iFontFaceElement->GetAttributeDes( KAtrUnicodeRange,
       
  1667                                                                                 lUnicodeRange );
       
  1668         if ( checkErrorUnicodeRange != KErrNoAttribute )
       
  1669         {
       
  1670           	//Function call to unicode-range bounds.
       
  1671             if(!IsWithinUnicodeRange( lUnicodeRange,
       
  1672                                                   outputChar ))
       
  1673             {
       
  1674                	currentPosOrigX += ( lFontHorzAdvX * lUnitsPerEmInverse ) * lFontSize;
       
  1675                 lIsWithinUnicodeRange = EFalse;
       
  1676                 break;
       
  1677             }
       
  1678         }*/
       
  1679 
       
  1680         //Text Anchor related.
       
  1681         //lTotalTextAdvance = lFontHorzAdvX * (TFloatFixPt)iText->Length() * lUnitsPerEmInverse * lFontSize;
       
  1682         // Calculate the exact total text advance instead of taking default per glyph
       
  1683         // advance which will approximate the value.
       
  1684         TFloatFixPt lGlyphHorzAdvX;
       
  1685         TInt langCodeFound( 0 );
       
  1686         // Calculate the total text advance in the following cases:
       
  1687         //     a. Text Anchor is middle
       
  1688         //     b. Text Anchor is end
       
  1689         //     c. Text Decoration is needed( Underline/Overline/Strikethrough )
       
  1690         if( lTextAnchor == 1 || lTextAnchor == 2 || lTextDecoration != -1 )
       
  1691             {  
       
  1692                lTotalTextAdvance= GetTotalTextAdvance(lK,lUnitsPerEmInverse,lFontSize,lMissingGlyphHorzAdvX,lFontHorzAdvX);
       
  1693             }
       
  1694 
       
  1695         if( lTextAnchor == 1 )//Middle
       
  1696         {
       
  1697           	currentPosOrigX -= (lTotalTextAdvance * TFloatFixPt(.5f));
       
  1698             origX -= (lTotalTextAdvance * TFloatFixPt(.5f));
       
  1699         }
       
  1700 
       
  1701         if( lTextAnchor == 2 )//End
       
  1702         {
       
  1703             currentPosOrigX -= lTotalTextAdvance;
       
  1704             origX -= lTotalTextAdvance;
       
  1705         }
       
  1706         //else default:start
       
  1707 
       
  1708         if( lAlphabetic != KZero )
       
  1709         {
       
  1710             //Should be rationally negative, but Adobe traverses positive.
       
  1711             currentPosOrigY += ( lAlphabetic * lUnitsPerEmInverse ) * lFontSize;
       
  1712         }
       
  1713 
       
  1714         if( lFontHorzOrgX != KZero )
       
  1715         {
       
  1716             //Should be rationally positive, but Adobe traverses negative.
       
  1717             currentPosOrigX -= ( lFontHorzOrgX * lUnitsPerEmInverse ) * lFontSize;
       
  1718             origX -= ( lFontHorzOrgX * lUnitsPerEmInverse ) * lFontSize;
       
  1719         }
       
  1720 
       
  1721     	/***********************/
       
  1722     	/* GLYPH ELEMENT       */
       
  1723     	/***********************/
       
  1724     	 //Assume that xml:lang matches lang code of glyph element.
       
  1725         //TInt lUnicodeLength( 0 );
       
  1726 		
       
  1727 		//The x coordinate is needed to draw the text decorations. 
       
  1728 		if(iArrayX)
       
  1729     		{
       
  1730     		origX=iArrayX->At(0);
       
  1731     		}
       
  1732 		TInt glyphEleCnt = iGlyphElements.Count();
       
  1733         for (TInt i=0; i < glyphEleCnt; i++)
       
  1734         {
       
  1735         	CSvgElementImpl* lGlyphElement = (CSvgElementImpl*)iGlyphElements[i];
       
  1736 
       
  1737         	if (lGlyphElement != NULL)
       
  1738         	{
       
  1739         		//have a valid glyph
       
  1740         		TInt checkErrorUnicode = lGlyphElement->GetAttributeDes( KAtrUnicode,
       
  1741                                                                            lUnicode );
       
  1742                 //check the glyph name
       
  1743                 TInt checkErrorGlyphName = lGlyphElement->GetAttributeDes( KAtrGlyphName,
       
  1744                                                                            lCurrGlyphName );
       
  1745               	if( checkErrorGlyphName == KErrNoAttribute )
       
  1746               	{
       
  1747               		lCurrGlyphName.Set( KGlyphNameNone );
       
  1748               	}
       
  1749 
       
  1750                 //check its language
       
  1751                 TInt checkErrorLangCode = lGlyphElement->GetAttributeDes( KAtrLang,
       
  1752                                                                             lLangCode );
       
  1753                 TPtrC lXmlLangAttr(this->XMLLang());
       
  1754 
       
  1755                 if( checkErrorLangCode != KErrNoAttribute ) //if Lang code present
       
  1756                 {
       
  1757                   	langCodeFound = lLangCode.CompareF( lXmlLangAttr );//compare xml:lang with Lang code.
       
  1758                 }
       
  1759 
       
  1760                 //if Lang code is matching && unicode attr. present, we are good.
       
  1761                 if ( (checkErrorUnicode != KErrNoAttribute) && (langCodeFound == 0) )
       
  1762                 {
       
  1763                   	//Checking and Introducing kerning(adjusting spacing).
       
  1764                     if( lPrevGlyphName.Length() > 0 )
       
  1765                     {
       
  1766                          if( IsKerningRequired( lPrevGlyphName, lCurrGlyphName, lPrevUnicode, lUnicode ))
       
  1767                          {
       
  1768                               currentPosOrigX -= ( lK * lUnitsPerEmInverse ) * lFontSize;
       
  1769                          }
       
  1770                     }
       
  1771 
       
  1772                     lGlyphElement->GetAttributeFloat( KAtrHorizAdvX,
       
  1773                                                        lGlyphHorzAdvX );
       
  1774 
       
  1775 	#ifdef SVG_FLOAT_BUILD
       
  1776                     if ( lGlyphHorzAdvX == TFloatFixPt( 0 ) )
       
  1777 	#else
       
  1778                     if ( lGlyphHorzAdvX == TFloatFixPt( 0,ETrue ) )
       
  1779 	#endif
       
  1780                     {
       
  1781                       	lGlyphHorzAdvX = /*(TFloatFixPt)lUnicodeLength **/ lFontHorzAdvX;
       
  1782                     }
       
  1783 
       
  1784                     TInt checkErrorShape = lGlyphElement->GetAttributePath( KAtrData,
       
  1785                                                                                   lShape );
       
  1786                   	/***********************/
       
  1787     				/* Drawing the Glyph   */
       
  1788     				/***********************/
       
  1789                     if ( checkErrorShape == KErrNone )
       
  1790                     {
       
  1791                         this->DrawShapeL( aGc, aElement );
       
  1792 						
       
  1793             			// Fix for UMAA-753ARS
       
  1794             			// Scale the strokewidth before applying 
       
  1795             			// the scaling for glyph
       
  1796             			ScaleStrokeWidth(aGc);
       
  1797     					
       
  1798     					// For multiple x, y get the current position 
       
  1799     					// from the array.
       
  1800     					if((iArrayX != NULL ) && ( i< iArrayX->Count() ))
       
  1801     						{
       
  1802     						currentPosOrigX = iArrayX->At(i);
       
  1803     						}
       
  1804     					if((iArrayY!=NULL) && (i<iArrayY->Count() ) )
       
  1805     						{
       
  1806     						currentPosOrigY = iArrayY->At(i);
       
  1807     						}
       
  1808     																	
       
  1809 						currentTM = this->GetCTM();
       
  1810 
       
  1811                         currentTM.Translate( currentPosOrigX,
       
  1812                                                      currentPosOrigY );
       
  1813                         currentTM.Scale( lUnitsPerEmInverse,
       
  1814                                                 minusOne * lUnitsPerEmInverse );
       
  1815                         currentTM.Scale( lFontSize, lFontSize );
       
  1816                         aGc->SetTransform( currentTM );
       
  1817 
       
  1818                         aGc->DrawL( lShape );
       
  1819 
       
  1820                         lPrevUnicode.Set(lUnicode);
       
  1821                         lPrevGlyphName.Set(lCurrGlyphName);
       
  1822 
       
  1823                         currentPosOrigX += ( lGlyphHorzAdvX * lUnitsPerEmInverse ) * lFontSize;
       
  1824 
       
  1825                     }
       
  1826                 }
       
  1827 
       
  1828         	}
       
  1829         	else
       
  1830         	{
       
  1831         		//need to use missing glyph for this one...
       
  1832         		//iGlyphElements.Insert(iMissingGlyphElement, i);
       
  1833 
       
  1834         		/***********************/
       
  1835                 /* Drawing MissingGlyph*/
       
  1836                 /***********************/
       
  1837 
       
  1838                	if ( checkErrShapeMG == KErrNone )
       
  1839                 {
       
  1840                    	this->DrawShapeL( aGc, aElement );
       
  1841 					
       
  1842 					// Fix for UMAA-753ARS
       
  1843             		// Scale the strokewidth before applying 
       
  1844             		// the scaling for glyph
       
  1845             		ScaleStrokeWidth(aGc);
       
  1846                    	
       
  1847                    	// For multiple x, y get the current position 
       
  1848     				// from the array.
       
  1849                    	if((iArrayX != NULL ) && ( i< iArrayX->Count() ))
       
  1850     						{
       
  1851     						currentPosOrigX = iArrayX->At(i);
       
  1852     						}
       
  1853     					if((iArrayY!=NULL) && (i<iArrayY->Count() ) )
       
  1854     						{
       
  1855     						currentPosOrigY = iArrayY->At(i);
       
  1856     						}
       
  1857                    	currentTM = this->GetCTM();
       
  1858 
       
  1859                    	currentTM.Translate( currentPosOrigX, currentPosOrigY );
       
  1860                    	currentTM.Scale( lUnitsPerEmInverse,
       
  1861                                     minusOne * lUnitsPerEmInverse );
       
  1862                    	currentTM.Scale( lFontSize, lFontSize );
       
  1863                    	aGc->SetTransform( currentTM );
       
  1864 					
       
  1865                    	aGc->DrawL( lShapeMG );
       
  1866                  }
       
  1867 
       
  1868                  currentPosOrigX += ( lMissingGlyphHorzAdvX * lUnitsPerEmInverse ) * lFontSize;
       
  1869 
       
  1870              }
       
  1871         }//end-for
       
  1872 		TGfxRectangle2D lBbox;
       
  1873 		if(iGlyphElements[glyphEleCnt-1] && lShape)
       
  1874 			{
       
  1875 			// Get the bbox for the last glyph element. 
       
  1876 			lShape->GetBounds(currentTM,lBbox);
       
  1877 			}
       
  1878 		else if ( lShapeMG )
       
  1879 			{
       
  1880 			// Get the bbox for the last missing-glyph element.
       
  1881 			lShapeMG->GetBounds(currentTM,lBbox);
       
  1882 			}
       
  1883 		currentPosOrigX=lBbox.iX+lBbox.iWidth;
       
  1884 /**********************************************************/
       
  1885 /* Text Decoration Implementation for SVG Fonts           */
       
  1886 /* The following attributes are supported in this section */
       
  1887 /* "underline-position"                                   */
       
  1888 /* "underline-thickness"                                  */
       
  1889 /* "overline-position"                                    */
       
  1890 /* "overline-thickness"                                   */
       
  1891 /* "strikethrough-position"                               */
       
  1892 /* "strikethrough-thickness"                              */
       
  1893 /**********************************************************/
       
  1894 
       
  1895        if( lTextDecoration != -1 )
       
  1896        {
       
  1897            TFloatFixPt lLineStartX( origX );//Text Anchored position(see under fontfaceFound section).
       
  1898            TFloatFixPt lLineStartY( currentPosOrigY );
       
  1899            TFloatFixPt lLineEndX( origX + lTotalTextAdvance );
       
  1900            TFloatFixPt lLineEndY( currentPosOrigY );
       
  1901            TFloatFixPt lStrokeThickness ( 1 );//default thickness > 0; pensize is set to 1 in Gfx2D.
       
  1902 
       
  1903            if( lTextDecoration == 1 )
       
  1904             {
       
  1905                if( lUnderlinePosition != KZero )
       
  1906                {
       
  1907                 //negative(minus sign) due to inverted font coordinate system
       
  1908                    lLineStartY = lLineEndY = currentPosOrigY - (lUnderlinePosition * lUnitsPerEmInverse) * lFontSize;
       
  1909                }
       
  1910                else if( lUnderlinePosition == KZero  && lDescent != KZero )
       
  1911                {
       
  1912                    lLineStartY = lLineEndY = currentPosOrigY - ((lDescent/TFloatFixPt(2)) * lUnitsPerEmInverse) * lFontSize;
       
  1913                }
       
  1914                else
       
  1915                {
       
  1916                    //default. No information provided( descent or underline position)
       
  1917                }
       
  1918                if( lUnderlineThickness != KZero )
       
  1919                {
       
  1920                 lStrokeThickness = lUnderlineThickness * lUnitsPerEmInverse * lFontSize ;
       
  1921                }
       
  1922            }
       
  1923 
       
  1924            if( lTextDecoration == 2 )
       
  1925            {
       
  1926             if( lOverlinePosition != KZero )
       
  1927                {
       
  1928                 //negative(minus sign) due to inverted font coordinate system
       
  1929                    lLineStartY = lLineEndY = currentPosOrigY - (lOverlinePosition * lUnitsPerEmInverse) * lFontSize;
       
  1930                }
       
  1931                else if( lOverlinePosition == KZero && lAscent != KZero )
       
  1932                {
       
  1933                    lLineStartY = lLineEndY = currentPosOrigY - (lAscent * lUnitsPerEmInverse) * lFontSize;
       
  1934                }
       
  1935                else
       
  1936                {
       
  1937                    //default. No information provided( ascent or overline position)
       
  1938                }
       
  1939                if( lOverlineThickness != KZero )
       
  1940                {
       
  1941                 lStrokeThickness = lOverlineThickness * lUnitsPerEmInverse * lFontSize ;
       
  1942                }
       
  1943            }
       
  1944 
       
  1945 
       
  1946            if( lTextDecoration == 3 )
       
  1947            {
       
  1948                if( lStrikethroughPosition != KZero )
       
  1949                {
       
  1950                 //negative(minus sign) due to inverted font coordinate system
       
  1951                    lLineStartY = lLineEndY = currentPosOrigY - (lStrikethroughPosition * lUnitsPerEmInverse) * lFontSize;
       
  1952                }
       
  1953                else if( lStrikethroughPosition == KZero && lAscent != KZero )
       
  1954                {
       
  1955                    lLineStartY = lLineEndY = currentPosOrigY - ((lAscent/TFloatFixPt(3)) * lUnitsPerEmInverse) * lFontSize;
       
  1956                }
       
  1957                else
       
  1958                {
       
  1959                    //default. No information provided( ascent or strikethrough position)
       
  1960                }
       
  1961                if( lStrikethroughThickness != KZero )
       
  1962                {
       
  1963                 lStrokeThickness = lStrikethroughThickness * lUnitsPerEmInverse * lFontSize ;
       
  1964                }
       
  1965            }
       
  1966 
       
  1967            TGfxLine2D lLine( lLineStartX ,lLineStartY, lLineEndX, lLineEndY );
       
  1968 
       
  1969            this->DrawShapeL( aGc, aElement );
       
  1970 
       
  1971            // Setting Stokewidth for SVG Fonts. Check if there exists a value or default value (1) is set.
       
  1972            if( ( lOverlineThickness != KZero ) || ( lUnderlineThickness != KZero ) || ( lStrikethroughThickness != KZero ) )
       
  1973            {
       
  1974                TGfxStroke lStroke = aGc->Stroke();
       
  1975                lStroke.SetStrokeWidth( lStrokeThickness); // relation to font co-ordinate system.
       
  1976                aGc->SetStroke( lStroke );
       
  1977            }
       
  1978 
       
  1979 
       
  1980            TGfxColor lForegroundColor(aGc->ForegroundColor());
       
  1981            if ( lForegroundColor.GetColor() == KGfxColorNull )
       
  1982            {
       
  1983            	if ( (aGc->Paint()) != NULL )
       
  1984                	aGc->SetForegroundColor(TGfxColor( (aGc->Paint())->GetColor() ));
       
  1985            }
       
  1986 
       
  1987        	aGc->DrawL( &lLine );
       
  1988        }//end of text decoration functionality
       
  1989     }
       
  1990     else
       
  1991     {
       
  1992 
       
  1993 /**********************************************************/
       
  1994 /* If SVG Font is not available then Bitmap Fonts are used*/
       
  1995 /* to render the text by calling the DrawString() function*/
       
  1996 /* of Gfx2D                                               */
       
  1997 /**********************************************************/
       
  1998             UpdateCurrentScaledFont();
       
  1999 
       
  2000         aGc->DrawStringL( iText->Des(),
       
  2001                          iPoint.iX,
       
  2002                          iPoint.iY,
       
  2003                          lTextAnchor,
       
  2004                          lTextDecoration,
       
  2005                          iFamilies,
       
  2006                          iWordSpacing,
       
  2007                          iLetterSpacing,
       
  2008                          iArrayRotate,
       
  2009                          iArrayX,
       
  2010                          iArrayY,
       
  2011                          iBoundingBox,
       
  2012 			 iBitmapFont,
       
  2013 			 iBitmapFontSpec );
       
  2014 
       
  2015         // Storing of the font is done in above routine
       
  2016         // only, hence removing below lines.
       
  2017         // store font info for bitmap font
       
  2018         //if ( iBitmapFont == NULL )
       
  2019       //iBitmapFont = GetCurrentFontScaled();
       
  2020 
       
  2021     }
       
  2022             // Fix for ScreenSaver Bug
       
  2023          CSvgDocumentImpl* doc = (CSvgDocumentImpl*)OwnerDocument();
       
  2024             if ( doc && doc->Engine() )
       
  2025             {
       
  2026              iGfx2dGc = doc->Engine()->GraphicsContext();
       
  2027             }
       
  2028     return EFalse;
       
  2029 }
       
  2030 
       
  2031 // -----------------------------------------------------------------------------
       
  2032 // void CSvgTextElementImpl::ScaleStrokeWidth(CGfx2dGc* aGc)
       
  2033 // Scale the stroke width in order to nullify the effect of scaling appiled on
       
  2034 // the glyph
       
  2035 // -----------------------------------------------------------------------------
       
  2036 void CSvgTextElementImpl::ScaleStrokeWidth(CGfx2dGc* aGc)
       
  2037 	{
       
  2038 	
       
  2039     TFloatFixPt lStrokeWidth;
       
  2040     CCssValue* lCssValue = NULL;
       
  2041     this->FindProperty( KCSS_ATTR_STROKEWIDTH, lCssValue);
       
  2042 	if ( lCssValue )
       
  2043     	{
       
  2044         lStrokeWidth = ( ( CFloatCssValueImpl * ) lCssValue )->Value();
       
  2045         if (lStrokeWidth <= TFloatFixPt(0))
       
  2046         	{
       
  2047             aGc->SetStrokeWidth( TFloatFixPt(0) );
       
  2048             }
       
  2049         else
       
  2050         	{
       
  2051     		// Get the font-size
       
  2052     		TFloatFixPt lFontSize( 10 );
       
  2053     		this->FindProperty( KCSS_ATTR_FONTSIZE, lCssValue, NULL );
       
  2054     		if ( lCssValue )
       
  2055         		{
       
  2056         		lFontSize = (( CFloatCssValueImpl * ) lCssValue )->Value();
       
  2057         		if(lFontSize <= TFloatFixPt(0) )
       
  2058         			{
       
  2059         			lFontSize = TFloatFixPt ( 10 );
       
  2060         			}
       
  2061         		}
       
  2062 			TFloatFixPt lUnitsPerEm( 1000 );
       
  2063 			
       
  2064 			// Get units-per-em
       
  2065 			if (iFontFaceElement != NULL)
       
  2066 				{
       
  2067 				iFontFaceElement->GetAttributeFloat( KAtrUnitsPerEm,
       
  2068                                                     lUnitsPerEm );
       
  2069 		
       
  2070 				#ifdef SVG_FLOAT_BUILD
       
  2071 	       				if ( lUnitsPerEm <= TFloatFixPt( 0 ) )
       
  2072         					{
       
  2073             				lUnitsPerEm = TFloatFixPt( 1000 );
       
  2074             				}
       
  2075 				#else
       
  2076 	       				if ( lUnitsPerEm <= TFloatFixPt( 0,ETrue ) )
       
  2077         					{
       
  2078               				lUnitsPerEm = TFloatFixPt( 1000 );
       
  2079             				}
       
  2080 				#endif
       
  2081 			
       
  2082 				}
       
  2083         
       
  2084             	lStrokeWidth=(lStrokeWidth*lUnitsPerEm)/lFontSize;
       
  2085         		aGc->SetStrokeWidth(lStrokeWidth);      
       
  2086            	}
       
  2087      	}
       
  2088 													
       
  2089 	}
       
  2090 
       
  2091 // *******************************************************
       
  2092 // From MSvgLocatable/MSvgTransformable
       
  2093 // ---------------------------------------------------------------------------
       
  2094 //
       
  2095 // ---------------------------------------------------------------------------
       
  2096 void CSvgTextElementImpl::GetBBox( TGfxRectangle2D& aBbox )
       
  2097     {
       
  2098     	if (iSVGFont)
       
  2099     	{
       
  2100     		//get the bounding boxes of
       
  2101     		//all of the glyphs in the child and add them together.
       
  2102     		GetBBoxForSVGText(aBbox);
       
  2103     	}
       
  2104     	else if (iBitmapFont)
       
  2105     	{
       
  2106     		GetBBoxForSystemText(aBbox);
       
  2107         }
       
  2108         else
       
  2109         {
       
  2110             //this is an error case if it gets to here
       
  2111             // When GetBBox is called just after PrepareDom, the font
       
  2112             // spec is not initialied yet. It happens only in DrawL.
       
  2113             // To take care of this issue, and give a correct bounding box,
       
  2114             // Bitmap font is assumed. Note: This would not work if
       
  2115             // SVG font is selected. This needs to be fixed more generically.
       
  2116 
       
  2117             UpdateCurrentScaledFont();
       
  2118         	if (iBitmapFont)
       
  2119         	    {
       
  2120         	    GetBBoxForSystemText(aBbox);
       
  2121         	    }
       
  2122         	else
       
  2123         	    {
       
  2124         	    aBbox.iY = iPoint.iY;
       
  2125         	    aBbox.iX = iPoint.iX;
       
  2126         	    aBbox.iWidth = 0;
       
  2127         	    aBbox.iHeight = 0;
       
  2128         	    }
       
  2129 
       
  2130         }
       
  2131     }
       
  2132 
       
  2133 // ---------------------------------------------------------------------------
       
  2134 //
       
  2135 // ---------------------------------------------------------------------------
       
  2136 void CSvgTextElementImpl::GetFourPointBBox( TSvgFourPointRect& aFourPointBBox )
       
  2137     {
       
  2138     	if (iSVGFont)
       
  2139     	{
       
  2140     		//get the bounding boxes of
       
  2141     		//all of the glyphs in the child and add them together.
       
  2142     		GetBBoxForSVGText(aFourPointBBox,this->GetCTM());
       
  2143     	}
       
  2144     	else if (iBitmapFont)
       
  2145     	{
       
  2146     		GetBBoxForSystemText(aFourPointBBox);
       
  2147         }
       
  2148         else
       
  2149         {
       
  2150         	//this is an error case if it gets to here
       
  2151         }
       
  2152     }
       
  2153 
       
  2154 void CSvgTextElementImpl::GetBBoxForSVGText( TGfxRectangle2D& aBbox )
       
  2155 {
       
  2156 	//bbox for svg fonts
       
  2157 	TSvgFourPointRect lFourPtRect;
       
  2158     GetBBoxForSVGText(lFourPtRect,this->GetCTM());
       
  2159 
       
  2160     lFourPtRect.GetTRect(aBbox);
       
  2161 }
       
  2162 
       
  2163 void CSvgTextElementImpl::GetBBoxForSVGText( TSvgFourPointRect& aFourPointBbox, const TGfxAffineTransform& aTransform)
       
  2164 {
       
  2165 	//bbox for svg fonts
       
  2166     TGfxRectangle2D lBbox;
       
  2167 
       
  2168 	TFloatFixPt lascent = Ascent();
       
  2169 	TFloatFixPt ldescent = Descent();
       
  2170 	
       
  2171 	// Fix for ANAE-739CPX
       
  2172 	// When ascent and descent are not specified, get the 
       
  2173 	// the translated and scaled bounding-box for each glyph
       
  2174 	// and then find the total bounding box.
       
  2175 	TFloatFixPt KZero;
       
  2176 	if(lascent<=KZero||ldescent<=KZero)
       
  2177 		{
       
  2178 	    TGfxRectangle2D lBbox1; /* Final bounding box for the text */
       
  2179 		TFloatFixPt lFontSize;
       
  2180         CCssValue* lCssValue = NULL;
       
  2181         
       
  2182         // Get the font-size
       
  2183     	this->FindProperty( KCSS_ATTR_FONTSIZE, lCssValue, NULL );
       
  2184     	if ( lCssValue )
       
  2185         	{
       
  2186         	lFontSize = (( CFloatCssValueImpl * ) lCssValue )->Value();
       
  2187         	if(lFontSize <= KZero )
       
  2188         		{
       
  2189         		lFontSize = TFloatFixPt ( KDefaultFontSize );
       
  2190         		}
       
  2191         	}
       
  2192 	
       
  2193         TFloatFixPt lUnitsPerEm( KDefaultUnitsPerEm );
       
  2194 		TFloatFixPt lUnitsPerEmInverse(KZero);
       
  2195 		
       
  2196 		// Get units-per-em
       
  2197 		if (iFontFaceElement != NULL)
       
  2198 			{
       
  2199            	iFontFaceElement->GetAttributeFloat( KAtrUnitsPerEm,
       
  2200                                                     lUnitsPerEm );
       
  2201 		
       
  2202 
       
  2203 	       	if ( lUnitsPerEm <= KZero  )
       
  2204           		{
       
  2205               	lUnitsPerEm = TFloatFixPt( KDefaultUnitsPerEm );
       
  2206             	}
       
  2207 	    
       
  2208             lUnitsPerEmInverse = TFloatFixPt( KOne ) / lUnitsPerEm;
       
  2209 			}
       
  2210 		
       
  2211 			TFloatFixPt lGlyphHorzAdvX(KZero);
       
  2212 			TFloatFixPt lFontHorzAdvX(KZero);
       
  2213 			TFloatFixPt lMissingGlyphHorzAdvX(KZero);
       
  2214 			TFloatFixPt lK(KZero);
       
  2215 			
       
  2216 			if(iSVGFont)
       
  2217 				{
       
  2218 				// Get horiz-adv-x
       
  2219 				iSVGFont->GetAttributeFloat( KAtrHorizAdvX, lFontHorzAdvX );
       
  2220 				}
       
  2221 			
       
  2222 			
       
  2223 			if (iMissingGlyphElement != NULL)
       
  2224         		{
       
  2225            		iMissingGlyphElement->GetAttributeFloat( KAtrHorizAdvX,
       
  2226                                                     lMissingGlyphHorzAdvX );
       
  2227 			
       
  2228 
       
  2229 				if ( lMissingGlyphHorzAdvX == KZero )
       
  2230 	  	   			{
       
  2231            			lMissingGlyphHorzAdvX = lFontHorzAdvX;
       
  2232            			}
       
  2233         		}
       
  2234         
       
  2235 			// Get "k" for hkern
       
  2236 			if(iHkernElement)
       
  2237 				{
       
  2238 				iHkernElement->GetAttributeFloat( KAtrK, lK );	
       
  2239 				}
       
  2240 			TFloatFixPt currentPosOrigX(iPoint.iX);
       
  2241 			
       
  2242 			// Find the total width of the BBox
       
  2243 			TFloatFixPt lTotalTextAdvance =GetTotalTextAdvance(lK,lUnitsPerEmInverse,lFontSize,lMissingGlyphHorzAdvX,lFontHorzAdvX);
       
  2244 			
       
  2245 			//Get the text-anchor
       
  2246 			TInt8   lTextAnchor =(TInt8)(
       
  2247 			((CIntCssValueImpl *)(iSvgStyleProperties->operator[](
       
  2248 									KCSS_ATTR_TEXTANCHOR)))->Value());
       
  2249 
       
  2250 			if( lTextAnchor == 1 )//Middle
       
  2251         		{
       
  2252           		currentPosOrigX -= (lTotalTextAdvance * TFloatFixPt(.5f));
       
  2253             	}
       
  2254 
       
  2255         	if( lTextAnchor == 2 )//End
       
  2256         		{
       
  2257             	currentPosOrigX -= lTotalTextAdvance;
       
  2258             	}
       
  2259         		
       
  2260 			TFloatFixPt minusOne( -1 );
       
  2261         	
       
  2262            	// (xMin1, yMin1) is the Top-left-corner and 
       
  2263         	// (xMax1, yMax1) is the bottom-right-corner 
       
  2264         	// of the final bounding box for the text    
       
  2265 	   		TFloatFixPt xMin1(KMAXFLOATFIX), yMin1(KMAXFLOATFIX), xMax1(KMINFLOATFIX), yMax1(KMINFLOATFIX);
       
  2266 	   		TGfxRectangle2D lBbox;
       
  2267 			const TDesC& ltext=*iText;
       
  2268 	    	TInt ltextLength = ltext.Length();
       
  2269 			TInt glyphEleCnt = iGlyphElements.Count();
       
  2270 	   	
       
  2271 	   		for (TInt i= 0; i < ltextLength && i < glyphEleCnt; i++)
       
  2272     			{
       
  2273        			CSvgElementImpl* lGlyphElement = (CSvgElementImpl*)iGlyphElements[i];
       
  2274         		
       
  2275         		CGfxGeneralPath* lShape = NULL;
       
  2276                 if(lGlyphElement||iMissingGlyphElement)
       
  2277                 	{
       
  2278                 		// Tranformation Matrix for positioning and scaling the BBox
       
  2279         			TGfxAffineTransform myCurrentTM =  aTransform;
       
  2280 			
       
  2281 					myCurrentTM.Translate( currentPosOrigX, iPoint.iY);
       
  2282         		
       
  2283             		myCurrentTM.Scale( lUnitsPerEmInverse,
       
  2284       	                           minusOne * lUnitsPerEmInverse );
       
  2285             		myCurrentTM.Scale( lFontSize, lFontSize );
       
  2286                 	
       
  2287                 	if(lGlyphElement)
       
  2288                 		{
       
  2289                 		TInt checkErrorShape = lGlyphElement->GetAttributePath( 
       
  2290                 											KAtrData,lShape );	
       
  2291 						
       
  2292                         lGlyphElement->GetAttributeFloat( KAtrHorizAdvX,
       
  2293                                                            lGlyphHorzAdvX );
       
  2294 
       
  2295     
       
  2296                         if ( lGlyphHorzAdvX == KZero )
       
  2297     	                    {
       
  2298                           	lGlyphHorzAdvX = /*(TFloatFixPt)lUnicodeLength **/ lFontHorzAdvX;
       
  2299                         	}
       
  2300                 		currentPosOrigX += ( lGlyphHorzAdvX * lUnitsPerEmInverse ) * lFontSize;
       
  2301                 		}
       
  2302 					else 
       
  2303 						{
       
  2304 						TInt checkErrorShape = iMissingGlyphElement->
       
  2305 								GetAttributePath(KAtrData,lShape );	
       
  2306 					
       
  2307 						currentPosOrigX += ( lMissingGlyphHorzAdvX * lUnitsPerEmInverse ) * lFontSize;
       
  2308 						}
       
  2309       				// Get the tranformed BBox for each glyph
       
  2310         			lShape->GetBounds(myCurrentTM,	lBbox);
       
  2311         		
       
  2312         			// Find the (xMin1,yMin1) and (xMax1, yMax1) for the total 
       
  2313         			// bounding box of text
       
  2314         			if(lBbox.iX<xMin1) xMin1=lBbox.iX;
       
  2315         			if(lBbox.iY<yMin1) yMin1=lBbox.iY;
       
  2316         			if((lBbox.iY+lBbox.iHeight)>yMax1) yMax1=lBbox.iY+lBbox.iHeight;
       
  2317         			if((lBbox.iX+lBbox.iWidth)>xMax1) xMax1=lBbox.iX+lBbox.iWidth;
       
  2318         			}
       
  2319             	     
       
  2320            		}
       
  2321         	lBbox1.iX=xMin1;
       
  2322         	lBbox1.iY=yMin1;
       
  2323         	lBbox1.iWidth=xMax1-xMin1;
       
  2324         	lBbox1.iHeight=yMax1-yMin1;
       
  2325          
       
  2326            	aFourPointBbox.SetRectPoints(lBbox1);
       
  2327 			return;		
       
  2328 		}
       
  2329 	//  End of fix for ANAE-739CPX
       
  2330 
       
  2331 	lBbox.iHeight = lascent + ldescent;
       
  2332 	lBbox.iWidth = TextAdvance(*iText);
       
  2333 
       
  2334 	TReal32 lascentReal = (TReal32)lascent;
       
  2335 	TReal32 ldescentReal = (TReal32)ldescent;
       
  2336 	TReal32 liHeightReal = (TReal32)lBbox.iHeight;
       
  2337 	TReal32 liWidthReal = (TReal32)lBbox.iWidth;
       
  2338 
       
  2339 		//////////////////// rotate without scaling again //////////////////////
       
  2340     lBbox.iX = iPoint.iX;
       
  2341     lBbox.iY = iPoint.iY - lascent;
       
  2342 
       
  2343     //at this point the bbox not scaled,translated but not rotated
       
  2344 
       
  2345     //should we create 1/scale factor or create with scale factor then get inverse
       
  2346     /*TGfxAffineTransform aScaleMat;
       
  2347     TReal32 inverseScale = 1.0/(TReal)iScale;
       
  2348     aScaleMat = TGfxAffineTransform::GetScaleInstance(inverseScale, inverseScale);
       
  2349     */
       
  2350 
       
  2351     const TGfxAffineTransform& ctm = aTransform;
       
  2352 
       
  2353   	TGfxPoint2D transformedPoint(lBbox.iX, lBbox.iY);
       
  2354     ctm.Transform(&transformedPoint, &transformedPoint, 1);
       
  2355 
       
  2356     TGfxPoint2D lTopLeftCorner(lBbox.iX, lBbox.iY);
       
  2357     TGfxPoint2D lTopRightCorner(lBbox.iX + lBbox.iWidth, lBbox.iY);
       
  2358     TGfxPoint2D lBottomLeftCorner(lBbox.iX, lBbox.iY + lBbox.iHeight);
       
  2359     TGfxPoint2D lBottomRightCorner(lBbox.iX + lBbox.iWidth, lBbox.iY + lBbox.iHeight);
       
  2360 
       
  2361     TGfxPoint2D lTransTopLeftCorner;
       
  2362     TGfxPoint2D lTransBottomLeftCorner;
       
  2363     TGfxPoint2D lTransTopRightCorner;
       
  2364     TGfxPoint2D lTransBottomRightCorner;
       
  2365 
       
  2366     ctm.Transform(&lTopLeftCorner, &lTransTopLeftCorner,1);
       
  2367     ctm.Transform(&lTopRightCorner, &lTransTopRightCorner,1);
       
  2368     ctm.Transform(&lBottomLeftCorner, &lTransBottomLeftCorner,1);
       
  2369     ctm.Transform(&lBottomRightCorner, &lTransBottomRightCorner,1);
       
  2370 
       
  2371     TFloatFixPt lXTranslation =  transformedPoint.iX - lTransTopLeftCorner.iX;
       
  2372     TFloatFixPt lYTranslation = (transformedPoint.iY - lTransTopLeftCorner.iY ); //- ascent;
       
  2373 
       
  2374     // X position is affected by anchor
       
  2375     switch( TextAnchor() )
       
  2376     {
       
  2377        	case EStartAnchor:
       
  2378            	//do nothing
       
  2379         break;
       
  2380        	case EMiddleAnchor:
       
  2381        		lXTranslation = lXTranslation - ( lBbox.iWidth / TFloatFixPt( 2 ) );
       
  2382         break;
       
  2383        	case EEndAnchor:
       
  2384            	lXTranslation = lXTranslation - lBbox.iWidth;
       
  2385         break;
       
  2386        	default:
       
  2387        	 	//do nothing
       
  2388        	break;
       
  2389     }
       
  2390 
       
  2391     lTransTopLeftCorner.iX = lTransTopLeftCorner.iX + lXTranslation;
       
  2392     lTransTopLeftCorner.iY = lTransTopLeftCorner.iY + lYTranslation;
       
  2393 
       
  2394     lTransTopRightCorner.iX = lTransTopRightCorner.iX + lXTranslation;
       
  2395     lTransTopRightCorner.iY = lTransTopRightCorner.iY + lYTranslation;
       
  2396 
       
  2397     lTransBottomLeftCorner.iX = lTransBottomLeftCorner.iX + lXTranslation;
       
  2398     lTransBottomLeftCorner.iY = lTransBottomLeftCorner.iY + lYTranslation;
       
  2399 
       
  2400     lTransBottomRightCorner.iX = lTransBottomRightCorner.iX + lXTranslation;
       
  2401     lTransBottomRightCorner.iY = lTransBottomRightCorner.iY + lYTranslation;
       
  2402 
       
  2403     //at this point I have the exact path coordinates of the bbox
       
  2404     aFourPointBbox.SetRectPoints(lTransTopLeftCorner, lTransTopRightCorner, lTransBottomLeftCorner, lTransBottomRightCorner);
       
  2405 
       
  2406 	//aFourPointBbox.SetRectPoints(aTopLeftCorner, aTopRightCorner, aBottomLeftCorner, aBottomRightCorner);
       
  2407 
       
  2408 }
       
  2409 
       
  2410 void CSvgTextElementImpl::GetBBoxForSystemText( TGfxRectangle2D& aBbox )
       
  2411 {
       
  2412 	//bbox for bitmap fonts
       
  2413 	TSvgFourPointRect lFourPtRect;
       
  2414     GetBBoxForSystemText(lFourPtRect);
       
  2415 
       
  2416     lFourPtRect.GetTRect(aBbox);
       
  2417 
       
  2418 }
       
  2419 
       
  2420 void CSvgTextElementImpl::GetBBoxForSystemText( TSvgFourPointRect& aFourPointBbox )
       
  2421 {
       
  2422     //bbox for bitmap fonts
       
  2423     TGfxRectangle2D lBbox;
       
  2424 
       
  2425     iScale = GetCurrentScale();
       
  2426 
       
  2427     if (iBoundingBox.iWidth == 0 && iBoundingBox.iHeight == 0)
       
  2428         {
       
  2429         iBoundingBox.iWidth  = iBitmapFont->TextWidthInPixels(iText->Des());
       
  2430         iBoundingBox.iHeight = iBitmapFont->FontMaxHeight();
       
  2431         }
       
  2432 
       
  2433     //scaled already for bitmap text...
       
  2434     lBbox.iWidth  = iBoundingBox.iWidth;
       
  2435     lBbox.iHeight = iBoundingBox.iHeight;
       
  2436     TFloatFixPt lascent = Ascent();
       
  2437     TFloatFixPt ldescent = TFloatFixPt(iBoundingBox.iHeight) - Ascent();
       
  2438     TReal32 linverseScale = 1.0/(TReal)iScale;
       
  2439     
       
  2440     TGfxAffineTransform lInitTranslationMat = TGfxAffineTransform::GetTranslateInstance(iPoint.iX,iPoint.iY);
       
  2441     TGfxAffineTransform lTotalMat = GetCTM();
       
  2442     lTotalMat.Concatenate(lInitTranslationMat);
       
  2443     TGfxAffineTransform lInverseScaleMat = TGfxAffineTransform::GetScaleInstance(linverseScale, linverseScale);
       
  2444     lTotalMat.Concatenate(lInverseScaleMat);
       
  2445     TGfxAffineTransform lDescentCorrectionMat =TGfxAffineTransform::GetTranslateInstance(0,ldescent);
       
  2446     lTotalMat.Concatenate(lDescentCorrectionMat);
       
  2447 
       
  2448     TGfxPoint2D lTopLeftCorner(0, TFloatFixPt(0) - lBbox.iHeight );
       
  2449     TGfxPoint2D lTopRightCorner(lBbox.iWidth , TFloatFixPt(0) - lBbox.iHeight );
       
  2450     TGfxPoint2D lBottomLeftCorner(0, 0);
       
  2451     TGfxPoint2D lBottomRightCorner(lBbox.iWidth, 0 );
       
  2452 
       
  2453     
       
  2454     TGfxPoint2D lTransTopLeftCorner;
       
  2455     TGfxPoint2D lTransBottomLeftCorner;
       
  2456     TGfxPoint2D lTransTopRightCorner;
       
  2457     TGfxPoint2D lTransBottomRightCorner;
       
  2458 
       
  2459 		//applying current rotation transform without the scale.
       
  2460     lTotalMat.Transform(&lTopLeftCorner, &lTransTopLeftCorner,1);
       
  2461     lTotalMat.Transform(&lTopRightCorner, &lTransTopRightCorner,1);
       
  2462     lTotalMat.Transform(&lBottomLeftCorner, &lTransBottomLeftCorner,1);
       
  2463     lTotalMat.Transform(&lBottomRightCorner, &lTransBottomRightCorner,1);
       
  2464 
       
  2465     TFloatFixPt lXTranslation = 0;
       
  2466     //TFixPt lXTranslation = transformedPoint.iX - iPoint.iX;
       
  2467 
       
  2468     TFloatFixPt lYTranslation = 0;
       
  2469 		//TFixPt lYTranslation = transformedPoint.iY - iPoint.iY;
       
  2470 
       
  2471     // X position is affected by anchor
       
  2472     switch( TextAnchor() )
       
  2473     {
       
  2474        	case EStartAnchor:
       
  2475            	//do nothing
       
  2476         break;
       
  2477        	case EMiddleAnchor:
       
  2478        		lXTranslation = lXTranslation - ( lBbox.iWidth / TFloatFixPt( 2 ) );
       
  2479         break;
       
  2480        	case EEndAnchor:
       
  2481            	lXTranslation = lXTranslation - lBbox.iWidth;
       
  2482         break;
       
  2483        	default:
       
  2484        	 	//do nothing
       
  2485        	break;
       
  2486     }
       
  2487 
       
  2488     lTransTopLeftCorner.iX += lXTranslation;
       
  2489     lTransTopLeftCorner.iY += lYTranslation;
       
  2490 
       
  2491     lTransTopRightCorner.iX += lXTranslation;
       
  2492     lTransTopRightCorner.iY += lYTranslation;
       
  2493 
       
  2494     lTransBottomLeftCorner.iX += lXTranslation;
       
  2495     lTransBottomLeftCorner.iY += lYTranslation;
       
  2496 
       
  2497     lTransBottomRightCorner.iX += lXTranslation;
       
  2498     lTransBottomRightCorner.iY += lYTranslation;
       
  2499 
       
  2500     //at this point I have the exact path coordinates of the bbox
       
  2501     aFourPointBbox.SetRectPoints(lTransTopLeftCorner, lTransTopRightCorner, lTransBottomLeftCorner, lTransBottomRightCorner);
       
  2502 }
       
  2503 
       
  2504 
       
  2505 // ---------------------------------------------------------------------------
       
  2506 //
       
  2507 // ---------------------------------------------------------------------------
       
  2508 void CSvgTextElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox )
       
  2509     {
       
  2510     if((iText->Des()).Length()==0)
       
  2511     	{
       
  2512     		aBbox.iHeight=0;
       
  2513     		aBbox.iWidth=0;
       
  2514     		aBbox.iX=0;
       
  2515     		aBbox.iY=0;
       
  2516     		return;
       
  2517     		
       
  2518     	}
       
  2519     //  If both bitmap font and SVG font are not present then 
       
  2520     //  attempt to fetch SVG font. If that fails then 
       
  2521     //  try obtaining the bitmap font
       
  2522    if ( iSVGFont  )
       
  2523     	{
       
  2524         TSvgFourPointRect lFourPtRect;
       
  2525         TGfxAffineTransform TM ;
       
  2526         GetBBoxForSVGText(lFourPtRect,TM);
       
  2527         
       
  2528         lFourPtRect.GetTRect(aBbox);
       
  2529         return;
       
  2530         }
       
  2531     
       
  2532     else
       
  2533     
       
  2534       	{
       
  2535       	
       
  2536       	TRAPD( ErrCode , CreateSVGFontL());
       
  2537       	if( ErrCode != KErrNotFound)
       
  2538       	   {
       
  2539             //first en cache the glymph and then 
       
  2540             //calculate total text advance
       
  2541             TSvgFourPointRect lFourPtRect;
       
  2542             TGfxAffineTransform TM ;
       
  2543         	GetBBoxForSVGText(lFourPtRect,TM);
       
  2544             lFourPtRect.GetTRect(aBbox);
       
  2545             return;
       
  2546             }
       
  2547        
       
  2548        
       
  2549        else
       
  2550             {
       
  2551             UpdateCurrentScaledFont();
       
  2552             iBoundingBox.iWidth = iBitmapFont->TextWidthInPixels(iText->Des());
       
  2553         	iBoundingBox.iHeight = iBitmapFont->FontMaxHeight();
       
  2554       
       
  2555         	      //unscaled for bitmap text...
       
  2556             aBbox.iWidth = iBoundingBox.iWidth;
       
  2557             TFloatFixPt ascent = Ascent();
       
  2558                 //aBbox.iHeight = ascent + Descent();
       
  2559 
       
  2560             aBbox.iHeight = iBoundingBox.iHeight;
       
  2561 
       
  2562             aBbox.iY = iPoint.iY - ascent;
       
  2563             
       
  2564             // X position is affected by anchor
       
  2565 		    switch( TextAnchor() )
       
  2566 		        {
       
  2567 		        case EStartAnchor:
       
  2568 		            aBbox.iX = iPoint.iX;
       
  2569 		            break;
       
  2570 		        case EMiddleAnchor:
       
  2571 		            aBbox.iX = iPoint.iX - ( aBbox.iWidth / TFloatFixPt( 2 ) );
       
  2572 		            break;
       
  2573 		        case EEndAnchor:
       
  2574 		            aBbox.iX = iPoint.iX - aBbox.iWidth;
       
  2575 		            break;
       
  2576 		        default:
       
  2577 		            aBbox.iX = iPoint.iX;
       
  2578 		            break;
       
  2579 		        }
       
  2580 		            
       
  2581             } 	
       
  2582       	 
       
  2583       	}
       
  2584       
       
  2585       	
       
  2586     }
       
  2587 
       
  2588 
       
  2589 
       
  2590 
       
  2591 void  CSvgTextElementImpl::SetRotateArray(CArrayFixFlat<TReal32>*& aRotate)
       
  2592     {
       
  2593      if ( iArrayRotate )
       
  2594         {
       
  2595         iArrayRotate->Reset();
       
  2596         delete iArrayRotate;
       
  2597         iArrayRotate= NULL;
       
  2598         }
       
  2599 
       
  2600      iArrayRotate= aRotate;
       
  2601 /*   TInt lCount= aRotate->Count();
       
  2602      iArrayRotate = new ( ELeave ) CArrayFixFlat<TReal32>( lCount );
       
  2603 
       
  2604      for (TInt i=0; i<lCount; i++)
       
  2605         {
       
  2606          iArrayRotate->AppendL((TReal32)aRotate->operator[](i));
       
  2607         }
       
  2608         */
       
  2609     }
       
  2610 
       
  2611 void CSvgTextElementImpl::SetXYArray(TUint16 aAtrId, CArrayFixFlat<TFloatFixPt>*& aX )
       
  2612     {
       
  2613     if (aAtrId== KAtrX)
       
  2614         {
       
  2615         if ( iArrayX )
       
  2616             {
       
  2617             iArrayX->Reset();
       
  2618             delete iArrayX;
       
  2619             iArrayX = NULL;
       
  2620             }
       
  2621         iArrayX= aX;
       
  2622         SetX(aX);
       
  2623         }
       
  2624     else
       
  2625         {
       
  2626         if ( iArrayY )
       
  2627             {
       
  2628             iArrayY->Reset();
       
  2629             delete iArrayY;
       
  2630             iArrayY = NULL;
       
  2631             }
       
  2632         iArrayY= aX;
       
  2633         SetY(aX);
       
  2634         }
       
  2635     }
       
  2636 
       
  2637 TFloatFixPt CSvgTextElementImpl::FontSize()
       
  2638 {
       
  2639     CCssValue* cssValue = NULL;
       
  2640     FindProperty( KCSS_ATTR_FONTSIZE, cssValue, this );
       
  2641     if ( cssValue )
       
  2642     {
       
  2643         TFloatFixPt fontsize = ((CFloatCssValueImpl*)cssValue)->Value();
       
  2644         if ( fontsize  <= TFloatFixPt( 0 ) )
       
  2645             fontsize = TFloatFixPt( 10 );
       
  2646         return fontsize;
       
  2647     }
       
  2648     else
       
  2649     {
       
  2650     	return 10;
       
  2651     }
       
  2652 }
       
  2653 
       
  2654 TFloatFixPt CSvgTextElementImpl::TextAdvance( const TDesC& aText, TInt aIndex )
       
  2655 {
       
  2656     if ( iBitmapFont )
       
  2657     {
       
  2658     	TInt advance = 0;
       
  2659         UpdateCurrentScaledFont();
       
  2660     	if ( iBitmapFont)
       
  2661     	{
       
  2662     		advance = ((CFbsFont*)iBitmapFont)->TextWidthInPixels(aText);
       
  2663 
       
  2664     		return TFloatFixPt(advance);
       
  2665     	}
       
  2666 
       
  2667     	return 0;
       
  2668     }
       
  2669     else if ( iSVGFont )
       
  2670     {
       
  2671     	//if an svg font...
       
  2672     	TReal32 fontHorzAdvX = 0.0;
       
  2673     	TFloatFixPt advanceX = TFloatFixPt( 0 );
       
  2674 
       
  2675 		TInt textLength = aText.Length();
       
  2676 		TInt glyphEleCnt = iGlyphElements.Count();
       
  2677 	   	for (TInt i= aIndex; i < (aIndex+textLength) && (i< glyphEleCnt); i++)
       
  2678     	{
       
  2679     		//assuming that glyph element cache is a parallel vector here
       
  2680     		CSvgElementImpl* lGlyphElement = (CSvgElementImpl*)iGlyphElements[i];
       
  2681 
       
  2682         	if (lGlyphElement != NULL)
       
  2683         	{
       
  2684     			lGlyphElement->GetAttributeFloat( KAtrHorizAdvX, advanceX );
       
  2685     			fontHorzAdvX += (TReal32)advanceX;
       
  2686     		}
       
  2687     	}
       
  2688 
       
  2689     	TFloatFixPt lUnitsPerEm = TFloatFixPt(1000);
       
  2690 
       
  2691 		if (iFontFaceElement)
       
  2692     	{
       
  2693         	iFontFaceElement->GetAttributeFloat( KAtrUnitsPerEm, lUnitsPerEm);
       
  2694 
       
  2695  			if (lUnitsPerEm == TFloatFixPt(0))
       
  2696  			{
       
  2697         		lUnitsPerEm = TFloatFixPt(1000);
       
  2698         	}
       
  2699  		}
       
  2700 
       
  2701  		// Must use TReal to prevent overflow
       
  2702         TReal32 retValue = fontHorzAdvX * (TReal32)FontSize() / (TReal32)lUnitsPerEm;
       
  2703     	return (TFloatFixPt)retValue;
       
  2704     }
       
  2705     else
       
  2706     {
       
  2707     	//case where we dont have a bitmap font or an svg font
       
  2708     	return 0;
       
  2709     }
       
  2710 }
       
  2711 
       
  2712 
       
  2713 
       
  2714 TFloatFixPt CSvgTextElementImpl::Ascent()
       
  2715 {
       
  2716     
       
  2717         //check for the bbox issue
       
  2718         if ( iSVGFont )
       
  2719         {
       
  2720         //if an svg font the ascent is this...
       
  2721 
       
  2722         TFloatFixPt lAscent, lUnitsPerEm;
       
  2723         TReal32 totalAscent = 0.0;
       
  2724 
       
  2725         if (iFontFaceElement)
       
  2726             {
       
  2727             iFontFaceElement->GetAttributeFloat( KAtrAscent,
       
  2728                                                     lAscent );
       
  2729 
       
  2730             iFontFaceElement->GetAttributeFloat( KAtrUnitsPerEm, lUnitsPerEm);
       
  2731 
       
  2732             if(lUnitsPerEm==TFloatFixPt(0))
       
  2733             	{
       
  2734             	lUnitsPerEm=TFloatFixPt(1000);
       
  2735             	}
       
  2736             totalAscent = (TReal32)lAscent * (TReal32)FontSize() / (TReal32)lUnitsPerEm;
       
  2737 
       
  2738             return (TFloatFixPt)totalAscent;
       
  2739             }
       
  2740 
       
  2741         //default value for ascent
       
  2742         return 0;
       
  2743         }
       
  2744         else if ( iBitmapFont )
       
  2745             {
       
  2746           //  if ( iBitmapFont )
       
  2747         
       
  2748         UpdateCurrentScaledFont();
       
  2749         //if a bitmap font the ascent is this....
       
  2750         TInt ascent = 10;
       
  2751 
       
  2752         if (iBitmapFont)
       
  2753             {
       
  2754             //Tweak factor is needed as font not behaving correctly for
       
  2755             // all languages.
       
  2756             ascent = iBitmapFont->FontMaxAscent() + 1;            
       
  2757             }
       
  2758         else
       
  2759             {
       
  2760             }
       
  2761 
       
  2762         return ( ascent >= 0 ) ? ascent : -ascent;
       
  2763         }
       
  2764            
       
  2765     else
       
  2766         {
       
  2767         //case where we dont have a bitmap font or svg font
       
  2768         return 0;
       
  2769         }
       
  2770     }
       
  2771 
       
  2772 const CFont* CSvgTextElementImpl::Font() const
       
  2773     {
       
  2774     return iBitmapFont;
       
  2775     }
       
  2776     
       
  2777 TFloatFixPt CSvgTextElementImpl::Descent()
       
  2778 {
       
  2779 	
       
  2780     //check for the bbox issue
       
  2781     if ( iSVGFont )
       
  2782     {
       
  2783     	//for svg fonts...
       
  2784     	//if an svg font the descent is this...
       
  2785 
       
  2786     	TFloatFixPt lDescent, lUnitsPerEm;
       
  2787     	TReal32 totalDescent = 0.0;
       
  2788 
       
  2789     	if (iFontFaceElement)
       
  2790     	{
       
  2791     		iFontFaceElement->GetAttributeFloat( KAtrDescent,
       
  2792                                                     lDescent );
       
  2793 
       
  2794             iFontFaceElement->GetAttributeFloat( KAtrUnitsPerEm, lUnitsPerEm);
       
  2795 
       
  2796             if(lUnitsPerEm==TFloatFixPt(0))
       
  2797             	{
       
  2798             	lUnitsPerEm=TFloatFixPt(1000);
       
  2799             	}
       
  2800             
       
  2801             totalDescent = (TReal32)lDescent * (TReal32)FontSize() / (TReal32)lUnitsPerEm;
       
  2802 
       
  2803             return ( totalDescent >= 0 ) ? (TFloatFixPt)totalDescent : (TFloatFixPt)-totalDescent;
       
  2804     	}
       
  2805 
       
  2806     	return 0;
       
  2807     }
       
  2808     else if ( iBitmapFont )
       
  2809         {
       
  2810         UpdateCurrentScaledFont();
       
  2811 		//for bitmap fonts...
       
  2812 		TInt descent = 10;
       
  2813 
       
  2814 		if (iBitmapFont)
       
  2815 		{
       
  2816 			descent = iBitmapFont->DescentInPixels();
       
  2817 		}
       
  2818 		else
       
  2819 		{
       
  2820 		}
       
  2821 
       
  2822 		return ( descent >= 0 ) ? descent : -descent;
       
  2823 
       
  2824         }
       
  2825     else
       
  2826     {
       
  2827     	//case where we dont have a bitmap font or svg font
       
  2828     	return 0;
       
  2829     }
       
  2830 }
       
  2831 
       
  2832 TTextAnchor CSvgTextElementImpl::TextAnchor()
       
  2833 {
       
  2834 
       
  2835     TInt anchor = ((CIntCssValueImpl*)((*iSvgStyleProperties)[KCSS_ATTR_TEXTANCHOR]))->Value();
       
  2836     return ( anchor == -1 ) ? EStartAnchor : (TTextAnchor)anchor;
       
  2837 }
       
  2838 
       
  2839 TBool CSvgTextElementImpl::LoadExternalSVGFontL(const TDesC& aFontFamily)
       
  2840 {
       
  2841     CSvgEngineImpl* lEngine = ((CSvgDocumentImpl*)iOwnerDocument)->Engine();
       
  2842     CSvgDocumentImpl* lNewFontDoc = NULL;
       
  2843 
       
  2844     if (lEngine == NULL)
       
  2845     {
       
  2846     	return EFalse;
       
  2847     }
       
  2848 
       
  2849     if ( lEngine->iFontHashMap->HasFontFamilyName(aFontFamily) )
       
  2850     {
       
  2851     	//already have that font
       
  2852     	return EFalse;
       
  2853     }
       
  2854     else
       
  2855     {
       
  2856     	CSvgBitmapFontProvider *tempBitmapFontProvider = ((CSvgDocumentImpl*)iOwnerDocument)->GetBitmapFontProvider();
       
  2857     	lNewFontDoc = CSvgDocumentImpl::NewL( tempBitmapFontProvider );
       
  2858     	lNewFontDoc->SetEngine(lEngine);
       
  2859     }
       
  2860 
       
  2861     if (aFontFamily.Length() > 0)
       
  2862     {
       
  2863     	TBuf<256> myFontUrl;
       
  2864     	myFontUrl.Copy(aFontFamily.Left(24));
       
  2865     	myFontUrl.Append(_L(".svg"));
       
  2866 
       
  2867     	if (FetchSvgFontL(myFontUrl, lNewFontDoc))
       
  2868     	{
       
  2869     		if ( lEngine->iFontHashMap->AddFontDocument(lNewFontDoc, aFontFamily) )
       
  2870     		{
       
  2871     			return ETrue;
       
  2872     		}
       
  2873     	}
       
  2874     }
       
  2875 
       
  2876     //If basic latin use SVG DEFAULT FONT
       
  2877     if ( iUseDefaultSVGFont && !lEngine->iFontHashMap->HasFontFamilyName(aFontFamily))
       
  2878     {
       
  2879     	if (FetchSvgFontL(_L("defaultsvgfont.svg"), lNewFontDoc))
       
  2880     	{
       
  2881           TBool aReturn =	lEngine->iFontHashMap->AddFontDocument(lNewFontDoc, KDefaultFont );
       
  2882 
       
  2883     		//this will overwrite whatever font family the element had set...
       
  2884     		//remove this to let fonts fall through to bitmap their specified bitmap fonts
       
  2885     		//SetFontFamilyL(_L("NokiaSansWide"));
       
  2886     		if(!aReturn)
       
  2887     		    {
       
  2888     		      if(lNewFontDoc)
       
  2889     		        {
       
  2890     		            delete lNewFontDoc;
       
  2891                         lNewFontDoc = NULL;  
       
  2892     		        }
       
  2893     		      
       
  2894     		    }
       
  2895     		return ETrue;
       
  2896     	}
       
  2897     	/*else if (LoadDefaultSvgFont(iNewFontDoc))
       
  2898     	{
       
  2899     		if (iEngine->AddFontDocument(iNewFontDoc, aFontFamily))
       
  2900     		{
       
  2901     			return ETrue;
       
  2902     		}
       
  2903     	}*/
       
  2904     }
       
  2905 
       
  2906     delete lNewFontDoc;
       
  2907     lNewFontDoc = NULL;
       
  2908     return EFalse;
       
  2909 }
       
  2910 
       
  2911 TBool CSvgTextElementImpl::IsEditable()
       
  2912 {
       
  2913  	return iEditable;
       
  2914 }
       
  2915 
       
  2916 TBool CSvgTextElementImpl::FetchSvgFontL(const TDesC& aUri, CSvgDocumentImpl* newFontDocument)
       
  2917 {
       
  2918 		CSvgErrorImpl* lmyError = CSvgErrorImpl::NewL();
       
  2919 
       
  2920     	//do a fetchimage style fetch of the SVG font file here...
       
  2921     	// Connect session
       
  2922         RFs lSession;
       
  2923         RFile fileHandle;
       
  2924         if ( lSession.Connect() == KErrNone )
       
  2925         {
       
  2926         	CSvgEngineImpl* lEngine = ((CSvgDocumentImpl*)iOwnerDocument)->Engine();
       
  2927 
       
  2928         	if (lEngine->FetchFont( aUri, lSession, fileHandle))
       
  2929         	{
       
  2930         		TBuf<512> aName;
       
  2931 
       
  2932 				fileHandle.Name(aName);
       
  2933 
       
  2934         		if ( aName.CompareF(aUri) == 0)
       
  2935         		{
       
  2936         			//need to attach this to the real document and just once for all text elements
       
  2937 	        		newFontDocument->Load( fileHandle, *lmyError );
       
  2938 				}
       
  2939 				else
       
  2940 				{
       
  2941 					lSession.Close();
       
  2942         			delete lmyError;
       
  2943         			return EFalse;
       
  2944 				}
       
  2945 
       
  2946         		if (lmyError->ErrorCode() == ESvgNoError)
       
  2947         		{
       
  2948         			lSession.Close();
       
  2949         			delete lmyError;
       
  2950         			return ETrue;
       
  2951         		}
       
  2952         	}
       
  2953         	else
       
  2954         	{
       
  2955         		lSession.Close();
       
  2956         	}
       
  2957         }
       
  2958 
       
  2959     	delete lmyError;
       
  2960         return EFalse;
       
  2961 }
       
  2962 
       
  2963 
       
  2964 /*TBool CSvgTextElementImpl::LoadDefaultSvgFont(CSvgDocumentImpl* newFontDocument)
       
  2965 {
       
  2966 		CSvgErrorImpl* myError = CSvgErrorImpl::NewL();
       
  2967 		CSvgEngineImpl* iEngine = ((CSvgDocumentImpl*)iOwnerDocument)->Engine();
       
  2968 
       
  2969    		TPtrC8 svgfontdata( (TUint8*)strSVGFont, User::StringLength((TUint8*)strSVGFont) );
       
  2970    		iEngine->newFontDocument->Load( svgfontdata, *myError );
       
  2971 
       
  2972    		if (myError->ErrorCode() != ESvgNoError)
       
  2973    		{
       
  2974    			delete myError;
       
  2975    			return EFalse;
       
  2976    		}
       
  2977 
       
  2978    		delete myError;
       
  2979    		return ETrue;
       
  2980 }*/
       
  2981 
       
  2982 /*** FROM MSvgMouseListener ***/
       
  2983 // ---------------------------------------------------------------------------
       
  2984 // mouse entered
       
  2985 // ---------------------------------------------------------------------------
       
  2986 TBool CSvgTextElementImpl::MouseEntered( RPointerArray<CSvgElementImpl>& aElements,
       
  2987                                     TInt /*aX*/, TInt /*aY*/ )
       
  2988 {
       
  2989 	CSvgEngineImpl* lEngine  = ( ( CSvgDocumentImpl* ) OwnerDocument() )->Engine();
       
  2990 
       
  2991 	TInt eleCnt = aElements.Count();
       
  2992 	for (TInt i = 0; i < eleCnt; i++ )
       
  2993 	{
       
  2994 		if ( aElements[i] == this )
       
  2995 		{
       
  2996 			lEngine->NotifyTextEntered(this);
       
  2997 			return ETrue;
       
  2998 		}
       
  2999     }
       
  3000 
       
  3001 	return EFalse;
       
  3002 }
       
  3003 
       
  3004 // ---------------------------------------------------------------------------
       
  3005 // Notified when the mouse pointer exits a visible svg element.
       
  3006 // ---------------------------------------------------------------------------
       
  3007 TBool CSvgTextElementImpl::MouseExited( RPointerArray<CSvgElementImpl>& aElements,
       
  3008                                    TInt /*aX*/, TInt /*aY*/ )
       
  3009 {
       
  3010 	CSvgEngineImpl* lEngine  = ( ( CSvgDocumentImpl* ) OwnerDocument() )->Engine();
       
  3011 
       
  3012 	TInt eleCnt = aElements.Count();
       
  3013 	for (TInt i = 0; i < eleCnt; i++ )
       
  3014 	{
       
  3015 		if ( aElements[i] == this )
       
  3016 		{
       
  3017 			lEngine->NotifyTextExited(this);
       
  3018 			return ETrue;
       
  3019 		}
       
  3020     }
       
  3021 
       
  3022     return EFalse;
       
  3023 }
       
  3024 
       
  3025 // ---------------------------------------------------------------------------
       
  3026 // Notified when the mouse pointer is moved inside a visible svg element.
       
  3027 // ---------------------------------------------------------------------------
       
  3028 TBool CSvgTextElementImpl::MouseMoved( RPointerArray<CSvgElementImpl>& /*aElements*/,
       
  3029                                        TInt /*aX*/, TInt /*aY*/ )
       
  3030 {
       
  3031     return EFalse;
       
  3032 }
       
  3033 
       
  3034 // ---------------------------------------------------------------------------
       
  3035 // Notified when the mouse pointer is pressed down on visible svg element.
       
  3036 // ---------------------------------------------------------------------------
       
  3037 TBool CSvgTextElementImpl::MousePressed( RPointerArray<CSvgElementImpl>& /*aElements*/,
       
  3038                                     TInt /*aX*/, TInt /*aY*/ )
       
  3039 {
       
  3040 	return EFalse;
       
  3041 }
       
  3042 
       
  3043 // ---------------------------------------------------------------------------
       
  3044 // Notified when the mouse pointer is released on on visible svg element.
       
  3045 // ---------------------------------------------------------------------------
       
  3046 TBool CSvgTextElementImpl::MouseReleased( RPointerArray<CSvgElementImpl>& aElements,
       
  3047                                     TInt /*aX*/, TInt /*aY*/ )
       
  3048 {
       
  3049 	CSvgEngineImpl* lEngine  = ( ( CSvgDocumentImpl* ) OwnerDocument() )->Engine();
       
  3050 
       
  3051 	TInt eleCnt = aElements.Count();
       
  3052 	for (TInt i = 0; i < eleCnt; i++ )
       
  3053 	{
       
  3054 		if ( aElements[i] == this )
       
  3055 		{
       
  3056 			lEngine->NotifyTextActivated(this);
       
  3057 			return ETrue;
       
  3058 		}
       
  3059   }
       
  3060 
       
  3061   return EFalse;
       
  3062 }
       
  3063 
       
  3064 // ---------------------------------------------------------------------------
       
  3065 //
       
  3066 // ---------------------------------------------------------------------------
       
  3067 void CSvgTextElementImpl::SetEditable( const TDesC& aValue )
       
  3068 {
       
  3069 	if (aValue.FindF(_L("simple")) == KErrNotFound && aValue.FindF(_L("true")) == KErrNotFound)
       
  3070 	{
       
  3071 		iEditable = EFalse;
       
  3072 	}
       
  3073 	else
       
  3074 	{
       
  3075 		iEditable = ETrue;
       
  3076 	}
       
  3077 }
       
  3078 
       
  3079 void CSvgTextElementImpl::Print( TBool aIsEncodeOn )
       
  3080 {
       
  3081 	if (!aIsEncodeOn)
       
  3082 	{
       
  3083 	#ifdef _DEBUG
       
  3084 	RDebug::Printf("<text x=\"%d\" y=\"%d\" editable=\"%d\" >hmm</text>", (int)iPoint.iX, (int)iPoint.iY, (int)IsEditable()/*, iText*/);
       
  3085 	#endif
       
  3086 	}
       
  3087 }
       
  3088 
       
  3089 void CSvgTextElementImpl::UpdateCurrentScaledFont()
       
  3090     {
       
  3091 
       
  3092     // Get latest scaling factor
       
  3093     TFloatFixPt scale = GetCurrentScale();
       
  3094 
       
  3095     TFloatFixPt fontsize = (TFloatFixPt)FontSize();
       
  3096 
       
  3097     TFloatFixPt fontHeight = scale * fontsize;
       
  3098     // RDebug::Printf("Requesting fontHeight: %d\n", (TInt)fontHeight);
       
  3099 
       
  3100     GetScaledFont( fontHeight, (*iFamilies)[0], iBitmapFont, iBitmapFontSpec );
       
  3101     // RDebug::Printf("Ascent : %d\n", (TInt)iBitmapFont->AscentInPixels());
       
  3102     // RDebug::Printf("Descent: %d\n", (TInt)iBitmapFont->DescentInPixels());
       
  3103     }
       
  3104 // --------------------------------------------------------------------------
       
  3105 //  void CGfx2dGcOpenVG::GetSystemFontScaled(TFloatFixPt aHeight,
       
  3106 //                                     const TDesC& aTypefaceName,//                                     CFont*& aFont,
       
  3107 //                                     TFontSpec& aFontSpec )
       
  3108 // ---------------------------------------------------------------------------
       
  3109  void CSvgTextElementImpl::GetScaledFont( TFloatFixPt aHeight,
       
  3110                                           const TDesC& aTypefaceName,
       
  3111                                           CFont*& aFont,
       
  3112                                           TFontSpec& aFontSpec )
       
  3113     {
       
  3114     if (aHeight >= TFloatFixPt(300))
       
  3115         {
       
  3116         aHeight = TFloatFixPt(300);
       
  3117         }
       
  3118 
       
  3119     // Calculate twip size
       
  3120     TInt twipsSize;
       
  3121     if( aHeight > TFloatFixPt(0) )
       
  3122         {
       
  3123         TInt xpixels,ypixels,xtwips,ytwips;
       
  3124         HAL::Get(HALData::EDisplayXPixels, xpixels);
       
  3125         HAL::Get(HALData::EDisplayYPixels, ypixels);
       
  3126         HAL::Get(HALData::EDisplayXTwips, xtwips);
       
  3127         HAL::Get(HALData::EDisplayYTwips, ytwips);
       
  3128 
       
  3129         if ( xpixels == 0 )
       
  3130             {
       
  3131             return;
       
  3132             }
       
  3133 
       
  3134         TFloatFixPt ratio = TFloatFixPt(xtwips)/(TFloatFixPt)xpixels;
       
  3135         twipsSize = (TInt) (ratio * aHeight);//((float)ytwips/ypixel) is same
       
  3136         }
       
  3137     else
       
  3138         {
       
  3139         return;
       
  3140         }
       
  3141 
       
  3142     TFontStrokeWeight strokeWeight = EStrokeWeightNormal;
       
  3143     TFontPosture fontPosture = EPostureUpright ;
       
  3144 
       
  3145     // Get font-weight
       
  3146     TInt32 fontweight = 1;
       
  3147     CCssValue* weightValue = NULL;
       
  3148     FindProperty( KCSS_ATTR_FONTWEIGHT, weightValue, this );
       
  3149 
       
  3150     if ( weightValue )
       
  3151         {
       
  3152         fontweight = ((CIntCssValueImpl*)weightValue)->Value();
       
  3153         }
       
  3154 
       
  3155     if ( ( fontweight == 1 ) ||
       
  3156          ( fontweight == 2 ) ||
       
  3157          ( fontweight == 9 ) ||
       
  3158          ( fontweight == 10 ) ||
       
  3159          ( fontweight == 11 ) ||
       
  3160          ( fontweight == 12 ) ) // Bold
       
  3161         {
       
  3162         strokeWeight = EStrokeWeightBold;
       
  3163         }
       
  3164     else
       
  3165         {
       
  3166         strokeWeight = EStrokeWeightNormal;
       
  3167         }
       
  3168 
       
  3169     // Get font-style
       
  3170     TInt32 style = 1;
       
  3171     CCssValue* styleValue = NULL;
       
  3172     FindProperty( KCSS_ATTR_FONTSTYLE, styleValue, this );
       
  3173 
       
  3174     if ( styleValue )
       
  3175         {
       
  3176         style = ((CIntCssValueImpl*)styleValue)->Value();
       
  3177         }
       
  3178 
       
  3179     if ( style == 1 )
       
  3180         {
       
  3181         //Italic
       
  3182         fontPosture = EPostureItalic;
       
  3183         }
       
  3184     else
       
  3185         {
       
  3186         fontPosture = EPostureUpright;
       
  3187         }
       
  3188 
       
  3189 
       
  3190     TFontStyle fontStyle( fontPosture, strokeWeight, EPrintPosNormal );
       
  3191 
       
  3192     // Get Latest required Font Spec.
       
  3193     TFontSpec tempFontSpec(aFontSpec);
       
  3194     tempFontSpec.iTypeface.iName = aTypefaceName.Left(24);
       
  3195     tempFontSpec.iHeight = twipsSize;
       
  3196     tempFontSpec.iFontStyle = fontStyle;
       
  3197 
       
  3198     CSvgBitmapFontProvider *tempBitmapFontProvider = ((CSvgDocumentImpl*)iOwnerDocument)->GetBitmapFontProvider();
       
  3199     if( aFont )
       
  3200         {
       
  3201         if(!(tempFontSpec == aFontSpec))
       
  3202             {
       
  3203             aFontSpec = tempFontSpec;
       
  3204             tempBitmapFontProvider->ReleaseFont(aFont);
       
  3205             tempBitmapFontProvider->GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
       
  3206             }
       
  3207         }
       
  3208         else
       
  3209         {
       
  3210         aFontSpec = tempFontSpec;
       
  3211         tempBitmapFontProvider->GetNearestFontToDesignHeightInTwips(aFont, aFontSpec);
       
  3212         }
       
  3213 
       
  3214     }
       
  3215 // ---------------------------------------------------------------------------
       
  3216     // Calculate the exact total text advance instead of taking default per glyph
       
  3217     // advance which will approximate the value.
       
  3218 // ---------------------------------------------------------------------------
       
  3219     TFloatFixPt CSvgTextElementImpl::GetTotalTextAdvance(const TFloatFixPt& alK,const TFloatFixPt& alUnitsPerEmInverse,const TFloatFixPt& alFontSize,const TFloatFixPt& alMissingGlyphHorzAdvX,const TFloatFixPt& alFontHorzAdvX)
       
  3220     {
       
  3221 		//Text Anchor related.
       
  3222         //lFontHorzAdvX = 400;
       
  3223         //lTotalTextAdvance = lFontHorzAdvX * (TFloatFixPt)iText->Length() * lUnitsPerEmInverse * lFontSize;
       
  3224         
       
  3225         
       
  3226         TFloatFixPt lGlyphHorzAdvX;
       
  3227         TInt langCodeFound( 0 );
       
  3228         TInt8   lTextAnchor =(TInt8)(((CIntCssValueImpl *)(iSvgStyleProperties->operator[](KCSS_ATTR_TEXTANCHOR)))->Value());
       
  3229         TPtrC16 lPrevGlyphName;
       
  3230         TPtrC16 lCurrGlyphName;
       
  3231         TFloatFixPt lK = alK; //kerning purpose....
       
  3232         TFloatFixPt KZero;
       
  3233         TFloatFixPt lTotalTextAdvance ( KZero );
       
  3234         TPtrC16 lUnicode;
       
  3235         TPtrC16 lLangCode; //ex: en-US or en-GB or ja-JP or zh-CN or en....
       
  3236         TPtrC16 lPrevUnicode;
       
  3237         TPtrC16 lUnicodeRange; //Max.Length "U+00AB-00AF"
       
  3238         TFloatFixPt lUnitsPerEmInverse = alUnitsPerEmInverse;
       
  3239         TFloatFixPt lFontSize =  alFontSize;
       
  3240         TFloatFixPt lFontHorzOrgX( 0 );
       
  3241         TFloatFixPt lFontHorzAdvX = alFontHorzAdvX;
       
  3242         TFloatFixPt lMissingGlyphHorzAdvX = alMissingGlyphHorzAdvX;
       
  3243     		
       
  3244             
       
  3245             TInt glyphEleCnt = iGlyphElements.Count();
       
  3246             for (TInt i=0; i < glyphEleCnt; i++)
       
  3247             {
       
  3248             	CSvgElementImpl* lGlyphElement = (CSvgElementImpl*)iGlyphElements[i];
       
  3249 
       
  3250             	if (lGlyphElement != NULL)
       
  3251             	{
       
  3252             		//have a valid glyph
       
  3253             		TInt checkErrorUnicode = lGlyphElement->GetAttributeDes( KAtrUnicode,
       
  3254                                                                                lUnicode );
       
  3255                     //check the glyph name
       
  3256                     TInt checkErrorGlyphName = lGlyphElement->GetAttributeDes( KAtrGlyphName,
       
  3257                                                                                lCurrGlyphName );
       
  3258                   	if( checkErrorGlyphName == KErrNoAttribute )
       
  3259                   	{
       
  3260                   		lCurrGlyphName.Set( KGlyphNameNone );
       
  3261                   	}
       
  3262 
       
  3263                     //check its language
       
  3264                     TInt checkErrorLangCode = lGlyphElement->GetAttributeDes( KAtrLang,
       
  3265                                                                                 lLangCode );
       
  3266                     TPtrC lXmlLangAttr(this->XMLLang());
       
  3267 
       
  3268                     if( checkErrorLangCode != KErrNoAttribute ) //if Lang code present
       
  3269                     {
       
  3270                       	langCodeFound = lLangCode.CompareF( lXmlLangAttr );//compare xml:lang with Lang code.
       
  3271                     }
       
  3272 
       
  3273                     //if Lang code is matching && unicode attr. present, we are good.
       
  3274                     if ( (checkErrorUnicode != KErrNoAttribute) && (langCodeFound == 0) )
       
  3275                     {
       
  3276                       	//Checking and Introducing kerning(adjusting spacing).
       
  3277                         if( lPrevGlyphName.Length() > 0 )
       
  3278                         {
       
  3279                              if( IsKerningRequired( lPrevGlyphName, lCurrGlyphName, lPrevUnicode, lUnicode ))
       
  3280                              {
       
  3281                                   lTotalTextAdvance -= ( lK * lUnitsPerEmInverse ) * lFontSize;
       
  3282                              }
       
  3283                         }
       
  3284 
       
  3285                         lGlyphElement->GetAttributeFloat( KAtrHorizAdvX,
       
  3286                                                            lGlyphHorzAdvX );
       
  3287 
       
  3288     	#ifdef SVG_FLOAT_BUILD
       
  3289                         if ( lGlyphHorzAdvX == TFloatFixPt( 0 ) )
       
  3290     	#else
       
  3291                         if ( lGlyphHorzAdvX == TFloatFixPt( 0,ETrue ) )
       
  3292     	#endif
       
  3293                         {
       
  3294                           	lGlyphHorzAdvX = /*(TFloatFixPt)lUnicodeLength **/ lFontHorzAdvX;
       
  3295                         }
       
  3296 
       
  3297                        
       
  3298                             lTotalTextAdvance += ( lGlyphHorzAdvX * lUnitsPerEmInverse ) * lFontSize;
       
  3299                           
       
  3300 
       
  3301                      }
       
  3302                     
       
  3303 
       
  3304             	}
       
  3305             	else
       
  3306             	{
       
  3307             		//need to use missing glyph for this one...
       
  3308             		
       
  3309                      lTotalTextAdvance += ( lMissingGlyphHorzAdvX * lUnitsPerEmInverse ) * lFontSize;
       
  3310                     
       
  3311                 }
       
  3312             }//end-for
       
  3313 
       
  3314             
       
  3315             return lTotalTextAdvance ;
       
  3316 
       
  3317     }// End Function    
       
  3318 void CSvgTextElementImpl::CreateSVGFontL()
       
  3319 {
       
  3320     CCssValue* lCssValue = NULL;
       
  3321     
       
  3322     TPtrC lFontFamily;
       
  3323     //Getting font-family property
       
  3324     this->FindProperty( KCSS_ATTR_FONTFAMILY, lCssValue,this );
       
  3325     if ( lCssValue && ((( CStrCssValueImpl * ) lCssValue )->Value()).Length() != 0)
       
  3326         {
       
  3327         lFontFamily.Set( ( ( CStrCssValueImpl * ) lCssValue )->Value() );
       
  3328         SetFontFamilyL( lFontFamily );
       
  3329         }
       
  3330 
       
  3331 		//attempt to load svg font files of same font family name
       
  3332 		//this boolean will be a problem if we want to be able to swap
       
  3333 		//font-family names on the fly and use svg fonts.
       
  3334   	if (!iTriedLoadingSVGFonts)
       
  3335    	    {
       
  3336     		LoadExternalSVGFontL(lFontFamily);
       
  3337     		iTriedLoadingSVGFonts = ETrue;
       
  3338    	    }
       
  3339 
       
  3340     //Retrieving Font Element Pointer from the Font Table
       
  3341     //if font in svg document
       
  3342     iSVGFont = NULL;
       
  3343     if ( iFamilies != NULL )
       
  3344         {
       
  3345     		TInt familiesCnt = iFamilies->Count();
       
  3346     		for (int i=0; i< familiesCnt; i++)
       
  3347             {
       
  3348             // In JSR-226 case, the engine may not have been created yet.            
       
  3349             if ( ((CSvgDocumentImpl*)iOwnerDocument)->Engine() )
       
  3350             	{
       
  3351             	iSVGFont = ( CSvgElementImpl * )((CSvgDocumentImpl*)iOwnerDocument)->Engine()->iFontHashMap->GetFontPtr(iFamilies->operator[]( i ));
       
  3352             	}
       
  3353 
       
  3354 			if (iSVGFont == NULL)
       
  3355 				{
       
  3356 				iSVGFont = ( CSvgElementImpl * )((CSvgDocumentImpl*)iOwnerDocument)->iFontHashMap->GetFontPtr(iFamilies->operator[]( i ) );
       
  3357 				}
       
  3358 				
       
  3359 	        if (iSVGFont != NULL)
       
  3360   	      		{
       
  3361     	    	//found a font with that family name...continue
       
  3362       	  		break;
       
  3363         		}
       
  3364     		}
       
  3365     	}
       
  3366 
       
  3367 /**********************************************************/
       
  3368 /* Checking for pre-defined SVG Fonts through the         */
       
  3369 /* retrieved pointer from the Font Table.                 */
       
  3370 /* IF the Font is found (ptr!=NULL), SVG Fonts are used   */
       
  3371 /* ELSE Bitmap Font is used through DrawString() method   */
       
  3372 /**********************************************************/
       
  3373 
       
  3374 	if(!iSVGFont)
       
  3375 		{
       
  3376 		User::Leave(KErrNotFound);
       
  3377 		}
       
  3378 
       
  3379     if ( iSVGFont != NULL && iSVGFont->HasChildNodes())
       
  3380         {
       
  3381         //we found an svg font and are using it...
       
  3382         //	iSVGFont->GetAttributeFloat( KAtrHorizOriginX, lFontHorzOrgX );
       
  3383         //	iSVGFont->GetAttributeFloat( KAtrHorizAdvX, lFontHorzAdvX );
       
  3384         //	lMissingGlyphHorzAdvX = lFontHorzAdvX; //Default Value
       
  3385         //	TInt checkErrShapeMG = -1;//To keep a value other than KErrNone. Should this be replaced
       
  3386        	CacheGlyphsForText();
       
  3387         }
       
  3388         
       
  3389    
       
  3390     
       
  3391     
       
  3392     
       
  3393 
       
  3394 }
       
  3395