os/textandloc/textrendering/textformatting/test/src/TBidiCursorPos.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
// Test code for GetNextVisualCursorPos functionality
sl@0
    19
#include <e32test.h>
sl@0
    20
sl@0
    21
#include "TGraphicsContext.h"
sl@0
    22
#include <gdi.h>
sl@0
    23
#include "TAGMA.H"
sl@0
    24
#include "TmLayoutImp.h"
sl@0
    25
#include "TMINTERP.H"
sl@0
    26
#include "tbidicursorpos.h"
sl@0
    27
sl@0
    28
namespace LocalToTBidiCursorPos
sl@0
    29
{
sl@0
    30
CTBidiCursorPosStep* TestStep;
sl@0
    31
#define TESTPOINT(p) TestStep->testpoint(p,(TText8*)__FILE__,__LINE__)
sl@0
    32
#define TESTPRINT(p) TestStep->print(p,(TText8*)__FILE__,__LINE__)
sl@0
    33
sl@0
    34
}
sl@0
    35
sl@0
    36
using namespace LocalToTBidiCursorPos;
sl@0
    37
sl@0
    38
class CTestSource : public CBase, public MTmSource
sl@0
    39
	{
sl@0
    40
public:
sl@0
    41
	static CTestSource* NewLC();
sl@0
    42
	~CTestSource();
sl@0
    43
	void ConstructL();
sl@0
    44
	// from MTmSource
sl@0
    45
	MGraphicsDeviceMap& FormatDevice() const { return *iScreenDevice; }
sl@0
    46
	MGraphicsDeviceMap& InterpretDevice() const { return *iScreenDevice; }
sl@0
    47
	TInt DocumentLength() const
sl@0
    48
		{
sl@0
    49
		return iText->Length();
sl@0
    50
		}
sl@0
    51
	void GetText(TInt aPos,TPtrC& aText, TTmCharFormat& aFormat) const
sl@0
    52
		{
sl@0
    53
		TTmCharFormat f;
sl@0
    54
		aFormat = f;
sl@0
    55
		aText.Set(iText->Mid(aPos));
sl@0
    56
		}
sl@0
    57
	void GetParagraphFormatL(TInt, RTmParFormat& aFormat) const
sl@0
    58
		{
sl@0
    59
		aFormat.CopyL(iParFormat);
sl@0
    60
		}
sl@0
    61
	TInt ParagraphStart(TInt) const { return 0; }
sl@0
    62
sl@0
    63
	void SetText(HBufC* aText) { iText = aText; }
sl@0
    64
sl@0
    65
private:
sl@0
    66
	CTestSource() {}
sl@0
    67
sl@0
    68
public:
sl@0
    69
	RTmParFormat iParFormat;
sl@0
    70
private:
sl@0
    71
	CTestGraphicsDevice* iScreenDevice;
sl@0
    72
	CWindowGc* iGc;
sl@0
    73
	HBufC* iText;
sl@0
    74
	};
sl@0
    75
sl@0
    76
// static
sl@0
    77
CTestSource* CTestSource::NewLC()
sl@0
    78
	{
sl@0
    79
	CTestSource* self = new(ELeave) CTestSource();
sl@0
    80
	CleanupStack::PushL(self);
sl@0
    81
	self->ConstructL();
sl@0
    82
	return self;
sl@0
    83
	}
sl@0
    84
sl@0
    85
void CTestSource::ConstructL()
sl@0
    86
	{
sl@0
    87
	TSize size(100, 100);
sl@0
    88
	iScreenDevice = CTestGraphicsDevice::NewL(size, 0);
sl@0
    89
	User::LeaveIfError(iScreenDevice->CreateContext(iGc));
sl@0
    90
	}
sl@0
    91
sl@0
    92
CTestSource::~CTestSource()
sl@0
    93
	{
sl@0
    94
	delete iScreenDevice;
sl@0
    95
	delete iGc;
sl@0
    96
	}
sl@0
    97
sl@0
    98
#define NO_OF_TEST_CASES 8
sl@0
    99
