--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textrendering/texthandling/ttext/T_CONVS.CPP Fri Jun 04 10:37:54 2010 +0100
@@ -0,0 +1,828 @@
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <txtetext.h>
+#include <txtglobl.h>
+#include <txtfmlyr.h>
+#include <s32mem.h>
+#include <s32file.h>
+#include <e32test.h>
+#include <fldbase.h>
+#include <fldbltin.h>
+#include <flddef.h>
+
+const TInt KTestCleanupStack=0x20;
+const TInt KTestExpandSize=0x20;
+
+LOCAL_D CTrapCleanup* TheTrapCleanup;
+LOCAL_D RTest test(_L("T_CONVS - EditableText Persistence"));
+LOCAL_D TPtrC bigBuf(_L("This is a very big buffer indeed, containing text and special characters,\
+ big enough to fill a segment of an editable text component that employs segmented storage"));
+
+////////////////////////////////////////////////////////////////////////////////////////////
+class TTestFieldFactory : public MTextFieldFactory
+ {
+public:
+ // from MTextFieldFactory
+ virtual CTextField* NewFieldL(TUid aFieldType);
+ // Creates a field of the type specified
+ // Returns NULL if it does not recognise/support the field type
+ };
+
+CTextField* TTestFieldFactory::NewFieldL(TUid aFieldType)
+// Creates a field (in aHeader) of the type specified in aHeader
+//
+ {
+ CTextField* field=NULL;
+ if (aFieldType==KDateTimeFieldUid)
+ field = (CTextField*)new(ELeave) CDateTimeField();
+ return field;
+ }
+/////////////////////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+void testCopy(T &aCopy,const T &anOriginal)
+//
+// Copy anOriginal to aCopy using memory-based streams.
+//
+ {
+ CBufSeg *buf=CBufSeg::NewL(KTestExpandSize);
+ if (buf==NULL)
+ test.Panic(_L("Allocating buffer"));
+
+// Write anOriginal out to the buffer.
+ RBufWriteStream out(*buf);
+ TRAPD(r,out<<anOriginal);
+ test(r==KErrNone);
+ TRAP(r,out.CommitL());
+ if (r!=KErrNone)
+ test.Panic(_L("Committing write stream"));
+
+// Read anOriginal in from the buffer.
+ RBufReadStream in(*buf);
+ TRAP(r,in>>aCopy);
+ test(r==KErrNone);
+
+// See if it's consumed the lot.
+ TRAP(r,in.ReadUint8L());
+ test(r==KErrEof);
+//
+ delete buf;
+ }
+
+_LIT(KOutputFile, "c:\\etext\\t_convs.tst");
+template <class T>
+void testStoreRestoreL(T& aCopy,const T& aOriginal)
+// Test document persistance.
+//
+ {
+ // set up the store
+ RFs theFs;
+ theFs.Connect();
+ //
+ theFs.Delete(KOutputFile);
+ theFs.MkDirAll(KOutputFile);
+ CFileStore* theStore=CDirectFileStore::CreateL(theFs,KOutputFile,EFileRead|EFileWrite);
+ CleanupStack::PushL(theStore);
+ theStore->SetTypeL(KDirectFileStoreLayoutUid);
+ //
+ // store the original
+ TStreamId id(0);
+ TRAPD(ret,id=aOriginal.StoreL(*theStore));
+ test(ret==KErrNone);
+ //
+ // restore into the copy
+ TRAP(ret,aCopy.RestoreL(*theStore,id));
+ test(ret==KErrNone);
+ //
+ // tidy up
+ CleanupStack::PopAndDestroy(); // theStore
+ theFs.Close();
+ }
+
+
+template <class T>
+void testCopyChain(T &aCopy,const T &anOriginal,TInt aExcludeCount,const CFormatLayer* aBase)
+//
+// Copy anOriginal to aCopy using memory-based streams.
+//
+ {
+ CBufSeg *buf=CBufSeg::NewL(KTestExpandSize);
+ if (buf==NULL)
+ test.Panic(_L("Allocating buffer"));
+
+// Write anOriginal out to the buffer.
+ RBufWriteStream out(*buf);
+ TRAPD(r,anOriginal.ExternalizeChainL(out,aExcludeCount));
+ test(r==KErrNone);
+ TRAP(r,out.CommitL());
+ if (r!=KErrNone)
+ test.Panic(_L("Committing write stream"));
+
+// Read anOriginal in from the buffer.
+ RBufReadStream in(*buf);
+ TRAP(r,aCopy.InternalizeChainL(in,aBase));
+ test(r==KErrNone);
+
+// See if it's consumed the lot.
+ TRAP(r,in.ReadUint8L());
+ test(r!=KErrNone);
+//
+ delete buf;
+ }
+
+
+LOCAL_C TInt IsEqual(const CPlainText* aCopy,const CPlainText* aOriginal)
+//
+// Returns true if aCopy contents matches aOriginal contents.
+// Takes account of multiple segments of a segmented text component.
+//
+ {
+ TInt lengthOfOriginal=aOriginal->DocumentLength();
+ TInt lengthOfCopy=aCopy->DocumentLength();
+ test(lengthOfOriginal==lengthOfCopy);
+//
+ TPtrC copy,orig;
+//
+ TInt lengthRead=0;
+ while(lengthRead<=lengthOfOriginal)
+ {
+ copy.Set((aCopy->Read(lengthRead)));
+ orig.Set((aOriginal->Read(lengthRead)));
+ for (TInt offset=0; offset<orig.Length(); offset++)
+ test(copy[offset]==orig[offset]);
+ lengthRead+=orig.Length();
+ }
+ test(lengthRead==lengthOfOriginal+1);
+ test(aCopy->FieldCount()==aOriginal->FieldCount());
+ return 1;
+ }
+
+
+void testPlainTextL(CEditableText::TDocumentStorage aStorage)
+//
+// Test streaming CPlainText.
+//
+ {// Create the plain text components.
+ test.Start(_L("Streaming CPlainText"));
+ CPlainText* copy=CPlainText::NewL(aStorage);
+ CPlainText* testDoc=CPlainText::NewL(aStorage);
+ //
+ // Set the original - empty
+ test.Start(_L("empty."));
+ testStoreRestoreL(*copy,*testDoc);
+ test(IsEqual(copy,testDoc));
+ //
+ test.Next(_L("paragraph delimiter"));
+ TRAPD(r,testDoc->InsertL(0,CEditableText::EParagraphDelimiter));
+ test(r==KErrNone);
+ testStoreRestoreL(*copy,*testDoc);
+ test(IsEqual(copy,testDoc));
+ //
+ // Next test with tons of text guaranteed to force segment break when using segmented storage.
+ test.Next(_L("big text component"));
+ testDoc->InsertL(0,bigBuf);
+ testStoreRestoreL(*copy,*testDoc);
+ test(IsEqual(copy,testDoc));
+ //
+ // Now test with field components.
+ test.Next(_L("big text doc with field components."));
+ TTestFieldFactory factory;
+ testDoc->SetFieldFactory(&factory);
+ copy->SetFieldFactory(&factory);
+ CTextField* field=NULL;
+ TRAPD(ret,
+ field=factory.NewFieldL(KDateTimeFieldUid));
+ test(ret==KErrNone);
+ TRAP(ret,
+ testDoc->InsertFieldL(0,field,KDateTimeFieldUid));
+ test(ret==KErrNone);
+ testStoreRestoreL(*copy,*testDoc);
+ test(IsEqual(copy,testDoc));
+ //
+ //
+ test.End();
+ delete copy;
+ delete testDoc;
+ }
+
+
+void testGlobalTextL(CEditableText::TDocumentStorage aStorage)
+//
+// Test streaming CGlobalText.
+//
+ {// Create the plain text components.
+ test.Next(_L("Streaming CGlobalText"));
+ CParaFormatLayer* paraLayer=CParaFormatLayer::NewL();
+ CCharFormatLayer* charLayer=CCharFormatLayer::NewL();
+ // Set something interesting in the layers:
+ CParaFormat* paraFormat1=CParaFormat::NewL(); TParaFormatMask paraMask1;
+ TCharFormat charFormat1; TCharFormatMask charMask1;
+ paraFormat1->iHorizontalAlignment=CParaFormat::ECenterAlign; paraMask1.SetAttrib(EAttAlignment);
+ paraFormat1->iLeftMarginInTwips=4000; paraMask1.SetAttrib(EAttLeftMargin);
+ paraLayer->SetL(paraFormat1,paraMask1);
+ charFormat1.iFontSpec.iFontStyle.SetPosture(EPostureItalic); charMask1.SetAttrib(EAttFontPosture);
+ charFormat1.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); charMask1.SetAttrib(EAttFontStrokeWeight);
+ charLayer->SetL(charFormat1,charMask1);
+ //
+ CGlobalText* copy=CGlobalText::NewL(paraLayer,charLayer,aStorage);
+ CGlobalText* testDoc=CGlobalText::NewL(paraLayer,charLayer,aStorage);
+
+// Set the original - empty
+ test.Start(_L("empty."));
+ testStoreRestoreL(*copy,*testDoc);
+ test(IsEqual(copy,testDoc));
+//
+ test.Next(_L("paragraph delimiter"));
+ TRAPD(r,testDoc->InsertL(0,CEditableText::EParagraphDelimiter));
+ test(r==KErrNone);
+ testStoreRestoreL(*copy,*testDoc);
+ test(IsEqual(copy,testDoc));
+
+// Next test with tons of text guaranteed to force segment break when using segmented storage.
+ test.Next(_L("big text component"));
+ testDoc->InsertL(0,bigBuf);
+ testStoreRestoreL(*copy,*testDoc);
+ test(IsEqual(copy,testDoc));
+
+ test.End();
+ test.End();
+ delete copy;
+ delete testDoc;
+ delete paraLayer;
+ delete charLayer;
+ delete paraFormat1;
+ }
+
+
+LOCAL_C TInt LayerIsEqual(const CParaFormatLayer* aRestored,const CParaFormatLayer* aOriginal)
+//
+// Returns true if aRestored contents matches aOriginal contents.
+//
+ {
+ CParaFormat* restored=NULL; TParaFormatMask rm;
+ CParaFormat* original=NULL; TParaFormatMask om;
+ TRAPD(r,restored=CParaFormat::NewL()); test(r==KErrNone);
+ TRAP(r,original=CParaFormat::NewL()); test(r==KErrNone);
+
+ aOriginal->SenseL(original,om);
+ aRestored->SenseL(restored,rm);
+
+ test(original->IsEqual(*restored));
+
+ delete restored;
+ delete original;
+ return 1;
+ }
+
+
+LOCAL_C TInt LayerIsEqual(const CCharFormatLayer* aRestored,const CCharFormatLayer* aOriginal)
+//
+// Returns true if aRestored contents matches aOriginal contents.
+//
+ {
+ TCharFormat restored; TCharFormatMask rm;
+ TCharFormat original; TCharFormatMask om;
+
+ aOriginal->Sense(original,om);
+ aRestored->Sense(restored,rm);
+
+ test(original.IsEqual(restored));
+
+ return 1;
+ }
+
+
+void testFmtLayerStoreL()
+//
+// Test the format layer StoreL().
+//
+ {
+ test.Start(_L("CParaFormatLayer"));
+// Create test layers.
+ CParaFormatLayer* pfl1=NULL;
+ CParaFormatLayer* restored=NULL;
+ CParaFormat* pf1=NULL;
+ TRAPD(r,restored=CParaFormatLayer::NewL()); test(r==KErrNone);
+ // Force *restored* to allocate storage for iteself by storing a null layer.
+ TParaFormatMask rm; rm.ClearAll(); CParaFormat* rpf=NULL;
+ restored->SetL(rpf,rm);
+ TRAP(r,pfl1=CParaFormatLayer::NewL()); test(r==KErrNone);
+ TRAP(r,pf1=CParaFormat::NewL()); test(r==KErrNone);
+ TParaFormatMask pm1;
+ pm1.SetAll(); // Sets all but the compound attributes.
+// TEST ONE DEFAULT CASES
+ test.Start(_L("Default paragraph format values."));
+ TRAP(r,pfl1->SetL(pf1,pm1)); test(r==KErrNone);
+ testCopy(*restored,*pfl1);
+ test(LayerIsEqual(restored,pfl1));
+ test(restored->SenseBase()==pfl1->SenseBase()); // Both should default to based on NULL
+// TEST TWO
+ test.Next(_L("Setting all attributes"));
+ pf1->iLeftMarginInTwips=5000; pm1.ClearAll(); pm1.SetAttrib(EAttLeftMargin);
+ pf1->iRightMarginInTwips=5001; pm1.SetAttrib(EAttRightMargin);
+ pf1->iIndentInTwips=5002;pm1.SetAttrib(EAttIndent);
+ pf1->iHorizontalAlignment=CParaFormat::ERightAlign; pm1.SetAttrib(EAttAlignment);
+ pf1->iVerticalAlignment=CParaFormat::ECenterAlign; pm1.SetAttrib(EAttVerticalAlignment);
+ pf1->iLineSpacingInTwips=5003; pm1.SetAttrib(EAttLineSpacing);
+ pf1->iLineSpacingControl=CParaFormat::ELineSpacingAtLeastInTwips; pm1.SetAttrib(EAttLineSpacingControl);
+ pf1->iSpaceBeforeInTwips=5004; pm1.SetAttrib(EAttSpaceBefore);
+ pf1->iSpaceAfterInTwips=5005; pm1.SetAttrib(EAttSpaceAfter);
+ pf1->iKeepTogether=ETrue; pm1.SetAttrib(EAttKeepTogether);
+ pf1->iKeepWithNext=ETrue; pm1.SetAttrib(EAttKeepWithNext);
+ pf1->iStartNewPage=ETrue; pm1.SetAttrib(EAttStartNewPage);
+ pf1->iWidowOrphan=ETrue; pm1.SetAttrib(EAttWidowOrphan);
+ pf1->iWrap=EFalse; pm1.SetAttrib(EAttWrap);
+ pf1->iBorderMarginInTwips=5006; pm1.SetAttrib(EAttBorderMargin);
+ pf1->iDefaultTabWidthInTwips=5007; pm1.SetAttrib(EAttDefaultTabWidth);
+ // TopBorder
+ TParaBorder top;
+ top.iLineStyle=TParaBorder::ESolid;
+ top.iThickness=4;
+ top.iAutoColor=ETrue;
+ pf1->SetParaBorderL(CParaFormat::EParaBorderTop,top);
+ pm1.SetAttrib(EAttTopBorder);
+ // BottomBorder
+ TParaBorder bottom;
+ bottom.iLineStyle=TParaBorder::ESolid;
+ bottom.iThickness=4;
+ bottom.iAutoColor=ETrue;
+ pf1->SetParaBorderL(CParaFormat::EParaBorderBottom,bottom);
+ pm1.SetAttrib(EAttBottomBorder);
+ // LeftBorder
+ TParaBorder left;
+ left.iLineStyle=TParaBorder::ESolid;
+ left.iThickness=4;
+ left.iAutoColor=ETrue;
+ pf1->SetParaBorderL(CParaFormat::EParaBorderLeft,left);
+ pm1.SetAttrib(EAttLeftBorder);
+ // RightBorder
+ TParaBorder right;
+ right.iLineStyle=TParaBorder::ESolid;
+ right.iThickness=4;
+ top.iAutoColor=ETrue;
+ pf1->SetParaBorderL(CParaFormat::EParaBorderRight,right);
+ pm1.SetAttrib(EAttRightBorder);
+ // Bullet
+ pf1->iBullet=new(ELeave)TBullet;
+ TUint charCode=5008;
+ pf1->iBullet->iCharacterCode=(TUint8)charCode;
+ pf1->iBullet->iHeightInTwips=5009;
+ pf1->iBullet->iTypeface.iName=_L("Duncan");
+ pf1->iBullet->iTypeface.SetIsProportional(EFalse);
+ pf1->iBullet->iTypeface.SetIsSerif(EFalse);
+ pm1.SetAttrib(EAttBullet);
+ // 2 Tab Stops.
+ TTabStop tab1,tab2;
+ tab1.iTwipsPosition=5010; tab1.iType=TTabStop::ERightTab;
+ tab2.iTwipsPosition=5011; tab2.iType=TTabStop::ECenteredTab;
+ pf1->StoreTabL(tab1);
+ pf1->StoreTabL(tab2);
+ pm1.SetAttrib(EAttTabStop);
+//
+ TRAP(r,pfl1->SetL(pf1,pm1));
+ testCopy(*restored,*pfl1);
+ test(LayerIsEqual(restored,pfl1));
+ test(restored->SenseBase()==pfl1->SenseBase()); // Both should default to based on NULL
+ test.End();
+//
+ delete pf1;
+ delete pfl1;
+ delete restored;
+//
+// Now the CCharFormatLayer Store/Restore
+//
+ test.Next(_L("CCharFormatLayer"));
+//
+ test.Start(_L("Setting all attributes"));
+// Create test layers.
+ CCharFormatLayer* cfl1=NULL;
+ CCharFormatLayer* cRestored=NULL;
+ TCharFormat cf1; TCharFormatMask cm1;
+//
+ TRAP(r,cRestored=CCharFormatLayer::NewL()); test(r==KErrNone);
+ // Force *restored* to allocate storage for iteself by storing a null layer.
+ TCharFormatMask rcm; rcm.ClearAll(); TCharFormat rcf;
+ cRestored->SetL(rcf,rcm);
+//
+ TRAP(r,cfl1=CCharFormatLayer::NewL()); test(r==KErrNone);
+//
+ TRgb color(20,20,20);
+ cf1.iFontPresentation.iTextColor=color; cm1.SetAttrib(EAttColor);
+ cf1.iFontSpec.iTypeface.iName=_L("DUNCANXZE");
+ cf1.iFontSpec.iTypeface.SetIsProportional(ETrue); cm1.SetAttrib(EAttFontTypeface);
+ cf1.iFontSpec.iTypeface.SetIsSerif(EFalse);
+ cf1.iFontSpec.iFontStyle.SetBitmapType(EMonochromeGlyphBitmap);
+
+ cf1.iFontSpec.iHeight=6000; cm1.SetAttrib(EAttFontHeight);
+ cf1.iFontSpec.iFontStyle.SetPosture(EPostureItalic); cm1.SetAttrib(EAttFontPosture);
+ cf1.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); cm1.SetAttrib(EAttFontStrokeWeight);
+ cf1.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSuperscript); cm1.SetAttrib(EAttFontPrintPos);
+ cf1.iFontPresentation.iUnderline=EUnderlineOn; cm1.SetAttrib(EAttFontUnderline);
+ cf1.iFontPresentation.iStrikethrough=EStrikethroughOn; cm1.SetAttrib(EAttFontStrikethrough);
+ cf1.iFontPresentation.iHighlightColor=color; cm1.SetAttrib(EAttFontHighlightColor);
+ cf1.iFontPresentation.iHighlightStyle=TFontPresentation::EFontHighlightNormal; cm1.SetAttrib(EAttFontHighlightStyle);
+//
+ TRAP(r,cfl1->SetL(cf1,cm1));
+ test(r==KErrNone);
+ testCopy(*cRestored,*cfl1);
+ test(LayerIsEqual(cRestored,cfl1));
+
+ TCharFormat rfmt;
+ TCharFormatMask rmask;
+ cRestored->Sense(rfmt, rmask);
+ test(rfmt.iFontSpec.iFontStyle.BitmapType() == EMonochromeGlyphBitmap);
+
+//
+ delete cfl1;
+ delete cRestored;
+ test.End();
+ }
+
+
+LOCAL_C TInt ChainIsEqual(const CParaFormatLayer* aCopy,const CParaFormatLayer* aOriginal)
+//
+// Tests that the restored chain is identical to the original chain.
+//
+ {
+ TInt origChainCount=aOriginal->ChainCount();
+ /*TInt copyChainCount=*/aCopy->ChainCount();
+// Check the chain heads are equal.
+ test(LayerIsEqual(aCopy,aOriginal));
+ TInt descendantCount=origChainCount-1;
+
+ const CFormatLayer* nextCopyLayer=aCopy->SenseBase();
+ const CFormatLayer* nextOrigLayer=aOriginal->SenseBase();
+ for (TInt loop=0;loop<descendantCount;loop++)
+ {
+ test(LayerIsEqual((CParaFormatLayer*)nextCopyLayer,(CParaFormatLayer*)nextOrigLayer));
+
+ nextCopyLayer=nextCopyLayer->SenseBase();
+ nextOrigLayer=nextOrigLayer->SenseBase();
+ }
+ return 1;
+ }
+
+
+LOCAL_C TInt ChainIsEqual(const CCharFormatLayer* aCopy,const CCharFormatLayer* aOriginal)
+//
+// Tests that the restored chain is identical to the original chain.
+//
+ {
+ TInt origChainCount=aOriginal->ChainCount();
+ /*TInt copyChainCount=*/aCopy->ChainCount();
+// Check the chain heads are equal.
+ test(LayerIsEqual(aCopy,aOriginal));
+ TInt descendantCount=origChainCount-1;
+
+ const CFormatLayer* nextCopyLayer=aCopy->SenseBase();
+ const CFormatLayer* nextOrigLayer=aOriginal->SenseBase();
+ for (TInt loop=0;loop<descendantCount;loop++)
+ {
+ test(LayerIsEqual((CCharFormatLayer*)nextCopyLayer,(CCharFormatLayer*)nextOrigLayer));
+
+ nextCopyLayer=nextCopyLayer->SenseBase();
+ nextOrigLayer=nextOrigLayer->SenseBase();
+ }
+ return 1;
+ }
+
+
+void DoParaChainL()
+//
+// Tests the streaming of a chain of format layers
+//
+ {
+ test.Next(_L("Re/StoreChainL()"));
+ test.Start(_L("CParaFormatLayer"));
+// Create the chain of para format layers.
+ CParaFormatLayer* l1=CParaFormatLayer::NewL();
+ CParaFormatLayer* l2=CParaFormatLayer::NewL();
+ CParaFormatLayer* l3=CParaFormatLayer::NewL();
+ CParaFormatLayer* l4=CParaFormatLayer::NewL();
+// Chain together.
+ l1->SetBase(l2);
+ l2->SetBase(l3);
+ l3->SetBase(l4);
+// Create head of restored format stream, and force it to get storage.
+ CParaFormatLayer* restoredChainHead=CParaFormatLayer::NewL();
+ CParaFormat* restoredParaFormat=CParaFormat::NewL();
+ TParaFormatMask restoredParaMask;
+ restoredParaMask.ClearAll();
+ restoredChainHead->SetL(restoredParaFormat,restoredParaMask);
+// General paraformat and its mask.
+ CParaFormat* paraFormat=CParaFormat::NewL();
+ TParaFormatMask paraMask;
+ paraMask.ClearAll();
+// Set layer one stuff
+ TTabStop tab1,tab2;
+ tab1.iTwipsPosition=5000; tab2.iTwipsPosition=5001;
+ tab1.iType=TTabStop::ERightTab; tab2.iType=TTabStop::ECenteredTab;
+ paraFormat->StoreTabL(tab1);
+ paraFormat->StoreTabL(tab2);
+ paraMask.SetAttrib(EAttTabStop);
+ l1->SetL(paraFormat,paraMask);
+ paraMask.ClearAll();
+// Set layer two stuff
+ TParaBorder top1;
+ top1.iLineStyle=TParaBorder::ESolid;
+ top1.iThickness=3;
+ top1.iAutoColor=ETrue;
+ paraFormat->SetParaBorderL(CParaFormat::EParaBorderTop,top1);
+ paraMask.SetAttrib(EAttTopBorder);
+ l2->SetL(paraFormat,paraMask);
+ paraMask.ClearAll();
+// Set the layer 3 stuff.
+ paraFormat->iBullet=new(ELeave)TBullet;
+ paraFormat->iBullet->iTypeface.iName=_L("SKELTON");
+ paraFormat->iBullet->iTypeface.SetIsProportional(EFalse);
+ paraFormat->iBullet->iTypeface.SetIsSerif(EFalse);
+ paraFormat->iBullet->iHeightInTwips=3003;
+ paraFormat->iBullet->iCharacterCode=32;
+ paraMask.SetAttrib(EAttBullet);
+ l3->SetL(paraFormat,paraMask);
+ paraMask.ClearAll();
+// Set the layer 4 stuff.
+ paraFormat->iHorizontalAlignment=CParaFormat::EJustifiedAlign; paraMask.SetAttrib(EAttAlignment);
+ paraFormat->iSpaceAfterInTwips=6000; paraMask.SetAttrib(EAttSpaceAfter);
+ paraFormat->iKeepTogether=ETrue; paraMask.SetAttrib(EAttKeepTogether);
+ l4->SetL(paraFormat,paraMask);
+// NOW DO IT
+ testCopyChain(*restoredChainHead,*l1,0,(const CFormatLayer*)NULL);
+ TInt restoredChainCount=restoredChainHead->ChainCount();
+ test(ChainIsEqual(restoredChainHead,l1));
+// DESTROY STUFF
+ CParaFormatLayer* current=restoredChainHead;
+ CParaFormatLayer* next=(CParaFormatLayer*)restoredChainHead->SenseBase();
+ delete current;
+ for (TInt loop=0;loop<restoredChainCount-1;loop++)
+ {
+ current=next;
+ next=(CParaFormatLayer*)current->SenseBase();
+ delete current;
+ }
+ delete l1;
+ delete l2;
+ delete l3;
+ delete l4;
+ delete paraFormat;
+ delete restoredParaFormat;
+ }
+
+
+void DoCharChainL()
+//
+//
+//
+ {
+ test.Next(_L("CCharFormatLayer"));
+// Create the chain of character format layers.
+ CCharFormatLayer* cl1=CCharFormatLayer::NewL();
+ CCharFormatLayer* cl2=CCharFormatLayer::NewL();
+ CCharFormatLayer* cl3=CCharFormatLayer::NewL();
+ CCharFormatLayer* cl4=CCharFormatLayer::NewL();
+// Chain together.
+ cl1->SetBase(cl2);
+ cl2->SetBase(cl3);
+ cl3->SetBase(cl4);
+// Create head of restored format stream, and force it to get storage.
+ CCharFormatLayer* rChar=CCharFormatLayer::NewL();
+ TCharFormat restoredCharFormat;
+ TCharFormatMask restoredCharMask;
+ restoredCharMask.ClearAll();
+ rChar->SetL(restoredCharFormat,restoredCharMask);
+// General charformat and its mask.
+ TCharFormat charFormat; TCharFormatMask charMask;
+ charMask.ClearAll();
+// Set layer one stuff
+ charFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); charMask.SetAttrib(EAttFontStrokeWeight);
+ charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); charMask.SetAttrib(EAttFontPosture);
+ charFormat.iFontPresentation.iUnderline=EUnderlineOn; charMask.SetAttrib(EAttFontUnderline);
+ cl1->SetL(charFormat,charMask);
+ charMask.ClearAll();
+// Set layer two stuff
+ charFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSubscript); charMask.SetAttrib(EAttFontPrintPos);
+ cl2->SetL(charFormat,charMask);
+ charMask.ClearAll();
+// Set the layer 3 stuff.
+ charFormat.iFontPresentation.iStrikethrough=EStrikethroughOn; charMask.SetAttrib(EAttFontStrikethrough);
+ cl3->SetL(charFormat,charMask);
+ charMask.ClearAll();
+// Set the layer 4 stuff.
+ charFormat.iFontSpec.iTypeface.iName=_L("Arial");
+ charFormat.iFontSpec.iHeight=200;
+ charMask.SetAttrib(EAttFontHeight);
+ charMask.SetAttrib(EAttFontTypeface);
+ cl4->SetL(charFormat,charMask);
+// NOW DO IT
+ test.Start(_L("Chain 4 layers deep, terminating on a based on NULL"));
+ testCopyChain(*rChar,*cl1,0,(const CFormatLayer*)NULL);
+ TInt restoredChainCount=rChar->ChainCount();
+ test(ChainIsEqual(rChar,cl1));
+// DESTROY STUFF
+ CCharFormatLayer* chCurrent=rChar;
+ CCharFormatLayer* chNext=(CCharFormatLayer*)rChar->SenseBase();
+ delete chCurrent;
+ for (TInt loop=0;loop<restoredChainCount-1;loop++)
+ {
+ chCurrent=chNext;
+ chNext=(CCharFormatLayer*)chCurrent->SenseBase();
+ delete chCurrent;
+ }
+ delete cl1;
+ delete cl2;
+ delete cl3;
+ delete cl4;
+ }
+
+
+void DoCharChainVariant1()
+//
+// Case 2: Where the chain does not terminate at a NULL link.
+//
+ {
+// Create the chain of character format layers.
+ CCharFormatLayer* cl1=CCharFormatLayer::NewL();
+ CCharFormatLayer* cl2=CCharFormatLayer::NewL();
+ CCharFormatLayer* cl3=CCharFormatLayer::NewL();
+ CCharFormatLayer* cl4=CCharFormatLayer::NewL();
+// Chain together.
+ cl1->SetBase(cl2);
+ cl2->SetBase(cl3);
+ cl3->SetBase(cl4);
+// Create head of restored format stream, and force it to get storage.
+ CCharFormatLayer* rChar=CCharFormatLayer::NewL();
+ TCharFormat restoredCharFormat;
+ TCharFormatMask restoredCharMask;
+ restoredCharMask.ClearAll();
+ rChar->SetL(restoredCharFormat,restoredCharMask);
+// General charformat and its mask.
+ TCharFormat charFormat; TCharFormatMask charMask;
+ charMask.ClearAll();
+// Set layer one stuff
+ charFormat.iFontSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); charMask.SetAttrib(EAttFontStrokeWeight);
+ charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic); charMask.SetAttrib(EAttFontPosture);
+ charFormat.iFontPresentation.iUnderline=EUnderlineOn; charMask.SetAttrib(EAttFontUnderline);
+ cl1->SetL(charFormat,charMask);
+ charMask.ClearAll();
+// Set layer two stuff
+ charFormat.iFontSpec.iFontStyle.SetPrintPosition(EPrintPosSubscript); charMask.SetAttrib(EAttFontPrintPos);
+ cl2->SetL(charFormat,charMask);
+ charMask.ClearAll();
+// Set the layer 3 stuff.
+ charFormat.iFontPresentation.iStrikethrough=EStrikethroughOn; charMask.SetAttrib(EAttFontStrikethrough);
+ cl3->SetL(charFormat,charMask);
+ charMask.ClearAll();
+// Set the layer 4 stuff.
+ charFormat.iFontSpec.iTypeface.iName=_L("Arial");
+ charFormat.iFontSpec.iHeight=200;
+ charMask.SetAttrib(EAttFontHeight);
+ charMask.SetAttrib(EAttFontTypeface);
+ cl4->SetL(charFormat,charMask);
+// NOW DO IT
+ test.Next(_L("Chain 3 layers deep, terminating on a non-NULL based-on"));
+ testCopyChain(*rChar,*cl1,1,(const CFormatLayer*)cl4);
+ TInt restoredChainCount=rChar->ChainCount();
+ test(ChainIsEqual(rChar,cl1));
+// DESTROY STUFF
+ CCharFormatLayer* chCurrent=rChar;
+ CCharFormatLayer* chNext=(CCharFormatLayer*)rChar->SenseBase();
+ delete chCurrent;
+ for (TInt loop=0;loop<restoredChainCount-2;loop++)
+ {
+ chCurrent=chNext;
+ chNext=(CCharFormatLayer*)chCurrent->SenseBase();
+ delete chCurrent;
+ }
+ delete cl1;
+ delete cl2;
+ delete cl3;
+ delete cl4;
+
+ test.End();
+ test.End();
+ test.End();
+ }
+
+
+void testFmtLayerStoreChainL()
+//
+// Controls the testing of the chainig stuff.
+//
+ {
+ DoParaChainL();
+ DoCharChainL();
+ DoCharChainVariant1();
+// DoCharChainVariant2(); TO BE IMPLEMENTED
+// doCharChainVariant3(); TO BE IMPLEMENTED
+ }
+
+
+void testFmtLayerL()
+//
+// Tests the streaming of format layers.
+//
+ {
+ testFmtLayerStoreL();
+ testFmtLayerStoreChainL();
+ }
+
+
+LOCAL_C void setupCleanup()
+//
+// Initialise the cleanup stack.
+//
+ {
+
+ TheTrapCleanup=CTrapCleanup::New();
+ TRAPD(r,\
+ {\
+ for (TInt i=KTestCleanupStack;i>0;i--)\
+ CleanupStack::PushL((TAny*)1);\
+ test(r==KErrNone);\
+ CleanupStack::Pop(KTestCleanupStack);\
+ });
+ }
+
+
+LOCAL_C void DeleteDataFile(const TDesC& aFullName)
+ {
+ RFs fsSession;
+ TInt err = fsSession.Connect();
+ if(err == KErrNone)
+ {
+ TEntry entry;
+ if(fsSession.Entry(aFullName, entry) == KErrNone)
+ {
+ RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
+ err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+ if(err != KErrNone)
+ {
+ RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
+ }
+ err = fsSession.Delete(aFullName);
+ if(err != KErrNone)
+ {
+ RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
+ }
+ }
+ fsSession.Close();
+ }
+ else
+ {
+ RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+ }
+ }
+
+GLDEF_C TInt E32Main()
+//
+// Test streaming conversions.
+//
+ {
+ setupCleanup();
+ test.Title();
+ __UHEAP_MARK;
+
+ test.Start(_L(" @SYMTestCaseID:SYSLIB-ETEXT-LEGACY-T_CONVS-0001 EText components using Flat Storage "));
+ TRAPD(r,testPlainTextL(CEditableText::EFlatStorage));
+ test(r==KErrNone);
+ TRAP(r,testGlobalTextL(CEditableText::EFlatStorage));
+ test(r==KErrNone);
+
+//
+ test.Next(_L("EText components using Segmented storage"));
+ TRAP(r,testPlainTextL(CEditableText::ESegmentedStorage));
+ test(r==KErrNone);
+ TRAP(r,testGlobalTextL(CEditableText::ESegmentedStorage));
+ test(r==KErrNone);
+
+ test.Next(_L("Format Layer components"));
+ TRAP(r,testFmtLayerL());
+ test(r==KErrNone);
+
+// test.End();
+ __UHEAP_MARKEND;
+
+ ::DeleteDataFile(KOutputFile); //deletion of data files must be before call to End() - DEF047652
+ test.End();
+ test.Close();
+ delete TheTrapCleanup;
+
+ return 0;
+ }
+