--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fontservices/textshaperplugin/test/CreateTestData/T_SHAP_createTestData.cpp Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,504 @@
+/*
+* Copyright (c) 2008-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:
+* Creates test data files that are used by TC_SHAP_shapeText.cpp test.
+* This tool uses the Unicode test input text defined in inputData.h and
+* shapes the text by calling the IcuLayoutEngine API ShapeText().
+* The result, along with the input text is stored in the test data files with
+* extensions .dat
+* First, the reference input data is stored in the data files in the following format, seperated by a delimiter - | :
+* Length (of the input data string) Font typeface name | Font file name | Starting offset in the input string | End offset in the input string | Input text string
+* Then the result of the shaping is stored in data files in the following format:
+* Output glyph count Output glyphs Glyph X and Y coordinates Glyph advances Glyph indices Output character count
+* The TC_SHAP_shape_Text test is programmed to read in files in this format, and this format only.
+* This tool needs to be run, and new test data files need to be created everytime the
+* IcuLayoutEngine shaping rules are changed/edited/appended.
+* IN ORDER TO CREATE NEW TEST DATA FILES USING THIS UTILITY, YOU WILL NEED TO:
+* 1. Add a new TInputData entry in inputData.txt
+* 2. Delete any old data files in %EPOCROOT%epoc32\winscw\c\
+* 3. Run the test.
+* IN ORDER TO GET THE TC_SHAP_shapeText TEST FILE TO USE THIS NEW DATA, YOU WILL NEED TO:
+* 1. Add your new test file in perforce to:
+* IcuLayoutEngine/test/testdata/...
+* They will have been added to %EPOCROOT%epoc32\winscw\c
+* 2. Update the bld.inf file for IcuLayoutEngine to export this file to z:\test\data\...
+* 3. Update the .cpp file by adding the a new literal at the top of the file with the new filename to be used.
+* 4. Update the TC_SHAP_shapeText.iby file in IcuLayoutEngine/test to include the new file.
+* THIS TOOL SHOULD ONLY BE RUN BY SOMEONE WHO KNOWS WHAT HE/SHE IS DOING!!
+*
+*/
+
+
+#include <e32def.h>
+#include <e32test.h>
+#include <e32std.h>
+#include <f32file.h>
+#include <fntstore.h>
+#include <s32file.h>
+
+#include <graphics/openfontrasterizer.h>
+#include <graphics/openfontconstants.h>
+#include <graphics/shapeimpl.h>
+#include "inputData.h"
+
+const TUint32 KDevanagariScriptCode = 0x64657661;
+const TUint32 KKannadaScriptCode = 0x6B6E6461;
+const TUint32 KHindiLanguageCode = 0x48494E20;
+const TUint32 KKannadaLanguageCode = 0x4B414E20;
+const TUint32 KGujaratiScriptCode = 0x67756A72;
+const TUint32 KGujaratiLanguageCode = 0x47554A20;
+const TUint32 KBengaliScriptCode = 0x62656E67;
+const TUint32 KBengaliLanguageCode = 0x42454E20;
+const TUint32 KTamilScriptCode = 0x74616D6C;
+const TUint32 KTamilLanguageCode = 0x54414D20;
+const TUint32 KTeluguScriptCode = 0x74656C75;
+const TUint32 KTeluguLanguageCode = 0x54454C20;
+const TUint32 KGurmukhiScriptCode = 0x67757275;
+const TUint32 KGurmukhiLanguageCode = 0;
+const TUint32 KMalayalamScriptCode = 0x6d6c796d;
+const TUint32 KMalayalamLanguageCode = 0x4d4c5220;
+
+
+_LIT16(KDelimiter, "|");
+
+//RTest Macros etc
+static RTest TheTest(_L("T_SHAP_createTestData"));
+static void Check(TInt aValue, TInt aLine)
+ {
+ if(!aValue)
+ {
+ TheTest(EFalse, aLine);
+ }
+ }
+
+static void Check(TInt aValue, TInt aExpected, TInt aLine)
+ {
+ if(aValue != aExpected)
+ {
+ RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
+ TheTest(EFalse, aLine);
+ }
+ }
+
+#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
+#define TEST(arg) ::Check((arg), __LINE__)
+
+/*
+Used for cleanup of RImplInfoArray implementationArray below
+This method is stolen from FbsTop.cpp
+*/
+LOCAL_C void ResetAndDestroyRImplInfoPtrArray(TAny* aPtr)
+ {
+ RImplInfoPtrArray* array = reinterpret_cast <RImplInfoPtrArray*> (aPtr);
+ array->ResetAndDestroy();
+ }
+
+/*
+Load all ECOM implemented rasterizer DLLs.
+This method is stolen from CFbTop::LoadOpenFontLibraries()
+*/
+LOCAL_C void LoadOpenFontLibraries(CFontStore* aFontStore)
+ {
+
+ RImplInfoPtrArray implementationArray;
+ TCleanupItem cleanup(ResetAndDestroyRImplInfoPtrArray, &implementationArray);
+ CleanupStack::PushL(cleanup);
+ TInt error;
+ TInt ecomerror;
+ TInt ecomnotready;
+ TUid uid = {KUidOpenFontRasterizerPlunginInterface};
+
+ // Making sure that no race situation arises
+ // If ECom is not ready, give it another chance and try again. if it still doesn't work
+ // after the third try, then it just carries on quietly and fails...
+ for (ecomnotready =0; ecomnotready <3; ecomnotready++)
+ {
+ TRAP(ecomerror,REComSession::ListImplementationsL(uid,implementationArray));
+ if (!ecomerror)
+ {
+ break;
+ }
+ else
+ {
+ ecomerror = 0;
+ User::After(0);
+ }
+ }
+
+ const TInt availCount = implementationArray.Count();
+ for (TInt count=0;count<availCount;++count)
+ {
+ const CImplementationInformation* info = implementationArray[count];
+ TUid rasterizerUid = info->ImplementationUid();
+ // Create a rasterizer
+ COpenFontRasterizer* rasterizer=0;
+ TRAP(error,rasterizer = COpenFontRasterizer::NewL(rasterizerUid));
+ if (!error)
+ {
+ // Install it in the font store.
+ TRAP(error,aFontStore->InstallRasterizerL(rasterizer));
+ if (error)
+ delete rasterizer;
+ }
+ }
+ CleanupStack::PopAndDestroy(&implementationArray);
+
+ }
+
+LOCAL_C void WriteInputData(RWriteStream& aStream, const TInputData& aInputData)
+ {
+ //output the input data to the file
+ TPtrC input = aInputData.TextInput();
+ TInt length = input.Length();
+ TInt start = aInputData.iStart;
+ if (start < 0)
+ start += length;
+ TInt end = aInputData.iEnd;
+ if (end <= 0)
+ end += length;
+
+ aStream.WriteInt16L(length);
+
+ aStream.WriteL(aInputData.TypeFaceName());
+ aStream.WriteL(KDelimiter);
+
+ aStream.WriteL(aInputData.FontFilename());
+ aStream.WriteL(KDelimiter);
+
+ aStream.WriteInt16L(start);
+ aStream.WriteL(KDelimiter);
+ aStream.WriteInt16L(end);
+ aStream.WriteL(KDelimiter);
+
+ aStream.WriteL(input);
+ aStream.WriteL(KDelimiter);
+ }
+
+static void WriteOutputData(RWriteStream& aStream, const TInputData& aInputData,
+ TUint32 aScript, TUint32 aLanguage)
+ {
+ //SHAPE THE TEXT
+
+ TPtrC input = aInputData.TextInput();
+ TInt length = input.Length();
+ TInt start = aInputData.iStart;
+ if (start < 0)
+ start += length;
+ TInt end = aInputData.iEnd;
+ if (end <= 0)
+ end += length;
+
+ //set up font store and install rasterizer(s)
+ CFontStore* fontStore = CFontStore::NewL(&User::Heap());
+ fontStore->iKPixelWidthInTwips = 11860;
+ fontStore->iKPixelHeightInTwips = 11860;
+ CleanupStack::PushL(fontStore);
+ LoadOpenFontLibraries(fontStore);
+
+ //add required font file
+ TRAPD( err, fontStore->AddFileL(aInputData.FontFilename()) );
+ TEST(err==KErrNone);
+
+ CBitmapFont* font;
+ TFontSpec fontSpec(aInputData.TypeFaceName(), 12);
+ fontStore->GetNearestFontToDesignHeightInPixels((CFont*&)font, fontSpec);
+ CleanupStack::PushL(font);
+
+ CShaper* theShaper = NULL;
+ CShaperFactory* shaperFactory = NULL;
+
+ RImplInfoPtrArray implementationArray;
+ TCleanupItem cleanup(ResetAndDestroyRImplInfoPtrArray, &implementationArray);
+ CleanupStack::PushL(cleanup);
+ TInt error;
+ TInt ecomerror;
+ TInt ecomnotready;
+ TUid uid = {KUidShaperFactoryPlunginInterface};
+
+ // Making sure that no race situation arises between FBserv and Ecom
+ // If ECom is not ready, give it another chance and try again. if it still doesn't work
+ // after the third try, then it just carries on quietly and fails...
+ for (ecomnotready =0; ecomnotready <3; ecomnotready++)
+ {
+ TRAP(ecomerror,REComSession::ListImplementationsL(uid,implementationArray));
+ if (!ecomerror)
+ {
+ break;
+ }
+ else
+ {
+ ecomerror = 0;
+ User::After(0);
+ }
+ }
+
+ const TInt availCount = implementationArray.Count();
+ for (TInt count=0;count<availCount;++count)
+ {
+ const CImplementationInformation* info = implementationArray[count];
+ TUid shaperFactoryUid = info->ImplementationUid();
+ // Create a shaper factory
+ //CShaperFactory* shaperFactory = 0;
+ TRAP(error,shaperFactory = CShaperFactory::NewL(shaperFactoryUid));
+ TEST2(error, KErrNone);
+ // Create a shaper
+ TRAPD(err, theShaper = shaperFactory->NewShaperL(font, aScript, aLanguage, &User::Heap()));
+ TEST2(err, KErrNone);
+ }
+ CleanupStack::PopAndDestroy(&implementationArray);
+
+ CleanupStack::PushL(shaperFactory);
+ CleanupStack::PushL(theShaper);
+
+ // create the data to be shaped
+ // this uses testData, defined in testData.h
+ CShaper::TInput shaperInput;
+ shaperInput.iText = &input;
+ shaperInput.iStart = start;
+ shaperInput.iEnd = end;
+
+ TShapeHeader* output = NULL;
+ err = theShaper->ShapeText(output, shaperInput, &User::Heap());
+ TEST2(err,KErrNone);
+ CleanupStack::PushL(output);
+
+
+ //AND FILL THE FILE UP WITH THE RESULTS
+
+ //first the glyph count
+ aStream.WriteInt16L(output->iGlyphCount);
+ TInt glyphCount(output->iGlyphCount);
+ TInt i;
+
+ //then the Glyphs
+ TUint32* shapePtr32 = (reinterpret_cast<TUint32*>(&output->iBuffer[0]));
+ for(i=0; i <glyphCount; i++)
+ {
+ aStream.WriteInt32L(*shapePtr32);
+ shapePtr32++;
+ }
+
+ //then the X and Y positions
+ TUint16* shapePtr16 = (reinterpret_cast<TUint16*>(shapePtr32));
+ for(i=0; i<glyphCount*2; i++)
+ {
+ aStream.WriteInt16L(*shapePtr16);
+ shapePtr16++;
+ }
+
+ //then the advance
+ aStream.WriteInt16L(*shapePtr16);
+ shapePtr16++;
+ aStream.WriteInt16L(*shapePtr16);
+ shapePtr16++;
+
+ //then the indices
+ for(i=0; i<glyphCount; i++)
+ {
+ aStream.WriteInt16L(*shapePtr16);
+ shapePtr16++;
+ }
+
+ //then the character count
+ aStream.WriteInt16L(output->iCharacterCount);
+
+ CleanupStack::PopAndDestroy(output);
+ CleanupStack::PopAndDestroy(theShaper);
+ CleanupStack::PopAndDestroy(shaperFactory);
+ REComSession::FinalClose();
+
+ CleanupStack::Pop(font);
+ fontStore->ReleaseFont(font);
+ CleanupStack::PopAndDestroy(fontStore);
+
+ //close the ecom session opened by LoadOpenFontLibraries()
+ REComSession::FinalClose();
+ }
+
+static void MainL()
+ {
+ RFs fs;
+ RFile file;
+ RFileBuf buf;
+
+ // Create the Devanagari test data files
+ const TInt numberOfTests
+ = sizeof(TNR_Dev_OTInputData)/sizeof(TNR_Dev_OTInputData[0]);
+ for (TInt i = 0; i != numberOfTests; ++i)
+ {
+ const TInputData& data = TNR_Dev_OTInputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ // note this uses RFile::Create so that users of this utility cannot accidentally write over
+ // files created before. If this test fails, you need to ensure that the file specified by
+ // KFileName is correct, and if so delete it before running this utility.
+ TEST2(file.Create(fs, data.OutputFilename(), EFileWrite), KErrNone);
+
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ //write to the stream
+ WriteInputData(stream, data);
+ WriteOutputData(stream, data, KDevanagariScriptCode, KHindiLanguageCode);
+
+ CleanupStack::PopAndDestroy(2); //buf, fs
+ }
+
+ // Create the Kannada test data files
+ const TInt numberOfKanTests = sizeof(Kannada_InputData)/sizeof(Kannada_InputData[0]);
+ for (TInt i = 0; i != numberOfKanTests; i++)
+ {
+ const TInputData& kan_data = Kannada_InputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEST2(file.Create(fs, kan_data.OutputFilename(), EFileWrite), KErrNone);
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ WriteInputData(stream, kan_data);
+ WriteOutputData(stream, kan_data, KKannadaScriptCode, KKannadaLanguageCode);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+
+ // Create the Gujarati test data files
+ const TInt numberOfGujTests = sizeof(Gujarati_InputData)/sizeof(Gujarati_InputData[0]);
+ for (TInt i = 0; i != numberOfGujTests; i++)
+ {
+ const TInputData& kan_data = Gujarati_InputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEST2(file.Create(fs, kan_data.OutputFilename(), EFileWrite), KErrNone);
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ WriteInputData(stream, kan_data);
+ WriteOutputData(stream, kan_data, KGujaratiScriptCode, KGujaratiLanguageCode);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+
+ // Create the Bengali test data files
+ const TInt numberOfBenTests = sizeof(Bengali_InputData)/sizeof(Bengali_InputData[0]);
+ for (TInt i = 0; i != numberOfBenTests; i++)
+ {
+ const TInputData& ben_data = Bengali_InputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEST2(file.Create(fs, ben_data.OutputFilename(), EFileWrite), KErrNone);
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ WriteInputData(stream, ben_data);
+ WriteOutputData(stream, ben_data, KBengaliScriptCode, KBengaliLanguageCode);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+ // Create the Tamil test data files
+ const TInt numberOfTamTests = sizeof(Tamil_InputData)/sizeof(Tamil_InputData[0]);
+ for (TInt i = 0; i != numberOfTamTests; i++)
+ {
+ const TInputData& tam_data = Tamil_InputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEST2(file.Create(fs, tam_data.OutputFilename(), EFileWrite), KErrNone);
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ WriteInputData(stream, tam_data);
+ WriteOutputData(stream, tam_data, KTamilScriptCode, KTamilLanguageCode);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+ // Create the Telugu test data files
+ const TInt numberOfTelTests = sizeof(Telugu_InputData)/sizeof(Telugu_InputData[0]);
+ for (TInt i = 0; i != numberOfTelTests; i++)
+ {
+ const TInputData& tel_data = Telugu_InputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEST2(file.Create(fs, tel_data.OutputFilename(), EFileWrite), KErrNone);
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ WriteInputData(stream, tel_data);
+ WriteOutputData(stream, tel_data, KTeluguScriptCode, KTeluguLanguageCode);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+ // Create the Gurmukhi test data files
+ const TInt numberOfGurTests = sizeof(Gurmukhi_InputData)/sizeof(Gurmukhi_InputData[0]);
+ for (TInt i = 0; i != numberOfGurTests; i++)
+ {
+ const TInputData& tel_data = Gurmukhi_InputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEST2(file.Create(fs, tel_data.OutputFilename(), EFileWrite), KErrNone);
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ WriteInputData(stream, tel_data);
+ WriteOutputData(stream, tel_data, KGurmukhiScriptCode, KGurmukhiLanguageCode);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+
+ // Create the Malayalam test data files
+ const TInt numberOfMalaTests = sizeof(Malayalam_InputData)/sizeof(Malayalam_InputData[0]);
+ for (TInt i = 0; i != numberOfMalaTests; i++)
+ {
+ const TInputData& tel_data = Malayalam_InputData[i];
+ User::LeaveIfError(fs.Connect());
+ CleanupClosePushL(fs);
+ TEST2(file.Create(fs, tel_data.OutputFilename(), EFileWrite), KErrNone);
+ CleanupClosePushL(buf);
+ buf.Attach(file);
+ RWriteStream stream(&buf);
+
+ WriteInputData(stream, tel_data);
+ WriteOutputData(stream, tel_data, KMalayalamScriptCode, KMalayalamLanguageCode);
+
+ CleanupStack::PopAndDestroy(2);
+ }
+ }
+
+TInt E32Main()
+ {
+ __UHEAP_MARK;
+
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ if(!cleanup)
+ return KErrNoMemory;
+
+ TRAPD(err, MainL());
+ TEST2(err, KErrNone);
+
+ delete cleanup;
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+