sl@0
   100
class TPos
sl@0
   101
	{
sl@0
   102
public:
sl@0
   103
	TInt iPos;
sl@0
   104
	TBool iLeading;
sl@0
   105
	};
sl@0
   106
class TAugmentedPos
sl@0
   107
	{
sl@0
   108
public:
sl@0
   109
	TInt iPos;
sl@0
   110
	TBool iLeading;
sl@0
   111
	TBool iOptional;
sl@0
   112
	};
sl@0
   113
sl@0
   114
const TAugmentedPos expectedCursorPos[NO_OF_TEST_CASES][40] = {
sl@0
   115
	{ {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {5, 1, 0},
sl@0
   116
		{4, 1, 0}, {3, 1, 0}, {7, 0, 0}, {8, 0, 0},
sl@0
   117
		{9, 0, 0} },
sl@0
   118
	{ {1, 0, 0}, {2, 0, 0}, {10, 1, 0}, {9, 1, 0},
sl@0
   119
		{8, 1, 0}, {7, 1, 0}, {6, 0, 0}, {7, 0, 0},
sl@0
   120
		{4, 1, 0}, {3, 1, 0}, {2, 1, 0}, {12, 0, 0},
sl@0
   121
		{13, 0, 0} },
sl@0
   122
	{ {1, 0, 0}, {2, 0, 0}, {5, 1, 1}, {4, 1, 0},
sl@0
   123
		{3, 1, 1}, {2, 1, 1}, {7, 0, 0}, {8, 0, 0},
sl@0
   124
		{9, 0, 0} },
sl@0
   125
	{ {1, 0, 0}, {2, 0, 0}, {3, 0, 0}, {5, 1, 0},
sl@0
   126
		{4, 1, 0}, {3, 1, 0}, {7, 0, 0}, {8, 0, 0},
sl@0
   127
		{9, 0, 0}, {11, 1, 0}, {10, 1, 0}, {9, 1, 0},
sl@0
   128
		{13, 0, 0}, {14, 0, 0}, {15, 0, 0} },
sl@0
   129
	{ {2, 0, 0}, {3, 0, 0}, {4, 0, 0} },
sl@0
   130
	{ {3, 0, 0}, {4, 0, 0} },
sl@0
   131
	{ {1, 0, 0}, {2, 0, 0}, {6, 1, 0}, {5, 1, 0},
sl@0
   132
		{4, 1, 0}, {3, 1, 0}, {2, 1, 0}, {8, 0, 0},
sl@0
   133
		{9, 0, 0} },
sl@0
   134
	{ {1, 0, 0}, {2, 0, 0}, {8, 1, 0}, {7, 1, 0},
sl@0
   135
		{6, 1, 0}, {5, 1, 0}, {4, 1, 0}, {3, 1, 0},
sl@0
   136
		{2, 1, 0}, {10, 0, 0}, {11, 0, 0} }
sl@0
   137
	};
sl@0
   138
sl@0
   139
const TPos startPos[NO_OF_TEST_CASES] = { {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} };
sl@0
   140
sl@0
   141
const TInt numberOfCursorPositionsToCheck[NO_OF_TEST_CASES] = {9, 13, 9, 15, 3, 2, 9, 11};
sl@0
   142
const TBool moveToLeft[NO_OF_TEST_CASES] = {EFalse, EFalse, EFalse, ETrue, ETrue, EFalse, ETrue, ETrue};
sl@0
   143
const TBool rightToLeftPara[NO_OF_TEST_CASES] = {EFalse, EFalse, EFalse, ETrue, EFalse, EFalse, ETrue, ETrue};
sl@0
   144
sl@0
   145
void GetNextVisualCursorPosTestsL(CTmTextLayout* aLayout, CTestSource* aSource)
sl@0
   146
	{
sl@0
   147
	// Testcase 1
sl@0
   148
	_LIT(KBidi1, "abc\x644\x644\x644zzz\x2029");
sl@0
   149
sl@0
   150
	// Testcase 2 (0x32 and 0x39 changed to 0x6F2 and 0x0F9, see note below)
sl@0
   151
	_LIT(KBidi2, "ab\x644\x644\x644\x6F2\x6F9\x644\x644\x644\x644zy\x2029");
sl@0
   152
sl@0
   153
	// Testcase 3
sl@0
   154
	_LIT(KBidi3, "ab\x202ejk\x202cjkl\x2029");
sl@0
   155
sl@0
   156
	// Testcase 4
sl@0
   157
	_LIT(KBidi4, "\x644\x644\x644xyz\x644\x644\x644xyz\x644\x644\x644\x2029");
sl@0
   158
sl@0
   159
	// Testcase 5
sl@0
   160
	_LIT(KBidi5, "\x647\x64b\x647\x647\x2029");
sl@0
   161
sl@0
   162
	// Testcase 6
sl@0
   163
	_LIT(KBidi6, "a\x302\x317z\x2029");
sl@0
   164
sl@0
   165
	// Testcase 7 (0x31 and 0x32 changed to 0x6F1 and 0x0F2, see note below)
sl@0
   166
	_LIT(KBidi7, "\x644\x644\x6F1\x6F2\x2e\x33\x34\x644\x644\x2029");
sl@0
   167
sl@0
   168
	// Testcase 8 (0x31 - 0x35 changed to 0x6F1 - 0x0F5, see note below)
sl@0
   169
	_LIT(KBidi8, "\x644\x644\x6F1\x2c\x6F2\x6F3\x2e\x6F4\x6F5\x644\x644\x2029");
sl@0
   170
sl@0
   171
// Note: Test cases 2 and 7 have been changed to use \x6F0-\x6F9, Extended Arabic Digits,
sl@0
   172
// These have the bidirectional class "EN",the same as ASCII digits.
sl@0
   173
// These have been used in preference to ASCII digits
sl@0
   174
// to work around a CodeWarrior preprocessor/C-Cover problem.
sl@0
   175
// For more detils see DEF042186
sl@0
   176
sl@0
   177
	HBufC* logicalText[NO_OF_TEST_CASES];
sl@0
   178
	logicalText[0] = KBidi1().AllocLC();
sl@0
   179
	logicalText[1] = KBidi2().AllocLC();
sl@0
   180
	logicalText[2] = KBidi3().AllocLC();
sl@0
   181
	logicalText[3] = KBidi4().AllocLC();
sl@0
   182
	logicalText[4] = KBidi5().AllocLC();
sl@0
   183
	logicalText[5] = KBidi6().AllocLC();
sl@0
   184
	logicalText[6] = KBidi7().AllocLC();
sl@0
   185
	logicalText[7] = KBidi8().AllocLC();
sl@0
   186
sl@0
   187
	TTmFormatParam format;
sl@0
   188
	format.iStartChar = 0;
sl@0
   189
	format.iEndChar = 0;
sl@0
   190
	format.iLineInPar = 0;
sl@0
   191
sl@0
   192
	TTmDocPos pos(0, ETrue);
sl@0
   193
	TTmPosInfo2 info;
sl@0
   194
	int charIndex;
sl@0
   195
	TBuf<40> msg;
sl@0
   196
sl@0
   197
	for (TInt ii = 0; ii < NO_OF_TEST_CASES; ii++)
sl@0
   198
		{
sl@0
   199
		msg.Format(_L("GetNextVisualCursorPos test case %d\n"), ii + 1);
sl@0
   200
		TESTPRINT(msg);
sl@0
   201
		aSource->SetText(logicalText[ii]);
sl@0
   202
		format.iEndChar = logicalText[ii]->Length();
sl@0
   203
		if (rightToLeftPara[ii])
sl@0
   204
			aSource->iParFormat.iFlags |= RTmParFormat::ERightToLeft;
sl@0
   205
		aLayout->SetTextL(*aSource, format);
sl@0
   206
sl@0
   207
		charIndex = 0;
sl@0
   208
		pos.iPos = startPos[ii].iPos;
sl@0
   209
		pos.iLeadingEdge = startPos[ii].iLeading;
sl@0
   210
		while (aLayout->GetNextVisualCursorPos(pos, info, moveToLeft[ii]))
sl@0
   211
			{
sl@0
   212
			while (info.iDocPos.iPos != expectedCursorPos[ii][charIndex].iPos
sl@0
   213
				|| info.iDocPos.iLeadingEdge != expectedCursorPos[ii][charIndex].iLeading)
sl@0
   214
				{
sl@0
   215
                TESTPOINT(expectedCursorPos[ii][charIndex].iOptional);
sl@0
   216
				++charIndex;
sl@0
   217
				TESTPOINT(charIndex != numberOfCursorPositionsToCheck[ii]);
sl@0
   218
				}
sl@0
   219
			pos = info.iDocPos;
sl@0
   220
			++charIndex;
sl@0
   221
			TESTPOINT(charIndex <= numberOfCursorPositionsToCheck[ii]);
sl@0
   222
			}
sl@0
   223
		TESTPOINT(charIndex == numberOfCursorPositionsToCheck[ii]);
sl@0
   224
		aSource->iParFormat.iFlags &= ~(RTmParFormat::ERightToLeft); // reset back to default of LeftToRight
sl@0
   225
		}
sl@0
   226
sl@0
   227
	CleanupStack::PopAndDestroy(NO_OF_TEST_CASES); // cleanup all HBufC* stored in logicalText array
sl@0
   228
	}
sl@0
   229
sl@0
   230
/**
sl@0
   231
@SYMTestCaseID 			SYSLIB-FORM-UT-3610
sl@0
   232
@SYMTestCaseDesc  		Testing behaviour of r2l text when wrapping occurs and bidirectional text allowed
sl@0
   233
@SYMTestPriority  		High
sl@0
   234
@SYMTestActions 		1. Have some arabic text
sl@0
   235
						2. Set wrap width to 10 chars
sl@0
   236
						3. Set alignment to NormalBidirectional
sl@0
   237
						4. Call CTmTextLayout::SetTextL
sl@0
   238
						5. Retrieve the cursor position
sl@0
   239
						6. Check the lineinfo to ensure that the innerRect TL.iX parameter is positive.
sl@0
   240
@SYMTestExpectedResults	The innerRect that holds text top left x position is positive.
sl@0
   241
@SYMDEF					DEF109737,PDEF110819,PDEF110820,PDEF110821
sl@0
   242
*/
sl@0
   243
void DEF109737(CTmTextLayout* aLayout, CTestSource* aSource)
sl@0
   244
	{
sl@0
   245
	//R2L paragraph wrapping
sl@0
   246
	_LIT(KLllHahHah1, "lll\x62D\x62D\x2029\x62D\x62D\x2029");
sl@0
   247
	HBufC* buf = HBufC::NewLC(KLllHahHah1().Length());
sl@0
   248
	*buf = KLllHahHah1;
sl@0
   249
	aSource->SetText(buf);
sl@0
   250
	aSource->iParFormat.iFlags = 1;
sl@0
   251
	aSource->iParFormat.iAlignment = RTmParFormat::EAlignNormalBidirectional;
sl@0
   252
	TTmFormatParam format;
sl@0
   253
	format.iStartChar = 0;
sl@0
   254
	format.iEndChar = buf->Length();
sl@0
   255
	format.iLineInPar = 0;
sl@0
   256
	format.iWrapWidth = 10;
sl@0
   257
	aLayout->SetTextL(*aSource, format);
sl@0
   258
	TTmLineInfo lineInfo;
sl@0
   259
	TPoint position;
sl@0
   260
	TInt width;
sl@0
   261
	TInt ascent;
sl@0
   262
	TInt descent;
sl@0
   263
	TInt type = 0;
sl@0
   264
	TInt pos = 0;
sl@0
   265
	TTmDocPosSpec posSpec(pos,static_cast<TTmDocPosSpec::TType>(type));
sl@0
   266
	TBool result = aLayout->GetCursor(posSpec, ECursorVertical,
sl@0
   267
									lineInfo, position, width, ascent, descent);
sl@0
   268
	TESTPOINT(result);
sl@0
   269
	//Test that the LHS is non negative. Because we are allowing bidirectional text the
sl@0
   270
	//text shouldnt wrap to next line but instead the cursor can scroll left or right to see the text.
sl@0
   271
	TESTPOINT(lineInfo.iInnerRect.iTl.iX >= 0);
sl@0
   272
	CleanupStack::PopAndDestroy(buf);
sl@0
   273
	}
sl@0
   274
sl@0
   275
/** INC041367 - Cursor in wrong position when it is one char before the
sl@0
   276
beginning of RTL text.
sl@0
   277
sl@0
   278
Tests that the cursor is always hanging to the right in a left to right
sl@0
   279
paragraph. This prevents the cursor from being confusingly positioned on top of
sl@0
   280
a little L, for example.
sl@0
   281
*/
sl@0
   282
void INC041367(CTmTextLayout* aLayout, CTestSource* aSource)
sl@0
   283
	{
sl@0
   284
	_LIT(KLllHahHah, "lll\x62D\x62D\x2029");
sl@0
   285
sl@0
   286
	HBufC* buf = HBufC::NewLC(KLllHahHah().Length());
sl@0
   287
	*buf = KLllHahHah;
sl@0
   288
	aSource->SetText(buf);
sl@0
   289
	aSource->iParFormat.iFlags = 0;
sl@0
   290
	TTmFormatParam format;
sl@0
   291
	format.iStartChar = 0;
sl@0
   292
	format.iEndChar = buf->Length();
sl@0
   293
	format.iLineInPar = 0;
sl@0
   294
	aLayout->SetTextL(*aSource, format);
sl@0
   295
	TTmLineInfo lineInfo;
sl@0
   296
	for (TInt pos = 0; pos != 6; ++pos)
sl@0
   297
		{
sl@0
   298
		for (TInt type = 0; type != 4; ++type)
sl@0
   299
			{
sl@0
   300
			TPoint position;
sl@0
   301
			TInt width;
sl@0
   302
			TInt ascent;
sl@0
   303
			TInt descent;
sl@0
   304
			TTmDocPosSpec posSpec(pos,
sl@0
   305
				static_cast<TTmDocPosSpec::TType>(type));
sl@0
   306
			TBool result = aLayout->GetCursor(posSpec, ECursorVertical,
sl@0
   307
				lineInfo, position, width, ascent, descent);
sl@0
   308
			TESTPOINT(result);
sl@0
   309
			TESTPOINT(0 < width);
sl@0
   310
			}
sl@0
   311
		}
sl@0
   312
	CleanupStack::PopAndDestroy(buf);
sl@0
   313
	}
sl@0
   314
sl@0
   315
TVerdict CTBidiCursorPosStep::doTestStepL()
sl@0
   316
	{
sl@0
   317
    SetTestStepResult(EPass);
sl@0
   318
    TestStep = this;
sl@0
   319
    TESTPRINT(_L("TBidiCursorPos - GetNextVisualCursorPos tests"));
sl@0
   320
	CTmTextLayout* layout = new(ELeave) CTmTextLayout;
sl@0
   321
	CleanupStack::PushL(layout);
sl@0
   322
	CTestSource* source = CTestSource::NewLC();
sl@0
   323
	TESTPRINT(_L(" @SYMTestCaseID:SYSLIB-FORM-UT-3610 GetNextVisualCursorPos tests "));
sl@0
   324
	GetNextVisualCursorPosTestsL(layout, source);
sl@0
   325
	TESTPRINT(_L("INC041367"));
sl@0
   326
	INC041367(layout, source);
sl@0
   327
	TESTPRINT(_L("DEF109737"));
sl@0
   328
	DEF109737(layout, source);
sl@0
   329
	
sl@0
   330
	CleanupStack::PopAndDestroy(source);
sl@0
   331
	CleanupStack::PopAndDestroy(layout);
sl@0
   332
	return TestStepResult();
sl@0
   333
	}
sl@0
   334