os/textandloc/textrendering/texthandling/spml/T_RTPAR.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 1997-2009 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: 
    15 *
    16 */
    17 
    18 
    19 #include "T_RTPAR.H"
    20 
    21 ////////////////////////////////////////////
    22 // CRichTextReader
    23 ////////////////////////////////////////////
    24 
    25 CRichTextReader* CRichTextReader::NewL()
    26 	{
    27 	CRichTextReader* self=new(ELeave) CRichTextReader;
    28 	CleanupStack::PushL(self);
    29 	self->ConstructL();
    30 	CleanupStack::Pop();
    31 	return self;
    32 	}
    33 
    34 
    35 CRichTextReader::CRichTextReader()
    36 	{
    37 	// init variables
    38 	iParaStart = 0;
    39 	iConsoleExists = EFalse;
    40 	}
    41 	 
    42 
    43 void CRichTextReader::ConstructL()
    44 	{ 
    45 	// construct PML writer
    46 	iPMLWriter = CPMLWriter::NewL();
    47 	
    48 	// construct RichText bits
    49 	iThisParaFormat = CParaFormat::NewL();
    50 	iPrevParaFormat = CParaFormat::NewL();
    51 	}
    52 
    53 
    54 void CRichTextReader::Destruct()
    55 	{
    56 	// iConsole.Destroy();
    57 	Adt::Destroy(iPMLWriter);
    58 	Adt::Destroy(iThisParaFormat);
    59 	Adt::Destroy(iPrevParaFormat);
    60 	if (iBorder)
    61 		delete(iBorder);	// only delete if it hasn't been used (if it has RT destroys it automatically)
    62 	}
    63 
    64 
    65 CBufSeg* CRichTextReader::ConvertRichText(CRichText* aRichTextDoc)
    66 // Quiet version of the RichText->PML parser
    67 // Takes RT doc passed in, reads its global format,
    68 // then reads the character and paragraph formats phrase by phrase
    69 	{
    70 	iRichTextDoc = aRichTextDoc;
    71 	iDocLength = iRichTextDoc->DocumentLength();
    72 	SenseGlobalFormat();
    73 
    74 	TInt nextPhrase;
    75 	TInt readPos = 0;
    76 	 while (readPos < iDocLength)
    77 	 	{
    78 		nextPhrase = TranslatePhrase(readPos);
    79 		readPos += nextPhrase;
    80 		}
    81 	iPMLWriter->Delete(1);		// remove end-of-document paragraph delimiter
    82 	return iPMLWriter->ReturnPmlDoc();
    83 	}
    84 
    85 
    86 CBufSeg* CRichTextReader::ConvertRichText(CRichText* aRichTextDoc, RConsole aConsole)
    87 // Version of the RichText->PML parser with console output (primarily for debugging)
    88 // Takes RT doc passed in, reads its global format,
    89 // then reads the character and paragraph formats phrase by phrase
    90 	{
    91 	iConsoleExists = ETrue;
    92 	iRichTextDoc = aRichTextDoc;
    93 	iConsole = aConsole;
    94 	iDocLength = iRichTextDoc->DocumentLength();
    95 	SenseGlobalFormat();
    96 
    97 	TInt nextPhrase;
    98 	TInt readPos = 0;
    99 	while (readPos <= iDocLength)
   100 	 	{
   101 		nextPhrase = TranslatePhrase(readPos);
   102 		readPos += nextPhrase;
   103 		}
   104 	iPMLWriter->Delete(1);
   105 	iPMLWriter->Output(iConsole);	// output PML doc to screen
   106 	return iPMLWriter->ReturnPmlDoc();
   107 	}
   108 
   109 
   110 void CRichTextReader::SenseGlobalFormat()
   111 // Senses global format & writes it to PML
   112 	{  
   113 	// construct rich text bits
   114 	const CParaFormatLayer* globalParaFormatLayer;	   	// initialised with factory settings
   115 	const CCharFormatLayer* globalCharFormatLayer;
   116 	CParaFormat* globalParaFormat = CParaFormat::NewL();
   117 	TCharFormat globalCharFormat;
   118 
   119 	// Sense global format
   120 	globalParaFormatLayer = iRichTextDoc->SenseGlobalParaFormatLayer();
   121 	globalParaFormatLayer->SenseEffectiveL(globalParaFormat);
   122 	globalCharFormatLayer = iRichTextDoc->SenseGlobalCharFormatLayer();
   123 	globalCharFormatLayer->SenseEffective(globalCharFormat);
   124 
   125 	// now set it
   126 	iPMLWriter->SetTag(EGlobal, ETagStart);		// output <G
   127  	CompareParaToFactory(globalParaFormat);	// step through format, adding all != factory settings
   128 	CompareCharToFactory(globalCharFormat);	// ...
   129 	iPMLWriter->SetTag(EGlobal, ETagEnd);		// output >\n
   130 
   131 	// initialise iPrevXxxxFormat
   132 	globalParaFormatLayer->SenseEffectiveL(iPrevParaFormat);
   133 	globalCharFormatLayer->SenseEffective(iPrevCharFormat);
   134 
   135 	// destroy rich text bits
   136 	Adt::Destroy(globalParaFormat);
   137 	} 
   138 
   139 
   140 TInt CRichTextReader::TranslatePhrase(TInt aReadPos)
   141 // Output any new formatting being applied to this phrase
   142 // First check whether this phrase is the start of a new paragraph
   143 // If so check the paragraph format
   144 // Next check the character formatting of the phrase
   145 	{
   146 	CPicture* pic; // dummy pointer for senseChars
   147 	TPtrC currentPhrase;
   148 	TUint pmlWritePos;
   149 
   150 	TInt currentParaStart = aReadPos;		
   151 
   152 	// paragraph formatting
   153 	if (currentParaStart != 0)			  // doesn't work for position=0 -- Duncan!!
   154 		iRichTextDoc->ParagraphStart(currentParaStart);
   155 	if ((currentParaStart > iParaStart)||(aReadPos == 0)) // is it a new paragraph?
   156 		{
   157 		iParaStart = currentParaStart;
   158 		// delete para delimiter
   159 		if (aReadPos > 0)
   160 			iPMLWriter->Delete(1); // deletes 1 chars previous to the current insert pos
   161 		// add para tag
   162 		iPMLWriter->SetTag(EParagraph, ETagStart);
   163 		iRichTextDoc->SenseParagraphFormatL(aReadPos,iThisParaFormat); // get para format
   164 		CompareParaFormats(); // compare to previous paragraph to get changes
   165 		iRichTextDoc->SenseParagraphFormatL(aReadPos,iPrevParaFormat); // set prevParaFormat to current & copy compound attributes
   166 		iPrevParaFormat->iTopBorder=CopyBorderL(iThisParaFormat->iTopBorder,iPrevParaFormat->iTopBorder);
   167 		iPrevParaFormat->iBottomBorder=CopyBorderL(iThisParaFormat->iBottomBorder,iPrevParaFormat->iBottomBorder);
   168 		iPrevParaFormat->iLeftBorder=CopyBorderL(iThisParaFormat->iLeftBorder,iPrevParaFormat->iLeftBorder);
   169 		iPrevParaFormat->iRightBorder=CopyBorderL(iThisParaFormat->iRightBorder,iPrevParaFormat->iRightBorder);
   170 		iPrevParaFormat->iBullet=CopyBulletL(iThisParaFormat->iBullet,iPrevParaFormat->iBullet);
   171 		iPMLWriter->SetTag(EParagraph, ETagEnd);
   172 
   173 		}
   174 
   175 	// character formatting
   176 	iPMLWriter->SetTag(ECharacter, ETagStart);
   177 	pmlWritePos = iPMLWriter->WritePos();
   178 	iRichTextDoc->SenseChars(aReadPos,currentPhrase,iThisCharFormat,pic);	// get char format
   179 	CompareCharFormats();	// compare to previous
   180 	iRichTextDoc->SenseChars(aReadPos,currentPhrase,iPrevCharFormat,pic);	// get char format
   181 	if (pmlWritePos == iPMLWriter->WritePos())
   182 		iPMLWriter->Delete(3);		// delete tag start if tag is empty
   183 	else
   184 		iPMLWriter->SetTag(ECharacter, ETagEnd); // else close tag
   185 
   186 	iPMLWriter->Insert(currentPhrase);	// output text of phrase to PML
   187 	return currentPhrase.Length();		// return relative pos of start of next phrase
   188 	}
   189 
   190 
   191 TParaBorder* CRichTextReader::CopyBorderL(const TParaBorder* aFrom,TParaBorder* aTo)
   192 // copies one paragraph border to another, creating or destroying where necessary
   193 	{
   194 	if (!aFrom)
   195 		{
   196 		if (aTo)
   197 			delete(aTo);
   198 		return NULL;  // No border cell in the original
   199 		}
   200 	else
   201 		{
   202 		if (!aTo)
   203 			aTo = new(ELeave) TParaBorder;
   204 		*aTo = *aFrom;
   205 		return aTo;
   206 		}
   207 	}
   208 	
   209 
   210 TBullet* CRichTextReader::CopyBulletL(const TBullet* aFrom,TBullet* aTo)
   211 // copies one bullet to another, creating or destroying where necessary
   212 	{
   213 	if (!aFrom)
   214 		{
   215 		if (aTo)
   216 			delete(aTo);
   217 		return NULL;  // No bullet cell in the original
   218 		}
   219 	else
   220 		{
   221 		if (!aTo)
   222 			aTo = new(ELeave) TBullet;
   223 		*aTo = *aFrom;
   224 		return aTo;
   225 		}
   226 	}
   227 	
   228 
   229 void CRichTextReader::CompareParaToFactory(CParaFormat* aSensedParaFormat)
   230 // Compares the supplied paragraph format to the factory defaults and acts on any differences
   231 	{
   232 	// create a new reference format with factory settings
   233 	CParaFormat* refParaFormat = CParaFormat::NewL();
   234 	// step through, comparing aSensedParaFormat to the reference
   235 	// if any attributes differ, set the differences in the PML doc
   236 	if (aSensedParaFormat->iLanguage != refParaFormat->iLanguage)
   237 		iPMLWriter->SetFormat(EAttParaLanguage, aSensedParaFormat->iLanguage);
   238 	if (aSensedParaFormat->iLeftMargin != refParaFormat->iLeftMargin)
   239 		iPMLWriter->SetFormat(EAttLeftMargin, aSensedParaFormat->iLeftMargin);
   240 	if (aSensedParaFormat->iRightMargin != refParaFormat->iRightMargin)
   241 		iPMLWriter->SetFormat(EAttRightMargin, aSensedParaFormat->iRightMargin);
   242 	if (aSensedParaFormat->iIndent != refParaFormat->iIndent)
   243 		iPMLWriter->SetFormat(EAttIndent, aSensedParaFormat->iIndent);
   244 	if (aSensedParaFormat->iAlignment != refParaFormat->iAlignment)
   245 		iPMLWriter->SetFormat(EAttAlignment, aSensedParaFormat->iAlignment);
   246 	if (aSensedParaFormat->iLineSpacing != refParaFormat->iLineSpacing)
   247 		iPMLWriter->SetFormat(EAttLineSpacing, aSensedParaFormat->iLineSpacing);
   248 	if (aSensedParaFormat->iLineSpacingControl != refParaFormat->iLineSpacingControl)
   249 		iPMLWriter->SetFormat(EAttLineSpacingControl, aSensedParaFormat->iLineSpacingControl);
   250 	if (aSensedParaFormat->iSpaceBefore != refParaFormat->iSpaceBefore)
   251 		iPMLWriter->SetFormat(EAttSpaceBefore, aSensedParaFormat->iSpaceBefore);
   252 	if (aSensedParaFormat->iSpaceAfter != refParaFormat->iSpaceAfter)
   253 		iPMLWriter->SetFormat(EAttSpaceAfter, aSensedParaFormat->iSpaceAfter);
   254 	if (aSensedParaFormat->iKeepTogether != refParaFormat->iKeepTogether)
   255 		iPMLWriter->SetFormat(EAttKeepTogether, aSensedParaFormat->iKeepTogether);
   256 	if (aSensedParaFormat->iKeepWithNext != refParaFormat->iKeepWithNext)
   257 		iPMLWriter->SetFormat(EAttKeepWithNext, aSensedParaFormat->iKeepWithNext);
   258 	if (aSensedParaFormat->iStartNewPage != refParaFormat->iStartNewPage)
   259 		iPMLWriter->SetFormat(EAttStartNewPage, aSensedParaFormat->iStartNewPage);
   260 	if (aSensedParaFormat->iWidowOrphan != refParaFormat->iWidowOrphan)
   261 		iPMLWriter->SetFormat(EAttWidowOrphan, aSensedParaFormat->iWidowOrphan);
   262 	if (aSensedParaFormat->iBorderMargin != refParaFormat->iBorderMargin)
   263 		iPMLWriter->SetFormat(EAttBorderMargin, aSensedParaFormat->iBorderMargin);
   264 	if (aSensedParaFormat->iTopBorder)
   265 		{
   266 		if (refParaFormat->iTopBorder == NULL)
   267 			iPMLWriter->SetFormat(EAttTopBorder, aSensedParaFormat->iTopBorder);
   268 		else if ((aSensedParaFormat->iTopBorder->iLineStyle != refParaFormat->iTopBorder->iLineStyle)
   269 		||(aSensedParaFormat->iTopBorder->iAutoColor != refParaFormat->iTopBorder->iAutoColor)
   270 		||(aSensedParaFormat->iTopBorder->iColor != refParaFormat->iTopBorder->iColor))
   271 			{
   272 			iPMLWriter->SetFormat(EAttTopBorder, aSensedParaFormat->iTopBorder);
   273 			}
   274 		}
   275 	if (aSensedParaFormat->iBottomBorder)
   276 		{  
   277 		if (refParaFormat->iTopBorder == NULL)
   278 			iPMLWriter->SetFormat(EAttBottomBorder, aSensedParaFormat->iBottomBorder);
   279 		else if ((aSensedParaFormat->iBottomBorder->iLineStyle != refParaFormat->iBottomBorder->iLineStyle)
   280 		||(aSensedParaFormat->iBottomBorder->iAutoColor != refParaFormat->iBottomBorder->iAutoColor)
   281 		||(aSensedParaFormat->iBottomBorder->iColor != refParaFormat->iBottomBorder->iColor))
   282 			{
   283 			iPMLWriter->SetFormat(EAttBottomBorder, aSensedParaFormat->iBottomBorder);
   284 			}
   285 		}
   286 	if (aSensedParaFormat->iLeftBorder)
   287 		{  
   288 		if (refParaFormat->iTopBorder == NULL)
   289 			iPMLWriter->SetFormat(EAttLeftBorder, aSensedParaFormat->iLeftBorder);
   290 		else if ((aSensedParaFormat->iLeftBorder->iLineStyle != refParaFormat->iLeftBorder->iLineStyle)
   291 		||(aSensedParaFormat->iLeftBorder->iAutoColor != refParaFormat->iLeftBorder->iAutoColor)
   292 		||(aSensedParaFormat->iLeftBorder->iColor != refParaFormat->iLeftBorder->iColor))
   293 			{
   294 			iPMLWriter->SetFormat(EAttLeftBorder, aSensedParaFormat->iLeftBorder);
   295 			}
   296 		}
   297 	if (aSensedParaFormat->iRightBorder)
   298 		{  
   299 		if (refParaFormat->iTopBorder == NULL)
   300 			iPMLWriter->SetFormat(EAttRightBorder, aSensedParaFormat->iRightBorder);
   301 		else if ((aSensedParaFormat->iRightBorder->iLineStyle != refParaFormat->iRightBorder->iLineStyle)
   302 		||(aSensedParaFormat->iRightBorder->iAutoColor != refParaFormat->iRightBorder->iAutoColor)
   303 		||(aSensedParaFormat->iRightBorder->iColor != refParaFormat->iRightBorder->iColor))
   304 			{
   305 			iPMLWriter->SetFormat(EAttRightBorder, aSensedParaFormat->iRightBorder);
   306 			}
   307 		}
   308 	if (aSensedParaFormat->iBullet)
   309 		{  
   310 		if (refParaFormat->iBullet == NULL)
   311 			iPMLWriter->SetFormat(EAttBullet, aSensedParaFormat->iBullet);
   312 		if ((aSensedParaFormat->iBullet->iCharacterCode != refParaFormat->iBullet->iCharacterCode)
   313 		||(aSensedParaFormat->iBullet->iHeight != refParaFormat->iBullet->iHeight)
   314 		||(aSensedParaFormat->iBullet->iTypeface.iName != refParaFormat->iBullet->iTypeface.iName)
   315 		||(aSensedParaFormat->iBullet->iTypeface.iFlags != refParaFormat->iBullet->iTypeface.iFlags))
   316 			{	
   317 			iPMLWriter->SetFormat(EAttBullet, aSensedParaFormat->iBullet);
   318 			}
   319 		}
   320 	if (aSensedParaFormat->iDefaultTabWidth != refParaFormat->iDefaultTabWidth)
   321 		iPMLWriter->SetFormat(EAttDefaultTabWidth, aSensedParaFormat->iDefaultTabWidth);
   322 	CheckTabList(aSensedParaFormat, refParaFormat);	// tabs are sensed separately
   323 
   324 	// Destroy ref format
   325 	Adt::Destroy(refParaFormat);
   326 	}
   327 
   328 void CRichTextReader::CompareCharToFactory(TCharFormat aSensedCharFormat)
   329 // Compares the supplied character format to the factory defaults and acts on any differences
   330 	{
   331 	// create a new reference format with factory settings
   332 	TCharFormat refCharFormat;
   333 	// step through, comparing aSensedCharFormat to the reference
   334 	// if any attributes differ, set the differences in the PML doc
   335 	if (aSensedCharFormat.iLanguage != refCharFormat.iLanguage)
   336 		iPMLWriter->SetFormat(EAttCharLanguage, aSensedCharFormat.iLanguage);
   337 	if (aSensedCharFormat.iColor != refCharFormat.iColor)
   338 		iPMLWriter->SetFormat(EAttColor, aSensedCharFormat.iColor.RgbToUint());
   339 	if (aSensedCharFormat.iFontSpec.iTypeface.iName != refCharFormat.iFontSpec.iTypeface.iName)
   340 		iPMLWriter->SetFormat(EAttFontTypefaceName, aSensedCharFormat.iFontSpec.iTypeface);
   341 	if (aSensedCharFormat.iFontSpec.iTypeface.iFlags != refCharFormat.iFontSpec.iTypeface.iFlags)
   342 		iPMLWriter->SetFormat(EAttFontTypefaceFlags, aSensedCharFormat.iFontSpec.iTypeface);
   343 	if (aSensedCharFormat.iFontSpec.iHeight != refCharFormat.iFontSpec.iHeight)
   344 		iPMLWriter->SetFormat(EAttFontHeight, aSensedCharFormat.iFontSpec.iHeight);
   345 	if (aSensedCharFormat.iFontSpec.iPosture != refCharFormat.iFontSpec.iPosture)
   346 		iPMLWriter->SetFormat(EAttFontPosture, aSensedCharFormat.iFontSpec.iPosture);
   347 	if (aSensedCharFormat.iFontSpec.iStrokeWeight != refCharFormat.iFontSpec.iStrokeWeight)
   348 		iPMLWriter->SetFormat(EAttFontStrokeWeight, aSensedCharFormat.iFontSpec.iStrokeWeight);
   349 	if (aSensedCharFormat.iFontSpec.iPos != refCharFormat.iFontSpec.iPos)
   350 		iPMLWriter->SetFormat(EAttFontPrintPos, aSensedCharFormat.iFontSpec.iPos);
   351 	if (aSensedCharFormat.iFontSpec.iUnderline != refCharFormat.iFontSpec.iUnderline)
   352 		iPMLWriter->SetFormat((TTextFormatAttribute)EAttFontUnderline, aSensedCharFormat.iFontSpec.iUnderline);
   353 	if (aSensedCharFormat.iFontSpec.iStrikethrough != refCharFormat.iFontSpec.iStrikethrough)
   354 		iPMLWriter->SetFormat(EAttFontStrikethrough, aSensedCharFormat.iFontSpec.iStrikethrough);
   355 	}
   356 
   357 
   358 void CRichTextReader::CompareParaFormats()
   359 // compares the current para format with the format of the previous para
   360 // any differences are output to PML
   361 	{
   362 	if (iThisParaFormat->iLanguage != iPrevParaFormat->iLanguage)
   363 		iPMLWriter->SetFormat(EAttParaLanguage, iThisParaFormat->iLanguage);
   364 	if (iThisParaFormat->iLeftMargin != iPrevParaFormat->iLeftMargin)
   365 		iPMLWriter->SetFormat(EAttLeftMargin, iThisParaFormat->iLeftMargin);
   366 	if (iThisParaFormat->iRightMargin != iPrevParaFormat->iRightMargin)
   367 		iPMLWriter->SetFormat(EAttRightMargin, iThisParaFormat->iRightMargin);
   368 	if (iThisParaFormat->iIndent != iPrevParaFormat->iIndent)
   369 		iPMLWriter->SetFormat(EAttIndent, iThisParaFormat->iIndent);
   370 	if (iThisParaFormat->iAlignment != iPrevParaFormat->iAlignment)
   371 		iPMLWriter->SetFormat(EAttAlignment, iThisParaFormat->iAlignment);
   372 	if (iThisParaFormat->iLineSpacing != iPrevParaFormat->iLineSpacing)
   373 		iPMLWriter->SetFormat(EAttLineSpacing, iThisParaFormat->iLineSpacing);
   374 	if (iThisParaFormat->iLineSpacingControl != iPrevParaFormat->iLineSpacingControl)
   375 		iPMLWriter->SetFormat(EAttLineSpacingControl, iThisParaFormat->iLineSpacingControl);
   376 	if (iThisParaFormat->iSpaceBefore != iPrevParaFormat->iSpaceBefore)
   377 		iPMLWriter->SetFormat(EAttSpaceBefore, iThisParaFormat->iSpaceBefore);
   378 	if (iThisParaFormat->iSpaceAfter != iPrevParaFormat->iSpaceAfter)
   379 		iPMLWriter->SetFormat(EAttSpaceAfter, iThisParaFormat->iSpaceAfter);
   380 	if (iThisParaFormat->iKeepTogether != iPrevParaFormat->iKeepTogether)
   381 		iPMLWriter->SetFormat(EAttKeepTogether, iThisParaFormat->iKeepTogether);
   382 	if (iThisParaFormat->iKeepWithNext != iPrevParaFormat->iKeepWithNext)
   383 		iPMLWriter->SetFormat(EAttKeepWithNext, iThisParaFormat->iKeepWithNext);
   384 	if (iThisParaFormat->iStartNewPage != iPrevParaFormat->iStartNewPage)
   385 		iPMLWriter->SetFormat(EAttStartNewPage, iThisParaFormat->iStartNewPage);
   386 	if (iThisParaFormat->iWidowOrphan != iPrevParaFormat->iWidowOrphan)
   387 		iPMLWriter->SetFormat(EAttWidowOrphan, iThisParaFormat->iWidowOrphan);
   388 	if (iThisParaFormat->iBorderMargin != iPrevParaFormat->iBorderMargin)
   389 		iPMLWriter->SetFormat(EAttBorderMargin, iThisParaFormat->iBorderMargin);
   390 	if (iThisParaFormat->iTopBorder)
   391 		{
   392 		if (iPrevParaFormat->iTopBorder == NULL)  
   393 			iPMLWriter->SetFormat(EAttTopBorder, iThisParaFormat->iTopBorder);
   394 		else if ((iThisParaFormat->iTopBorder->iLineStyle != iPrevParaFormat->iTopBorder->iLineStyle)
   395 		||(iThisParaFormat->iTopBorder->iAutoColor != iPrevParaFormat->iTopBorder->iAutoColor)
   396 		||(iThisParaFormat->iTopBorder->iColor != iPrevParaFormat->iTopBorder->iColor))
   397 			{
   398 			iPMLWriter->SetFormat(EAttTopBorder, iThisParaFormat->iTopBorder);
   399 			}
   400 		}
   401 	if (iThisParaFormat->iBottomBorder)
   402 		{  
   403 		if (iPrevParaFormat->iBottomBorder == NULL)  
   404 			iPMLWriter->SetFormat(EAttBottomBorder, iThisParaFormat->iBottomBorder);
   405 		else if ((iThisParaFormat->iBottomBorder->iLineStyle != iPrevParaFormat->iBottomBorder->iLineStyle)
   406 		||(iThisParaFormat->iBottomBorder->iAutoColor != iPrevParaFormat->iBottomBorder->iAutoColor)
   407 		||(iThisParaFormat->iBottomBorder->iColor != iPrevParaFormat->iBottomBorder->iColor))
   408 			{
   409 			iPMLWriter->SetFormat(EAttBottomBorder, iThisParaFormat->iBottomBorder);
   410 			}
   411 		}
   412 	if (iThisParaFormat->iLeftBorder)
   413 		{  
   414 		if (iPrevParaFormat->iLeftBorder == NULL)  
   415 			iPMLWriter->SetFormat(EAttLeftBorder, iThisParaFormat->iLeftBorder);
   416 		if ((iThisParaFormat->iLeftBorder->iLineStyle != iPrevParaFormat->iLeftBorder->iLineStyle)
   417 		||(iThisParaFormat->iLeftBorder->iAutoColor != iPrevParaFormat->iLeftBorder->iAutoColor)
   418 		||(iThisParaFormat->iLeftBorder->iColor != iPrevParaFormat->iLeftBorder->iColor))
   419 			{
   420 			iPMLWriter->SetFormat(EAttLeftBorder, iThisParaFormat->iLeftBorder);
   421 			}
   422 		}
   423 	if (iThisParaFormat->iRightBorder)
   424 		{  
   425 		if (iPrevParaFormat->iRightBorder == NULL)  
   426 			iPMLWriter->SetFormat(EAttRightBorder, iThisParaFormat->iRightBorder);
   427 		if ((iThisParaFormat->iRightBorder->iLineStyle != iPrevParaFormat->iRightBorder->iLineStyle)
   428 		||(iThisParaFormat->iRightBorder->iAutoColor != iPrevParaFormat->iRightBorder->iAutoColor)
   429 		||(iThisParaFormat->iRightBorder->iColor != iPrevParaFormat->iRightBorder->iColor))
   430 			{
   431 			iPMLWriter->SetFormat(EAttRightBorder, iThisParaFormat->iRightBorder);
   432 			}
   433 		}
   434  	if (iThisParaFormat->iBullet)
   435 		{  
   436 		if (iPrevParaFormat->iBullet == NULL)  
   437 			iPMLWriter->SetFormat(EAttBullet, iThisParaFormat->iBullet);
   438 		else if ((iThisParaFormat->iBullet->iCharacterCode != iPrevParaFormat->iBullet->iCharacterCode)
   439 		||(iThisParaFormat->iBullet->iHeight != iPrevParaFormat->iBullet->iHeight)
   440 		||(iThisParaFormat->iBullet->iTypeface.iName != iPrevParaFormat->iBullet->iTypeface.iName)
   441 		||(iThisParaFormat->iBullet->iTypeface.iFlags != iPrevParaFormat->iBullet->iTypeface.iFlags))
   442 			{	
   443 			iPMLWriter->SetFormat(EAttBullet, iThisParaFormat->iBullet);
   444 			}
   445 		}
   446 	if (iThisParaFormat->iDefaultTabWidth != iPrevParaFormat->iDefaultTabWidth)
   447 		iPMLWriter->SetFormat(EAttDefaultTabWidth, iThisParaFormat->iDefaultTabWidth);
   448 	CheckTabList(iThisParaFormat, iPrevParaFormat);	// tabs are sensed separately
   449 	}
   450 
   451 
   452 void CRichTextReader::CheckTabList(CParaFormat* aFormatOne, CParaFormat* aFormatTwo)
   453 // Check whether the first (current) and second formats' tablists differ
   454 // If they do, output whole of first list to PML
   455 	{
   456 	TBool output = EFalse;
   457 	if (aFormatOne->TabCount() != aFormatTwo->TabCount())
   458 		output = ETrue;	// output to PML
   459 	else 
   460 		{
   461 		// lists are same length: check that all members are the same
   462 		TInt index = 0;
   463 		TBool dif = EFalse;
   464 		while ((index < aFormatOne->TabCount())&&(!dif))
   465 			{
   466 			if (aFormatOne->TabStop(index) != aFormatTwo->TabStop(index))
   467 				output = ETrue;	// output to PML
   468 			index++;
   469 			}
   470 		}
   471 	if (output)
   472 		{
   473 		for (TInt i=0; i < aFormatOne->TabCount(); i++)
   474 			iPMLWriter->SetFormat(EAttTabStop, aFormatOne->TabStop(i));
   475 		}
   476 	}
   477 
   478 
   479 void CRichTextReader::CompareCharFormats()
   480 	{
   481 	if (iThisCharFormat.iLanguage != iPrevCharFormat.iLanguage)
   482 		iPMLWriter->SetFormat(EAttCharLanguage, iThisCharFormat.iLanguage);
   483 	if (iThisCharFormat.iColor != iPrevCharFormat.iColor)
   484 		iPMLWriter->SetFormat(EAttColor, iThisCharFormat.iColor.RgbToUint());
   485 	if (iThisCharFormat.iFontSpec.iTypeface.iName != iPrevCharFormat.iFontSpec.iTypeface.iName)
   486 		iPMLWriter->SetFormat(EAttFontTypefaceName, iThisCharFormat.iFontSpec.iTypeface);
   487 	if (iThisCharFormat.iFontSpec.iTypeface.iFlags != iPrevCharFormat.iFontSpec.iTypeface.iFlags)
   488 		iPMLWriter->SetFormat(EAttFontTypefaceFlags, iThisCharFormat.iFontSpec.iTypeface);
   489 	if (iThisCharFormat.iFontSpec.iHeight != iPrevCharFormat.iFontSpec.iHeight)
   490 		iPMLWriter->SetFormat(EAttFontHeight, iThisCharFormat.iFontSpec.iHeight);
   491 	if (iThisCharFormat.iFontSpec.iPosture != iPrevCharFormat.iFontSpec.iPosture)
   492 		iPMLWriter->SetFormat(EAttFontPosture, iThisCharFormat.iFontSpec.iPosture);
   493 	if (iThisCharFormat.iFontSpec.iStrokeWeight != iPrevCharFormat.iFontSpec.iStrokeWeight)
   494 		iPMLWriter->SetFormat(EAttFontStrokeWeight, iThisCharFormat.iFontSpec.iStrokeWeight);
   495 	if (iThisCharFormat.iFontSpec.iPos != iPrevCharFormat.iFontSpec.iPos)
   496 		iPMLWriter->SetFormat(EAttFontPrintPos, iThisCharFormat.iFontSpec.iPos);
   497 	if (iThisCharFormat.iFontSpec.iUnderline != iPrevCharFormat.iFontSpec.iUnderline)
   498 		iPMLWriter->SetFormat(EAttFontUnderline, iThisCharFormat.iFontSpec.iUnderline);
   499 	if (iThisCharFormat.iFontSpec.iStrikethrough != iPrevCharFormat.iFontSpec.iStrikethrough)
   500 		iPMLWriter->SetFormat(EAttFontStrikethrough, iThisCharFormat.iFontSpec.iStrikethrough);
   501 	}
   502 
   503 
   504 
   505 
   506 //////////////////////////////////////////////////////
   507 // CPMLWriter
   508 //////////////////////////////////////////////////////
   509 
   510 CPMLWriter* CPMLWriter::NewL()
   511 	{
   512 	CPMLWriter* self=new(ELeave) CPMLWriter;
   513 	self->Construct();
   514 	return self;
   515 	}
   516 
   517 
   518 CPMLWriter::CPMLWriter()
   519 	{
   520 	// init variables
   521 	}
   522 	 
   523 
   524 void CPMLWriter::Construct()
   525 	{
   526 	iTextBuf = CBufSeg::New(64);  // create buffer with granularity 64
   527 	}
   528 
   529 
   530 void CPMLWriter::Destruct()
   531 	{
   532 	Adt::Destroy(iTextBuf);
   533 	}
   534 
   535 
   536 void CPMLWriter::ExpandBuf(const TDes8& aBuffer, TDes& aTarget)
   537 	//
   538 	// Input 8 bit buffer to be returned by ref. as an 8/16-bit version
   539 	// Used for unicode compatability
   540 	//
   541 	{
   542 	TText textPointer;
   543 	for (TInt pos=0 ; pos<aBuffer.Length() ; pos++ )
   544 		{
   545 		textPointer = aBuffer[pos];
   546 		aTarget.Append(textPointer);
   547 		}
   548 	}
   549 
   550 
   551 void CPMLWriter::SquashBuf(const TDesC& aBuffer, TDes8& aTarget)
   552 	//
   553 	// Input 8/16 bit buffer and an 8-bit target to be copied into.
   554 	// Used for unicode compatability
   555 	//
   556 	{
   557 	TText textPointer;
   558 	for (TInt pos=0; pos<aBuffer.Length(); pos++)
   559 		{
   560 		textPointer = aBuffer[pos];
   561 		aTarget.Append(textPointer);
   562 		}
   563 	}
   564 
   565 
   566 void CPMLWriter::Insert(const TDesC& aBuf)
   567 // insert aBuf into PML doc
   568 	{
   569 	TUint bufLength = aBuf.Length();
   570 	TBuf8<128> temp;
   571 	SquashBuf(aBuf,temp);
   572 	iTextBuf->InsertL(iInsertPos, temp, bufLength);
   573 	iInsertPos += bufLength; 
   574 	}
   575 
   576 
   577 void CPMLWriter::Delete(TUint aLength)
   578 // delete back from current insert pos aLength (characters)
   579 	{ 
   580 	iTextBuf->Delete(iInsertPos-aLength, aLength);
   581 	iInsertPos -= aLength;
   582 	}
   583 
   584 
   585 void CPMLWriter::Output(RConsole aConsole)
   586 // output buffer to screen
   587 	{ 
   588 	TBuf8<1> tempBuf;
   589 	TInt readPos = 0;
   590 	while (readPos < iTextBuf->Size())
   591 		{
   592 		iTextBuf->Read(readPos, tempBuf, 1);
   593 		TBuf<1> wideTemp;
   594 		ExpandBuf(tempBuf,wideTemp);
   595 		aConsole.Write(wideTemp);
   596 		readPos++;
   597 		}
   598 	}
   599 
   600 
   601 void CPMLWriter::SetTag(TTagType aTagType, TTagStatus aStatus)
   602 // insert a tag-open or tag-close into the PML doc
   603 	{
   604 	if (aStatus == ETagStart)
   605 		{
   606 		switch (aTagType)
   607 			{
   608 			case EGlobal:
   609 				Insert(_L("\n<G "));
   610 				break;
   611 			case EParagraph:
   612 				Insert(_L("\n<P "));
   613 				break;
   614 			case ECharacter:
   615 				Insert(_L("<C "));
   616 				break;
   617 			case EControl:
   618 				Insert(_L("<X "));
   619 				break;
   620 			}
   621 		}
   622 	if (aStatus == ETagEnd)
   623 		{
   624 		switch (aTagType)
   625 			{
   626 			case EGlobal:
   627 				Insert(_L(">\n"));
   628 				break;
   629 			case EParagraph:
   630 				Insert(_L(">\n"));
   631 				break;
   632 			case ECharacter:
   633 				Insert(_L(">"));
   634 				break;
   635 			case EControl:
   636 				Insert(_L(">"));
   637 				break;
   638 			}
   639 		}
   640 	}
   641 
   642 
   643 void CPMLWriter::SetTab(TTabStop aTabStop)
   644 // insert a tab into the PML doc
   645 	{
   646 	TBuf<80> tagBuf;
   647 	tagBuf.Format(_L("Tab=,%d"),aTabStop.iPosition);	// put 2nd paramater in first
   648 	switch (aTabStop.iType)								// insert 1st paramater after "="
   649 		{
   650 		case ENullTab:
   651 			tagBuf.Insert(4,_L("Null"));				
   652 			break;
   653 		case ELeftTab:
   654 			tagBuf.Insert(4,_L("Left"));
   655 			break;
   656 		case ECenteredTab:
   657 			tagBuf.Insert(4,_L("Centered"));
   658 			break;
   659 		case ERightTab:
   660 			tagBuf.Insert(4,_L("Right"));
   661 			break;
   662 		}
   663 	Insert(tagBuf);
   664 	}
   665 
   666 /* The setFormat functions add the stipulated formatting to the PML doc */
   667 
   668 void CPMLWriter::SetFormat(TTextFormatAttribute aAttribute, TInt aValue)
   669 	{
   670 	TBuf<80> outputBuf;
   671 	switch (aAttribute)
   672 		{
   673 		// Para Formats
   674 		case EAttParaLanguage:
   675 			outputBuf.Format(_L("ParaLanguage=%d "),aValue);
   676 			Insert(outputBuf);
   677 			break;
   678 		case EAttLeftMargin:
   679 			outputBuf.Format(_L("LeftMargin=%d "),aValue);
   680 			Insert(outputBuf);
   681 			break;
   682 		case EAttRightMargin:
   683 			outputBuf.Format(_L("RightMargin=%d "),aValue);
   684 			Insert(outputBuf);
   685 			break;
   686 		case EAttIndent:
   687 			outputBuf.Format(_L("Indent=%d "),aValue);
   688 			Insert(outputBuf);
   689 			break;
   690 		case EAttAlignment:
   691 			ProcessAlignment(aValue);
   692 			break;
   693 		case EAttLineSpacing:
   694 			outputBuf.Format(_L("LineSpacing=%d "),aValue);
   695 			Insert(outputBuf);
   696 			break;
   697 		case EAttLineSpacingControl:
   698 			ProcessLineSpacingControl(aValue);
   699 			break;
   700 		case EAttSpaceBefore:
   701 			outputBuf.Format(_L("SpaceBefore=%d "),aValue);
   702 			Insert(outputBuf);
   703 			break;
   704 		case EAttSpaceAfter:
   705 			outputBuf.Format(_L("SpaceAfter=%d "),aValue);
   706 			Insert(outputBuf);
   707 			break;
   708 		case EAttKeepTogether:
   709 			ProcessBooleanAtt(aAttribute, aValue);
   710 			break;
   711 		case EAttKeepWithNext:
   712 			ProcessBooleanAtt(aAttribute, aValue);
   713 			break;
   714 		case EAttStartNewPage:
   715 			ProcessBooleanAtt(aAttribute, aValue);
   716 			break;
   717 		case EAttWidowOrphan:
   718 			ProcessBooleanAtt(aAttribute, aValue);
   719 			break;
   720 		case EAttBorderMargin:
   721 			outputBuf.Format(_L("BorderMargin=%d "),aValue);
   722 			Insert(outputBuf);
   723 			break;
   724 		case EAttDefaultTabWidth:
   725 			outputBuf.Format(_L("DefaultTabWidth=%d "),aValue);
   726 			Insert(outputBuf);
   727 			break;
   728 
   729 	// Char formats
   730 		case EAttCharLanguage:
   731 			outputBuf.Format(_L("Language=%d "),aValue);
   732 			Insert(outputBuf);
   733 			break;
   734 		case EAttColor:
   735 			outputBuf.Format(_L("Color=%d "),aValue);
   736 			Insert(outputBuf);
   737 			break;
   738 		case EAttFontHeight:
   739 			outputBuf.Format(_L("FontHeight=%d "),aValue);
   740 			Insert(outputBuf);
   741 			break;
   742 		case EAttFontPosture:
   743 			ProcessBooleanAtt(aAttribute, aValue);
   744 			break;
   745 		case EAttFontStrokeWeight:
   746 			ProcessBooleanAtt(aAttribute, aValue);
   747 			break;
   748 		case EAttFontPrintPos:
   749 			ProcessFontPrintPos(aValue);
   750 			break;
   751 		case EAttFontUnderline:
   752 			ProcessBooleanAtt(aAttribute, aValue);
   753 			break;
   754 		case EAttFontStrikethrough:
   755 			ProcessBooleanAtt(aAttribute, aValue);
   756 			break;
   757 		case EAttFontTypefaceFlags:
   758 			outputBuf.Format(_L("TypefaceFlags=%d "),aValue);
   759 			Insert(outputBuf);
   760 			break;
   761 		}
   762 	}
   763 
   764 
   765 void CPMLWriter::SetFormat(TTextFormatAttribute aAttribute, const TTypeface &aTypeface)
   766 	{
   767 	TBuf<80> outputBuf;
   768 	switch (aAttribute)
   769 		{
   770 		case EAttFontTypefaceName:
   771 			outputBuf.Format(_L("TypefaceName=%S "),&aTypeface.iName);
   772 			break;
   773 		case EAttFontTypefaceFlags:
   774 			outputBuf.Format(_L("TypefaceFlags=%u "),aTypeface.iFlags);
   775 			break;
   776 		}
   777 	Insert(outputBuf);
   778 	}
   779 
   780 void CPMLWriter::SetFormat(TTextFormatAttribute aAttribute, TParaBorder* aParaBorder)
   781 	{
   782 	TBuf<80> outputBuf;
   783 	TBuf<80> values;
   784 	values.Format(_L("%d,%d,%d"),aParaBorder->iLineStyle,aParaBorder->iAutoColor,aParaBorder->iColor.RgbToUint());
   785 	outputBuf.Insert(0,values);
   786 	switch (aAttribute)
   787 		{
   788 		case EAttTopBorder:
   789 			outputBuf.Insert(0,_L("TopBorder="));
   790 			break;
   791 		case EAttBottomBorder:
   792 			outputBuf.Insert(0,_L("BottomBorder="));
   793 			break;
   794 		case EAttLeftBorder:
   795 			outputBuf.Insert(0,_L("LeftBorder="));
   796 			break;
   797 		case EAttRightBorder:
   798 			outputBuf.Insert(0,_L("RightBorder="));
   799 			break;
   800 		}
   801 	Insert(outputBuf);
   802 	}
   803 
   804 
   805 void CPMLWriter::SetFormat(TTextFormatAttribute /*aAttribute*/, TBullet* aBullet)
   806 	{
   807 	TBuf<80> outputBuf;
   808 	outputBuf.Format(_L("%d,%u,%u,"),aBullet->iCharacterCode,aBullet->iHeight,
   809 															aBullet->iTypeface.iFlags);
   810 	TBuf<128> wideTemp; // long enough??
   811 	ExpandBuf(aBullet->iTypeface.iName,wideTemp);
   812 	outputBuf.Append(wideTemp);
   813 	outputBuf.Append(_L(" "));
   814 	outputBuf.Insert(0,_L("Bullet="));
   815 	Insert(outputBuf);
   816 	}
   817 
   818 
   819 void CPMLWriter::SetFormat(TTextFormatAttribute /*aAttribute*/, TTabStop aTabStop)
   820 	{
   821 	TBuf<80> outputBuf;
   822 	outputBuf.Format(_L("Tabstop=%u,"),aTabStop.iPosition);
   823 	switch (aTabStop.iType)
   824 		{
   825 		case ENullTab:
   826 			outputBuf.Append(_L("Null "));
   827 			break;
   828 		case ELeftTab:
   829 			outputBuf.Append(_L("Left "));
   830 			break;
   831 		case ERightTab:
   832 			outputBuf.Append(_L("Right "));
   833 			break;
   834 		case ECenteredTab:
   835 			outputBuf.Append(_L("Centered "));
   836 			break;
   837 		}
   838 	Insert(outputBuf);
   839 	}
   840 
   841 
   842 void CPMLWriter::ProcessAlignment(TInt aValue)
   843 	{
   844 	TBuf<80> outputBuf;
   845 	switch (aValue)
   846 		{
   847 		case 0:
   848 			outputBuf.Insert(0,_L("Alignment=Left "));
   849 			break;
   850 		case 1:
   851 			outputBuf.Insert(0,_L("Alignment=Center "));
   852 			break;
   853 		case 2:
   854 			outputBuf.Insert(0,_L("Alignment=Right "));
   855 			break;
   856 		case 3:
   857 			outputBuf.Insert(0,_L("Alignment=Justified "));
   858 			break;
   859 		}
   860 	Insert(outputBuf);
   861 	}
   862 
   863 
   864 void CPMLWriter::ProcessLineSpacingControl(TInt aValue)
   865 	{
   866 	TBuf<80> outputBuf;
   867 	switch (aValue)
   868 		{
   869 		case 0:
   870 			outputBuf.Insert(0,_L("LineSpacingControl=Atleast "));
   871 			break;
   872 		case 1:
   873 			outputBuf.Insert(0,_L("LineSpacingControl=Exactly "));
   874 			break;
   875 		}
   876 	Insert(outputBuf);
   877 	}
   878 
   879 
   880 void CPMLWriter::ProcessFontPrintPos(TInt aValue)
   881 	{
   882 	TBuf<80> outputBuf;
   883 	switch (aValue)
   884 		{
   885 		case 0:
   886 			outputBuf.Insert(0,_L("PrintPos=Normal "));
   887 			break;
   888 		case 1:
   889 			outputBuf.Insert(0,_L("PrintPos=SuperScript "));
   890 			break;
   891 		case 2:
   892 			outputBuf.Insert(0,_L("PrintPos=SubScript "));
   893 			break;
   894 		}
   895 	Insert(outputBuf);
   896 	}
   897 
   898 
   899  void CPMLWriter::ProcessBooleanAtt(TTextFormatAttribute aAttribute, TInt aValue)
   900 	{
   901 	TBuf<80> outputBuf;
   902 	switch (aAttribute)
   903 		{
   904 		case EAttKeepTogether:
   905 			outputBuf.Insert(0,_L("KeepTogether "));
   906 			break;
   907 		case EAttKeepWithNext:
   908 			outputBuf.Insert(0,_L("KeepWithNext "));
   909 			break;
   910 		case EAttStartNewPage:
   911 			outputBuf.Insert(0,_L("StartNewPage "));
   912 			break;
   913 		case EAttWidowOrphan:
   914 			outputBuf.Insert(0,_L("WidowOrphan "));
   915 			break;
   916 		case EAttFontPosture:
   917 			outputBuf.Insert(0,_L("Italic "));
   918 			break;
   919 		case EAttFontStrokeWeight:
   920 			outputBuf.Insert(0,_L("Bold "));
   921 			break;
   922 		case EAttFontUnderline:
   923 			outputBuf.Insert(0,_L("Underline "));
   924 			break;
   925 		case EAttFontStrikethrough:
   926 			outputBuf.Insert(0,_L("Strikethrough "));
   927 			break;
   928 		}
   929 	if (aValue == 0)	// Boolean NOT
   930 		outputBuf.Insert(0,_L("!"));
   931 	Insert(outputBuf);
   932 	}