os/textandloc/textrendering/texthandling/stext/TXTFMSTM.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/textandloc/textrendering/texthandling/stext/TXTFMSTM.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,1868 @@
     1.4 +/*
     1.5 +* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 +* This component and the accompanying materials are made available
     1.8 +* under the terms of "Eclipse Public License v1.0"
     1.9 +* which accompanies this distribution, and is available
    1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +*
    1.12 +* Initial Contributors:
    1.13 +* Nokia Corporation - initial contribution.
    1.14 +*
    1.15 +* Contributors:
    1.16 +*
    1.17 +* Description: 
    1.18 +*
    1.19 +*/
    1.20 +
    1.21 +
    1.22 +#include <e32std.h>
    1.23 +
    1.24 +#include <s32strm.h>
    1.25 +#include <s32mem.h>
    1.26 +#include "TXTFRMAT.H"
    1.27 +#include <txtfmstm.h>
    1.28 +
    1.29 +#include "TXTSTD.H"
    1.30 +#include "OstTraceDefinitions.h"
    1.31 +#ifdef OST_TRACE_COMPILER_IN_USE
    1.32 +#include "TXTFMSTMTraces.h"
    1.33 +#endif
    1.34 +
    1.35 +
    1.36 +const TInt KMaxFormatStreamLength=0x400;  // 1024 bytes
    1.37 +
    1.38 +// Standard attributes
    1.39 +const TUint KFontProportional=0x01;
    1.40 +const TUint KFontSerif=0x02;
    1.41 +const TUint KFontSymbol=0x04;
    1.42 +
    1.43 +const TUint KTypefaceFlags=sizeof(TUint8);
    1.44 +const TInt KTypeSize=sizeof(TUint8);
    1.45 +const TInt KColor=sizeof(TUint8)+sizeof(TUint8)+sizeof(TUint8);
    1.46 +const TInt KFontHeight=sizeof(TInt32);
    1.47 +const TInt KParaBorderThickness=sizeof(TInt32);
    1.48 +const TInt KTabPosition=sizeof(TUint32);
    1.49 +const TInt KTabType=sizeof(TUint8);
    1.50 +
    1.51 +// Paragraph format attributes
    1.52 +const TInt KVariableLengthAttribute=0;
    1.53 +const TInt KParaLanguage=sizeof(TUint8);
    1.54 +const TInt KParaFillColor=KColor;
    1.55 +const TInt KParaLeftMargin=sizeof(TInt32);
    1.56 +const TInt KParaRightMargin=sizeof(TInt32);
    1.57 +const TInt KParaIndent=sizeof(TInt32);
    1.58 +const TInt KParaAlignment=sizeof(TUint8);
    1.59 +const TInt KParaVerticalAlignment=sizeof(TUint8);
    1.60 +const TInt KParaLineSpacing=sizeof(TInt32);
    1.61 +const TInt KParaLineSpacingControl=sizeof(TUint8);
    1.62 +const TInt KParaSpaceBefore=sizeof(TInt32);
    1.63 +const TInt KParaSpaceAfter=sizeof(TInt32);
    1.64 +const TInt KParaKeepTogether=sizeof(TUint8);
    1.65 +const TInt KParaKeepWithNext=sizeof(TUint8);
    1.66 +const TInt KParaStartNewPage=sizeof(TUint8);
    1.67 +const TInt KParaWidowOrphan=sizeof(TUint8);
    1.68 +const TInt KParaWrap=sizeof(TUint8);
    1.69 +const TInt KParaBorderMargin=sizeof(TInt32);
    1.70 +const TInt KParaTopBorder=sizeof(TUint8)+KParaBorderThickness+KColor+sizeof(TUint8);//linestyle/thickness/color/autocolor
    1.71 +const TInt KParaBottomBorder=KParaTopBorder;
    1.72 +const TInt KParaLeftBorder=KParaTopBorder;
    1.73 +const TInt KParaRightBorder=KParaTopBorder;
    1.74 +const TInt KParaBullet=KVariableLengthAttribute;
    1.75 +const TInt KParaDefaultTabWidth=sizeof(TUint32);
    1.76 +const TInt KParaTabStop=KTabPosition+KTabType;
    1.77 +const TInt KParaFillSystemColor=sizeof(TUint8);
    1.78 +const TInt KParaBulletSystemColor=sizeof(TUint8);
    1.79 +const TInt KParaTopBorderSystemColor=sizeof(TUint8);
    1.80 +const TInt KParaBottomBorderSystemColor=sizeof(TUint8);
    1.81 +const TInt KParaLeftBorderSystemColor=sizeof(TUint8);
    1.82 +const TInt KParaRightBorderSystemColor=sizeof(TUint8);
    1.83 +const TInt KParaLanguageX=sizeof(TInt32);
    1.84 +const TInt KParaBulletX=sizeof(TInt32) + 2;
    1.85 +const TInt KBitmapType=sizeof(TUint8);
    1.86 +
    1.87 +// Character format attributes
    1.88 +const TInt KCharLanguage=sizeof(TUint8);
    1.89 +const TInt KCharColor=KColor;
    1.90 +const TInt KCharHighlightColor=KColor;
    1.91 +const TInt KCharHighlightStyle=sizeof(TUint8);
    1.92 +const TInt KCharStrikethrough=sizeof(TUint8);
    1.93 +const TInt KCharUnderline=sizeof(TUint8);
    1.94 +const TInt KCharStrokeWeight=sizeof(TUint8);
    1.95 +const TInt KCharPosture=sizeof(TUint8);
    1.96 +const TInt KCharPrintPos=sizeof(TUint8);
    1.97 +const TInt KCharFontHeight=KFontHeight;
    1.98 +const TInt KCharTypeface=KVariableLengthAttribute;
    1.99 +const TInt KCharHiddenText=sizeof(TUint8);
   1.100 +const TInt KCharPictureAlignment=sizeof(TUint8);
   1.101 +const TInt KCharTextSystemColor=sizeof(TUint8);
   1.102 +const TInt KCharFontHighlightSystemColor=sizeof(TUint8);
   1.103 +const TInt KCharLanguageX=sizeof(TInt32);
   1.104 +const TInt KCharParserTag=sizeof(TUint32);
   1.105 +
   1.106 +/*
   1.107 +Lookup table indexed by TTextFormatAttribute enumerated constants.
   1.108 +Specifies the length in bytes of the format attributes.
   1.109 +*/
   1.110 +static const TInt8 TheAttributeLength[EAttributeCount] =
   1.111 +	{
   1.112 +	// Paragraph attribute value lengths.	
   1.113 +	KParaLanguage,
   1.114 +	KParaFillColor,
   1.115 +	KParaLeftMargin,
   1.116 +	KParaRightMargin,
   1.117 +	KParaIndent,
   1.118 +	KParaAlignment,
   1.119 +	KParaVerticalAlignment,
   1.120 +	KParaLineSpacing,
   1.121 +	KParaLineSpacingControl,
   1.122 +	KParaSpaceBefore,
   1.123 +	KParaSpaceAfter,
   1.124 +	KParaKeepTogether,
   1.125 +	KParaKeepWithNext,
   1.126 +	KParaStartNewPage,
   1.127 +	KParaWidowOrphan,
   1.128 +	KParaWrap,
   1.129 +	KParaBorderMargin,
   1.130 +	KParaTopBorder,
   1.131 +	KParaBottomBorder,
   1.132 +	KParaLeftBorder,
   1.133 +	KParaRightBorder,
   1.134 +	KParaBullet,
   1.135 +	KParaDefaultTabWidth,
   1.136 +	KParaTabStop,
   1.137 +
   1.138 +	// Character attribute value lengths.
   1.139 +	KCharLanguage,
   1.140 +	KCharColor,
   1.141 +	KCharHighlightColor,
   1.142 +	KCharHighlightStyle,
   1.143 +	KCharFontHeight,
   1.144 +	KCharStrikethrough,
   1.145 +	KCharUnderline,
   1.146 +	KCharStrokeWeight,
   1.147 +	KCharPosture,
   1.148 +	KCharPrintPos,
   1.149 +	KCharTypeface,
   1.150 +	KCharHiddenText,
   1.151 +	KCharPictureAlignment,
   1.152 +
   1.153 +	// Lengths of extended attributes.
   1.154 +	KParaFillSystemColor,
   1.155 +	KParaBulletSystemColor,
   1.156 +	KParaTopBorderSystemColor,
   1.157 +	KParaBottomBorderSystemColor,
   1.158 +	KParaLeftBorderSystemColor,
   1.159 +	KParaRightBorderSystemColor,
   1.160 +	KCharTextSystemColor,
   1.161 +	KCharFontHighlightSystemColor,
   1.162 +	KParaLanguageX,
   1.163 +	KCharLanguageX,
   1.164 +	KParaBulletX,
   1.165 +    KBitmapType,
   1.166 +
   1.167 +	// Lengths of internal attributes
   1.168 +	KCharParserTag
   1.169 +	};
   1.170 +
   1.171 +
   1.172 +DLLEXPORT_C void RFormatStream::__DbgTestInvariant()const
   1.173 +// Provides class invariants.
   1.174 +// This class invariant checks the integrity of a completed format stream.
   1.175 +// As such, this invariant is only called by those methods that act upon a completed
   1.176 +// format stream; that is, not the set methods, since the format stream will not be complete until
   1.177 +// this call has completed.
   1.178 +//
   1.179 +	{
   1.180 +#ifdef _DEBUG
   1.181 +		__ASSERT_DEBUG(DoInvariantCheck(),User::Invariant());
   1.182 +#endif
   1.183 +	}
   1.184 +
   1.185 +void RFormatStream::TestInvariantL()const
   1.186 +// Provides class invariants.
   1.187 +// This class invariant checks the integrity of a completed format stream.
   1.188 +// As such, this invariant is only called by those methods that act upon a completed
   1.189 +// format stream; that is, not the set methods, since the format stream will not be complete until
   1.190 +// this call has completed.
   1.191 +//
   1.192 +	{
   1.193 +	if (!DoInvariantCheck())
   1.194 +		User::Leave(KErrCorrupt);
   1.195 +	}
   1.196 +
   1.197 +TBool RFormatStream::DoInvariantCheck() const
   1.198 +// Provides class invariants.
   1.199 +// This class invariant checks the integrity of a completed format stream.
   1.200 +// As such, this invariant is only called by those methods that act upon a completed
   1.201 +// format stream; that is, not the set methods, since the format stream will not be complete until
   1.202 +// this call has completed.
   1.203 +//
   1.204 +	{
   1.205 +	if (!iBase)
   1.206 +		return ETrue;
   1.207 +	if (iEnd>iBase)
   1.208 +		{// Assert: stream is self consistent
   1.209 +		// Walks through the stream (aBuffer), checking that it is in a consistent state.
   1.210 +		// (1) All entries in the buffer conform to a TYPE-VALUE structure, checking that
   1.211 +		// types do not occur in contiguous bytes.  ie there is a value.
   1.212 +		// (2) Checks that all encountered types are valid types.
   1.213 +		// (3) Checks that the buffer has not changed size as a result of this check
   1.214 +		// (4) Checks that all attributes in the stream occur only once.  Done by taking a register
   1.215 +		// as each attribute is read from the stream.  (The exception to this rule are Tab identifiers
   1.216 +		// which, if present, will typically occur several times in the stream).
   1.217 +		//
   1.218 +		enum {ENotPresent,EPresent};
   1.219 +		TInt8 attributeRegister[EAttributeCount];
   1.220 +		for (TInt offset=0;offset<EAttributeCount;offset++)
   1.221 +			{// Mark attributeRegister as all absent
   1.222 +			attributeRegister[offset]=(TInt8)ENotPresent;  // clear all items in the register
   1.223 +			}
   1.224 +		TUint8* tempStreamLoc=iBase;
   1.225 +		TUint8* streamLoc=iBase;
   1.226 +		TUint8* endOfStreamLoc=iEnd;
   1.227 +		TUint8 data=0;
   1.228 +		while (streamLoc<endOfStreamLoc)
   1.229 +			{
   1.230 +			data=*streamLoc;
   1.231 +			streamLoc++;
   1.232 +// Assert: data read is a valid format attribute type.
   1.233 +			if (!(data<((TUint8)EAttributeCount))) return EFalse;
   1.234 +			if (data!=EAttTabStop)
   1.235 +				{// Tab Identifiers can occur multiple times in a stream!!
   1.236 +// Assert: attribute type does not already exist in attributeRegister.
   1.237 +				if (!(attributeRegister[data]!=(TInt8)EPresent)) return EFalse;
   1.238 +				}
   1.239 +			attributeRegister[data]=(TInt8)EPresent;
   1.240 +			tempStreamLoc=streamLoc+Length(streamLoc,(TTextFormatAttribute)data);
   1.241 +			if (!(tempStreamLoc>=streamLoc)) return EFalse;
   1.242 +			streamLoc=tempStreamLoc;
   1.243 +			}
   1.244 +// Assert: everything is still the same size.
   1.245 +		if (!(streamLoc==endOfStreamLoc)) return EFalse;
   1.246 +		}
   1.247 +	return ETrue;
   1.248 +	}
   1.249 +
   1.250 +static inline TUint32 Read32(const TUint8* aPtr)
   1.251 +	{
   1.252 +	TUint32 val = aPtr[0];
   1.253 +	val |= aPtr[1] << 8;
   1.254 +	val |= aPtr[2] << 16;
   1.255 +	val |= aPtr[3] << 24;
   1.256 +	return val;
   1.257 +	}
   1.258 +
   1.259 +
   1.260 +static inline void Write32(TUint8*& aPtr,TUint32 aVal)
   1.261 +	{
   1.262 +	*aPtr++ = TUint8(aVal);
   1.263 +	*aPtr++ = TUint8(aVal >> 8);
   1.264 +	*aPtr++ = TUint8(aVal >> 16);
   1.265 +	*aPtr++ = TUint8(aVal >> 24);
   1.266 +	}
   1.267 +
   1.268 +
   1.269 +RFormatStream::RFormatStream():
   1.270 +	iBase(NULL),
   1.271 +	iEnd(NULL)
   1.272 +	{
   1.273 +	}
   1.274 +
   1.275 +		
   1.276 +// Allocate the buffer
   1.277 +void RFormatStream::AllocL(TInt aSize)
   1.278 +	{
   1.279 +    TUint8* pT = reinterpret_cast<TUint8*>(User::ReAllocL(iBase, aSize));
   1.280 +    
   1.281 +    iBase=pT;
   1.282 +    iEnd=pT+aSize;
   1.283 +	}
   1.284 +
   1.285 +
   1.286 +void RFormatStream::Reset()
   1.287 +// Free all storage
   1.288 +//
   1.289 +	{
   1.290 +	if (iBase)
   1.291 +		{
   1.292 +		User::Free(iBase);
   1.293 +		iBase = iEnd = NULL;
   1.294 +		}
   1.295 +	}
   1.296 +
   1.297 +
   1.298 +void RFormatStream::CopyL(const RFormatStream& aSource)
   1.299 +	{
   1.300 +	TInt size = aSource.iEnd - aSource.iBase;
   1.301 +	if (size < 0)
   1.302 +	    {
   1.303 +	    OstTrace0( TRACE_DUMP, RFORMATSTREAM_COPYL, "EDebug" );
   1.304 +	    }
   1.305 +	__ASSERT_DEBUG(size >= 0,Panic(EDebug));
   1.306 +	if (size == 0)
   1.307 +		Reset();
   1.308 +	else
   1.309 +		{
   1.310 +		AllocL(size);
   1.311 +		Mem::Copy(iBase,aSource.iBase,size);
   1.312 +		}
   1.313 +	}
   1.314 +
   1.315 +
   1.316 +/*
   1.317 +Write the bytecode to a stream. Don't write internal attributes; these are not part of the stored format,
   1.318 +but are used for transitory marking of text by URL parsers, etc.
   1.319 +*/
   1.320 +void RFormatStream::ExternalizeL(RWriteStream& aStream) const
   1.321 +	{
   1.322 +	__TEST_INVARIANT;
   1.323 +	
   1.324 +	const TUint8* base=iBase;
   1.325 +	if (base)
   1.326 +		{
   1.327 +		const TUint8* end = base;
   1.328 +		while (end < iEnd && *end < EExternalizedAttributeCount)
   1.329 +			{
   1.330 +			int bytes = TheAttributeLength[*end++];
   1.331 +			if (bytes == 0)
   1.332 +				bytes = *end++;
   1.333 +			end += bytes;
   1.334 +			}
   1.335 +		int length = end - base;
   1.336 +		aStream.WriteInt32L(length);
   1.337 +		aStream.WriteL(base,length);
   1.338 +		}
   1.339 +	else
   1.340 +		aStream.WriteInt32L(0);
   1.341 +	}
   1.342 +
   1.343 +
   1.344 +void RFormatStream::InternalizeL(RReadStream& aStream)
   1.345 +// Load the buffer from the specified stream
   1.346 +//
   1.347 +	{
   1.348 +	TestInvariantL();
   1.349 +
   1.350 +	TInt length=aStream.ReadInt32L();
   1.351 +	//
   1.352 +	if (length<0 || length>KMaxFormatStreamLength)
   1.353 +		User::Leave(KErrCorrupt);
   1.354 +	//
   1.355 +	if (length==0)
   1.356 +		Reset();
   1.357 +	else
   1.358 +		{
   1.359 +		AllocL(length);
   1.360 +		aStream.ReadL(iBase,length);
   1.361 +		}
   1.362 +
   1.363 +	TestInvariantL();
   1.364 +	}
   1.365 +
   1.366 +
   1.367 +// Return a pointer to the stored bytecode and put its length in bytes in aLength.
   1.368 +const TUint8* RFormatStream::Ptr(TInt& aLength) const
   1.369 +	{
   1.370 +	__TEST_INVARIANT;
   1.371 +	aLength=iEnd-iBase;
   1.372 +	if (!((iBase==NULL && aLength==0) || (iBase!=NULL && aLength>0)))
   1.373 +	    {
   1.374 +	    OstTrace0( TRACE_DUMP, RFORMATSTREAM_PTR, "ECorruptFormatLayer" );
   1.375 +	    }
   1.376 +	__ASSERT_DEBUG((iBase==NULL && aLength==0) || (iBase!=NULL && aLength>0),Panic(ECorruptFormatLayer));
   1.377 +	return iBase;
   1.378 +	}
   1.379 +
   1.380 +
   1.381 +// Save the attributes of aCharFormat specified by the corresponding mask aMask.
   1.382 +void RFormatStream::SetCharFormatL(const TCharFormatX& aCharFormatX,const TCharFormatXMask& aMask)
   1.383 +	{
   1.384 +	TInt size=DoCalcSizeCharFormat(aCharFormatX,aMask);
   1.385 +	if (size==0)
   1.386 +		Reset();
   1.387 +	else
   1.388 +		{
   1.389 +		AllocL(size);  // delete the current contents, after allocing a temporary
   1.390 +		DoStoreCharFormat(aCharFormatX,aMask);
   1.391 +		}
   1.392 +
   1.393 +	__TEST_INVARIANT;
   1.394 +	}
   1.395 +
   1.396 +
   1.397 +void RFormatStream::SetParaFormatL(const CParaFormat& aDesiredFormat,const TParaFormatMask& aDesiredMask,
   1.398 +											const CParaFormat& aCurrentFormat)
   1.399 +// Sets the format layer with the specified paragraph format attributes.
   1.400 +// If a leave occurs at any stage, then revert back to original state, and
   1.401 +// propagate the leave.
   1.402 +//
   1.403 +	{
   1.404 +	TInt size=DoCalcSizeParaFormat(aDesiredFormat,aDesiredMask,aCurrentFormat);
   1.405 +	if (size==0)
   1.406 +		Reset();
   1.407 +	else
   1.408 +		{
   1.409 +		AllocL(size);  // delete the current contents, after allocing a temporary
   1.410 +		DoSetParaFormat(aDesiredFormat,aDesiredMask,aCurrentFormat);
   1.411 +		}
   1.412 +
   1.413 +	__TEST_INVARIANT;
   1.414 +	}
   1.415 +	
   1.416 +// Write an auxiliary attribute for a system colour byte. Update aPtr.
   1.417 +static void WriteSystemColor(TUint8*& aPtr,TTextFormatNonMaskableAttribute aAttrib,const TLogicalRgb& aColor)
   1.418 +	{
   1.419 +	TUint8 index = (TUint8)aColor.SystemColorIndex();
   1.420 +	if (index)
   1.421 +		{
   1.422 +		*aPtr++ = TUint8(aAttrib);
   1.423 +		*aPtr++ = index;
   1.424 +		}
   1.425 +	}
   1.426 +
   1.427 +
   1.428 +// Read a system colour byte into a logical colour. Don't change aPtr.
   1.429 +static void ReadSystemColor(const TUint8* aPtr,TLogicalRgb& aColor)
   1.430 +	{
   1.431 +	TUint index = *aPtr;
   1.432 +	aColor.SetSystemColorIndex(index); 
   1.433 +	}
   1.434 +
   1.435 +
   1.436 +// Write paragraph attributes specified by aDesiredMask from aDesiredFormat to the stream.
   1.437 +void RFormatStream::DoSetParaFormat(const CParaFormat& aDesiredFormat,
   1.438 +									TParaFormatMask aMask,
   1.439 +									const CParaFormat& aCurrentFormat)
   1.440 +	{
   1.441 +	TUint8* ptr=iBase;
   1.442 +	if (aMask.AttribIsSet(EAttFillColor))
   1.443 +		{
   1.444 +		*ptr++=TUint8(EAttFillColor);
   1.445 +		ptr=Store(ptr,aDesiredFormat.iFillColor);
   1.446 +		}
   1.447 +	if (aMask.AttribIsSet(EAttLeftMargin))
   1.448 +		{
   1.449 +		*ptr++=TUint8(EAttLeftMargin);
   1.450 +		Write32(ptr,aDesiredFormat.iLeftMarginInTwips);
   1.451 +		}
   1.452 +	if (aMask.AttribIsSet(EAttRightMargin))
   1.453 +		{
   1.454 +		*ptr++=TUint8(EAttRightMargin);
   1.455 +		Write32(ptr,aDesiredFormat.iRightMarginInTwips);
   1.456 +		}
   1.457 +	if (aMask.AttribIsSet(EAttIndent))
   1.458 +		{
   1.459 +		*ptr++=TUint8(EAttIndent);
   1.460 +		Write32(ptr,aDesiredFormat.iIndentInTwips);
   1.461 +		}
   1.462 +	if (aMask.AttribIsSet(EAttAlignment))
   1.463 +		{
   1.464 +		*ptr++=TUint8(EAttAlignment);
   1.465 +		*ptr++=TUint8(aDesiredFormat.iHorizontalAlignment);
   1.466 +		}
   1.467 +	if (aMask.AttribIsSet(EAttVerticalAlignment))
   1.468 +		{
   1.469 +		*ptr++=TUint8(EAttVerticalAlignment);
   1.470 +		*ptr++=TUint8(aDesiredFormat.iVerticalAlignment);
   1.471 +		}
   1.472 +	if (aMask.AttribIsSet(EAttLineSpacing))
   1.473 +		{
   1.474 +		*ptr++=TUint8(EAttLineSpacing);
   1.475 +		Write32(ptr,aDesiredFormat.iLineSpacingInTwips);
   1.476 +		}
   1.477 +	if (aMask.AttribIsSet(EAttLineSpacingControl))
   1.478 +		{
   1.479 +		*ptr++=TUint8(EAttLineSpacingControl);
   1.480 +		*ptr++=TUint8(aDesiredFormat.iLineSpacingControl);
   1.481 +		}
   1.482 +	if (aMask.AttribIsSet(EAttSpaceBefore))
   1.483 +		{
   1.484 +		*ptr++=TUint8(EAttSpaceBefore);
   1.485 +		Write32(ptr,aDesiredFormat.iSpaceBeforeInTwips);
   1.486 +		}
   1.487 +	if (aMask.AttribIsSet(EAttSpaceAfter))
   1.488 +		{
   1.489 +		*ptr++=TUint8(EAttSpaceAfter);
   1.490 +		Write32(ptr,aDesiredFormat.iSpaceAfterInTwips);
   1.491 +		}
   1.492 +	if (aMask.AttribIsSet(EAttKeepTogether))
   1.493 +		{
   1.494 +		*ptr++=TUint8(EAttKeepTogether);
   1.495 +		*ptr++=TUint8(aDesiredFormat.iKeepTogether!=EFalse);
   1.496 +		}
   1.497 +	if (aMask.AttribIsSet(EAttKeepWithNext))
   1.498 +		{
   1.499 +		*ptr++=TUint8(EAttKeepWithNext);
   1.500 +		*ptr++=TUint8(aDesiredFormat.iKeepWithNext!=EFalse);
   1.501 +		}
   1.502 +	if (aMask.AttribIsSet(EAttStartNewPage))
   1.503 +		{
   1.504 +		*ptr++=TUint8(EAttStartNewPage);
   1.505 +		*ptr++=TUint8(aDesiredFormat.iStartNewPage!=EFalse);
   1.506 +		}
   1.507 +	if (aMask.AttribIsSet(EAttWidowOrphan))
   1.508 +		{
   1.509 +		*ptr++=TUint8(EAttWidowOrphan);
   1.510 +		*ptr++=TUint8(aDesiredFormat.iWidowOrphan!=EFalse);
   1.511 +		}
   1.512 +	if (aMask.AttribIsSet(EAttWrap))
   1.513 +		{
   1.514 +		*ptr++=TUint8(EAttWrap);
   1.515 +		*ptr++=TUint8(aDesiredFormat.iWrap!=EFalse);
   1.516 +		}
   1.517 +	if (aMask.AttribIsSet(EAttBorderMargin))
   1.518 +		{
   1.519 +		*ptr++=TUint8(EAttBorderMargin);
   1.520 +		Write32(ptr,aDesiredFormat.iBorderMarginInTwips);
   1.521 +		}
   1.522 +	if ( aDesiredFormat.BordersPresent() || aCurrentFormat.BordersPresent() )
   1.523 +		{
   1.524 +		if (aMask.AttribIsSet(EAttTopBorder))
   1.525 +			ptr=StoreBorder(ptr,EAttTopBorder,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderTop));
   1.526 +		if (aMask.AttribIsSet(EAttBottomBorder))
   1.527 +			ptr=StoreBorder(ptr,EAttBottomBorder,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderBottom));
   1.528 +		if (aMask.AttribIsSet(EAttLeftBorder))
   1.529 +			ptr=StoreBorder(ptr,EAttLeftBorder,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderLeft));
   1.530 +		if (aMask.AttribIsSet(EAttRightBorder))
   1.531 +			ptr=StoreBorder(ptr,EAttRightBorder,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderRight));
   1.532 +		}
   1.533 +	if (aMask.AttribIsSet(EAttDefaultTabWidth))
   1.534 +		{
   1.535 +		*ptr++=TUint8(EAttDefaultTabWidth);
   1.536 +		Write32(ptr,aDesiredFormat.iDefaultTabWidthInTwips);
   1.537 +		}
   1.538 +	if (aMask.AttribIsSet(EAttTabStop))
   1.539 +		{
   1.540 +		TUint8* tptr=ptr;	// prevent stacking of ptr;
   1.541 +		StoreTabs(tptr,aDesiredFormat,aCurrentFormat,ETrue);
   1.542 +		ptr=tptr;
   1.543 +		}
   1.544 +	if (aMask.AttribIsSet(EAttBullet))
   1.545 +		{
   1.546 +		if (aDesiredFormat.iBullet || aCurrentFormat.iBullet)
   1.547 +			{
   1.548 +			if (aDesiredFormat.iBullet)
   1.549 +				ptr = StoreBullet(ptr,*aDesiredFormat.iBullet);
   1.550 +			else if (aCurrentFormat.iBullet)
   1.551 +				ptr = StoreBullet(ptr,TBullet());
   1.552 +			}
   1.553 +		}
   1.554 +	if (!(aDesiredFormat.iLanguage & ~0xFF) && aMask.AttribIsSet(EAttParaLanguage))
   1.555 +		{
   1.556 +		*ptr++=TUint8(EAttParaLanguage);
   1.557 +		*ptr++=TUint8(aDesiredFormat.iLanguage);
   1.558 +		}
   1.559 +
   1.560 +	/*
   1.561 +	Write the auxiliary attributes for system colours, language codes greater than 255, etc.
   1.562 +	These must go at the end of the stream because they will not be recognised by earlier versions
   1.563 +	of ETEXT and will prevent any further attributes from being read.
   1.564 +	*/
   1.565 +	if (aMask.AttribIsSet(EAttFillColor))
   1.566 +		WriteSystemColor(ptr,EAttFillSystemColor,aDesiredFormat.iFillColor);
   1.567 +	if (aMask.AttribIsSet(EAttBullet))
   1.568 +		{
   1.569 +		if (aDesiredFormat.iBullet)
   1.570 +			WriteSystemColor(ptr,EAttBulletSystemColor,aDesiredFormat.iBullet->iColor);
   1.571 +		else if (aCurrentFormat.iBullet)
   1.572 +			WriteSystemColor(ptr,EAttBulletSystemColor,TBullet().iColor);
   1.573 +		}
   1.574 +	if (aDesiredFormat.BordersPresent())
   1.575 +		{
   1.576 +		if (aMask.AttribIsSet(EAttTopBorder))
   1.577 +			WriteSystemColor(ptr,EAttTopBorderSystemColor,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderTop).iColor);
   1.578 +		if (aMask.AttribIsSet(EAttBottomBorder))
   1.579 +			WriteSystemColor(ptr,EAttBottomBorderSystemColor,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderBottom).iColor);
   1.580 +		if (aMask.AttribIsSet(EAttLeftBorder))
   1.581 +			WriteSystemColor(ptr,EAttLeftBorderSystemColor,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderLeft).iColor);
   1.582 +		if (aMask.AttribIsSet(EAttRightBorder))
   1.583 +			WriteSystemColor(ptr,EAttRightBorderSystemColor,aDesiredFormat.ParaBorder(CParaFormat::EParaBorderRight).iColor);
   1.584 +		}
   1.585 +	if ((aDesiredFormat.iLanguage & ~0xFF) && aMask.AttribIsSet(EAttParaLanguage))
   1.586 +		{
   1.587 +		*ptr++ = TUint8(EAttParaLanguageX);
   1.588 +		Write32(ptr,aDesiredFormat.iLanguage);
   1.589 +		}
   1.590 +	if (aMask.AttribIsSet(EAttBullet))
   1.591 +		{
   1.592 +		if (aDesiredFormat.iBullet || aCurrentFormat.iBullet)
   1.593 +			{
   1.594 +			TBullet bullet;
   1.595 +			const TBullet* b = aDesiredFormat.iBullet;
   1.596 +			if (!b)
   1.597 +				b = &bullet;
   1.598 +			*ptr++ = TUint8(EAttBulletX);
   1.599 +			*ptr++ = TUint8(b->iStyle);
   1.600 +			Write32(ptr,b->iStartNumber);
   1.601 +			*ptr++ = TUint8(b->iAlignment);
   1.602 +			}
   1.603 +		}
   1.604 +	}
   1.605 +
   1.606 +
   1.607 +TInt RFormatStream::DoCalcSizeParaFormat(const CParaFormat& aDesiredFormat,TParaFormatMask aMask,
   1.608 +										 const CParaFormat& aCurrentFormat)
   1.609 +// determine the amount of memory required to store the
   1.610 +// specified attriubutes from the specified paragraph format.
   1.611 +//
   1.612 +	{
   1.613 +	TInt size=0;
   1.614 +	if (aMask.AttribIsSet(EAttFillColor))
   1.615 +		{
   1.616 +		size+=(KTypeSize+KParaFillColor);
   1.617 +		if (aDesiredFormat.iFillColor.SystemColorIndex())
   1.618 +			size += KTypeSize + KParaFillSystemColor;
   1.619 +		}
   1.620 +	if (aMask.AttribIsSet(EAttLeftMargin))
   1.621 +		size+=(KTypeSize+KParaLeftMargin);
   1.622 +	if (aMask.AttribIsSet(EAttRightMargin))
   1.623 +		size+=(KTypeSize+KParaRightMargin);
   1.624 +	if (aMask.AttribIsSet(EAttIndent))
   1.625 +		size+=(KTypeSize+KParaIndent);
   1.626 +	if (aMask.AttribIsSet(EAttAlignment))
   1.627 +		size+=(KTypeSize+KParaAlignment);
   1.628 +	if (aMask.AttribIsSet(EAttVerticalAlignment))
   1.629 +		size+=(KTypeSize+KParaVerticalAlignment);
   1.630 +	if (aMask.AttribIsSet(EAttLineSpacing))
   1.631 +		size+=(KTypeSize+KParaLineSpacing);
   1.632 +	if (aMask.AttribIsSet(EAttLineSpacingControl))
   1.633 +		size+=(KTypeSize+KParaLineSpacingControl);
   1.634 +	if (aMask.AttribIsSet(EAttSpaceBefore))
   1.635 +		size+=(KTypeSize+KParaSpaceBefore);
   1.636 +	if (aMask.AttribIsSet(EAttSpaceAfter))
   1.637 +		size+=(KTypeSize+KParaSpaceAfter);
   1.638 +	if (aMask.AttribIsSet(EAttKeepTogether))
   1.639 +		size+=(KTypeSize+KParaKeepTogether);
   1.640 +	if (aMask.AttribIsSet(EAttKeepWithNext))
   1.641 +		size+=(KTypeSize+KParaKeepWithNext);
   1.642 +	if (aMask.AttribIsSet(EAttStartNewPage))
   1.643 +		size+=(KTypeSize+KParaStartNewPage);
   1.644 +	if (aMask.AttribIsSet(EAttWidowOrphan))
   1.645 +		size+=(KTypeSize+KParaWidowOrphan);
   1.646 +	if (aMask.AttribIsSet(EAttWrap))
   1.647 +		size+=(KTypeSize+KParaWrap);
   1.648 +	if (aMask.AttribIsSet(EAttBorderMargin))
   1.649 +		size+=(KTypeSize+KParaBorderMargin);
   1.650 +	if ( aDesiredFormat.BordersPresent() || aCurrentFormat.BordersPresent() )
   1.651 +		{
   1.652 +		if (aMask.AttribIsSet(EAttTopBorder))
   1.653 +			{
   1.654 +			size+=(KTypeSize+
   1.655 +			sizeof(TUint8)+  // line style
   1.656 +			sizeof(TInt32)+  // line thickness
   1.657 +			KColor+
   1.658 +			sizeof(TUint8));  // auto color flag
   1.659 +			if (aDesiredFormat.ParaBorder(CParaFormat::EParaBorderTop).iColor.SystemColorIndex())
   1.660 +				size += KTypeSize + KParaTopBorderSystemColor;
   1.661 +			}
   1.662 +		if (aMask.AttribIsSet(EAttBottomBorder))
   1.663 +			{
   1.664 +			size+=(KTypeSize+
   1.665 +			sizeof(TUint8)+  // line style
   1.666 +			sizeof(TInt32)+  // line thickness
   1.667 +			KColor+
   1.668 +			sizeof(TUint8));  // auto color flag
   1.669 +			if (aDesiredFormat.ParaBorder(CParaFormat::EParaBorderBottom).iColor.SystemColorIndex())
   1.670 +				size += KTypeSize + KParaBottomBorderSystemColor;
   1.671 +			}
   1.672 +		if (aMask.AttribIsSet(EAttLeftBorder))
   1.673 +			{
   1.674 +			size+=(KTypeSize+
   1.675 +			sizeof(TUint8)+  // line style
   1.676 +			sizeof(TInt32)+  // line thickness
   1.677 +			KColor+
   1.678 +			sizeof(TUint8));  // auto color flag
   1.679 +			if (aDesiredFormat.ParaBorder(CParaFormat::EParaBorderLeft).iColor.SystemColorIndex())
   1.680 +				size += KTypeSize + KParaLeftBorderSystemColor;
   1.681 +			}
   1.682 +		if (aMask.AttribIsSet(EAttRightBorder))
   1.683 +			{
   1.684 +			size+=(KTypeSize+
   1.685 +			sizeof(TUint8)+  // line style
   1.686 +			sizeof(TInt32)+  // line thickness
   1.687 +			KColor+
   1.688 +			sizeof(TUint8));  // auto color flag
   1.689 +			if (aDesiredFormat.ParaBorder(CParaFormat::EParaBorderRight).iColor.SystemColorIndex())
   1.690 +				size += KTypeSize + KParaBulletSystemColor;
   1.691 +			}
   1.692 +		}
   1.693 +	if (aMask.AttribIsSet(EAttDefaultTabWidth))
   1.694 +		size+=(KTypeSize+KParaDefaultTabWidth);
   1.695 +	if (aMask.AttribIsSet(EAttTabStop))
   1.696 +		{
   1.697 +		TUint8* ptr=NULL;
   1.698 +		size+=StoreTabs(ptr,aDesiredFormat,aCurrentFormat,EFalse);
   1.699 +		}
   1.700 +	if (aMask.AttribIsSet(EAttBullet))
   1.701 +		{
   1.702 +		if (aDesiredFormat.iBullet || aCurrentFormat.iBullet)
   1.703 +			{
   1.704 +			size += KTypeSize +
   1.705 +					sizeof(TUint8) +		// length of following data
   1.706 +					sizeof(TText) +			// iCharacterCode
   1.707 +					KFontHeight +			// iHeightInTwips
   1.708 +					sizeof(TUint8) +		// iHanging indent
   1.709 +					KCharColor +			// iColor
   1.710 +					sizeof(TUint8) +		// typeface name size
   1.711 +					KTypefaceFlags;			// typeface flags
   1.712 +
   1.713 +			if (aDesiredFormat.iBullet)
   1.714 +				size += aDesiredFormat.iBullet->iTypeface.iName.Size();  // font name
   1.715 +
   1.716 +			if ((aDesiredFormat.iBullet && aDesiredFormat.iBullet->iColor.SystemColorIndex()) ||
   1.717 +				(aCurrentFormat.iBullet))
   1.718 +				size += KTypeSize + KParaBulletSystemColor;
   1.719 +
   1.720 +			size += KTypeSize + KParaBulletX;
   1.721 +			}
   1.722 +		}
   1.723 +	if (aMask.AttribIsSet(EAttParaLanguage))
   1.724 +		{
   1.725 +		if (aDesiredFormat.iLanguage & ~0xFF)
   1.726 +			size += KTypeSize + KParaLanguageX;
   1.727 +		else
   1.728 +			size += KTypeSize + KParaLanguage;
   1.729 +		}
   1.730 +	return size;
   1.731 +	}
   1.732 +
   1.733 +
   1.734 +// Store the specified values in this (allocated) format stream.
   1.735 +void RFormatStream::DoStoreCharFormat(const TCharFormatX& aCharFormat,TCharFormatXMask aMask)
   1.736 +	{
   1.737 +	TUint8* ptr = iBase;
   1.738 +	const TCharFormat format = aCharFormat.iCharFormat;
   1.739 +
   1.740 +	if (aMask.AttribIsSet(EAttColor))
   1.741 +		{
   1.742 +		*ptr++=TUint8(EAttColor);
   1.743 +		ptr=Store(ptr,format.iFontPresentation.iTextColor);
   1.744 +		}
   1.745 +	if (aMask.AttribIsSet(EAttFontHighlightColor))
   1.746 +		{
   1.747 +		*ptr++=TUint8(EAttFontHighlightColor);
   1.748 +		ptr=Store(ptr,format.iFontPresentation.iHighlightColor);
   1.749 +		}
   1.750 +	if (aMask.AttribIsSet(EAttFontHighlightStyle))
   1.751 +		{
   1.752 +		*ptr++=TUint8(EAttFontHighlightStyle);
   1.753 +		*ptr++=(TUint8)format.iFontPresentation.iHighlightStyle;
   1.754 +		}
   1.755 +	if (aMask.AttribIsSet(EAttFontStrikethrough))
   1.756 +		{
   1.757 +		*ptr++=TUint8(EAttFontStrikethrough);
   1.758 +		*ptr++=(TUint8)format.iFontPresentation.iStrikethrough;
   1.759 +		}
   1.760 +	if (aMask.AttribIsSet(EAttFontUnderline))
   1.761 +		{
   1.762 +		*ptr++=TUint8(EAttFontUnderline);
   1.763 +		*ptr++=(TUint8)format.iFontPresentation.iUnderline;
   1.764 +		}
   1.765 +	if (aMask.AttribIsSet(EAttFontHeight))
   1.766 +		{
   1.767 +		*ptr++=TUint8(EAttFontHeight);
   1.768 +		Write32(ptr,format.iFontSpec.iHeight);
   1.769 +		}
   1.770 +	if (aMask.AttribIsSet(EAttFontPosture))
   1.771 +		{
   1.772 +		*ptr++=TUint8(EAttFontPosture);
   1.773 +		*ptr++=TUint8(format.iFontSpec.iFontStyle.Posture());
   1.774 +		}
   1.775 +	if (aMask.AttribIsSet(EAttFontStrokeWeight))
   1.776 +		{
   1.777 +		*ptr++=TUint8(EAttFontStrokeWeight);
   1.778 +		*ptr++=TUint8(format.iFontSpec.iFontStyle.StrokeWeight());
   1.779 +		}
   1.780 +	if (aMask.AttribIsSet(EAttFontPrintPos))
   1.781 +		{
   1.782 +		*ptr++=TUint8(EAttFontPrintPos);
   1.783 +		*ptr++=TUint8(format.iFontSpec.iFontStyle.PrintPosition());
   1.784 +		}
   1.785 +	if (aMask.AttribIsSet(EAttFontTypeface))
   1.786 +		{
   1.787 +		*ptr++=TUint8(EAttFontTypeface);
   1.788 +		ptr=Store(ptr,format.iFontSpec.iTypeface);
   1.789 +		*ptr++=TUint8(EAttBitmapType);
   1.790 +		*ptr++=TUint8(format.iFontSpec.iFontStyle.BitmapType());
   1.791 +		}
   1.792 +	if (!(format.iLanguage & ~0xFF) && aMask.AttribIsSet(EAttCharLanguage))
   1.793 +		{
   1.794 +		*ptr++=TUint8(EAttCharLanguage);
   1.795 +		*ptr++=TUint8(format.iLanguage);
   1.796 +		}
   1.797 +	if (aMask.AttribIsSet(EAttFontHiddenText))
   1.798 +		{
   1.799 +		*ptr++=TUint8(EAttFontHiddenText);
   1.800 +		*ptr++=TUint8(format.iFontPresentation.iHiddenText!=EFalse);
   1.801 +		}
   1.802 +	if (aMask.AttribIsSet(EAttFontPictureAlignment))
   1.803 +		{
   1.804 +		*ptr++=TUint8(EAttFontPictureAlignment);
   1.805 +		*ptr++=TUint8(format.iFontPresentation.iPictureAlignment);
   1.806 +		}
   1.807 +
   1.808 +	// Auxiliary attributes for system colours, etc.
   1.809 +	if (aMask.AttribIsSet(EAttColor))
   1.810 +		WriteSystemColor(ptr,EAttTextSystemColor,format.iFontPresentation.iTextColor);
   1.811 +	if (aMask.AttribIsSet(EAttFontHighlightColor))
   1.812 +		WriteSystemColor(ptr,EAttFontHighlightSystemColor,format.iFontPresentation.iHighlightColor);
   1.813 +	if ((format.iLanguage & ~0xFF) && aMask.AttribIsSet(EAttCharLanguage))
   1.814 +		{
   1.815 +		*ptr++ = TUint8(EAttCharLanguageX);
   1.816 +		Write32(ptr,format.iLanguage);
   1.817 +		}
   1.818 +
   1.819 +	// Internal character attributes:
   1.820 +	if (aMask.AttribIsSet(EAttParserTag))
   1.821 +		{
   1.822 +		*ptr++ = TUint8(EAttParserTag);
   1.823 +		Write32(ptr,aCharFormat.iParserTag);
   1.824 +		}
   1.825 +	}
   1.826 +
   1.827 +
   1.828 +TInt RFormatStream::DoCalcSizeCharFormat(const TCharFormatX& aCharFormatX,const TCharFormatXMask& aMask)
   1.829 +	{
   1.830 +	TInt size = 0;
   1.831 +	const TCharFormat format = aCharFormatX.iCharFormat;
   1.832 +
   1.833 +	if (aMask.AttribIsSet(EAttColor))
   1.834 +		{
   1.835 +		size+=(KTypeSize+KCharColor);
   1.836 +		if (format.iFontPresentation.iTextColor.SystemColorIndex())
   1.837 +			size += KTypeSize + KCharTextSystemColor;
   1.838 +		}
   1.839 +	if (aMask.AttribIsSet(EAttFontHighlightColor))
   1.840 +		{
   1.841 +		size+=(KTypeSize+KCharHighlightColor);
   1.842 +		if (format.iFontPresentation.iHighlightColor.SystemColorIndex())
   1.843 +			size += KTypeSize + KCharFontHighlightSystemColor;
   1.844 +		}
   1.845 +	if (aMask.AttribIsSet(EAttFontHighlightStyle))
   1.846 +		size+=(KTypeSize+KCharHighlightStyle);
   1.847 +	if (aMask.AttribIsSet(EAttFontStrikethrough))
   1.848 +		size+=(KTypeSize+KCharStrikethrough);
   1.849 +	if (aMask.AttribIsSet(EAttFontUnderline))
   1.850 +		size+=(KTypeSize+KCharUnderline);
   1.851 +	if (aMask.AttribIsSet(EAttFontHeight))
   1.852 +		size+=(KTypeSize+KCharFontHeight);
   1.853 +	if (aMask.AttribIsSet(EAttFontPosture))
   1.854 +		size+=(KTypeSize+KCharPosture);
   1.855 +	if (aMask.AttribIsSet(EAttFontStrokeWeight))
   1.856 +		size+=(KTypeSize+KCharStrokeWeight);
   1.857 +	if (aMask.AttribIsSet(EAttFontPrintPos))
   1.858 +		size+=(KTypeSize+KCharPrintPos);
   1.859 +	if (aMask.AttribIsSet(EAttFontTypeface))
   1.860 +		{
   1.861 +		TUint8 length=(TUint8)format.iFontSpec.iTypeface.iName.Size();
   1.862 +		size+=(KTypeSize+sizeof(TUint8)+length+sizeof(TUint8));  // size in bytes
   1.863 +		size+=(KTypeSize+KBitmapType);
   1.864 +		}
   1.865 +	if (aMask.AttribIsSet(EAttCharLanguage))
   1.866 +		{
   1.867 +		if (format.iLanguage & ~0xFF)
   1.868 +			size += KTypeSize + KCharLanguageX;
   1.869 +		else
   1.870 +			size += KTypeSize + KCharLanguage;
   1.871 +		}
   1.872 +	if (aMask.AttribIsSet(EAttFontHiddenText))
   1.873 +		size+=(KTypeSize+KCharHiddenText);
   1.874 +	if (aMask.AttribIsSet(EAttFontPictureAlignment))
   1.875 +		size+=(KTypeSize+KCharPictureAlignment);
   1.876 +
   1.877 +	// Internal character attributes
   1.878 +	if (aMask.AttribIsSet(EAttParserTag))
   1.879 +		size += KTypeSize + KCharParserTag;
   1.880 +	
   1.881 +	return size;
   1.882 +	}
   1.883 +
   1.884 +void RFormatStream::RemoveRedundantCharFormat(TCharFormatMask& aMask,
   1.885 +											  const TCharFormatX& aFormat,const TCharFormatX& aEffectiveFormat)
   1.886 +	{
   1.887 +	TCharFormatXMask mask = aMask;
   1.888 +	const TCharFormat format = aFormat.iCharFormat;
   1.889 +	const TCharFormat effective_format = aEffectiveFormat.iCharFormat;
   1.890 +
   1.891 +	if (mask.AttribIsSet(EAttColor))
   1.892 +		{
   1.893 +		if (format.iFontPresentation.iTextColor==effective_format.iFontPresentation.iTextColor)
   1.894 +			mask.ClearAttrib(EAttColor);
   1.895 +		}
   1.896 +	if (mask.AttribIsSet(EAttFontHighlightColor))
   1.897 +		{
   1.898 +		if (format.iFontPresentation.iHighlightColor==effective_format.iFontPresentation.iHighlightColor)
   1.899 +			mask.ClearAttrib(EAttFontHighlightColor);
   1.900 +		}
   1.901 +	if (mask.AttribIsSet(EAttFontHighlightStyle))
   1.902 +		{
   1.903 +		if (format.iFontPresentation.iHighlightStyle==effective_format.iFontPresentation.iHighlightStyle)
   1.904 +			mask.ClearAttrib(EAttFontHighlightStyle);
   1.905 +		}
   1.906 +	if (mask.AttribIsSet(EAttFontStrikethrough))
   1.907 +		{
   1.908 +		if (format.iFontPresentation.iStrikethrough==effective_format.iFontPresentation.iStrikethrough)
   1.909 +			mask.ClearAttrib(EAttFontStrikethrough);
   1.910 +		}
   1.911 +	if (mask.AttribIsSet(EAttFontUnderline))
   1.912 +		{
   1.913 +		if (format.iFontPresentation.iUnderline==effective_format.iFontPresentation.iUnderline)
   1.914 +			mask.ClearAttrib(EAttFontUnderline);
   1.915 +		}
   1.916 +	if (mask.AttribIsSet(EAttFontHeight))
   1.917 +		{
   1.918 +		if (format.iFontSpec.iHeight==effective_format.iFontSpec.iHeight)
   1.919 +			mask.ClearAttrib(EAttFontHeight);
   1.920 +		}
   1.921 +	if (mask.AttribIsSet(EAttFontPosture))
   1.922 +		{
   1.923 +		if (format.iFontSpec.iFontStyle.Posture()==effective_format.iFontSpec.iFontStyle.Posture())
   1.924 +			mask.ClearAttrib(EAttFontPosture);
   1.925 +		}
   1.926 +	if (mask.AttribIsSet(EAttFontStrokeWeight))
   1.927 +		{
   1.928 +		if (format.iFontSpec.iFontStyle.StrokeWeight()==effective_format.iFontSpec.iFontStyle.StrokeWeight())
   1.929 +			mask.ClearAttrib(EAttFontStrokeWeight);
   1.930 +		}
   1.931 +	if (mask.AttribIsSet(EAttFontPrintPos))
   1.932 +		{
   1.933 +		if (format.iFontSpec.iFontStyle.PrintPosition()==effective_format.iFontSpec.iFontStyle.PrintPosition())
   1.934 +			mask.ClearAttrib(EAttFontPrintPos);
   1.935 +		}
   1.936 +	if (mask.AttribIsSet(EAttFontTypeface))
   1.937 +		{
   1.938 +		if (format.iFontSpec.iTypeface==effective_format.iFontSpec.iTypeface)
   1.939 +			mask.ClearAttrib(EAttFontTypeface);
   1.940 +		}
   1.941 +	if (mask.AttribIsSet(EAttCharLanguage))
   1.942 +		{
   1.943 +		if (format.iLanguage==effective_format.iLanguage)
   1.944 +			mask.ClearAttrib(EAttCharLanguage);
   1.945 +		}
   1.946 +	if (mask.AttribIsSet(EAttFontHiddenText))
   1.947 +		{
   1.948 +		if (format.iFontPresentation.iHiddenText==effective_format.iFontPresentation.iHiddenText)
   1.949 +			mask.ClearAttrib(EAttFontHiddenText);
   1.950 +		}
   1.951 +	if (mask.AttribIsSet(EAttFontPictureAlignment))
   1.952 +		{
   1.953 +		if (format.iFontPresentation.iPictureAlignment==effective_format.iFontPresentation.iPictureAlignment)
   1.954 +			mask.ClearAttrib(EAttFontPictureAlignment);
   1.955 +		}
   1.956 +	if (mask.AttribIsSet(EAttParserTag))
   1.957 +		{
   1.958 +		if (aFormat.iParserTag == aEffectiveFormat.iParserTag)
   1.959 +			mask.ClearAttrib(EAttParserTag);
   1.960 +		}
   1.961 +	aMask = mask;
   1.962 +	}
   1.963 +
   1.964 +
   1.965 +void RFormatStream::SenseParaFormatL(CParaFormat& aParaFormat,TParaFormatMask& aMask,CParaFormat::TParaFormatGetMode aMode)const
   1.966 +// Dumps contents of the stream into aParaFormat.  The attributes written to aParaFormat
   1.967 +// are determined by the mode, aMode.
   1.968 +// If the mode is EAllAttributes, then all attributes are written,
   1.969 +// if the mode is EFixedAttributes, then only the fixed atttibutes are written,
   1.970 +// ie, not tabs,borders,bullet (which are variable).
   1.971 +// For each format attribute found in the stream:
   1.972 +// write it into a ParaFormat if the corresponding flag in aMask is not set,
   1.973 +// and set this flag showing the attribute has been written into aParaFormat.
   1.974 +//
   1.975 +// If aMode is EAllAttributes this function may leave through out-of-memory allocating paragraph borders,
   1.976 +// bullets or tabs.
   1.977 +// If aMode is EFixedAttributes, this function is guaranteed not to leave.
   1.978 +//
   1.979 +	{
   1.980 +	__TEST_INVARIANT;
   1.981 +
   1.982 +	TUint8* ptr=iBase;
   1.983 +	if (ptr==NULL)
   1.984 +		return;
   1.985 +	TParaFormatMask old_mask = aMask;
   1.986 +	TParaFormatMask new_mask = aMask;
   1.987 +	TUint8* end=iEnd;
   1.988 +	TParaBorder* b = NULL;
   1.989 +
   1.990 +	while (ptr < end)
   1.991 +		{
   1.992 +		TUint8 type = *ptr;
   1.993 +		ptr += KTypeSize;
   1.994 +		switch (type)
   1.995 +			{
   1.996 +			case EAttFillColor:
   1.997 +				if (!old_mask.AttribIsSet(EAttFillColor))
   1.998 +					{
   1.999 +					new_mask.SetAttrib(EAttFillColor);
  1.1000 +					ptr=ReadValue(ptr,aParaFormat.iFillColor);
  1.1001 +					}
  1.1002 +				else
  1.1003 +					ptr+=KParaFillColor;
  1.1004 +				break;
  1.1005 +			case EAttLeftMargin:
  1.1006 +				if (!old_mask.AttribIsSet(EAttLeftMargin))
  1.1007 +					{
  1.1008 +					new_mask.SetAttrib(EAttLeftMargin);
  1.1009 +					aParaFormat.iLeftMarginInTwips = Read32(ptr);
  1.1010 +					}
  1.1011 +				ptr+=KParaLeftMargin;
  1.1012 +				break;
  1.1013 +			case EAttRightMargin:
  1.1014 +				if (!old_mask.AttribIsSet(EAttRightMargin))
  1.1015 +					{
  1.1016 +					new_mask.SetAttrib(EAttRightMargin);
  1.1017 +					aParaFormat.iRightMarginInTwips = Read32(ptr);
  1.1018 +					}
  1.1019 +				ptr+=KParaRightMargin;
  1.1020 +				break;
  1.1021 +			case EAttIndent:
  1.1022 +				if (!old_mask.AttribIsSet(EAttIndent))
  1.1023 +					{
  1.1024 +					new_mask.SetAttrib(EAttIndent);
  1.1025 +					aParaFormat.iIndentInTwips = Read32(ptr);
  1.1026 +					}
  1.1027 +				ptr+=KParaIndent;
  1.1028 +				break;
  1.1029 +			case EAttAlignment:
  1.1030 +				if (!old_mask.AttribIsSet(EAttAlignment))
  1.1031 +					{
  1.1032 +					new_mask.SetAttrib(EAttAlignment);
  1.1033 +					aParaFormat.iHorizontalAlignment=CParaFormat::TAlignment(*ptr);
  1.1034 +					}
  1.1035 +				ptr+=KParaAlignment;
  1.1036 +				break;
  1.1037 +			case EAttVerticalAlignment:
  1.1038 +				if (!old_mask.AttribIsSet(EAttVerticalAlignment))
  1.1039 +					{
  1.1040 +					new_mask.SetAttrib(EAttVerticalAlignment);
  1.1041 +					aParaFormat.iVerticalAlignment=CParaFormat::TAlignment(*ptr);
  1.1042 +					}
  1.1043 +				ptr+=KParaVerticalAlignment;
  1.1044 +				break;
  1.1045 +			case EAttLineSpacing:
  1.1046 +				if (!old_mask.AttribIsSet(EAttLineSpacing))
  1.1047 +					{
  1.1048 +					new_mask.SetAttrib(EAttLineSpacing);
  1.1049 +					aParaFormat.iLineSpacingInTwips = Read32(ptr);
  1.1050 +					}
  1.1051 +				ptr+=KParaLineSpacing;
  1.1052 +				break;
  1.1053 +			case EAttLineSpacingControl:
  1.1054 +				if (!old_mask.AttribIsSet(EAttLineSpacingControl))
  1.1055 +					{
  1.1056 +					new_mask.SetAttrib(EAttLineSpacingControl);
  1.1057 +					aParaFormat.iLineSpacingControl=(CParaFormat::TLineSpacingControl)*ptr;
  1.1058 +					}
  1.1059 +				ptr+=KParaLineSpacingControl;
  1.1060 +				break;
  1.1061 +			case EAttSpaceBefore:
  1.1062 +				if (!old_mask.AttribIsSet(EAttSpaceBefore))
  1.1063 +					{
  1.1064 +					new_mask.SetAttrib(EAttSpaceBefore);
  1.1065 +					aParaFormat.iSpaceBeforeInTwips = Read32(ptr);
  1.1066 +					}
  1.1067 +				ptr+=KParaSpaceBefore;
  1.1068 +				break;
  1.1069 +			case EAttSpaceAfter:
  1.1070 +				if (!old_mask.AttribIsSet(EAttSpaceAfter))
  1.1071 +					{
  1.1072 +					new_mask.SetAttrib(EAttSpaceAfter);
  1.1073 +					aParaFormat.iSpaceAfterInTwips = Read32(ptr);
  1.1074 +					}
  1.1075 +				ptr+=KParaSpaceAfter;
  1.1076 +				break;
  1.1077 +			case EAttKeepTogether:
  1.1078 +				if (!old_mask.AttribIsSet(EAttKeepTogether))
  1.1079 +					{
  1.1080 +					new_mask.SetAttrib(EAttKeepTogether);
  1.1081 +					aParaFormat.iKeepTogether=TBool(*ptr);
  1.1082 +					}
  1.1083 +				ptr+=KParaKeepTogether;
  1.1084 +				break;
  1.1085 +			case EAttKeepWithNext:
  1.1086 +				if (!old_mask.AttribIsSet(EAttKeepWithNext))
  1.1087 +					{
  1.1088 +					new_mask.SetAttrib(EAttKeepWithNext);
  1.1089 +					aParaFormat.iKeepWithNext=(TBool)*ptr;
  1.1090 +					}
  1.1091 +				ptr+=KParaKeepWithNext;
  1.1092 +				break;
  1.1093 +			case EAttStartNewPage:
  1.1094 +				if (!old_mask.AttribIsSet(EAttStartNewPage))
  1.1095 +					{
  1.1096 +					new_mask.SetAttrib(EAttStartNewPage);
  1.1097 +					aParaFormat.iStartNewPage=TBool(*ptr);
  1.1098 +					}
  1.1099 +				ptr+=KParaStartNewPage;
  1.1100 +				break;
  1.1101 +			case EAttWidowOrphan:
  1.1102 +				if (!old_mask.AttribIsSet(EAttWidowOrphan))
  1.1103 +					{
  1.1104 +					new_mask.SetAttrib(EAttWidowOrphan);
  1.1105 +					aParaFormat.iWidowOrphan=TBool(*ptr);
  1.1106 +					}
  1.1107 +				ptr+=KParaWidowOrphan;
  1.1108 +				break;
  1.1109 +			case EAttWrap:
  1.1110 +				if (!old_mask.AttribIsSet(EAttWrap))
  1.1111 +					{
  1.1112 +					new_mask.SetAttrib(EAttWrap);
  1.1113 +					aParaFormat.iWrap=TBool(*ptr);
  1.1114 +					}
  1.1115 +				ptr+=KParaWrap;
  1.1116 +				break;
  1.1117 +			case EAttBorderMargin:
  1.1118 +				if (!old_mask.AttribIsSet(EAttBorderMargin))
  1.1119 +					{
  1.1120 +					new_mask.SetAttrib(EAttBorderMargin);
  1.1121 +					aParaFormat.iBorderMarginInTwips = Read32(ptr);
  1.1122 +					}
  1.1123 +				ptr+=KParaBorderMargin;
  1.1124 +				break;
  1.1125 +			case EAttTopBorder:
  1.1126 +				if (aMode==CParaFormat::EFixedAttributes || old_mask.AttribIsSet(EAttTopBorder) )
  1.1127 +					{
  1.1128 +					ptr+=KParaTopBorder;
  1.1129 +					}
  1.1130 +				else
  1.1131 +					{
  1.1132 +					TParaBorder border;
  1.1133 +					ptr=ReadValue(ptr,border);
  1.1134 +					aParaFormat.SetParaBorderL(CParaFormat::EParaBorderTop,border);
  1.1135 +					new_mask.SetAttrib(EAttTopBorder);
  1.1136 +					}
  1.1137 +				break;
  1.1138 +			case EAttBottomBorder:
  1.1139 +				if (aMode==CParaFormat::EFixedAttributes || old_mask.AttribIsSet(EAttBottomBorder))
  1.1140 +					{
  1.1141 +					ptr+=KParaBottomBorder;
  1.1142 +					}
  1.1143 +				else
  1.1144 +					{
  1.1145 +					TParaBorder border;
  1.1146 +					ptr=ReadValue(ptr,border);
  1.1147 +					aParaFormat.SetParaBorderL(CParaFormat::EParaBorderBottom,border);
  1.1148 +					new_mask.SetAttrib(EAttBottomBorder);
  1.1149 +					}
  1.1150 +				break;
  1.1151 +			case EAttLeftBorder:
  1.1152 +				if (aMode==CParaFormat::EFixedAttributes || old_mask.AttribIsSet(EAttLeftBorder))
  1.1153 +					{
  1.1154 +					ptr+=KParaLeftBorder;
  1.1155 +					}
  1.1156 +				else
  1.1157 +					{
  1.1158 +					TParaBorder border;
  1.1159 +					ptr=ReadValue(ptr,border);
  1.1160 +					aParaFormat.SetParaBorderL(CParaFormat::EParaBorderLeft,border);
  1.1161 +					new_mask.SetAttrib(EAttLeftBorder);
  1.1162 +					}
  1.1163 +				break;
  1.1164 +			case EAttRightBorder:
  1.1165 +				if (aMode==CParaFormat::EFixedAttributes || old_mask.AttribIsSet(EAttRightBorder))
  1.1166 +					{
  1.1167 +					ptr+=KParaRightBorder;
  1.1168 +					}
  1.1169 +				else
  1.1170 +					{
  1.1171 +					TParaBorder border;
  1.1172 +					ptr=ReadValue(ptr,border);
  1.1173 +					aParaFormat.SetParaBorderL(CParaFormat::EParaBorderRight,border);
  1.1174 +					new_mask.SetAttrib(EAttRightBorder);
  1.1175 +					}
  1.1176 +				break;
  1.1177 +			case EAttDefaultTabWidth:
  1.1178 +				if (!old_mask.AttribIsSet(EAttDefaultTabWidth))
  1.1179 +					{
  1.1180 +					new_mask.SetAttrib(EAttDefaultTabWidth);
  1.1181 +					aParaFormat.iDefaultTabWidthInTwips = Read32(ptr);
  1.1182 +					}
  1.1183 +				ptr+=KParaDefaultTabWidth;
  1.1184 +				break;
  1.1185 +			case EAttTabStop:
  1.1186 +				{
  1.1187 +				if (aMode==CParaFormat::EFixedAttributes || old_mask.AttribIsSet(EAttTabStop))
  1.1188 +					ptr += KParaTabStop;
  1.1189 +				else
  1.1190 +					{
  1.1191 +					ptr=ReadTabL(ptr,aParaFormat);
  1.1192 +					new_mask.SetAttrib(EAttTabStop);
  1.1193 +					}
  1.1194 +				break;
  1.1195 +				}
  1.1196 +			case EAttBullet:
  1.1197 +				{
  1.1198 +				if (aMode==CParaFormat::EFixedAttributes || old_mask.AttribIsSet(EAttBullet))
  1.1199 +					{
  1.1200 +					ptr+=*ptr+1;  // variable length attribute
  1.1201 +					}
  1.1202 +				else
  1.1203 +					{
  1.1204 +					TBullet* bullet=aParaFormat.iBullet;
  1.1205 +					if (!bullet)
  1.1206 +						aParaFormat.iBullet=bullet=new(ELeave) TBullet;
  1.1207 +					ptr=ReadValue(ptr,*bullet);
  1.1208 +					new_mask.SetAttrib(EAttBullet);
  1.1209 +					//coverity[memory_leak]
  1.1210 +					}
  1.1211 +				break;
  1.1212 +				}
  1.1213 +			case EAttParaLanguage:
  1.1214 +				if (!old_mask.AttribIsSet(EAttParaLanguage))
  1.1215 +					{
  1.1216 +					new_mask.SetAttrib(EAttParaLanguage);
  1.1217 +					aParaFormat.iLanguage=TInt32(*ptr);
  1.1218 +					}
  1.1219 +				ptr+=KParaLanguage;
  1.1220 +				break;
  1.1221 +
  1.1222 +			// Auxiliary attributes for system colours, etc.
  1.1223 +			case EAttFillSystemColor:
  1.1224 +				if (!old_mask.AttribIsSet(EAttFillColor))
  1.1225 +					ReadSystemColor(ptr,aParaFormat.iFillColor);
  1.1226 +				ptr++;
  1.1227 +				break;
  1.1228 +			case EAttBulletSystemColor:
  1.1229 +				if (aMode != CParaFormat::EFixedAttributes && !old_mask.AttribIsSet(EAttBullet) &&
  1.1230 +					aParaFormat.iBullet)
  1.1231 +					ReadSystemColor(ptr,aParaFormat.iBullet->iColor);
  1.1232 +				ptr++;					
  1.1233 +				break;
  1.1234 +			case EAttTopBorderSystemColor:
  1.1235 +				if (aMode != CParaFormat::EFixedAttributes && !old_mask.AttribIsSet(EAttTopBorder))
  1.1236 +					{
  1.1237 +					b = aParaFormat.ParaBorderPtr(CParaFormat::EParaBorderTop);
  1.1238 +					if (b)
  1.1239 +						ReadSystemColor(ptr,b->iColor);
  1.1240 +					}
  1.1241 +				ptr++;
  1.1242 +				break;
  1.1243 +			case EAttBottomBorderSystemColor:
  1.1244 +				if (aMode != CParaFormat::EFixedAttributes && !old_mask.AttribIsSet(EAttBottomBorder))
  1.1245 +					{
  1.1246 +					b = aParaFormat.ParaBorderPtr(CParaFormat::EParaBorderBottom);
  1.1247 +					if (b)
  1.1248 +						ReadSystemColor(ptr,b->iColor);
  1.1249 +					}
  1.1250 +				ptr++;
  1.1251 +				break;
  1.1252 +			case EAttLeftBorderSystemColor:
  1.1253 +				if (aMode != CParaFormat::EFixedAttributes && !old_mask.AttribIsSet(EAttLeftBorder))
  1.1254 +					{
  1.1255 +					b = aParaFormat.ParaBorderPtr(CParaFormat::EParaBorderLeft);
  1.1256 +					if (b)
  1.1257 +						ReadSystemColor(ptr,b->iColor);
  1.1258 +					}
  1.1259 +				ptr++;
  1.1260 +				break;
  1.1261 +			case EAttRightBorderSystemColor:
  1.1262 +				if (aMode != CParaFormat::EFixedAttributes && !old_mask.AttribIsSet(EAttRightBorder))
  1.1263 +					{
  1.1264 +					b = aParaFormat.ParaBorderPtr(CParaFormat::EParaBorderRight);
  1.1265 +					if (b)
  1.1266 +						ReadSystemColor(ptr,b->iColor);
  1.1267 +					}
  1.1268 +				ptr++;
  1.1269 +				break;
  1.1270 +			case EAttParaLanguageX:
  1.1271 +				if (!old_mask.AttribIsSet(EAttParaLanguage))
  1.1272 +					{
  1.1273 +					new_mask.SetAttrib(EAttParaLanguage);
  1.1274 +					aParaFormat.iLanguage = Read32(ptr);
  1.1275 +					}
  1.1276 +				ptr += KParaLanguageX;
  1.1277 +				break;
  1.1278 +			case EAttBulletX:
  1.1279 +				if (aMode == CParaFormat::EFixedAttributes || old_mask.AttribIsSet(EAttBullet) ||
  1.1280 +					!aParaFormat.iBullet)
  1.1281 +					ptr += KParaBulletX;
  1.1282 +				else
  1.1283 +					{
  1.1284 +					aParaFormat.iBullet->iStyle = (TBullet::TStyle)(*ptr++);
  1.1285 +					aParaFormat.iBullet->iStartNumber = Read32(ptr);
  1.1286 +					ptr += sizeof(TInt32);
  1.1287 +					aParaFormat.iBullet->iAlignment = (TBullet::TAlignment)(*ptr++);
  1.1288 +					}
  1.1289 +				break;
  1.1290 +
  1.1291 +			default:  // have maybe read an attribute defined by a later version; stop here
  1.1292 +				aMask = new_mask;
  1.1293 +				return;
  1.1294 +			}
  1.1295 +		}
  1.1296 +	aMask = new_mask;
  1.1297 +	}
  1.1298 +
  1.1299 +/*
  1.1300 +Extract format attributes selected by cleared bits in aMask.
  1.1301 +Put them into aCharFormatX if the corresponding bit in aMask is NOT set, and set the bit.
  1.1302 +*/
  1.1303 +void RFormatStream::SenseCharFormat(TCharFormatX& aCharFormat,TCharFormatXMask& aMask) const
  1.1304 +	{
  1.1305 +	__TEST_INVARIANT;
  1.1306 +
  1.1307 +	TUint8* ptr = iBase;
  1.1308 +	if (ptr == NULL)
  1.1309 +		return;
  1.1310 +	TCharFormatXMask old_mask = aMask;
  1.1311 +	TCharFormatXMask new_mask = aMask;
  1.1312 +	TUint8* end = iEnd;
  1.1313 +	TCharFormat& format = aCharFormat.iCharFormat;
  1.1314 +
  1.1315 +	while (ptr<end)
  1.1316 +		{
  1.1317 +		TUint8 type = *ptr;
  1.1318 +		ptr+=KTypeSize;
  1.1319 +		switch (type)
  1.1320 +			{
  1.1321 +			case EAttColor:
  1.1322 +				if (!old_mask.AttribIsSet(EAttColor))
  1.1323 +					{
  1.1324 +					new_mask.SetAttrib(EAttColor);
  1.1325 +					ptr=ReadValue(ptr,format.iFontPresentation.iTextColor);
  1.1326 +					}
  1.1327 +				else
  1.1328 +					ptr+=KCharColor;
  1.1329 +				break;
  1.1330 +			case EAttFontHighlightColor:
  1.1331 +				if (!old_mask.AttribIsSet(EAttFontHighlightColor))
  1.1332 +					{
  1.1333 +					new_mask.SetAttrib(EAttFontHighlightColor);
  1.1334 +					ptr=ReadValue(ptr,format.iFontPresentation.iHighlightColor);
  1.1335 +					}
  1.1336 +				else
  1.1337 +					ptr+=KCharHighlightColor;
  1.1338 +				break;
  1.1339 +			case EAttFontHighlightStyle:
  1.1340 +				if (!old_mask.AttribIsSet(EAttFontHighlightStyle))
  1.1341 +					{
  1.1342 +					new_mask.SetAttrib(EAttFontHighlightStyle);
  1.1343 +					format.iFontPresentation.iHighlightStyle=(TFontPresentation::TFontHighlightStyle)*ptr;
  1.1344 +					}
  1.1345 +				ptr+=KCharHighlightStyle;
  1.1346 +				break;
  1.1347 +			case EAttFontStrikethrough:
  1.1348 +				if (!old_mask.AttribIsSet(EAttFontStrikethrough))
  1.1349 +					{
  1.1350 +					new_mask.SetAttrib(EAttFontStrikethrough);
  1.1351 +					format.iFontPresentation.iStrikethrough=(TFontStrikethrough)*ptr;
  1.1352 +					}
  1.1353 +				ptr+=KCharStrikethrough;
  1.1354 +				break;
  1.1355 +			case EAttFontUnderline:
  1.1356 +				if (!old_mask.AttribIsSet(EAttFontUnderline))
  1.1357 +					{
  1.1358 +					new_mask.SetAttrib(EAttFontUnderline);
  1.1359 +					format.iFontPresentation.iUnderline=(TFontUnderline)*ptr;
  1.1360 +					}
  1.1361 +				ptr+=KCharUnderline;
  1.1362 +				break;
  1.1363 +			case EAttFontHeight:
  1.1364 +				if (!old_mask.AttribIsSet(EAttFontHeight))
  1.1365 +					{
  1.1366 +					new_mask.SetAttrib(EAttFontHeight);
  1.1367 +					format.iFontSpec.iHeight = Read32(ptr);
  1.1368 +					}
  1.1369 +				ptr+=KCharFontHeight;
  1.1370 +				break;
  1.1371 +			case EAttFontPosture:
  1.1372 +				if (!old_mask.AttribIsSet(EAttFontPosture))
  1.1373 +					{
  1.1374 +					new_mask.SetAttrib(EAttFontPosture);
  1.1375 +					format.iFontSpec.iFontStyle.SetPosture((TFontPosture)*ptr);
  1.1376 +					}
  1.1377 +				ptr+=KCharPosture;
  1.1378 +				break;
  1.1379 +			case EAttFontStrokeWeight:
  1.1380 +				if (!old_mask.AttribIsSet(EAttFontStrokeWeight))
  1.1381 +					{
  1.1382 +					new_mask.SetAttrib(EAttFontStrokeWeight);
  1.1383 +					format.iFontSpec.iFontStyle.SetStrokeWeight((TFontStrokeWeight)*ptr);
  1.1384 +					}
  1.1385 +				ptr+=KCharStrokeWeight;
  1.1386 +				break;
  1.1387 +			case EAttFontPrintPos:
  1.1388 +				if (!old_mask.AttribIsSet(EAttFontPrintPos))
  1.1389 +					{
  1.1390 +					new_mask.SetAttrib(EAttFontPrintPos);
  1.1391 +					format.iFontSpec.iFontStyle.SetPrintPosition((TFontPrintPosition)*ptr);
  1.1392 +					}
  1.1393 +				ptr+=KCharPrintPos;
  1.1394 +				break;
  1.1395 +			case EAttFontTypeface:
  1.1396 +				if (!old_mask.AttribIsSet(EAttFontTypeface))
  1.1397 +					{
  1.1398 +					new_mask.SetAttrib(EAttFontTypeface);
  1.1399 +					ptr=ReadValue(ptr,format.iFontSpec.iTypeface);  // updates ptr
  1.1400 +					}
  1.1401 +				else
  1.1402 +					ptr+=*ptr+1;	// variable length attribute
  1.1403 +				break;
  1.1404 +			case EAttBitmapType:
  1.1405 +				if (!old_mask.AttribIsSet(EAttFontTypeface))
  1.1406 +					{
  1.1407 +					format.iFontSpec.iFontStyle.SetBitmapType(static_cast <TGlyphBitmapType> (*ptr));
  1.1408 +					}
  1.1409 +				ptr+=KBitmapType;
  1.1410 +				break;
  1.1411 +			case EAttCharLanguage:
  1.1412 +				if (!old_mask.AttribIsSet(EAttCharLanguage))
  1.1413 +					{
  1.1414 +					new_mask.SetAttrib(EAttCharLanguage);
  1.1415 +					format.iLanguage=*ptr;
  1.1416 +					}
  1.1417 +				ptr+=KCharLanguage;
  1.1418 +				break;
  1.1419 +			case EAttFontHiddenText:
  1.1420 +				if (!old_mask.AttribIsSet(EAttFontHiddenText))
  1.1421 +					{
  1.1422 +					new_mask.SetAttrib(EAttFontHiddenText);
  1.1423 +					format.iFontPresentation.iHiddenText=(TBool)*ptr;
  1.1424 +					}
  1.1425 +				ptr+=KCharHiddenText;
  1.1426 +				break;
  1.1427 +			case EAttFontPictureAlignment:
  1.1428 +				if (!old_mask.AttribIsSet(EAttFontPictureAlignment))
  1.1429 +					{
  1.1430 +					new_mask.SetAttrib(EAttFontPictureAlignment);
  1.1431 +					format.iFontPresentation.iPictureAlignment=(TFontPresentation::TAlignment)*ptr;
  1.1432 +					}
  1.1433 +				ptr+=KCharPictureAlignment;
  1.1434 +				break;
  1.1435 +
  1.1436 +			// Auxiliary attributes for system colours, etc.
  1.1437 +			case EAttTextSystemColor:
  1.1438 +				if (!old_mask.AttribIsSet(EAttColor))
  1.1439 +					ReadSystemColor(ptr,format.iFontPresentation.iTextColor);
  1.1440 +				ptr++;
  1.1441 +				break;
  1.1442 +
  1.1443 +			case EAttFontHighlightSystemColor:
  1.1444 +				if (!old_mask.AttribIsSet(EAttFontHighlightColor))
  1.1445 +					ReadSystemColor(ptr,format.iFontPresentation.iHighlightColor);
  1.1446 +				ptr++;
  1.1447 +				break;
  1.1448 +
  1.1449 +			case EAttCharLanguageX:
  1.1450 +				if (!old_mask.AttribIsSet(EAttCharLanguage))
  1.1451 +					{
  1.1452 +					new_mask.SetAttrib(EAttCharLanguage);
  1.1453 +					format.iLanguage = Read32(ptr);
  1.1454 +					}
  1.1455 +				ptr += KCharLanguageX;
  1.1456 +				break;
  1.1457 +
  1.1458 +			// Internal character attributes:
  1.1459 +			case EAttParserTag:
  1.1460 +				if (!old_mask.AttribIsSet(EAttParserTag))
  1.1461 +					{
  1.1462 +					new_mask.SetAttrib(EAttParserTag);
  1.1463 +					aCharFormat.iParserTag = Read32(ptr);
  1.1464 +					}
  1.1465 +				ptr += KCharParserTag;
  1.1466 +				break;
  1.1467 +
  1.1468 +			default:	// have maybe read an attribute defined by a later version; stop here
  1.1469 +				aMask = new_mask;
  1.1470 +				return;
  1.1471 +			}
  1.1472 +		}
  1.1473 +	aMask = new_mask;
  1.1474 +	}
  1.1475 +
  1.1476 +/** Swaps the contents of this stream with aStream.
  1.1477 +@param aStream Object to swap contents with. */
  1.1478 +void RFormatStream::Swap(RFormatStream& aStream)
  1.1479 +	{
  1.1480 +	TUint8* t = iBase;
  1.1481 +	iBase = aStream.iBase;
  1.1482 +	aStream.iBase = t;
  1.1483 +	t = iEnd;
  1.1484 +	iEnd = aStream.iEnd;
  1.1485 +	aStream.iEnd = t;
  1.1486 +	}
  1.1487 +
  1.1488 +TInt RFormatStream::StoreTabs(TUint8*& aPtr,const CParaFormat& aDesiredFormat,const CParaFormat& aCurrentFormat,TBool aStoreData)
  1.1489 +// Merges the tabs from the desired paraFormat with those from the current effective paraFormat, resolving differences
  1.1490 +// as described below, and store the resultant tablist in this layer.
  1.1491 +// If aStoreData is false, then return the number of bytes necessary to store all required tabs
  1.1492 +//
  1.1493 +	{
  1.1494 +	TInt requiredTabCount=0;
  1.1495 +	TInt desiredTabCount=aDesiredFormat.TabCount();
  1.1496 +	TInt currentTabCount=aCurrentFormat.TabCount();
  1.1497 +	if (desiredTabCount==0 && currentTabCount==0)
  1.1498 +		{// Nothing needs to be stored.
  1.1499 +		return requiredTabCount;
  1.1500 +		}
  1.1501 +	if (desiredTabCount>0 && currentTabCount>0)
  1.1502 +		{// The 2 tab lists need merging.
  1.1503 +		requiredTabCount=MergeTabLists(aPtr,aDesiredFormat,desiredTabCount,aCurrentFormat,currentTabCount,aStoreData);
  1.1504 +		}
  1.1505 +	else if (desiredTabCount>0 && currentTabCount==0)
  1.1506 +			{// There are no previous tabs to merge so just store all the desired ones.
  1.1507 +			if (aStoreData)
  1.1508 +				StoreAllTabs(aPtr,aDesiredFormat);
  1.1509 +			else
  1.1510 +				requiredTabCount+=desiredTabCount;
  1.1511 +			}
  1.1512 +		else if (desiredTabCount==0 && currentTabCount>0)
  1.1513 +				{// We want to delete (NULL) all existing tabs.
  1.1514 +				if (aStoreData)
  1.1515 +					{
  1.1516 +					for (TInt index=0;index<currentTabCount;index++)
  1.1517 +						{
  1.1518 +						TTabStop tab=aCurrentFormat.TabStop(index);
  1.1519 +						tab.iType=TTabStop::ENullTab;
  1.1520 +						StoreTab(aPtr,tab);
  1.1521 +						}
  1.1522 +					}
  1.1523 +				else requiredTabCount+=currentTabCount;
  1.1524 +				}
  1.1525 +	return requiredTabCount*(KTypeSize+KParaTabStop);
  1.1526 +	}
  1.1527 +
  1.1528 +
  1.1529 +TInt RFormatStream::MergeTabLists(TUint8*& aPtr,const CParaFormat& aDesiredFormat,TInt aDesiredTabCount,
  1.1530 +								  const CParaFormat& aCurrentFormat,TInt aCurrentTabCount,TBool aStoreData)
  1.1531 +// Compares the desired tablist (from a dialog interaction) with that of the current tablist.
  1.1532 +// The resulting tab stop is stored if aStoreData is TRUE.
  1.1533 +// There may be 2 tabs for any for any given tabstops.
  1.1534 +// The possible results of the comparison are:
  1.1535 +// (1) Tab is in desired but not current --> Store the desired tab.
  1.1536 +// (2) Tab is in current but not desired --> Null the current and store.
  1.1537 +// (3) Tab is in both current and desired -->
  1.1538 +//			(i) if tab type is the same then store nothing -- rely on the base one being inherited.
  1.1539 +//			(ii)if tab type is not same then store the current -- overriding whatevers in the base.
  1.1540 +//
  1.1541 +	{
  1.1542 +	TInt requiredTabCount=0;
  1.1543 +	TInt offsetInDesired,offsetInCurrent;
  1.1544 +	offsetInDesired=offsetInCurrent=0;
  1.1545 +	TTabStop desiredTab,currentTab;
  1.1546 +	while ((offsetInDesired!=aDesiredTabCount) && (offsetInCurrent!=aCurrentTabCount))
  1.1547 +		{// Do this until we exhaust one of the tab lists.
  1.1548 +		desiredTab=aDesiredFormat.TabStop(offsetInDesired);
  1.1549 +		currentTab=aCurrentFormat.TabStop(offsetInCurrent);
  1.1550 +		if (desiredTab.iTwipsPosition<currentTab.iTwipsPosition)
  1.1551 +			{
  1.1552 +			if (aStoreData)
  1.1553 +				aPtr=StoreTab(aPtr,desiredTab);  // Store desiredTab.
  1.1554 +			else 
  1.1555 +				requiredTabCount++;
  1.1556 +			offsetInDesired++;  // Move to the next tab in the desired tablist.
  1.1557 +			continue;
  1.1558 +			}
  1.1559 +		if (desiredTab.iTwipsPosition>currentTab.iTwipsPosition)
  1.1560 +			{
  1.1561 +			if (aStoreData)
  1.1562 +				{
  1.1563 +				currentTab.iType=TTabStop::ENullTab;  // Null the current current tab.
  1.1564 +				aPtr=StoreTab(aPtr,currentTab);  // Store NULL'd currentTab
  1.1565 +				}
  1.1566 +			else
  1.1567 +				requiredTabCount++;
  1.1568 +			offsetInCurrent++;  // Move to the next tab in the current tablist.
  1.1569 +			continue;
  1.1570 +			}
  1.1571 +		if (desiredTab.iTwipsPosition==currentTab.iTwipsPosition)
  1.1572 +			{
  1.1573 +			if (desiredTab.iType!=currentTab.iType)
  1.1574 +				{// Store desired type to override the one from the lower layer.
  1.1575 +				if (aStoreData)
  1.1576 +					aPtr=StoreTab(aPtr,desiredTab);
  1.1577 +				else
  1.1578 +					requiredTabCount++;
  1.1579 +				}// Otherwise rely on the one in the base - store nothing but increment.
  1.1580 +			offsetInDesired++;
  1.1581 +			offsetInCurrent++;
  1.1582 +			continue;
  1.1583 +			}
  1.1584 +		}
  1.1585 +	TInt currentLeftToDo=aCurrentTabCount-offsetInCurrent;
  1.1586 +	TInt desiredLeftToDo=aDesiredTabCount-offsetInDesired;
  1.1587 +	// Spot which list is exhausted and process the rest of the remainder appropriately.
  1.1588 +	if (currentLeftToDo)
  1.1589 +		{// Store null'd remainder of current tab list.
  1.1590 +		for (;offsetInCurrent<aCurrentTabCount;offsetInCurrent++)
  1.1591 +			{
  1.1592 +			if (aStoreData)
  1.1593 +				{
  1.1594 +				currentTab=aCurrentFormat.TabStop(offsetInCurrent);
  1.1595 +				currentTab.iType=TTabStop::ENullTab;  // Null the current current tab.
  1.1596 +				aPtr=StoreTab(aPtr,currentTab);  // Store NULL'd currentTab
  1.1597 +				}
  1.1598 +			else
  1.1599 +				requiredTabCount++;
  1.1600 +			}
  1.1601 +		}
  1.1602 +	if (desiredLeftToDo)
  1.1603 +		{// Store remainder of desired tab list.
  1.1604 +		for (;offsetInDesired<aDesiredTabCount;offsetInDesired++)
  1.1605 +			{
  1.1606 +			if (aStoreData)
  1.1607 +				aPtr=StoreTab(aPtr,aDesiredFormat.TabStop(offsetInDesired));
  1.1608 +			else
  1.1609 +				requiredTabCount++;
  1.1610 +			}
  1.1611 +		}
  1.1612 +// ASSERT: The tabList offsets are as we would expect in a normal (correct) completion.	
  1.1613 +	if (offsetInDesired!=aDesiredTabCount)
  1.1614 +	    {
  1.1615 +	    OstTrace0( TRACE_FATAL, RFORMATSTREAM_MERGETABLISTS, "EStoreTabError" );
  1.1616 +	    }
  1.1617 +	__ASSERT_ALWAYS(offsetInDesired==aDesiredTabCount,Panic(EStoreTabError));
  1.1618 +	if (offsetInCurrent!=aCurrentTabCount)
  1.1619 +	    {
  1.1620 +	    OstTrace0( TRACE_FATAL, DUP1_RFORMATSTREAM_MERGETABLISTS, "EStoreTabError" );
  1.1621 +	    }
  1.1622 +	__ASSERT_ALWAYS(offsetInCurrent==aCurrentTabCount,Panic(EStoreTabError));
  1.1623 +	return requiredTabCount;
  1.1624 +	}
  1.1625 +
  1.1626 +
  1.1627 +// Writes all tabs from aSource.
  1.1628 +void RFormatStream::StoreAllTabs(TUint8*& aPtr,const CParaFormat& aSource)
  1.1629 +	{
  1.1630 +	int tabs = aSource.TabCount();
  1.1631 +	for (TInt index = 0;index < tabs; index++)
  1.1632 +		aPtr = StoreTab(aPtr,TTabStop(aSource.TabStop(index)));
  1.1633 +	}
  1.1634 +
  1.1635 +
  1.1636 +TUint8* RFormatStream::StoreBullet(TUint8* aPtr,const TBullet& aBullet)
  1.1637 +	{
  1.1638 +	// Write the attribute code and leave a gap for the length.
  1.1639 +	*aPtr++ = TUint8(EAttBullet);
  1.1640 +	TUint8* length_ptr = aPtr++;
  1.1641 +
  1.1642 +	// Store the font height.
  1.1643 +	Write32(aPtr,aBullet.iHeightInTwips);
  1.1644 +
  1.1645 +	// Store the bullet character code.
  1.1646 +	aPtr[0] = (TUint8)(aBullet.iCharacterCode);
  1.1647 +	aPtr[1] = (TUint8)(aBullet.iCharacterCode >> 8);
  1.1648 +	aPtr += sizeof(TText);
  1.1649 +
  1.1650 +	// Store the hanging indent
  1.1651 +	*aPtr++ = TUint8(aBullet.iHangingIndent != FALSE);
  1.1652 +
  1.1653 +	// Store the colour.
  1.1654 +	aPtr = Store(aPtr,aBullet.iColor);
  1.1655 +
  1.1656 +	// Store the typeface
  1.1657 +	aPtr = Store(aPtr,aBullet.iTypeface);
  1.1658 +
  1.1659 +	// Store the number of data bytes stored.
  1.1660 +	*length_ptr = (TUint8)(aPtr - length_ptr - 1);
  1.1661 +
  1.1662 +	return aPtr;
  1.1663 +	}
  1.1664 +
  1.1665 +
  1.1666 +TUint8* RFormatStream::StoreBorder(TUint8* aPtr,TTextFormatAttribute aType,const TParaBorder& aSource)
  1.1667 +// Stores paragraph border attributes.
  1.1668 +// Writes the line style, thickness,autoColor flag
  1.1669 +// and Color, from aSource to the end of the format stream.
  1.1670 +// aType is converted from an enum to a TUint8 as it is stored in the format stream.
  1.1671 +//
  1.1672 +	{
  1.1673 +	*aPtr++=TUint8(aType);
  1.1674 +	// border line style
  1.1675 +	*aPtr++=TUint8(aSource.iLineStyle);
  1.1676 +	// border line thickness
  1.1677 +	Write32(aPtr,aSource.iThickness);
  1.1678 +	// border color
  1.1679 +	aPtr=Store(aPtr,aSource.iColor);
  1.1680 +	// border autocolor
  1.1681 +	*aPtr++=TUint8(aSource.iAutoColor!=EFalse);
  1.1682 +	return aPtr;
  1.1683 +	}
  1.1684 +
  1.1685 +
  1.1686 +TUint8* RFormatStream::StoreTab(TUint8* aPtr,const TTabStop& aSource)
  1.1687 +// Stores a tabstop compound attribute at the end of the stream.
  1.1688 +// Writes the tabstop twips position and the tab type, from aSource, to the end of the format stream.
  1.1689 +// aType is converted from an enum to a TUint8 as it is stored in the format stream.
  1.1690 +// The tab type is compressed from a TTabType enum to a TUint8.
  1.1691 +// Uses InsertL, which may cause expansion of the stream storage, and thus may fail.
  1.1692 +//
  1.1693 +	{
  1.1694 +	*aPtr++=TUint8(EAttTabStop);
  1.1695 +	// Store tab poisition.
  1.1696 +	Write32(aPtr,aSource.iTwipsPosition);
  1.1697 +	// Compress the tab type.
  1.1698 +	*aPtr++=TUint8(aSource.iType);
  1.1699 +	return aPtr;
  1.1700 +	}
  1.1701 +
  1.1702 +
  1.1703 +TUint8* RFormatStream::Store(TUint8* aPtr,const TLogicalRgb& aRgb)
  1.1704 +   // Store color value
  1.1705 +   //
  1.1706 +   	{
  1.1707 +	*aPtr++=TUint8(aRgb.Red());
  1.1708 +	*aPtr++=TUint8(aRgb.Green());
  1.1709 +	*aPtr++=TUint8(aRgb.Blue());
  1.1710 +	return aPtr;
  1.1711 +   	}
  1.1712 +
  1.1713 +
  1.1714 +TUint8* RFormatStream::Store(TUint8* aPtr,const TTypeface& aTypeface)
  1.1715 +// Stores typeface name and flags.
  1.1716 +//
  1.1717 +	{
  1.1718 +	//
  1.1719 +	// Store typeface name size
  1.1720 +	TUint8 length=TUint8(aTypeface.iName.Size());
  1.1721 +	length+=KTypefaceFlags;
  1.1722 +	*aPtr++=length;  // byte count.
  1.1723 +	//
  1.1724 +	// Store typeface name
  1.1725 +	aPtr=Mem::Copy(aPtr,aTypeface.iName.Ptr(),length-KTypefaceFlags);
  1.1726 +	//
  1.1727 +	// Store typeface flags
  1.1728 +	TUint8 flags=0;
  1.1729 +	if (aTypeface.IsProportional())
  1.1730 +		flags|=KFontProportional;
  1.1731 +	if (aTypeface.IsSerif())
  1.1732 +		flags|=KFontSerif;	
  1.1733 +	if (aTypeface.IsSymbol())
  1.1734 +		flags|=KFontSymbol;
  1.1735 +	*aPtr=flags;
  1.1736 +	aPtr+=KTypefaceFlags;
  1.1737 +	//
  1.1738 +	return aPtr;
  1.1739 +	}
  1.1740 +
  1.1741 +TUint8* RFormatStream::ReadValue(TUint8* aPtr,TLogicalRgb& aRgb)const
  1.1742 +// Reads a color value from storage.
  1.1743 +//
  1.1744 +	{
  1.1745 +	aRgb.SetRed(*aPtr++);
  1.1746 +	aRgb.SetGreen(*aPtr++);
  1.1747 +	aRgb.SetBlue(*aPtr++);
  1.1748 +	aRgb.SetSystemColorIndex(0);
  1.1749 +	return aPtr;
  1.1750 +	}
  1.1751 +
  1.1752 +
  1.1753 +TUint8* RFormatStream::ReadValue(TUint8* aPtr,TParaBorder& aBorder)const
  1.1754 +// Reads a paragraph border from storage.
  1.1755 +//
  1.1756 +	{
  1.1757 +	// Read line style
  1.1758 +	aBorder.iLineStyle=TParaBorder::TLineStyle(*aPtr++);
  1.1759 +	// Read thickness
  1.1760 +	aBorder.iThickness = Read32(aPtr);
  1.1761 +	aPtr+=sizeof(TInt32);
  1.1762 +	// Read color
  1.1763 +	aPtr=ReadValue(aPtr,aBorder.iColor);  // returns aPtr
  1.1764 +	// Read autocolor
  1.1765 +	aBorder.iAutoColor=TBool(*aPtr++);
  1.1766 +	return aPtr;
  1.1767 +	}
  1.1768 +
  1.1769 +
  1.1770 +TUint8* RFormatStream::ReadValue(TUint8* aPtr,TBullet& aBullet)const
  1.1771 +// Read the bullet compound attribute.
  1.1772 +//
  1.1773 +	{
  1.1774 +	// Read the length of this bullet attribute
  1.1775 +	aPtr++;  // length not used in this context, skip it
  1.1776 +	// Read bullet twips height into target
  1.1777 +	aBullet.iHeightInTwips = Read32(aPtr);
  1.1778 +	aPtr+=sizeof(TInt32);
  1.1779 +	// Read bullet character code into target.
  1.1780 +	aBullet.iCharacterCode = (TText)aPtr[0] | ((TText)aPtr[1] << 8);
  1.1781 +	aPtr+=sizeof(TText);
  1.1782 +	// Read hanging indent.
  1.1783 +	aBullet.iHangingIndent=TBool(*aPtr++);
  1.1784 +	// Read Color.
  1.1785 +	aPtr=ReadValue(aPtr,aBullet.iColor);  // returns aPtr
  1.1786 +	// Read typeface
  1.1787 +	return ReadValue(aPtr,aBullet.iTypeface);  // returns aPtr
  1.1788 +	}
  1.1789 +
  1.1790 +
  1.1791 +TUint8* RFormatStream::ReadValue(TUint8* aPtr,TTypeface& aTypeface)const
  1.1792 +// Read a typeface name from storage and associated flags.
  1.1793 +//
  1.1794 +	{
  1.1795 +	//
  1.1796 +	// Read typeface name size
  1.1797 +	TInt length=*aPtr++;
  1.1798 +	//
  1.1799 +	// Read typeface name
  1.1800 +	TInt typefaceLength=length-KTypefaceFlags;
  1.1801 +	
  1.1802 +	if ((typefaceLength%2)!=0)
  1.1803 +	    {
  1.1804 +	    OstTrace0( TRACE_DUMP, RFORMATSTREAM_READVALUE, "ECorruptFormatLayer" );
  1.1805 +	    }
  1.1806 +	__ASSERT_DEBUG((typefaceLength%2)==0,Panic(ECorruptFormatLayer)); // must be an even number
  1.1807 +
  1.1808 +	TPtr name=aTypeface.iName.Des();
  1.1809 +	Mem::Copy(CONST_CAST(TText*,name.Ptr()),aPtr,typefaceLength);
  1.1810 +	typefaceLength>>=1;
  1.1811 +	name.SetLength(typefaceLength);
  1.1812 +
  1.1813 +	aPtr+=length-KTypefaceFlags;
  1.1814 +	//
  1.1815 +	// Read typeface name flags
  1.1816 +	TInt attrib=0;
  1.1817 +	TUint flags=*aPtr;
  1.1818 +	if (flags & KFontProportional)
  1.1819 +		attrib|=TTypeface::EProportional;
  1.1820 +	if (flags & KFontSerif)
  1.1821 +		attrib|=TTypeface::ESerif;
  1.1822 +	if (flags & KFontSymbol)
  1.1823 +		attrib|=TTypeface::ESymbol;
  1.1824 +	aTypeface.SetAttributes(attrib);  // reset the attributes
  1.1825 +	return aPtr+KTypefaceFlags;
  1.1826 +	}
  1.1827 +
  1.1828 +
  1.1829 +TUint8* RFormatStream::ReadTabL(TUint8* aPtr,CParaFormat& aTarget)const
  1.1830 +// Read the tab stop data from the stream, located at aPos, into 
  1.1831 +// a temporary TTabStop, and use this to fill in aTarget.
  1.1832 +// Does not read the tab if one already exists at the same twips position.
  1.1833 +// (Implementation of tab inheritance policy).
  1.1834 +// aPos is updated manually, rather than using Length(), since this is
  1.1835 +// a compound attribute.
  1.1836 +//
  1.1837 +	{
  1.1838 +	TTabStop tab;
  1.1839 +	// Read tab position
  1.1840 +	tab.iTwipsPosition = Read32(aPtr);
  1.1841 +	aPtr+=sizeof(TInt32);
  1.1842 +	// Read tab type
  1.1843 +	tab.iType=TTabStop::TTabType(*aPtr++);
  1.1844 +	// Set this tab in the paragraph format
  1.1845 +	TInt ret=aTarget.LocateTab(tab.iTwipsPosition);		// is this necessary
  1.1846 +	if (ret==KTabNotFound)
  1.1847 +		aTarget.StoreTabL(tab);
  1.1848 +	return aPtr;
  1.1849 +	}
  1.1850 +
  1.1851 +
  1.1852 +TInt RFormatStream::Length(TUint8*& aPtr,TTextFormatAttribute aType) const
  1.1853 +// Returns the length of a Type's value
  1.1854 +// A length of zero in the lookup table, indicates a variable
  1.1855 +// length value.  In this case, the length is stored in the byte
  1.1856 +// following the type, which is read and returned.
  1.1857 +// aPtr is incremented by the appropriate amount following a read.
  1.1858 +//
  1.1859 +	{
  1.1860 +	TInt length=TheAttributeLength[aType];
  1.1861 +
  1.1862 +	if (length<0)
  1.1863 +	    {
  1.1864 +	    OstTrace0( TRACE_DUMP, RFORMATSTREAM_LENGTH, "EAttributeLengthLookupNegative" );
  1.1865 +	    }
  1.1866 +	__ASSERT_DEBUG(length>=0,Panic(EAttributeLengthLookupNegative));
  1.1867 +	if (length>0)
  1.1868 +		return length;
  1.1869 +	else
  1.1870 +		return *aPtr++;
  1.1871 +	}