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