os/textandloc/textrendering/textformatting/test/src/TBidiCursorPos.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/textandloc/textrendering/textformatting/test/src/TBidiCursorPos.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,334 @@
     1.4 +/*
     1.5 +* Copyright (c) 2002-2010 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 +// Test code for GetNextVisualCursorPos functionality
    1.22 +#include <e32test.h>
    1.23 +
    1.24 +#include "TGraphicsContext.h"
    1.25 +#include <gdi.h>
    1.26 +#include "TAGMA.H"
    1.27 +#include "TmLayoutImp.h"
    1.28 +#include "TMINTERP.H"
    1.29 +#include "tbidicursorpos.h"
    1.30 +
    1.31 +namespace LocalToTBidiCursorPos
    1.32 +{
    1.33 +CTBidiCursorPosStep* TestStep;
    1.34 +#define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
    1.35 +#define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
    1.36 +
    1.37 +}
    1.38 +
    1.39 +using namespace LocalToTBidiCursorPos;
    1.40 +
    1.41 +class CTestSource : public CBase, public MTmSource
    1.42 +	{
    1.43 +public:
    1.44 +	static CTestSource* NewLC();
    1.45 +	~CTestSource();
    1.46 +	void ConstructL();
    1.47 +	// from MTmSource
    1.48 +	MGraphicsDeviceMap& FormatDevice() const { return *iScreenDevice; }
    1.49 +	MGraphicsDeviceMap& InterpretDevice() const { return *iScreenDevice; }
    1.50 +	TInt DocumentLength() const
    1.51 +		{
    1.52 +		return iText->Length();
    1.53 +		}
    1.54 +	void GetText(TInt aPos,TPtrC& aText, TTmCharFormat& aFormat) const
    1.55 +		{
    1.56 +		TTmCharFormat f;
    1.57 +		aFormat = f;
    1.58 +		aText.Set(iText->Mid(aPos));
    1.59 +		}
    1.60 +	void GetParagraphFormatL(TInt, RTmParFormat& aFormat) const
    1.61 +		{
    1.62 +		aFormat.CopyL(iParFormat);
    1.63 +		}
    1.64 +	TInt ParagraphStart(TInt) const { return 0; }
    1.65 +
    1.66 +	void SetText(HBufC* aText) { iText = aText; }
    1.67 +
    1.68 +private:
    1.69 +	CTestSource() {}
    1.70 +
    1.71 +public:
    1.72 +	RTmParFormat iParFormat;
    1.73 +private:
    1.74 +	CTestGraphicsDevice* iScreenDevice;
    1.75 +	CWindowGc* iGc;
    1.76 +	HBufC* iText;
    1.77 +	};
    1.78 +
    1.79 +// static
    1.80 +CTestSource* CTestSource::NewLC()
    1.81 +	{
    1.82 +	CTestSource* self = new(ELeave) CTestSource();
    1.83 +	CleanupStack::PushL(self);
    1.84 +	self->ConstructL();
    1.85 +	return self;
    1.86 +	}
    1.87 +
    1.88 +void CTestSource::ConstructL()
    1.89 +	{
    1.90 +	TSize size(100, 100);
    1.91 +	iScreenDevice = CTestGraphicsDevice::NewL(size, 0);
    1.92 +	User::LeaveIfError(iScreenDevice->CreateContext(iGc));
    1.93 +	}
    1.94 +
    1.95 +CTestSource::~CTestSource()
    1.96 +	{
    1.97 +	delete iScreenDevice;
    1.98 +	delete iGc;
    1.99 +	}
   1.100 +
   1.101 +#define NO_OF_TEST_CASES 8
   1.102 +
   1.103 +class TPos
   1.104 +	{
   1.105 +public:
   1.106 +	TInt iPos;
   1.107 +	TBool iLeading;
   1.108 +	};
   1.109 +class TAugmentedPos
   1.110 +	{
   1.111 +public:
   1.112 +	TInt iPos;
   1.113 +	TBool iLeading;
   1.114 +	TBool iOptional;
   1.115 +	};
   1.116 +
   1.117 +const TAugmentedPos expectedCursorPos[NO_OF_TEST_CASES][40] = {
   1.118 +	{ {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {5, 1, 0},
   1.119 +		{4, 1, 0}, {3, 1, 0}, {7, 0, 0}, {8, 0, 0},
   1.120 +		{9, 0, 0} },
   1.121 +	{ {1, 0, 0}, {2, 0, 0}, {10, 1, 0}, {9, 1, 0},
   1.122 +		{8, 1, 0}, {7, 1, 0}, {6, 0, 0}, {7, 0, 0},
   1.123 +		{4, 1, 0}, {3, 1, 0}, {2, 1, 0}, {12, 0, 0},
   1.124 +		{13, 0, 0} },
   1.125 +	{ {1, 0, 0}, {2, 0, 0}, {5, 1, 1}, {4, 1, 0},
   1.126 +		{3, 1, 1}, {2, 1, 1}, {7, 0, 0}, {8, 0, 0},
   1.127 +		{9, 0, 0} },
   1.128 +	{ {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {5, 1, 0},
   1.129 +		{4, 1, 0}, {3, 1, 0}, {7, 0, 0}, {8, 0, 0},
   1.130 +		{9, 0, 0}, {11, 1, 0}, {10, 1, 0}, {9, 1, 0},
   1.131 +		{13, 0, 0}, {14, 0, 0}, {15, 0, 0} },
   1.132 +	{ {2, 0, 0}, {3, 0, 0}, {4, 0, 0} },
   1.133 +	{ {3, 0, 0}, {4, 0, 0} },
   1.134 +	{ {1, 0, 0}, {2, 0, 0}, {6, 1, 0}, {5, 1, 0},
   1.135 +		{4, 1, 0}, {3, 1, 0}, {2, 1, 0}, {8, 0, 0},
   1.136 +		{9, 0, 0} },
   1.137 +	{ {1, 0, 0}, {2, 0, 0}, {8, 1, 0}, {7, 1, 0},
   1.138 +		{6, 1, 0}, {5, 1, 0}, {4, 1, 0}, {3, 1, 0},
   1.139 +		{2, 1, 0}, {10, 0, 0}, {11, 0, 0} }
   1.140 +	};
   1.141 +
   1.142 +const TPos startPos[NO_OF_TEST_CASES] = { {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} };
   1.143 +
   1.144 +const TInt numberOfCursorPositionsToCheck[NO_OF_TEST_CASES] = {9, 13, 9, 15, 3, 2, 9, 11};
   1.145 +const TBool moveToLeft[NO_OF_TEST_CASES] = {EFalse, EFalse, EFalse, ETrue, ETrue, EFalse, ETrue, ETrue};
   1.146 +const TBool rightToLeftPara[NO_OF_TEST_CASES] = {EFalse, EFalse, EFalse, ETrue, EFalse, EFalse, ETrue, ETrue};
   1.147 +
   1.148 +void GetNextVisualCursorPosTestsL(CTmTextLayout* aLayout, CTestSource* aSource)
   1.149 +	{
   1.150 +	// Testcase 1
   1.151 +	_LIT(KBidi1, "abc\x644\x644\x644zzz\x2029");
   1.152 +
   1.153 +	// Testcase 2 (0x32 and 0x39 changed to 0x6F2 and 0x0F9, see note below)
   1.154 +	_LIT(KBidi2, "ab\x644\x644\x644\x6F2\x6F9\x644\x644\x644\x644zy\x2029");
   1.155 +
   1.156 +	// Testcase 3
   1.157 +	_LIT(KBidi3, "ab\x202ejk\x202cjkl\x2029");
   1.158 +
   1.159 +	// Testcase 4
   1.160 +	_LIT(KBidi4, "\x644\x644\x644xyz\x644\x644\x644xyz\x644\x644\x644\x2029");
   1.161 +
   1.162 +	// Testcase 5
   1.163 +	_LIT(KBidi5, "\x647\x64b\x647\x647\x2029");
   1.164 +
   1.165 +	// Testcase 6
   1.166 +	_LIT(KBidi6, "a\x302\x317z\x2029");
   1.167 +
   1.168 +	// Testcase 7 (0x31 and 0x32 changed to 0x6F1 and 0x0F2, see note below)
   1.169 +	_LIT(KBidi7, "\x644\x644\x6F1\x6F2\x2e\x33\x34\x644\x644\x2029");
   1.170 +
   1.171 +	// Testcase 8 (0x31 - 0x35 changed to 0x6F1 - 0x0F5, see note below)
   1.172 +	_LIT(KBidi8, "\x644\x644\x6F1\x2c\x6F2\x6F3\x2e\x6F4\x6F5\x644\x644\x2029");
   1.173 +
   1.174 +// Note: Test cases 2 and 7 have been changed to use \x6F0-\x6F9, Extended Arabic Digits,
   1.175 +// These have the bidirectional class "EN",the same as ASCII digits.
   1.176 +// These have been used in preference to ASCII digits
   1.177 +// to work around a CodeWarrior preprocessor/C-Cover problem.
   1.178 +// For more detils see DEF042186
   1.179 +
   1.180 +	HBufC* logicalText[NO_OF_TEST_CASES];
   1.181 +	logicalText[0] = KBidi1().AllocLC();
   1.182 +	logicalText[1] = KBidi2().AllocLC();
   1.183 +	logicalText[2] = KBidi3().AllocLC();
   1.184 +	logicalText[3] = KBidi4().AllocLC();
   1.185 +	logicalText[4] = KBidi5().AllocLC();
   1.186 +	logicalText[5] = KBidi6().AllocLC();
   1.187 +	logicalText[6] = KBidi7().AllocLC();
   1.188 +	logicalText[7] = KBidi8().AllocLC();
   1.189 +
   1.190 +	TTmFormatParam format;
   1.191 +	format.iStartChar = 0;
   1.192 +	format.iEndChar = 0;
   1.193 +	format.iLineInPar = 0;
   1.194 +
   1.195 +	TTmDocPos pos(0, ETrue);
   1.196 +	TTmPosInfo2 info;
   1.197 +	int charIndex;
   1.198 +	TBuf<40> msg;
   1.199 +
   1.200 +	for (TInt ii = 0; ii < NO_OF_TEST_CASES; ii++)
   1.201 +		{
   1.202 +		msg.Format(_L("GetNextVisualCursorPos test case %d\n"), ii + 1);
   1.203 +		TESTPRINT(msg);
   1.204 +		aSource->SetText(logicalText[ii]);
   1.205 +		format.iEndChar = logicalText[ii]->Length();
   1.206 +		if (rightToLeftPara[ii])
   1.207 +			aSource->iParFormat.iFlags |= RTmParFormat::ERightToLeft;
   1.208 +		aLayout->SetTextL(*aSource, format);
   1.209 +
   1.210 +		charIndex = 0;
   1.211 +		pos.iPos = startPos[ii].iPos;
   1.212 +		pos.iLeadingEdge = startPos[ii].iLeading;
   1.213 +		while (aLayout->GetNextVisualCursorPos(pos, info, moveToLeft[ii]))
   1.214 +			{
   1.215 +			while (info.iDocPos.iPos != expectedCursorPos[ii][charIndex].iPos
   1.216 +				|| info.iDocPos.iLeadingEdge != expectedCursorPos[ii][charIndex].iLeading)
   1.217 +				{
   1.218 +                TESTPOINT(expectedCursorPos[ii][charIndex].iOptional);
   1.219 +				++charIndex;
   1.220 +				TESTPOINT(charIndex != numberOfCursorPositionsToCheck[ii]);
   1.221 +				}
   1.222 +			pos = info.iDocPos;
   1.223 +			++charIndex;
   1.224 +			TESTPOINT(charIndex <= numberOfCursorPositionsToCheck[ii]);
   1.225 +			}
   1.226 +		TESTPOINT(charIndex == numberOfCursorPositionsToCheck[ii]);
   1.227 +		aSource->iParFormat.iFlags &= ~(RTmParFormat::ERightToLeft); // reset back to default of LeftToRight
   1.228 +		}
   1.229 +
   1.230 +	CleanupStack::PopAndDestroy(NO_OF_TEST_CASES); // cleanup all HBufC* stored in logicalText array
   1.231 +	}
   1.232 +
   1.233 +/**
   1.234 +@SYMTestCaseID 			SYSLIB-FORM-UT-3610
   1.235 +@SYMTestCaseDesc  		Testing behaviour of r2l text when wrapping occurs and bidirectional text allowed
   1.236 +@SYMTestPriority  		High
   1.237 +@SYMTestActions 		1. Have some arabic text
   1.238 +						2. Set wrap width to 10 chars
   1.239 +						3. Set alignment to NormalBidirectional
   1.240 +						4. Call CTmTextLayout::SetTextL
   1.241 +						5. Retrieve the cursor position
   1.242 +						6. Check the lineinfo to ensure that the innerRect TL.iX parameter is positive.
   1.243 +@SYMTestExpectedResults	The innerRect that holds text top left x position is positive.
   1.244 +@SYMDEF					DEF109737,PDEF110819,PDEF110820,PDEF110821
   1.245 +*/
   1.246 +void DEF109737(CTmTextLayout* aLayout, CTestSource* aSource)
   1.247 +	{
   1.248 +	//R2L paragraph wrapping
   1.249 +	_LIT(KLllHahHah1, "lll\x62D\x62D\x2029\x62D\x62D\x2029");
   1.250 +	HBufC* buf = HBufC::NewLC(KLllHahHah1().Length());
   1.251 +	*buf = KLllHahHah1;
   1.252 +	aSource->SetText(buf);
   1.253 +	aSource->iParFormat.iFlags = 1;
   1.254 +	aSource->iParFormat.iAlignment = RTmParFormat::EAlignNormalBidirectional;
   1.255 +	TTmFormatParam format;
   1.256 +	format.iStartChar = 0;
   1.257 +	format.iEndChar = buf->Length();
   1.258 +	format.iLineInPar = 0;
   1.259 +	format.iWrapWidth = 10;
   1.260 +	aLayout->SetTextL(*aSource, format);
   1.261 +	TTmLineInfo lineInfo;
   1.262 +	TPoint position;
   1.263 +	TInt width;
   1.264 +	TInt ascent;
   1.265 +	TInt descent;
   1.266 +	TInt type = 0;
   1.267 +	TInt pos = 0;
   1.268 +	TTmDocPosSpec posSpec(pos,static_cast<TTmDocPosSpec::TType>(type));
   1.269 +	TBool result = aLayout->GetCursor(posSpec, ECursorVertical,
   1.270 +									lineInfo, position, width, ascent, descent);
   1.271 +	TESTPOINT(result);
   1.272 +	//Test that the LHS is non negative. Because we are allowing bidirectional text the
   1.273 +	//text shouldnt wrap to next line but instead the cursor can scroll left or right to see the text.
   1.274 +	TESTPOINT(lineInfo.iInnerRect.iTl.iX >= 0);
   1.275 +	CleanupStack::PopAndDestroy(buf);
   1.276 +	}
   1.277 +
   1.278 +/** INC041367 - Cursor in wrong position when it is one char before the
   1.279 +beginning of RTL text.
   1.280 +
   1.281 +Tests that the cursor is always hanging to the right in a left to right
   1.282 +paragraph. This prevents the cursor from being confusingly positioned on top of
   1.283 +a little L, for example.
   1.284 +*/
   1.285 +void INC041367(CTmTextLayout* aLayout, CTestSource* aSource)
   1.286 +	{
   1.287 +	_LIT(KLllHahHah, "lll\x62D\x62D\x2029");
   1.288 +
   1.289 +	HBufC* buf = HBufC::NewLC(KLllHahHah().Length());
   1.290 +	*buf = KLllHahHah;
   1.291 +	aSource->SetText(buf);
   1.292 +	aSource->iParFormat.iFlags = 0;
   1.293 +	TTmFormatParam format;
   1.294 +	format.iStartChar = 0;
   1.295 +	format.iEndChar = buf->Length();
   1.296 +	format.iLineInPar = 0;
   1.297 +	aLayout->SetTextL(*aSource, format);
   1.298 +	TTmLineInfo lineInfo;
   1.299 +	for (TInt pos = 0; pos != 6; ++pos)
   1.300 +		{
   1.301 +		for (TInt type = 0; type != 4; ++type)
   1.302 +			{
   1.303 +			TPoint position;
   1.304 +			TInt width;
   1.305 +			TInt ascent;
   1.306 +			TInt descent;
   1.307 +			TTmDocPosSpec posSpec(pos,
   1.308 +				static_cast<TTmDocPosSpec::TType>(type));
   1.309 +			TBool result = aLayout->GetCursor(posSpec, ECursorVertical,
   1.310 +				lineInfo, position, width, ascent, descent);
   1.311 +			TESTPOINT(result);
   1.312 +			TESTPOINT(0 < width);
   1.313 +			}
   1.314 +		}
   1.315 +	CleanupStack::PopAndDestroy(buf);
   1.316 +	}
   1.317 +
   1.318 +TVerdict CTBidiCursorPosStep::doTestStepL()
   1.319 +	{
   1.320 +    SetTestStepResult(EPass);
   1.321 +    TestStep = this;
   1.322 +    TESTPRINT(_L("TBidiCursorPos - GetNextVisualCursorPos tests"));
   1.323 +	CTmTextLayout* layout = new(ELeave) CTmTextLayout;
   1.324 +	CleanupStack::PushL(layout);
   1.325 +	CTestSource* source = CTestSource::NewLC();
   1.326 +	TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-3610 GetNextVisualCursorPos tests "));
   1.327 +	GetNextVisualCursorPosTestsL(layout, source);
   1.328 +	TESTPRINT(_L("INC041367"));
   1.329 +	INC041367(layout, source);
   1.330 +	TESTPRINT(_L("DEF109737"));
   1.331 +	DEF109737(layout, source);
   1.332 +	
   1.333 +	CleanupStack::PopAndDestroy(source);
   1.334 +	CleanupStack::PopAndDestroy(layout);
   1.335 +	return TestStepResult();
   1.336 +	}
   1.337 +