messagingappbase/smilengine/xhtml/src/xhtmlparser.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2007 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:   Provides CXhtmlParser class methods.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <coemain.h>
       
    21 #include <gulfont.h> 
       
    22 #include <eikenv.h> 
       
    23 #include <txtfrmat.h>
       
    24 #include <txtetext.h>
       
    25 #include <frmconst.h>
       
    26 #include <e32math.h>
       
    27 #include <gdi.h>
       
    28 #include <AknUtils.h>
       
    29 #include <fontids.hrh>
       
    30 #include <gmxmldocument.h>
       
    31 #include <gmxmlnode.h>
       
    32 #include <gmxmlelement.h>
       
    33 #include <gmxmltext.h>
       
    34 #include <smilliterals.h>
       
    35 
       
    36 #include "Xhtmldef.h"
       
    37 #include "xhtmlentityconverter.h"
       
    38 #include "xhtmlfontspecs.h"
       
    39 #include "xhtmlstack.h"
       
    40 #include "xhtmlstackmanager.h"
       
    41 #include "xhtmlhyperlink.h"
       
    42 #include "xhtmlparser.h"
       
    43 #include "xhtmlparserlogging.h"
       
    44 
       
    45 const TInt KNoListContext        = 0;
       
    46 const TInt KUnorderedListContext = 1;
       
    47 const TInt KOrderedListContext   = 2;
       
    48 const TInt KNoStylePosition      = -1;
       
    49 
       
    50 const TInt KListBullet   = 0x2022;
       
    51 const TInt KListBullet2  = 0x25E6;
       
    52 const TInt KPlainBullet  = 0x2d;  // '-'
       
    53 const TInt KPlainBullet2 = 0x2a;  // '*'
       
    54 const TInt KColon        = 0x3a;  // ':'
       
    55 const TInt KSemicolon    = 0x3b;  // ';' 
       
    56 
       
    57 const TInt KBlackColorCode = 0x000000;
       
    58 const TInt KWhiteColorCode = 0xffffff;
       
    59 const TInt KBlueColorCode  = 0xff0000;
       
    60 const TInt KLimeColorCode  = 0x00ff00;
       
    61 const TInt KRedColorCode   = 0x0000ff;
       
    62 
       
    63 const TInt KDefaultIndentWidth  = 4; // 4 spaces
       
    64 const TInt KDefaultMaxListLevels = 5;
       
    65 
       
    66 _LIT( KWhiteSpace, " " );
       
    67 _LIT( KHrSeparator, "__________" );
       
    68 _LIT16(KListNumberFormat, "%d. ");
       
    69 _LIT( KNullString, "" );
       
    70 
       
    71 const TInt KHyperLinkArrayGranularity = 16;
       
    72 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    73 const TText KZeroWidthSpace         = 0x200B;
       
    74 #endif
       
    75 
       
    76 // ---------------------------------------------------------
       
    77 // CXhtmlParser::NewL
       
    78 // ---------------------------------------------------------
       
    79 //
       
    80 EXPORT_C CXhtmlParser* CXhtmlParser::NewL( MXhtmlParserObserver* aParserObserver )
       
    81 	{
       
    82 	CXhtmlParser* self = new( ELeave ) CXhtmlParser( aParserObserver );
       
    83 	CleanupStack::PushL( self );
       
    84 	self->ConstructL();
       
    85 	CleanupStack::Pop( self ); 
       
    86 	return self;
       
    87 	};
       
    88 
       
    89 // ---------------------------------------------------------
       
    90 // CXhtmlParser::~CXhtmlParser 
       
    91 // ---------------------------------------------------------
       
    92 //
       
    93 CXhtmlParser::~CXhtmlParser()
       
    94 	{
       
    95 	if( iCurrentCharLayer )
       
    96 	    {
       
    97 		iCurrentCharLayer->Reset();
       
    98 		delete iCurrentCharLayer;
       
    99 	    }
       
   100 
       
   101 	delete iXmlParser;    
       
   102 	delete iXhtmlFontSpecs;
       
   103 	delete iHyperLinkAddress;
       
   104 	delete iStackManager;
       
   105 	delete iXmlDocument;
       
   106 	
       
   107 	if ( iHyperLinkArray )
       
   108 	    {
       
   109 	    iHyperLinkArray->ResetAndDestroy();
       
   110 	    delete iHyperLinkArray;
       
   111 	    }
       
   112 	}
       
   113 
       
   114 // ---------------------------------------------------------
       
   115 // CXhtmlParser::CreateDomL 
       
   116 // ---------------------------------------------------------
       
   117 //
       
   118 EXPORT_C void CXhtmlParser::CreateDomL( RFs &aRFs, const TDesC& aFileToParse )
       
   119 	{	
       
   120 	XHTMLLOG_WRITE( "CXhtmlParser::CreateDomL in" );
       
   121 	User::LeaveIfError( iXmlParser->ParseFile( aRFs, aFileToParse ) );
       
   122 	XHTMLLOG_WRITE( "CXhtmlParser::CreateDomL out" );
       
   123 	}
       
   124 	
       
   125 // ---------------------------------------------------------
       
   126 // CXhtmlParser::CreateDomL 
       
   127 // ---------------------------------------------------------
       
   128 //
       
   129 EXPORT_C void CXhtmlParser::CreateDomL( RFile& aFileHandleToParse )
       
   130 	{
       
   131 	XHTMLLOG_WRITE( "CXhtmlParser::CreateDomL in" );
       
   132 	User::LeaveIfError( iXmlParser->ParseFile( aFileHandleToParse ) );
       
   133 	XHTMLLOG_WRITE( "CXhtmlParser::CreateDomL out" );
       
   134 	}
       
   135 	
       
   136 // ---------------------------------------------------------
       
   137 // CXhtmlParser::ParseL 
       
   138 // ---------------------------------------------------------
       
   139 //
       
   140 EXPORT_C void CXhtmlParser::ParseL( CRichText& aRichText )
       
   141 	{
       
   142 	XHTMLLOG_WRITE( "CXhtmlParser::ParseL in" );
       
   143 	iRichText = &aRichText;
       
   144    	
       
   145    	ResetValues();
       
   146    	ParseDomL( iXmlDocument);
       
   147 	XHTMLLOG_WRITE( "CXhtmlParser::ParseL out" );
       
   148 	}
       
   149 	
       
   150 // ---------------------------------------------------------
       
   151 // CXhtmlParser::Cancel 
       
   152 // ---------------------------------------------------------
       
   153 //	
       
   154 EXPORT_C void CXhtmlParser::Cancel()
       
   155     {
       
   156     iXmlParser->Cancel();
       
   157     }
       
   158 
       
   159 // ---------------------------------------------------------
       
   160 // CXhtmlParser::SetFonts 
       
   161 // ---------------------------------------------------------
       
   162 //
       
   163 EXPORT_C void CXhtmlParser::SetFonts( const CFont* aBigFont,
       
   164 	                                  const CFont* aDefaultFont,
       
   165 	                                  const CFont* aSmallFont,
       
   166 	                                  const CFont* aCourierFont )
       
   167     {
       
   168     iXhtmlFontSpecs->SetFonts( aBigFont, aDefaultFont, aSmallFont, aCourierFont );
       
   169     }
       
   170 
       
   171 // ---------------------------------------------------------
       
   172 // CXhtmlParser::SetDefaultTextColor 
       
   173 // ---------------------------------------------------------
       
   174 //   
       
   175 EXPORT_C void CXhtmlParser::SetDefaultTextColor( TRgb aColor )
       
   176     {
       
   177     iTextColor = aColor;
       
   178     }
       
   179     
       
   180 // ---------------------------------------------------------
       
   181 // CXhtmlParser::SetMode
       
   182 // 
       
   183 // ---------------------------------------------------------
       
   184 // 
       
   185 EXPORT_C void CXhtmlParser::SetMode( TBool aPlainText, TBool aShowUrls )
       
   186     {
       
   187     iPlainText = aPlainText;
       
   188     iShowUrls = aShowUrls;
       
   189     }
       
   190 
       
   191 // ---------------------------------------------------------
       
   192 // CXhtmlParser::HyperLink 
       
   193 // ---------------------------------------------------------
       
   194 // 
       
   195 EXPORT_C TInt CXhtmlParser::HyperLink( TInt aIndex, 
       
   196                         TInt& aStartPos, TInt& aEndPos,
       
   197                         TPtrC& aAddress )
       
   198     {
       
   199     if ( aIndex >= iHyperLinkArray->Count() )
       
   200         {
       
   201         return KErrArgument;
       
   202         }
       
   203         
       
   204     CXhtmlHyperLink* hpLink = (*iHyperLinkArray)[aIndex];
       
   205     aStartPos = hpLink->StartPosition();
       
   206     aEndPos = hpLink->EndPosition();
       
   207     
       
   208     if ( hpLink->Address() )
       
   209         {
       
   210         TPtr tmpPtr = hpLink->Address()->Des();
       
   211         aAddress.Set( tmpPtr );
       
   212         }
       
   213     else
       
   214         {
       
   215         aAddress.Set(KNullString);
       
   216         }
       
   217     return KErrNone;
       
   218     }
       
   219                 
       
   220 // ---------------------------------------------------------
       
   221 // CXhtmlParser::HyperLinkCount 
       
   222 // ---------------------------------------------------------
       
   223 // 
       
   224 EXPORT_C TInt CXhtmlParser::HyperLinkCount()
       
   225     {
       
   226     if ( iHyperLinkArray )
       
   227         {
       
   228         return iHyperLinkArray->Count();
       
   229         }
       
   230     return 0;        
       
   231     }
       
   232     
       
   233 // ---------------------------------------------------------
       
   234 // CXhtmlParser::ParseFileCompleteL
       
   235 // ---------------------------------------------------------
       
   236 //
       
   237 void CXhtmlParser::ParseFileCompleteL()
       
   238     {
       
   239 	XHTMLLOG_WRITE( "CXhtmlParser::ParseFileCompleteL in" );
       
   240     delete iXmlDocument;
       
   241     iXmlDocument = iXmlParser->DetachXMLDoc();
       
   242     
       
   243     TRAPD( error, iObserver->ParseCompleteL() );
       
   244     
       
   245     if ( error )
       
   246         {
       
   247         iObserver->ParseError( error );
       
   248         }
       
   249 	XHTMLLOG_WRITE( "CXhtmlParser::ParseFileCompleteL out" );
       
   250     }
       
   251     
       
   252 // ---------------------------------------------------------
       
   253 // CXhtmlParser::CXhtmlParser
       
   254 // ---------------------------------------------------------
       
   255 //
       
   256 CXhtmlParser::CXhtmlParser(  MXhtmlParserObserver* aParserObserver ) :
       
   257    	iParsingAllowed( EFalse ),
       
   258 	iPlainText( EFalse ),
       
   259 	iShowUrls( EFalse ),
       
   260 	iPreformatted( 0 ),
       
   261 	iAlignment( CParaFormat::ELeftAlign ),
       
   262 	iStylePos( KNoStylePosition ),
       
   263 	iNewParagraph( EFalse ),
       
   264     iNewLines( 0 ),
       
   265 	iForcedNewLines( 0 ),
       
   266 	iSkipWhiteSpaces( ETrue ),
       
   267 	iAlignmentChanged( EFalse ),
       
   268 	iImageFound( EFalse ),
       
   269 	iFirstTextLineAdded( EFalse ),
       
   270 	iCurrentListContext( KNoListContext ), 
       
   271 	iDefListLevel( 0 ),
       
   272 	iBlockQuoteLevel( 0 ),
       
   273 	iHyperLinkPos( 0 ),
       
   274 	iTextColor( KBlackColorCode ),
       
   275     iObserver( aParserObserver ),
       
   276    	iIndentWidth( KDefaultIndentWidth ),
       
   277 	iMaxListLevels( KDefaultMaxListLevels )
       
   278    	{
       
   279 	}
       
   280 
       
   281 // ---------------------------------------------------------
       
   282 // CXhtmlParser::ConstructL
       
   283 // ---------------------------------------------------------
       
   284 //
       
   285 void CXhtmlParser::ConstructL()
       
   286 	{
       
   287 	iStackManager = CXhtmlStackManager::NewL();
       
   288     iXmlParser = CMDXMLParser::NewL( this );
       
   289         
       
   290 // This enables the correction of the following bug:
       
   291 //
       
   292 // ID: TPHU-72BFLV
       
   293 // Title: MMS Viewer: Whitespace characters are consumed in XHTML text     
       
   294 //
       
   295 // Partial correction to the bug is implemented in Symbian XML parser code.
       
   296 // This call sets XML parser to mode where all whitespaces are forwarded to
       
   297 // XHTML parser inside DOM document. So, actual whitespace handling is 
       
   298 // implemented inside XHTML parser.   
       
   299      
       
   300     iXmlParser->SetWhiteSpaceHandlingMode( ETrue );
       
   301         
       
   302     CXhtmlEntityConverter* converter =
       
   303         new ( ELeave ) CXhtmlEntityConverter();
       
   304 	            
       
   305 	//Ownership transferred to XML parser
       
   306    	iXmlParser->SetEntityConverter( converter ); 
       
   307        
       
   308     iXhtmlFontSpecs = new ( ELeave ) CXhtmlFontSpecs();
       
   309     iHyperLinkArray = new ( ELeave ) CArrayPtrFlat<CXhtmlHyperLink>( KHyperLinkArrayGranularity );
       
   310    	}
       
   311 
       
   312 // ---------------------------------------------------------
       
   313 // CXhtmlParser::ParseDomL 
       
   314 // ---------------------------------------------------------
       
   315 //
       
   316 void CXhtmlParser::ParseDomL( CMDXMLDocument* aXmlDocument )
       
   317 	{
       
   318 	XHTMLLOG_WRITE( "CXhtmlParser::ParseDomL in" );
       
   319     TCharFormat charFormat;
       
   320 	TCharFormatMask charFormatMask;
       
   321 
       
   322 	charFormat.iFontSpec = iXhtmlFontSpecs->DefaultFont()->FontSpecInTwips();
       
   323 	charFormat.iFontPresentation.iTextColor = iTextColor;
       
   324     
       
   325     charFormatMask.SetAttrib( EAttColor );
       
   326     charFormatMask.SetAttrib( EAttFontTypeface );
       
   327     charFormatMask.SetAttrib( EAttFontPosture );
       
   328     charFormatMask.SetAttrib( EAttFontHeight );
       
   329     charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
   330 
       
   331     // delete old CharFormatLayer
       
   332     
       
   333     if( iCurrentCharLayer )
       
   334 	    {
       
   335 		iCurrentCharLayer->Reset();
       
   336 		delete iCurrentCharLayer;
       
   337 		iCurrentCharLayer = NULL;
       
   338 	    }
       
   339 	    
       
   340 	// create new CharFormatLayer based on GlobalCharFormatLayer and
       
   341 	// custom font/color
       
   342     
       
   343 	CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL( charFormat,
       
   344 	    charFormatMask );
       
   345 	    	
       
   346 	charFormatLayer->SetBase( iRichText->GlobalCharFormatLayer() );
       
   347 	iCurrentCharLayer = charFormatLayer;
       
   348 		    
       
   349 	CMDXMLNode* node = aXmlDocument->DocumentElement();   
       
   350    
       
   351 	while( node )
       
   352 		{
       
   353 		OpenNodeL( node );
       
   354 		    
       
   355 		if( node->FirstChild() )
       
   356 		    {
       
   357 		    node = node->FirstChild();
       
   358 		    }
       
   359 		else if( node->NextSibling() )
       
   360 			{
       
   361 			CloseNodeL( node );
       
   362 			node = node->NextSibling();
       
   363 			}
       
   364 		else 
       
   365 			{
       
   366 			while( node )
       
   367 				{
       
   368 				CloseNodeL( node );
       
   369 				    				    
       
   370 				if( node->NextSibling() )
       
   371 					{
       
   372 					node = node->NextSibling();
       
   373 					break;
       
   374 					}				
       
   375 				node = node->ParentNode();			
       
   376 				}
       
   377 			}
       
   378 		}	
       
   379 	XHTMLLOG_WRITE( "CXhtmlParser::ParseDomL out" );
       
   380 	}
       
   381     	
       
   382 // ---------------------------------------------------------
       
   383 // CXhtmlParser::OpenNodeL
       
   384 // ---------------------------------------------------------
       
   385 //
       
   386 void CXhtmlParser::OpenNodeL( CMDXMLNode* aNode )
       
   387 	{
       
   388     switch( aNode->NodeType() )
       
   389         {
       
   390 	    case CMDXMLNode::EElementNode:
       
   391 	        {
       
   392 	        CMDXMLElement* element = static_cast<CMDXMLElement*>( aNode );
       
   393 	        
       
   394 	                
       
   395 	        // PrepareForBeginElementL does some operations needed before possible
       
   396 	        // attributes are handled.
       
   397 	        //
       
   398 	        // In practice PrepareForBeginElementL adds a new style to stylestack
       
   399 	        // If there is no attributes within this tag, this style is not used although
       
   400 	        // it is on the stack
       
   401 	        	        
       
   402 	        PrepareForBeginElementL( element->NodeName() );
       
   403                 
       
   404             // handle possible attributes related to begin tag
       
   405                 
       
   406             for( TInt i = 0; i<element->NumAttributes(); ++i )
       
   407                 {
       
   408                 TPtrC name;
       
   409                 TPtrC value;
       
   410                     
       
   411                 if ( element->AttributeDetails( i, name, value ) == KErrNone )
       
   412                     {
       
   413                     AttributeValueL( name, value );
       
   414                     }
       
   415                 }
       
   416     				
       
   417     		// Handles actual begin tag. If it doesn't cause changes to 
       
   418     		// style or paragraphs, doesn't do anything	
       
   419     				
       
   420     		BeginElementL( element->NodeName() );
       
   421             break;    		    
       
   422     		}
       
   423     		
       
   424 	    case CMDXMLNode::ETextNode:
       
   425     	    {
       
   426     		CMDXMLText* txt = static_cast<CMDXMLText*>( aNode );
       
   427     		  	
       
   428     		// Adds actual text to CRichText object.
       
   429     		// Style and paragraph format are added later when
       
   430     		// end tags are handled   	
       
   431     		  		
       
   432     		ContentL( txt->Data() );
       
   433             break;    		    
       
   434         	}
       
   435         	
       
   436 	    case CMDXMLNode::ECDATASectionNode:
       
   437     	    {
       
   438             // CDATA section skipped
       
   439     		break;
       
   440             }
       
   441             
       
   442         case CMDXMLNode::ECommentNode:
       
   443     	    {
       
   444     	    // comment skipped
       
   445        		break;
       
   446             }
       
   447             
       
   448         default:
       
   449             {
       
   450             break;
       
   451             }
       
   452 	    }
       
   453 	}
       
   454 
       
   455 // ---------------------------------------------------------
       
   456 // CXhtmlParser::CloseNode 
       
   457 // ---------------------------------------------------------
       
   458 //
       
   459 void CXhtmlParser::CloseNodeL( CMDXMLNode* aNode )
       
   460 	{
       
   461 	if( aNode->NodeType()==CMDXMLNode::EElementNode )
       
   462 		{
       
   463         EndElementL( aNode->NodeName() );
       
   464    		}	
       
   465 	}
       
   466 	
       
   467 // ---------------------------------------------------------
       
   468 // CXhtmlParser::PrepareForBeginElementL 
       
   469 // ---------------------------------------------------------
       
   470 //
       
   471 void CXhtmlParser::PrepareForBeginElementL( const TDesC& aName )
       
   472 	{
       
   473 	iAlignmentChanged = EFalse;
       
   474 	iImageFound = EFalse;
       
   475 	
       
   476 	if ( !aName.CompareF( KATag ) )
       
   477         {
       
   478         BeginHyperLink( iRichText->DocumentLength() );
       
   479         }
       
   480     else if ( !aName.CompareF( KImgTag ) )
       
   481         {
       
   482         iImageFound = ETrue;
       
   483         }
       
   484             
       
   485 	BeginStyleL();
       
   486 	}
       
   487    
       
   488 // ---------------------------------------------------------
       
   489 // CXhtmlParser::BeginElementL
       
   490 // ---------------------------------------------------------
       
   491 //
       
   492 void CXhtmlParser::BeginElementL( const TDesC& aName )
       
   493 	{
       
   494 	iImageFound = EFalse;
       
   495 	
       
   496 	// If default alignment changed within this tag, begin new paragraph with new alignment.
       
   497 	// Add information about changed alignment. This info is used later
       
   498 	// to end paragraph
       
   499 	
       
   500     if ( iAlignmentChanged )
       
   501 	    {
       
   502 	    iStackManager->StyleStack()->Top()->iAlignmentChanged = ETrue;
       
   503         iAlignmentChanged = EFalse;
       
   504 
       
   505         BeginParagraphL( iAlignment );
       
   506    		}
       
   507    		
       
   508 	if( !aName.CompareF( KHtmlTag ) )
       
   509 		{
       
   510 		}
       
   511     else if( !aName.CompareF( KHrTag ) )
       
   512         {
       
   513  	    BeginParagraphL( CParaFormat::ECenterAlign );
       
   514  	    // default alignment is center
       
   515  	    
       
   516 	    BeginStyleL();
       
   517 	
       
   518 	    TCharFormat charFormat;
       
   519 	    TCharFormatMask charFormatMask;
       
   520 		    
       
   521 	    charFormat.iFontSpec = iXhtmlFontSpecs->DefaultFont()->FontSpecInTwips();
       
   522 	 	    
       
   523 	    charFormatMask.SetAttrib( EAttFontHeight );
       
   524 	    charFormatMask.SetAttrib( EAttFontTypeface );
       
   525 	    charFormatMask.SetAttrib( EAttFontPosture );
       
   526         charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
   527 	
       
   528 	    ChangeCurrentStyleL(charFormat, charFormatMask);
       
   529 	    InsertTextL( KHrSeparator);
       
   530         }
       
   531     else if (!aName.CompareF( KDdTag ) )
       
   532 		{
       
   533 		BeginParagraphL( iAlignment );
       
   534         iDefListLevel++;
       
   535         }
       
   536     else if (!aName.CompareF( KDtTag ) )          
       
   537 	    {
       
   538 		InsertLineBreak();
       
   539 	    }        
       
   540     else if (!aName.CompareF( KDlTag ) )        
       
   541         {
       
   542         InsertLineBreak();
       
   543        	BeginParagraphL( iAlignment );
       
   544         }
       
   545    	else if( !aName.CompareF( KBodyTag ) )
       
   546 		{
       
   547 		BeginStyleL();
       
   548 		iParsingAllowed = ETrue;
       
   549 		}
       
   550 	else if( !aName.CompareF( KAbbrTag ) )
       
   551 		{
       
   552 		}
       
   553 	else if( !aName.CompareF( KAcronymTag ) )
       
   554 		{
       
   555 		}
       
   556 	else if( !aName.CompareF( KSpanTag ) )
       
   557 		{
       
   558 		}
       
   559 	else if( !aName.CompareF( KDivTag ) )
       
   560 		{
       
   561 		BeginParagraphL( iAlignment );
       
   562    		}
       
   563 	else if( !aName.CompareF( KBrTag ) )
       
   564 	    {
       
   565 	    InsertForcedLineBreak();
       
   566 	    }
       
   567 	else if( !aName.CompareF( KPTag ) )
       
   568 		{	
       
   569 		InsertLineBreak();
       
   570 		BeginParagraphL( iAlignment );
       
   571 		}
       
   572 	else if( !aName.CompareF( KSmallTag ) || !aName.CompareF( KBigTag ) )
       
   573 		{
       
   574 		TCharFormat charFormat;
       
   575 		TCharFormatMask charFormatMask;
       
   576 				
       
   577 		charFormatMask.SetAttrib( EAttFontTypeface );
       
   578 	    charFormatMask.SetAttrib( EAttFontPosture );
       
   579 	    charFormatMask.SetAttrib( EAttFontHeight );
       
   580 	    charFormatMask.SetAttrib( EAttFontStrokeWeight );	
       
   581 		
       
   582 		if ( !aName.CompareF( KSmallTag ) )
       
   583 		    {
       
   584 			charFormat.iFontSpec = iXhtmlFontSpecs->SmallFont()->FontSpecInTwips();
       
   585 		    }
       
   586 		else
       
   587 		    {
       
   588 			charFormat.iFontSpec = iXhtmlFontSpecs->BigFont()->FontSpecInTwips();
       
   589 		    }
       
   590 		BeginStyleL();
       
   591         ChangeCurrentStyleL(charFormat, charFormatMask);
       
   592 	    }
       
   593 		
       
   594 	else if( !aName.CompareF( KFontTag ) )
       
   595 		{
       
   596 		}
       
   597 	else if( !aName.CompareF( KBTag ) || !aName.CompareF( KStrongTag ) )
       
   598 		{
       
   599 		TCharFormat charFormat;
       
   600 		TCharFormatMask charFormatMask;
       
   601 		charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
   602 		charFormat.iFontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightBold );
       
   603 
       
   604         BeginStyleL();
       
   605         ChangeCurrentStyleL(charFormat, charFormatMask);
       
   606         }
       
   607 	else if( !aName.CompareF( KITag ) || !aName.CompareF( KEmTag ) || 
       
   608 	    !aName.CompareF( KCiteTag )	|| !aName.CompareF( KDfnTag ) ||
       
   609 	    !aName.CompareF( KVarTag ) )
       
   610 		{
       
   611 		TCharFormat charFormat;
       
   612 		TCharFormatMask charFormatMask;
       
   613 		
       
   614 		charFormatMask.SetAttrib( EAttFontPosture );
       
   615 		charFormat.iFontSpec.iFontStyle.SetPosture( EPostureItalic );
       
   616 		
       
   617 		BeginStyleL();
       
   618 		ChangeCurrentStyleL( charFormat, charFormatMask);
       
   619 		}
       
   620 	else if( !aName.CompareF( KAddressTag ) )
       
   621 		{
       
   622 		TCharFormat charFormat;
       
   623 		TCharFormatMask charFormatMask;
       
   624 		
       
   625 		charFormatMask.SetAttrib( EAttFontPosture );
       
   626 		charFormat.iFontSpec.iFontStyle.SetPosture( EPostureItalic );
       
   627 		
       
   628 		BeginStyleL();
       
   629 		ChangeCurrentStyleL(charFormat, charFormatMask);
       
   630 		
       
   631 		InsertLineBreak();
       
   632 		}
       
   633 	else if( !aName.CompareF( KKbdTag ) || !aName.CompareF( KCodeTag ) || 
       
   634 	    !aName.CompareF( KSampTag ) )
       
   635 		{
       
   636 		TCharFormat charFormat;
       
   637 		TCharFormatMask charFormatMask;
       
   638 		
       
   639 		charFormatMask.SetAttrib( EAttFontTypeface );
       
   640 	    charFormatMask.SetAttrib( EAttFontPosture );
       
   641 	    charFormatMask.SetAttrib( EAttFontHeight );
       
   642 	    charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
   643 
       
   644 		charFormat.iFontSpec = iXhtmlFontSpecs->CourierFont()->FontSpecInTwips();
       
   645 		
       
   646 		BeginStyleL();
       
   647 		ChangeCurrentStyleL( charFormat, charFormatMask );
       
   648 		}
       
   649 	else if( !aName.CompareF( KBlockquoteTag ) )
       
   650 		{
       
   651 		InsertLineBreak();
       
   652 		BeginParagraphL( iAlignment );
       
   653 	
       
   654         iBlockQuoteLevel++;
       
   655    		}
       
   656 	else if( !aName.CompareF( KPreTag ) )
       
   657 		{
       
   658 		if ( iPreformatted == 0 )
       
   659 		    {
       
   660 		    InsertLineBreak();
       
   661 		    InsertLineBreak();
       
   662 		    }
       
   663 		iPreformatted++;
       
   664 		}
       
   665 	else if( !aName.CompareF( KQTag ) )
       
   666 		{
       
   667 		}
       
   668 	else if ( !aName.CompareF( KH1Tag ) || !aName.CompareF( KH2Tag ) || 
       
   669 	    !aName.CompareF( KH3Tag )|| !aName.CompareF( KH4Tag ) || 
       
   670 	    !aName.CompareF( KH5Tag )|| !aName.CompareF( KH6Tag ) )
       
   671 		{
       
   672 		InsertLineBreak();
       
   673 		BeginParagraphL( iAlignment );
       
   674 		BeginStyleL();
       
   675 		
       
   676 		TCharFormat charFormat;
       
   677 		TCharFormatMask charFormatMask;
       
   678 		 
       
   679 		charFormatMask.SetAttrib( EAttFontTypeface );
       
   680 	    charFormatMask.SetAttrib( EAttFontPosture );
       
   681 	    charFormatMask.SetAttrib( EAttFontHeight );
       
   682 	    charFormatMask.SetAttrib( EAttFontStrokeWeight );
       
   683 		
       
   684 		if ( !aName.CompareF( KH1Tag ) )
       
   685 	        {
       
   686 	    	charFormat.iFontSpec = iXhtmlFontSpecs->H1Font()->FontSpecInTwips();
       
   687 	        }
       
   688 	    else if ( !aName.CompareF( KH2Tag ) )
       
   689 	        {
       
   690 	        charFormat.iFontSpec = iXhtmlFontSpecs->H2Font()->FontSpecInTwips();
       
   691 	        }
       
   692 	    else if ( !aName.CompareF( KH3Tag ) )
       
   693 	        {
       
   694 	        charFormat.iFontSpec = iXhtmlFontSpecs->H3Font()->FontSpecInTwips();
       
   695 	        }
       
   696 	    else if ( !aName.CompareF( KH4Tag ) )
       
   697 	        {
       
   698 	        charFormat.iFontSpec = iXhtmlFontSpecs->H4Font()->FontSpecInTwips();
       
   699 	        }
       
   700 	    else if ( !aName.CompareF( KH5Tag ) )
       
   701 	        {
       
   702 	        charFormat.iFontSpec = iXhtmlFontSpecs->H5Font()->FontSpecInTwips();
       
   703 	        }
       
   704 		else
       
   705 		    {
       
   706 		    charFormat.iFontSpec = iXhtmlFontSpecs->H6Font()->FontSpecInTwips();
       
   707 		    }
       
   708 		
       
   709 		charFormat.iFontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightBold );
       
   710         ChangeCurrentStyleL(charFormat, charFormatMask);
       
   711    		}
       
   712 	else if( !aName.CompareF( KUlTag ) )
       
   713 		{
       
   714         BeginListL( KUnorderedListContext );
       
   715     	}
       
   716     else if( !aName.CompareF( KOlTag ) )
       
   717 		{
       
   718         BeginListL( KOrderedListContext );
       
   719     	}
       
   720 	else if ( !aName.CompareF( KLiTag ) )
       
   721 		{
       
   722         BeginListItemL();
       
   723         BeginStyleL();
       
   724 		}
       
   725    	}
       
   726 
       
   727 // ---------------------------------------------------------
       
   728 // CXhtmlParser::EndElementL 
       
   729 // ---------------------------------------------------------
       
   730 //
       
   731 void CXhtmlParser::EndElementL( const TDesC& aName )
       
   732 	{
       
   733 	if ( !aName.CompareF( KHtmlTag ) )
       
   734 	    {
       
   735 	    ApplyStyleL();
       
   736 		
       
   737 		// last line break to the end of the document
       
   738         iRichText->InsertL( iRichText->DocumentLength(), 
       
   739 		                    CRichText::ELineBreak );
       
   740 	    }
       
   741 	else if ( !aName.CompareF( KBodyTag ) )
       
   742 	    {
       
   743 		EndStyleL();
       
   744 		iParsingAllowed = EFalse;
       
   745 	    }
       
   746 	else if ( !aName.CompareF( KATag ) )
       
   747         { 
       
   748         EndHyperLinkL( iRichText->DocumentLength() );
       
   749         }
       
   750     else if ( !aName.CompareF( KDdTag ) )
       
   751         {
       
   752    		EndParagraphL();
       
   753    		iDefListLevel--;
       
   754         }
       
   755     else if ( !aName.CompareF( KDtTag ) )        
       
   756         {
       
   757         }
       
   758     else if ( !aName.CompareF( KDlTag ) )        
       
   759         {
       
   760         InsertLineBreak();
       
   761         EndParagraphL();
       
   762         }
       
   763     else if( !aName.CompareF( KSmallTag ) || !aName.CompareF( KBigTag ) )
       
   764 	    {
       
   765 	    EndStyleL();
       
   766 	    }
       
   767 	else if ( !aName.CompareF( KBTag ) || !aName.CompareF( KStrongTag ) )
       
   768 		{
       
   769 		EndStyleL();
       
   770 		}
       
   771 	else if ( !aName.CompareF( KITag ) || !aName.CompareF( KEmTag ) || 
       
   772 	        !aName.CompareF( KCiteTag )	|| !aName.CompareF( KDfnTag ) || 
       
   773 	        !aName.CompareF( KVarTag ) )
       
   774 		{
       
   775 		EndStyleL();
       
   776 		}
       
   777 	else if ( !aName.CompareF( KAddressTag ) )
       
   778 		{
       
   779 		InsertLineBreak();
       
   780 		EndStyleL();
       
   781 		}
       
   782 	else if ( !aName.CompareF( KKbdTag ) || !aName.CompareF( KCodeTag ) ||
       
   783 	        !aName.CompareF( KSampTag ) ) 
       
   784 		{
       
   785 		EndStyleL();
       
   786 		}		
       
   787 	else if ( !aName.CompareF( KBlockquoteTag ) )
       
   788 		{
       
   789 		InsertLineBreak();
       
   790    		EndParagraphL();
       
   791 		iBlockQuoteLevel--;
       
   792 	    }
       
   793 	else if ( !aName.CompareF( KPreTag ) )
       
   794 	    {
       
   795 		if ( iPreformatted > 0 )
       
   796 		    {
       
   797 		    iPreformatted--;
       
   798 	
       
   799 		    if ( iPreformatted == 0 )
       
   800 		        {
       
   801 		        InsertLineBreak();
       
   802 	            InsertLineBreak();
       
   803 		        }
       
   804 		    }
       
   805 	    }
       
   806 	else if ( !aName.CompareF( KPTag ) )
       
   807         {
       
   808 		InsertLineBreak();
       
   809 		EndParagraphL();
       
   810         }
       
   811     else if ( !aName.CompareF( KDivTag ) )
       
   812         {
       
   813 		EndParagraphL();
       
   814         }
       
   815     else if ( !aName.CompareF( KQTag ) )
       
   816         {
       
   817         }  
       
   818 	else if ( !aName.CompareF( KH1Tag ) || !aName.CompareF( KH2Tag ) || 
       
   819 	        !aName.CompareF( KH3Tag )|| !aName.CompareF( KH4Tag ) || 
       
   820 	        !aName.CompareF( KH5Tag )|| !aName.CompareF( KH6Tag ) )
       
   821 		{
       
   822 		EndStyleL();
       
   823 		InsertLineBreak();
       
   824 		EndParagraphL();
       
   825 	    }
       
   826 	else if ( !aName.CompareF( KLiTag ) )
       
   827 		{
       
   828 		EndStyleL();
       
   829 		}
       
   830 	else if ( !aName.CompareF( KUlTag ) || !aName.CompareF( KOlTag ) )
       
   831 		{
       
   832 		EndListL();
       
   833    		}
       
   834    	else if( !aName.CompareF( KHrTag ) )
       
   835         {
       
   836         EndStyleL();
       
   837         InsertLineBreak();
       
   838         EndParagraphL();
       
   839         }
       
   840     else if( !aName.CompareF( KBrTag ) )
       
   841         {
       
   842         }
       
   843                 		   
       
   844     // if alignment was changed and a new paragraph added, end this paragraph  
       
   845     
       
   846     if ( iStackManager->StyleStack()->Top() && iStackManager->StyleStack()->Top()->iAlignmentChanged )
       
   847     {
       
   848         EndParagraphL();
       
   849    	}
       
   850    	EndStyleL(); // BeginStyleL has been called in PrepareForBeginElementL
       
   851 	}
       
   852 
       
   853 // ---------------------------------------------------------
       
   854 // CXhtmlParser::BeginStyleL
       
   855 // ---------------------------------------------------------
       
   856 //
       
   857 void CXhtmlParser::BeginStyleL()
       
   858     {
       
   859     if ( iStackManager->StyleStack()->Top() )
       
   860 	    {
       
   861         if ( iStylePos == KNoStylePosition )
       
   862 		    {
       
   863 		    iStylePos = iStackManager->StyleStack()->Top()->iStyleStart;    
       
   864 		    }
       
   865    		}
       
   866     TXhtmlStyleInfo* style = new( ELeave )
       
   867         TXhtmlStyleInfo( iRichText->DocumentLength(), iAlignment );
       
   868         
       
   869     iStackManager->StyleStack()->PushL( style );
       
   870     }
       
   871 
       
   872 // ---------------------------------------------------------
       
   873 // CXhtmlParser::EndStyleL 
       
   874 // ---------------------------------------------------------
       
   875 //
       
   876 void CXhtmlParser::EndStyleL()
       
   877     {
       
   878     if ( iStackManager->StyleStack()->Top() )
       
   879         {
       
   880         if ( iStylePos == KNoStylePosition )
       
   881 		    {
       
   882 		    iStylePos = iStackManager->StyleStack()->Top()->iStyleStart;  
       
   883 		    }
       
   884 		if ( iStackManager->StyleStack()->Top()->iStyleChanged )
       
   885 		    {
       
   886 		    ApplyStyleL();
       
   887 		    iStylePos = KNoStylePosition;
       
   888 		    iCurrentCharLayer = CleanCharLayer();
       
   889             }
       
   890         iAlignment = iStackManager->StyleStack()->Top()->iPrevAlign;    
       
   891         }
       
   892 
       
   893     iStackManager->StyleStack()->Pop();
       
   894     
       
   895     if ( iStackManager->StyleStack()->Top() )
       
   896         {
       
   897         iStackManager->StyleStack()->Top()->iStyleStart = iRichText->DocumentLength();
       
   898         }
       
   899     }
       
   900 
       
   901 // ---------------------------------------------------------
       
   902 // CXhtmlParser::ChangeCurrentStyleL 
       
   903 // ---------------------------------------------------------
       
   904 //
       
   905 void CXhtmlParser::ChangeCurrentStyleL(TCharFormat charFormat,
       
   906     TCharFormatMask charFormatMask)
       
   907     {
       
   908     ApplyStyleL();
       
   909     iStylePos = KNoStylePosition;
       
   910 
       
   911     if ( iStackManager->StyleStack()->Top() )
       
   912         {
       
   913         iStackManager->StyleStack()->Top()->iStyleChanged = ETrue;
       
   914         }
       
   915         
       
   916 	CCharFormatLayer* cfl = 
       
   917 	    CCharFormatLayer::NewL( charFormat, charFormatMask );
       
   918 	cfl->SetBase( iCurrentCharLayer );
       
   919 	iCurrentCharLayer = cfl;
       
   920     }
       
   921 
       
   922 // ---------------------------------------------------------
       
   923 // CXhtmlParser::ApplyStyle 
       
   924 // ---------------------------------------------------------
       
   925 //
       
   926 void CXhtmlParser::ApplyStyleL()
       
   927     {
       
   928     if ( iStylePos != KNoStylePosition && ( iRichText->DocumentLength() - iStylePos > 0 ) )
       
   929         {
       
   930         TCharFormat charFormat;
       
   931 	    TCharFormatMask charFormatMask;
       
   932 
       
   933 		iCurrentCharLayer->SenseEffective( charFormat );
       
   934 		charFormatMask.SetAll();
       
   935     
       
   936         if ( !iPlainText )
       
   937             {
       
   938             iRichText->ApplyCharFormatL( charFormat, charFormatMask, 
       
   939 		        iStylePos, iRichText->DocumentLength() - iStylePos );
       
   940             }
       
   941 
       
   942         }
       
   943     }
       
   944 
       
   945 // ---------------------------------------------------------
       
   946 // CXhtmlParser::BeginParagraphL 
       
   947 // ---------------------------------------------------------
       
   948 //
       
   949 void CXhtmlParser::BeginParagraphL( CParaFormat::TAlignment aAlignment )
       
   950     {
       
   951     if ( iStackManager->ParaStack()->Top() )
       
   952         {
       
   953         ApplyParagraphL( iStackManager->ParaStack()->Top()->iParaStart,
       
   954             iStackManager->ParaStack()->Top()->iAlignment );
       
   955         }
       
   956     if ( iFirstTextLineAdded )
       
   957         {
       
   958         AppendParagraphL( iPlainText ); 
       
   959         }
       
   960     else
       
   961         {
       
   962         iNewParagraph = ETrue;    
       
   963         }
       
   964     TXhtmlParaInfo* info = new( ELeave ) TXhtmlParaInfo( iRichText->DocumentLength(), aAlignment );
       
   965 	iStackManager->ParaStack()->PushL( info );
       
   966     }
       
   967 
       
   968 // ---------------------------------------------------------
       
   969 // CXhtmlParser::EndParagraphL 
       
   970 // ---------------------------------------------------------
       
   971 //
       
   972 void CXhtmlParser::EndParagraphL()
       
   973     {
       
   974     if (iStackManager->ParaStack()->Top())
       
   975         {
       
   976         ApplyParagraphL( iStackManager->ParaStack()->Top()->iParaStart,
       
   977             iStackManager->ParaStack()->Top()->iAlignment );
       
   978     
       
   979         if ( iFirstTextLineAdded )
       
   980             {
       
   981             AppendParagraphL( iPlainText ); 
       
   982             }
       
   983         else
       
   984             {
       
   985             iNewParagraph = ETrue;    
       
   986             }
       
   987         }
       
   988         
       
   989     iStackManager->ParaStack()->Pop();    
       
   990         
       
   991     if ( iStackManager->ParaStack()->Top() )
       
   992         {
       
   993         iStackManager->ParaStack()->Top()->iParaStart = iRichText->DocumentLength();
       
   994         }
       
   995     }
       
   996 
       
   997 // ---------------------------------------------------------
       
   998 // CXhtmlParser::ApplyParagraphL 
       
   999 // ---------------------------------------------------------
       
  1000 //
       
  1001 void CXhtmlParser::ApplyParagraphL( TInt aParaStart,
       
  1002     CParaFormat::TAlignment aAlignment )
       
  1003     {
       
  1004     TInt docLength = iRichText->DocumentLength();
       
  1005 	TInt paraLength = docLength - aParaStart;
       
  1006 
       
  1007     if ( paraLength > 0 )
       
  1008         {
       
  1009         CParaFormat* paraFormat = CParaFormat::NewL();
       
  1010 	    CleanupStack::PushL( paraFormat );
       
  1011 	    TParaFormatMask paraFormatMask = TParaFormatMask();
       
  1012 	
       
  1013         if ( aAlignment != CParaFormat::EUnspecifiedAlign )
       
  1014             {
       
  1015             paraFormatMask.SetAttrib( EAttAlignment );
       
  1016             paraFormat->iHorizontalAlignment = aAlignment;
       
  1017             }
       
  1018     
       
  1019         CGraphicsDevice* screenDevice = CCoeEnv::Static()->ScreenDevice();
       
  1020 
       
  1021         TInt indentWidthInTwips = iIndentWidth * screenDevice->HorizontalPixelsToTwips( 
       
  1022             iXhtmlFontSpecs->DefaultFont()->CharWidthInPixels( TChar(' ') ) );
       
  1023       
       
  1024         // check limits
       
  1025         
       
  1026         TInt leftLevel =
       
  1027             ( ( iStackManager->ListStack()->Count() + iDefListLevel + iBlockQuoteLevel ) < iMaxListLevels )
       
  1028             ? ( iStackManager->ListStack()->Count() + iDefListLevel + iBlockQuoteLevel  ) : iMaxListLevels;
       
  1029          
       
  1030         TInt rightLevel = ( iBlockQuoteLevel  < iMaxListLevels ) ? iBlockQuoteLevel : iMaxListLevels;
       
  1031      
       
  1032         // set indents 
       
  1033          
       
  1034    	    paraFormat->iLeftMarginInTwips = leftLevel * indentWidthInTwips;
       
  1035    	    paraFormat->iRightMarginInTwips = rightLevel * indentWidthInTwips;
       
  1036    	    
       
  1037    	    paraFormatMask.SetAttrib( EAttLeftMargin );
       
  1038    	    paraFormatMask.SetAttrib( EAttRightMargin );
       
  1039 
       
  1040         if (!iPlainText)
       
  1041             {
       
  1042             iRichText->ApplyParaFormatL( paraFormat, paraFormatMask, aParaStart,
       
  1043 		        paraLength );
       
  1044 
       
  1045             }
       
  1046 		CleanupStack::PopAndDestroy( paraFormat );
       
  1047 		}
       
  1048     }
       
  1049 
       
  1050 // ---------------------------------------------------------
       
  1051 // CXhtmlParser::BeginListL 
       
  1052 // ---------------------------------------------------------
       
  1053 //
       
  1054 void CXhtmlParser::BeginListL(TInt aListContext)
       
  1055     {
       
  1056     if ( iStackManager->ListStack()->Count() == 0 && iDefListLevel == 0)
       
  1057         {
       
  1058         InsertLineBreak();
       
  1059         }
       
  1060     BeginParagraphL( iAlignment );
       
  1061     
       
  1062     TXhtmlListInfo* info = new( ELeave ) TXhtmlListInfo( iCurrentListContext );
       
  1063     iStackManager->ListStack()->PushL( info );
       
  1064 	
       
  1065 	iCurrentListContext = aListContext;  
       
  1066     }
       
  1067 
       
  1068 // ---------------------------------------------------------
       
  1069 // CXhtmlParser::EndList 
       
  1070 // ---------------------------------------------------------
       
  1071 //
       
  1072 void CXhtmlParser::EndListL()
       
  1073     {
       
  1074     if ( ( iStackManager->ListStack()->Count() + iDefListLevel ) <= 1 )
       
  1075         {
       
  1076         InsertLineBreak();
       
  1077         }
       
  1078    	EndParagraphL();
       
  1079    	
       
  1080     if (iStackManager->ListStack()->Top())
       
  1081         {
       
  1082         iCurrentListContext = iStackManager->ListStack()->Top()->iListContext;
       
  1083         }   	
       
  1084     iStackManager->ListStack()->Pop();
       
  1085     }
       
  1086 
       
  1087 // ---------------------------------------------------------
       
  1088 // CXhtmlParser::BeginListItemL
       
  1089 // ---------------------------------------------------------
       
  1090 //
       
  1091 void CXhtmlParser::BeginListItemL()
       
  1092     {
       
  1093     TXhtmlListInfo *info = iStackManager->ListStack()->Top();
       
  1094     if ( !info )
       
  1095         {
       
  1096         return;
       
  1097         }
       
  1098     
       
  1099     if ( ( info->iListIndex > 0 ) && ( iNewLines == 0 ) && ( iForcedNewLines == 0 ) )
       
  1100         {
       
  1101         iRichText->InsertL( iRichText->DocumentLength(),
       
  1102             CRichText::EParagraphDelimiter );
       
  1103         }
       
  1104         
       
  1105     info->iListIndex++;
       
  1106 
       
  1107    	if ( iCurrentListContext == KOrderedListContext )
       
  1108 	    {
       
  1109 	    TBuf16<16> prefix;
       
  1110         prefix.Format( KListNumberFormat, info->iListIndex );
       
  1111         
       
  1112         HBufC* tmpString = prefix.AllocLC();
       
  1113         
       
  1114         TPtrC result; 
       
  1115         DoNumberConversion( tmpString, result );
       
  1116 
       
  1117         InsertTextL( result );
       
  1118         CleanupStack::PopAndDestroy( tmpString );
       
  1119 		}
       
  1120 	else
       
  1121 		{
       
  1122 		if ( iPlainText )
       
  1123             {
       
  1124             TInt bullet = ( iStackManager->ListStack()->Count() % 2 ) ? KPlainBullet : KPlainBullet2 ;
       
  1125             InsertCharacterL( TChar( bullet ) );
       
  1126             }
       
  1127         else
       
  1128             {
       
  1129             TInt bullet = ( iStackManager->ListStack()->Count() % 2 ) ? KListBullet : KListBullet2 ;
       
  1130             InsertCharacterL( TChar( bullet) );
       
  1131             }
       
  1132         }
       
  1133     }
       
  1134     
       
  1135 // ---------------------------------------------------------
       
  1136 // CXhtmlParser::BeginHyperLinkL 
       
  1137 // ---------------------------------------------------------
       
  1138 // 
       
  1139 void CXhtmlParser::BeginHyperLink( TInt aBeginPosition )
       
  1140     {
       
  1141 	XHTMLLOG_WRITE( "BeginHyperLinkL" );
       
  1142 
       
  1143     delete iHyperLinkAddress;
       
  1144     iHyperLinkAddress = NULL;
       
  1145         
       
  1146     iHyperLinkPos = aBeginPosition;
       
  1147     }
       
  1148  
       
  1149 // ---------------------------------------------------------
       
  1150 // CXhtmlParser::EndHyperLinkL 
       
  1151 // ---------------------------------------------------------
       
  1152 // 
       
  1153 void CXhtmlParser::EndHyperLinkL( TInt aEndPosition )
       
  1154     {
       
  1155 	XHTMLLOG_WRITE( "EndHyperLinkL");
       
  1156     
       
  1157     if ( iHyperLinkAddress )
       
  1158         {
       
  1159         CXhtmlHyperLink* hpLink = new (ELeave) CXhtmlHyperLink( iHyperLinkPos,
       
  1160             aEndPosition - 1 );
       
  1161     
       
  1162         TPtrC addrPtr = iHyperLinkAddress->Des();
       
  1163         hpLink->SetAddressL(addrPtr);
       
  1164               
       
  1165         delete iHyperLinkAddress;
       
  1166         iHyperLinkAddress = NULL;
       
  1167         
       
  1168         iHyperLinkArray->InsertL( iHyperLinkArray->Count(), hpLink );
       
  1169        
       
  1170         if ( iShowUrls )
       
  1171             {
       
  1172             InsertCharacterL( TChar(' ') );
       
  1173             InsertCharacterL( TChar('(') );
       
  1174             InsertTextL( hpLink->Address()->Des() );
       
  1175             InsertCharacterL( TChar(')') );
       
  1176             }
       
  1177         }
       
  1178     }
       
  1179 
       
  1180 // ---------------------------------------------------------
       
  1181 // CXhtmlParser::ContentL
       
  1182 // ---------------------------------------------------------
       
  1183 //
       
  1184 void CXhtmlParser::ContentL( const TDesC& aData )
       
  1185 	{	 
       
  1186     if ( !iParsingAllowed )
       
  1187         {
       
  1188         return;
       
  1189         } 
       
  1190 	
       
  1191     HBufC16* buffer = aData.Alloc();
       
  1192     CleanupStack::PushL( buffer );
       
  1193 
       
  1194     TPtr16 bufferPtr = buffer->Des();
       
  1195 
       
  1196     if( iPreformatted > 0 )
       
  1197         {        
       
  1198         // XHTML parsing, pre tag specified (preformatted text)
       
  1199         
       
  1200         TInt offset = 0;
       
  1201         TInt poffset = 0;
       
  1202         
       
  1203         TChar LF( 0x0A );
       
  1204         TChar CR( 0x0D );  
       
  1205 
       
  1206         if( bufferPtr.Locate( LF ) > 0 || bufferPtr.Locate( CR ) > 0 )
       
  1207             {
       
  1208             while( offset < bufferPtr.Length() )
       
  1209                 {
       
  1210                 TPtrC16 theRest = bufferPtr.Mid( offset );
       
  1211                 
       
  1212                 poffset = theRest.Locate( CR );
       
  1213                     
       
  1214                 if( poffset != KErrNotFound )
       
  1215                     {
       
  1216                     TPtrC16 first = theRest.Mid( 0, poffset );
       
  1217                     InsertTextL( first );
       
  1218                     
       
  1219                         iRichText->InsertL( iRichText->DocumentLength(), 
       
  1220 		                    CRichText::ELineBreak );
       
  1221 
       
  1222                         offset = offset + poffset + 1;
       
  1223                         
       
  1224                         // if next character is LF, add offset by one
       
  1225                         
       
  1226                         if ( theRest.Locate( LF ) == poffset + 1)
       
  1227                             {
       
  1228                             offset++;
       
  1229                             }
       
  1230                         }
       
  1231                     else
       
  1232                         {
       
  1233                          poffset = theRest.Locate( LF );
       
  1234                          
       
  1235                          if( poffset != KErrNotFound ) 
       
  1236                             {
       
  1237                             TPtrC16 first = theRest.Mid( 0, poffset );
       
  1238                             InsertTextL( first );
       
  1239                  
       
  1240                             iRichText->InsertL( iRichText->DocumentLength(), 
       
  1241 		                    CRichText::ELineBreak );
       
  1242 
       
  1243                             offset = offset + poffset + 1;
       
  1244                             }
       
  1245                         else
       
  1246                             {
       
  1247                             InsertTextL( theRest );
       
  1248                             break;
       
  1249                             }
       
  1250                         }
       
  1251                 } // while
       
  1252             }
       
  1253         else
       
  1254             {
       
  1255             // no newline(s) found, insert text as such
       
  1256             InsertTextL( bufferPtr );
       
  1257             }
       
  1258         }
       
  1259     else     
       
  1260         {
       
  1261         // XHTML parsing, pre tag not specified (extra whitespaces removed)
       
  1262         CollapseWhiteSpaces( bufferPtr );   
       
  1263 
       
  1264         if (bufferPtr.Length() > 0)
       
  1265             {
       
  1266             InsertTextL( bufferPtr );
       
  1267             }
       
  1268         }
       
  1269     CleanupStack::PopAndDestroy( buffer );
       
  1270     }
       
  1271 
       
  1272 // ---------------------------------------------------------
       
  1273 // CXhtmlParser::CollapseWhiteSpaces
       
  1274 //
       
  1275 // Function processes the whole text and converts any
       
  1276 // found sequence of white spaces into single space.
       
  1277 // ---------------------------------------------------------
       
  1278 //
       
  1279 void CXhtmlParser::CollapseWhiteSpaces( TDes& aData )
       
  1280     {
       
  1281     TInt whiteSpaces( 0 );
       
  1282     TInt currentPos( 0 );
       
  1283     
       
  1284     while( currentPos < aData.Length() )
       
  1285         {
       
  1286         if( aData[currentPos] == CEditableText::ESpace ||
       
  1287             aData[currentPos] == KZeroWidthSpace ||
       
  1288             ( aData[currentPos] >= 0x0009 && aData[currentPos] <= 0x000d ) )
       
  1289             {
       
  1290             whiteSpaces++;
       
  1291             }
       
  1292         else if( whiteSpaces > 0 )
       
  1293             {
       
  1294             currentPos = currentPos - whiteSpaces;
       
  1295 
       
  1296             if (iSkipWhiteSpaces)
       
  1297                 {
       
  1298                 aData.Delete( currentPos, whiteSpaces );
       
  1299                 iSkipWhiteSpaces = EFalse;
       
  1300                 }
       
  1301             else
       
  1302                 {
       
  1303                 aData.Replace( currentPos, whiteSpaces, KWhiteSpace );
       
  1304                 }
       
  1305             whiteSpaces = 0;
       
  1306             }
       
  1307         else
       
  1308             {
       
  1309             // no whitespaces at the beginning
       
  1310             iSkipWhiteSpaces = EFalse;
       
  1311             }
       
  1312         currentPos++;
       
  1313         }
       
  1314        
       
  1315     if( whiteSpaces > 0 )
       
  1316         {
       
  1317         if (iSkipWhiteSpaces)
       
  1318             {
       
  1319             aData.Delete( currentPos - whiteSpaces, whiteSpaces );
       
  1320             }
       
  1321         else
       
  1322             {
       
  1323             aData.Replace( currentPos - whiteSpaces, whiteSpaces, KWhiteSpace );
       
  1324             }
       
  1325         }    
       
  1326     }
       
  1327 
       
  1328 // ---------------------------------------------------------
       
  1329 // CXhtmlParser::AttributeValueL
       
  1330 // ---------------------------------------------------------
       
  1331 //
       
  1332 void CXhtmlParser::AttributeValueL( const TDesC& aName, const TDesC& aValue )
       
  1333 	{
       
  1334 	CParaFormat::TAlignment alignment = iAlignment;
       
  1335 
       
  1336     if( !aName.CompareF( KHrefAttr ) ) 
       
  1337         {
       
  1338         SetReferenceL( aValue ); 
       
  1339         }
       
  1340 	if( !aName.CompareF( KStyleAttr ) )
       
  1341 	    {
       
  1342 		TRgb colorValue = 0;
       
  1343 		TBool colorAttr = EFalse;
       
  1344 		TBool underlineAttr = EFalse;
       
  1345 		
       
  1346 		TInt offset = 0;
       
  1347 		TInt poffset = 0;
       
  1348 
       
  1349 		HBufC16* buffer = aValue.AllocLC();
       
  1350 
       
  1351 		TPtr16 bufferPtr = buffer->Des();
       
  1352 
       
  1353 		RemoveAllSpace( bufferPtr );
       
  1354 
       
  1355 		TPtrC nameStyle;
       
  1356 		TPtrC valueStyle;
       
  1357 		TBool transparent = EFalse;
       
  1358         
       
  1359         while( offset < bufferPtr.Length() )
       
  1360             {
       
  1361             TPtrC16 theRest = bufferPtr.Mid( offset );
       
  1362             poffset = theRest.Locate( TChar( KSemicolon ) );
       
  1363 
       
  1364 			if( poffset != KErrNotFound )
       
  1365                 {
       
  1366 			    TPtrC16 first = theRest.Mid( 0, poffset );
       
  1367 				SplitAttribute( first, nameStyle, valueStyle );
       
  1368 				offset = offset + poffset + 1;
       
  1369 			    }
       
  1370 			else
       
  1371 			    {
       
  1372 				SplitAttribute( theRest, nameStyle, valueStyle );
       
  1373 				offset = bufferPtr.Length();
       
  1374 			    }
       
  1375 				
       
  1376             if( !nameStyle.CompareF( KColorAttr ) )
       
  1377 			    {
       
  1378 				colorValue = ParseColor( valueStyle, transparent );
       
  1379 				colorAttr = ETrue;
       
  1380 				}
       
  1381 				
       
  1382 			if ( !nameStyle.CompareF( KTextDecorationAttr ) &&
       
  1383 			     !valueStyle.CompareF( KUnderlineAttr ) )
       
  1384 			    {
       
  1385 			    underlineAttr = ETrue;
       
  1386 			    }
       
  1387 				
       
  1388             if( !nameStyle.CompareF( KTextAlignAttr ) )
       
  1389                 {
       
  1390                 //left
       
  1391                 if ( !valueStyle.CompareF( KLeftAttr ) )
       
  1392                     {
       
  1393                     //set the align-value and use it in the paragraph-tag if set
       
  1394                     iAlignment = CParaFormat::ELeftAlign;
       
  1395                     }
       
  1396                 //center
       
  1397                 else if( !valueStyle.CompareF( KCenterAttr ) )
       
  1398                     {
       
  1399                     iAlignment = CParaFormat::ECenterAlign;                        
       
  1400                     }
       
  1401                     
       
  1402                 //right
       
  1403                 else if( !valueStyle.CompareF( KRightAttr ) )
       
  1404                     {
       
  1405                     iAlignment = CParaFormat::ERightAlign;
       
  1406                     }
       
  1407 
       
  1408                 //justified
       
  1409                 else if( !valueStyle.CompareF( KJustifyAttr ) )
       
  1410                     {
       
  1411                     iAlignment = CParaFormat::EJustifiedAlign;
       
  1412                     }
       
  1413                 }
       
  1414    		    }
       
  1415 
       
  1416 		CleanupStack::PopAndDestroy( buffer );  
       
  1417 				
       
  1418 		TCharFormat charFormat;
       
  1419 		TCharFormatMask charFormatMask;
       
  1420 		
       
  1421 		if( colorAttr )
       
  1422 		    {
       
  1423 			charFormatMask.SetAttrib( EAttColor );
       
  1424 			charFormat.iFontPresentation.iTextColor = colorValue;
       
  1425 		    }
       
  1426 		if ( underlineAttr )
       
  1427 		    {
       
  1428 			charFormatMask.SetAttrib( EAttFontUnderline );
       
  1429 			charFormat.iFontPresentation.iUnderline = EUnderlineOn;
       
  1430 		    }
       
  1431 	    ChangeCurrentStyleL(charFormat, charFormatMask);
       
  1432 	    }
       
  1433 
       
  1434 	if( !aName.CompareF( KColorAttr ) )
       
  1435 		{
       
  1436 		TBool transparent = EFalse;
       
  1437 		TRgb color = ParseColor( aValue, transparent );
       
  1438 		
       
  1439 		TCharFormat charFormat;
       
  1440 		TCharFormatMask charFormatMask;
       
  1441 
       
  1442 		charFormatMask.SetAttrib( EAttColor ); 
       
  1443 		charFormat.iFontPresentation.iTextColor = color;
       
  1444 		ChangeCurrentStyleL(charFormat, charFormatMask);
       
  1445 		}
       
  1446 	else if( !aName.CompareF( KAltAttr ) )
       
  1447 		{
       
  1448 		if( aValue.Length() > 0 && iImageFound)
       
  1449 		    {
       
  1450 			InsertTextL( aValue );
       
  1451 		    }
       
  1452 		}
       
  1453 	if ( alignment != iAlignment )
       
  1454 	    {
       
  1455 	    iAlignmentChanged = ETrue;
       
  1456 	    }
       
  1457 	}
       
  1458 
       
  1459 // ---------------------------------------------------------
       
  1460 // CXhtmlParser::SetReferenceL() 
       
  1461 // ---------------------------------------------------------
       
  1462 // 
       
  1463 void CXhtmlParser::SetReferenceL( const TDesC& aUrl )
       
  1464     {
       
  1465     delete iHyperLinkAddress;
       
  1466     iHyperLinkAddress = NULL;
       
  1467         
       
  1468     iHyperLinkAddress = HBufC::NewL( aUrl.Length() );
       
  1469     TPtr ptr = iHyperLinkAddress->Des();
       
  1470     ptr = aUrl;
       
  1471     }
       
  1472 
       
  1473 // ---------------------------------------------------------
       
  1474 // CXhtmlParser::RemoveAllSpace
       
  1475 // ---------------------------------------------------------
       
  1476 //
       
  1477 void CXhtmlParser::RemoveAllSpace( TDes& aString )
       
  1478     {
       
  1479 	const TChar KSpace = TChar( ' ' );  
       
  1480 	for( TInt offset = aString.Locate( KSpace ); offset != KErrNotFound;
       
  1481 	     offset = aString.Locate( KSpace ) )
       
  1482 	    {
       
  1483 		aString.Delete( offset, 1 );
       
  1484 	    }
       
  1485     }
       
  1486 
       
  1487 // ---------------------------------------------------------
       
  1488 // CXhtmlParser::SplitAttribute
       
  1489 // ---------------------------------------------------------
       
  1490 //
       
  1491 void CXhtmlParser::SplitAttribute( TPtrC& aString, TPtrC& aAttributeName, 
       
  1492                                     TPtrC& aAttributeValue )
       
  1493     {
       
  1494 	TInt offset = 0;
       
  1495     TInt poffset = 0;
       
  1496     TInt start = 0;
       
  1497 	
       
  1498     if( aString.Locate( TChar( KColon ) ) > 0 )
       
  1499         {
       
  1500         while( offset < aString.Length() )
       
  1501             {
       
  1502             TPtrC16 theRest = aString.Mid( offset );
       
  1503             poffset = theRest.Locate( TChar ( KColon ) );			
       
  1504 
       
  1505 			if( poffset != KErrNotFound )
       
  1506                 {
       
  1507                 aAttributeName.Set( theRest.Mid( start, poffset ) );
       
  1508 				aAttributeValue.Set( theRest.Mid( poffset + 1 ) );
       
  1509 				return;
       
  1510 				}
       
  1511 			}
       
  1512 	    }
       
  1513     }
       
  1514 
       
  1515 // ---------------------------------------------------------
       
  1516 // CXhtmlParser::ParseColor
       
  1517 // ---------------------------------------------------------
       
  1518 //
       
  1519 TRgb CXhtmlParser::ParseColor( const TDesC& aString, TBool& aTransparent )
       
  1520 	{
       
  1521 	aTransparent = ETrue;
       
  1522 	TRgb res = 0;
       
  1523 	if ( aString.Length()>1 )
       
  1524 		{
       
  1525 		TUint32 val = 0;
       
  1526 		if( aString[0] == '#' )
       
  1527 			{
       
  1528 			TLex lexer ( aString.Mid( 1 ) );
       
  1529 			if( lexer.Val( val, EHex, KWhiteColorCode )==KErrNone )
       
  1530 				{
       
  1531 				res = TRgb ((val&KBlueColorCode)>>16, 
       
  1532 				    (val&KLimeColorCode)>>8, (val&KRedColorCode));
       
  1533 				aTransparent = EFalse;
       
  1534 				}			
       
  1535 			}
       
  1536 		else if ( aString == KTransparentVal )
       
  1537 			{
       
  1538 			aTransparent = ETrue;
       
  1539 			}
       
  1540 		else
       
  1541 			{
       
  1542 			for( TInt n = 0; KColorNames[n]; n++ )
       
  1543 				{
       
  1544 				
       
  1545 				if ( !aString.CompareF( TPtrC(KColorNames[n]) ) )
       
  1546 					{					
       
  1547 					res = KColorValues[n];
       
  1548 
       
  1549 					aTransparent = EFalse;
       
  1550 					break;
       
  1551 					}
       
  1552 				}
       
  1553 			}
       
  1554 		}
       
  1555 	return res;
       
  1556 	}
       
  1557 
       
  1558 // ---------------------------------------------------------
       
  1559 // CXhtmlParser::CdataL
       
  1560 // ---------------------------------------------------------
       
  1561 //
       
  1562 void CXhtmlParser::CdataL( const TDesC& aData ) 
       
  1563 	{
       
  1564    	if ( iParsingAllowed )
       
  1565 	    {
       
  1566 		InsertTextL( aData );
       
  1567 	    }
       
  1568 	}
       
  1569 
       
  1570 // ---------------------------------------------------------
       
  1571 // CXhtmlParser::CleanCharLayer
       
  1572 // ---------------------------------------------------------
       
  1573 //
       
  1574 CCharFormatLayer* CXhtmlParser::CleanCharLayer()
       
  1575     {
       
  1576    	CCharFormatLayer* cfl = iCurrentCharLayer;
       
  1577 	const CCharFormatLayer* layer = static_cast<const CCharFormatLayer*>( cfl->SenseBase() );
       
  1578 	iCurrentCharLayer = const_cast<CCharFormatLayer*>( layer ); 
       
  1579 	       
       
  1580 	cfl->Reset();
       
  1581 	delete cfl;
       
  1582 	return iCurrentCharLayer;
       
  1583     }
       
  1584         	
       
  1585 // ---------------------------------------------------------
       
  1586 // Convert between arabic-indic digits and european digits based on existing language setting.
       
  1587 // So it'll convert any digit from the string
       
  1588 // to use either european digits or arabic-indic digits based on current settings.
       
  1589 // @param aFieldString: Data buffer used in conversion.
       
  1590 // @param aFieldData: Return converted data in this parameter.
       
  1591 // ---------------------------------------------------------
       
  1592 //
       
  1593 void CXhtmlParser::DoNumberConversion( HBufC* aFieldString, TPtrC& aFieldData ) const
       
  1594     {
       
  1595     if( aFieldString )
       
  1596         {
       
  1597     	TPtr tmpPtr = aFieldString->Des();
       
  1598     	if ( tmpPtr.Length() > 0 )
       
  1599             {
       
  1600             AknTextUtils::DisplayTextLanguageSpecificNumberConversion( tmpPtr );
       
  1601             }
       
  1602         aFieldData.Set( tmpPtr );
       
  1603         }
       
  1604     else
       
  1605         {
       
  1606         aFieldData.Set(KNullString);
       
  1607         }
       
  1608     }
       
  1609 
       
  1610 // ---------------------------------------------------------
       
  1611 // CXhtmlParser::ResetValuesL 
       
  1612 // ---------------------------------------------------------
       
  1613 //
       
  1614 void CXhtmlParser::ResetValues()
       
  1615 	{
       
  1616 	iParsingAllowed = EFalse;
       
  1617    	iPreformatted = 0;
       
  1618    	iAlignment = CParaFormat::ELeftAlign;
       
  1619    	iStylePos = KNoStylePosition;
       
  1620 	iNewParagraph = EFalse;
       
  1621     iNewLines = 0;
       
  1622 	iForcedNewLines = 0;
       
  1623 	iSkipWhiteSpaces = ETrue;
       
  1624     iAlignmentChanged = EFalse;
       
  1625     iImageFound = EFalse;
       
  1626     iFirstTextLineAdded = EFalse;
       
  1627    	iCurrentListContext = KNoListContext; 
       
  1628 	iDefListLevel = 0;
       
  1629 	iBlockQuoteLevel = 0;
       
  1630 	iHyperLinkPos = 0;
       
  1631 	iHyperLinkArray->ResetAndDestroy();
       
  1632 	}	    
       
  1633 
       
  1634 // ---------------------------------------------------------
       
  1635 // CXhtmlParser::InsertTextL 
       
  1636 // ---------------------------------------------------------
       
  1637 //
       
  1638 void CXhtmlParser::InsertTextL( const TDesC& aText )
       
  1639     {
       
  1640 #ifdef USE_LOGGER
       
  1641 	XHTMLLOG_WRITE( "InsertTextL" );
       
  1642 	HBufC* buf = HBufC::NewL( aText.Length() +4 );
       
  1643 	buf->Des().Append(_L("["));
       
  1644 	buf->Des().Append(aText);
       
  1645 	buf->Des().Append(_L("]"));
       
  1646   XHTMLLOG_WRITEF( _L("%S"), buf );
       
  1647 	delete buf;
       
  1648 #endif 
       
  1649 
       
  1650     TInt maxLines = ( iNewLines > iForcedNewLines ) ? iNewLines : iForcedNewLines;
       
  1651     
       
  1652     if ( !iFirstTextLineAdded )
       
  1653         {
       
  1654         maxLines = iForcedNewLines;
       
  1655         }
       
  1656     
       
  1657     if ( iNewParagraph )
       
  1658         {
       
  1659         maxLines--;
       
  1660         }
       
  1661         
       
  1662     for ( TInt i = 0; i < maxLines; i++ )
       
  1663         {
       
  1664         iRichText->InsertL( iRichText->DocumentLength(), 
       
  1665 		                    CRichText::ELineBreak );
       
  1666         }
       
  1667     iRichText->InsertL( iRichText->DocumentLength(), aText );
       
  1668 
       
  1669     iNewParagraph = EFalse;
       
  1670     iNewLines = 0;
       
  1671     iForcedNewLines = 0; 
       
  1672     
       
  1673     iFirstTextLineAdded = ETrue;
       
  1674     }
       
  1675 
       
  1676 // ---------------------------------------------------------
       
  1677 // CXhtmlParser::InsertCharacterL 
       
  1678 // ---------------------------------------------------------
       
  1679 //
       
  1680 void CXhtmlParser::InsertCharacterL( const TChar aText )
       
  1681     {
       
  1682 #ifdef USE_LOGGER
       
  1683 	XHTMLLOG_WRITE( "InsertCharacterL" );
       
  1684     
       
  1685     TBuf<2048> b;
       
  1686 	b.Append(_L("["));
       
  1687 	b.Append(aText);
       
  1688 	b.Append(_L("]"));
       
  1689 	XHTMLLOG_WRITEF( b );
       
  1690 #endif    
       
  1691     
       
  1692     TInt maxLines = ( iNewLines > iForcedNewLines ) ? iNewLines : iForcedNewLines;
       
  1693     
       
  1694     if ( !iFirstTextLineAdded )
       
  1695         {
       
  1696         maxLines = iForcedNewLines;
       
  1697         }
       
  1698             
       
  1699     if ( iNewParagraph )
       
  1700         {
       
  1701         maxLines--;
       
  1702         }
       
  1703         
       
  1704     for ( TInt i = 0; i < maxLines; i++ )
       
  1705         {
       
  1706         iRichText->InsertL( iRichText->DocumentLength(), 
       
  1707 		                    CRichText::ELineBreak );
       
  1708         }
       
  1709     iRichText->InsertL( iRichText->DocumentLength(), aText );
       
  1710 
       
  1711     iNewParagraph = EFalse;
       
  1712     iNewLines = 0;
       
  1713     iForcedNewLines = 0; 
       
  1714     
       
  1715     iFirstTextLineAdded = ETrue;
       
  1716     }
       
  1717 
       
  1718 // ---------------------------------------------------------
       
  1719 // CXhtmlParser::AppendParagraphL 
       
  1720 // ---------------------------------------------------------
       
  1721 //
       
  1722 void CXhtmlParser::AppendParagraphL( TBool aPlainText )
       
  1723     {
       
  1724 	XHTMLLOG_WRITE( "AppendParagraphL" );
       
  1725 
       
  1726     iSkipWhiteSpaces = ETrue;
       
  1727     
       
  1728     if ( !iNewParagraph )
       
  1729         {
       
  1730         
       
  1731         if ( aPlainText )
       
  1732             {
       
  1733             iRichText->InsertL( iRichText->DocumentLength(), 
       
  1734 		                    CRichText::ELineBreak );
       
  1735             }
       
  1736         else
       
  1737             {
       
  1738             iRichText->AppendParagraphL();
       
  1739             }
       
  1740         
       
  1741         iNewParagraph = ETrue; 
       
  1742         
       
  1743         if ( iNewLines < 2 )
       
  1744             {
       
  1745             iNewLines++;
       
  1746             }
       
  1747         }
       
  1748     }
       
  1749 
       
  1750 // ---------------------------------------------------------
       
  1751 // CXhtmlParser::InsertLineBreakL 
       
  1752 // ---------------------------------------------------------
       
  1753 //
       
  1754 void CXhtmlParser::InsertLineBreak()
       
  1755     {
       
  1756 	XHTMLLOG_WRITE( "InsertLineBreakL" );
       
  1757 
       
  1758     iSkipWhiteSpaces = ETrue;
       
  1759     if ( iNewLines < 2 )
       
  1760         {
       
  1761         iNewLines++;
       
  1762         }
       
  1763     }
       
  1764     
       
  1765 // ---------------------------------------------------------
       
  1766 // CXhtmlParser::InsertForcedLineBreakL 
       
  1767 // ---------------------------------------------------------
       
  1768 //
       
  1769 void CXhtmlParser::InsertForcedLineBreak()
       
  1770     {
       
  1771 	XHTMLLOG_WRITE( "InsertForcedLineBreakL"  );
       
  1772     
       
  1773     iSkipWhiteSpaces = ETrue;
       
  1774     iForcedNewLines++;
       
  1775     }