fontservices/textbase/sgdi/BIDI.CPP
author hgs
Mon, 12 Jul 2010 14:38:26 +0800
changeset 45 662fa7de7023
permissions -rw-r--r--
201024_05
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45
662fa7de7023 201024_05
hgs
parents:
diff changeset
     1
// Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies).
662fa7de7023 201024_05
hgs
parents:
diff changeset
     2
// All rights reserved.
662fa7de7023 201024_05
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
662fa7de7023 201024_05
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
662fa7de7023 201024_05
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
662fa7de7023 201024_05
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
662fa7de7023 201024_05
hgs
parents:
diff changeset
     7
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
     8
// Initial Contributors:
662fa7de7023 201024_05
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    10
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
    11
// Contributors:
662fa7de7023 201024_05
hgs
parents:
diff changeset
    12
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
    13
// Description:
662fa7de7023 201024_05
hgs
parents:
diff changeset
    14
// Bidirectional text reordering; based on the Unicode Bidirectional Reordering Algorithm.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    15
// 
662fa7de7023 201024_05
hgs
parents:
diff changeset
    16
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
    17
662fa7de7023 201024_05
hgs
parents:
diff changeset
    18
#include <bidi.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    19
#include "BidiCopy.h"
662fa7de7023 201024_05
hgs
parents:
diff changeset
    20
#include <s32std.h>
662fa7de7023 201024_05
hgs
parents:
diff changeset
    21
662fa7de7023 201024_05
hgs
parents:
diff changeset
    22
const TInt KBidirectionalStateOverrideStreamValueNone = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    23
const TInt KBidirectionalStateOverrideStreamValueLeftToRight = 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    24
const TInt KBidirectionalStateOverrideStreamValueRightToLeft = 2;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    25
662fa7de7023 201024_05
hgs
parents:
diff changeset
    26
inline TBool IsSupplementary(TUint aChar)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    27
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    28
@param aChar The 32-bit code point value of a Unicode character.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    29
662fa7de7023 201024_05
hgs
parents:
diff changeset
    30
@return True, if aChar is supplementary character; false, otherwise.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    31
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    32
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    33
	return (aChar > 0xFFFF);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    34
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    35
662fa7de7023 201024_05
hgs
parents:
diff changeset
    36
inline TBool IsHighSurrogate(TText16 aInt16)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    37
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    38
@return True, if aText16 is high surrogate; false, otherwise.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    39
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    40
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    41
	return (aInt16 & 0xFC00) == 0xD800;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    42
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    43
662fa7de7023 201024_05
hgs
parents:
diff changeset
    44
inline TBool IsLowSurrogate(TText16 aInt16)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    45
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    46
@return True, if aText16 is low surrogate; false, otherwise.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    47
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    48
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    49
	return (aInt16 & 0xFC00) == 0xDC00;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    50
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    51
662fa7de7023 201024_05
hgs
parents:
diff changeset
    52
inline TUint JoinSurrogate(TText16 aHighSurrogate, TText16 aLowSurrogate)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    53
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
    54
Combine a high surrogate and a low surrogate into a supplementary character.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    55
662fa7de7023 201024_05
hgs
parents:
diff changeset
    56
@return The 32-bit code point value of the generated Unicode supplementary
662fa7de7023 201024_05
hgs
parents:
diff changeset
    57
        character.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    58
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
    59
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    60
	return ((aHighSurrogate - 0xD7F7) << 10) + aLowSurrogate;
662fa7de7023 201024_05
hgs
parents:
diff changeset
    61
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    62
662fa7de7023 201024_05
hgs
parents:
diff changeset
    63
TBool TextDefaultsToRightToLeft(const TDesC& aText, TBool* aFound);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    64
662fa7de7023 201024_05
hgs
parents:
diff changeset
    65
TBidirectionalState::TCategory TBidirectionalState::CharToBdCat(TChar::TBdCategory aCat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    66
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    67
	return static_cast<TBidirectionalState::TCategory>(
662fa7de7023 201024_05
hgs
parents:
diff changeset
    68
		1 << static_cast<TInt>(aCat));
662fa7de7023 201024_05
hgs
parents:
diff changeset
    69
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    70
662fa7de7023 201024_05
hgs
parents:
diff changeset
    71
TBidirectionalState::TCategory TBidirectionalState::UintToBdCat(TUint aCat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    72
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    73
	return static_cast<TBidirectionalState::TCategory>(1 << aCat);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    74
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    75
662fa7de7023 201024_05
hgs
parents:
diff changeset
    76
void TBidirectionalState::TReorderContext::SetNextCategory(
662fa7de7023 201024_05
hgs
parents:
diff changeset
    77
	TChar::TBdCategory aCat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    78
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    79
	iNextCategory = CharToBdCat(aCat);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    80
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    81
662fa7de7023 201024_05
hgs
parents:
diff changeset
    82
void TBidirectionalState::TReorderContext::SetNextStrongCategory(
662fa7de7023 201024_05
hgs
parents:
diff changeset
    83
	TChar::TBdCategory aCat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    84
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    85
	iNextStrongCategory = CharToBdCat(aCat);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    86
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
    87
662fa7de7023 201024_05
hgs
parents:
diff changeset
    88
662fa7de7023 201024_05
hgs
parents:
diff changeset
    89
EXPORT_C void TBidirectionalState::ReverseGroups(TText* aStart,TInt aLength)
662fa7de7023 201024_05
hgs
parents:
diff changeset
    90
/** A utility to reverse text apart from combining characters, which remains after 
662fa7de7023 201024_05
hgs
parents:
diff changeset
    91
their base characters. This is what is needed when drawing right-to-left text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    92
662fa7de7023 201024_05
hgs
parents:
diff changeset
    93
@param aStart Start position of text to be reversed.
662fa7de7023 201024_05
hgs
parents:
diff changeset
    94
@param aLength Length of text to be reversed. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
    95
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
    96
	BidiCopy::ReverseCodes(aStart, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    97
	BidiCopy::DeleteUnreversedSurrogates(aStart, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    98
	BidiCopy::SubstituteMirrorImages(aStart, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
    99
	BidiCopy::CorrectGroups(aStart, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   100
	BidiCopy::CorrectSurrogatePairs(aStart, aLength);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   101
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   102
662fa7de7023 201024_05
hgs
parents:
diff changeset
   103
662fa7de7023 201024_05
hgs
parents:
diff changeset
   104
// A local helper function. Get the next character from a buffer. This
662fa7de7023 201024_05
hgs
parents:
diff changeset
   105
// function won't check buffer length.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   106
//
662fa7de7023 201024_05
hgs
parents:
diff changeset
   107
// @param aText The text buffer to read character from.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   108
// @param aCharacterIndex Count of characters to skip in aText.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   109
// @return The character.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   110
TUint GetOneCharacter(const TText16 *aText, TInt aCharacterIndex)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   111
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   112
	const TText16 *p = aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   113
	TUint c = 0xFFFF;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   114
	while (aCharacterIndex >= 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   115
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   116
		c = *p++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   117
		ASSERT(!IsLowSurrogate(c));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   118
		if (IsHighSurrogate(c))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   119
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   120
			ASSERT(IsLowSurrogate(*p));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   121
			c = JoinSurrogate(c, *p++);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   122
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   123
		--aCharacterIndex;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   124
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   125
	return c;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   126
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   127
662fa7de7023 201024_05
hgs
parents:
diff changeset
   128
662fa7de7023 201024_05
hgs
parents:
diff changeset
   129
TInt TBidirectionalState::GenerateBdRunArray(const TText* aText, TInt aLength,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   130
	TBidirectionalState::TRunInfo* aRun, TInt aMaxRuns)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   131
/** Analyse the input text for runs of characters that share the same
662fa7de7023 201024_05
hgs
parents:
diff changeset
   132
bidirectional class. Categories TChar::EEuropeanNumberSeparator and
662fa7de7023 201024_05
hgs
parents:
diff changeset
   133
TChar::ECommonNumberSeparator are kept as singletons due to a limitation in
662fa7de7023 201024_05
hgs
parents:
diff changeset
   134
the reordering logic.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   135
@param aText The text to be analysed.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   136
@param aLength The length of the text to be analysed.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   137
@param aRun	Output buffer for the runs after analysis. May be null if there 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   138
is to be no output.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   139
@param aMaxRuns The size of the aRun array. No more than this number of runs 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   140
will be	output.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   141
@return The number of runs that are required for the full results of the
662fa7de7023 201024_05
hgs
parents:
diff changeset
   142
analysis.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   143
@internalTechnology */	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   144
    {
662fa7de7023 201024_05
hgs
parents:
diff changeset
   145
	if (aLength == 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   146
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   147
		if (aRun && 0 < aMaxRuns)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   148
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   149
			aRun[0].iCategory = TChar::EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   150
			aRun[0].iStart = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   151
			aRun[0].iLength = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   152
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   153
		return 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   154
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   155
	int runs = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   156
	int run_start = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   157
	int run_end = 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   158
	const TText* p = aText;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   159
	const TText* q = p + aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   160
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   161
	// get the character pointed by 'p', then move 'p' to next character, and adjust 'run_end' if need
662fa7de7023 201024_05
hgs
parents:
diff changeset
   162
	TChar pc = ::GetOneCharacter(p, 0);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   163
	TChar::TBdCategory cur_cat = pc.GetBdCategory();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   164
	++p;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   165
	if (IsSupplementary(pc))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   166
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   167
		++p;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   168
		run_end = 2;	// run_end points to "end" of current character
662fa7de7023 201024_05
hgs
parents:
diff changeset
   169
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   170
	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   171
	while (p < q)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   172
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   173
		// get the character pointed by 'p'
662fa7de7023 201024_05
hgs
parents:
diff changeset
   174
		pc = ::GetOneCharacter(p, 0);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   175
		
662fa7de7023 201024_05
hgs
parents:
diff changeset
   176
		TChar::TBdCategory new_cat = pc.GetBdCategory();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   177
		if (new_cat != cur_cat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   178
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   179
			if (new_cat == TChar::ENonSpacingMark &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
   180
				cur_cat != TChar::ELeftToRightEmbedding &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
   181
				cur_cat != TChar::ELeftToRightOverride &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
   182
				cur_cat != TChar::ERightToLeftEmbedding &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
   183
				cur_cat != TChar::ERightToLeftOverride &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
   184
				cur_cat != TChar::EPopDirectionalFormat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   185
				new_cat = cur_cat;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   186
			else if (p < q - 1 &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
   187
					 (new_cat == TChar::EWhitespace ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   188
					  new_cat == TChar::EEuropeanNumberSeparator ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   189
					  new_cat == TChar::ECommonNumberSeparator))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   190
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   191
				TChar nextChar = ::GetOneCharacter(p, 1);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   192
				TChar::TBdCategory next_cat = nextChar.GetBdCategory();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   193
				if (new_cat == TChar::EWhitespace)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   194
					{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   195
					if ((cur_cat == TChar::ELeftToRight ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   196
						 cur_cat == TChar::ERightToLeft ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   197
						 cur_cat == TChar::ERightToLeftArabic) && cur_cat == next_cat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   198
						new_cat = cur_cat;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   199
					}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   200
				else if (cur_cat == TChar::EEuropeanNumber && next_cat == TChar::EEuropeanNumber)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   201
					new_cat = TChar::EEuropeanNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   202
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   203
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   204
662fa7de7023 201024_05
hgs
parents:
diff changeset
   205
		if (new_cat != cur_cat ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   206
			cur_cat == TChar::EEuropeanNumberSeparator ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   207
			cur_cat == TChar::ECommonNumberSeparator)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   208
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   209
			if (aRun && runs < aMaxRuns)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   210
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   211
				aRun[runs].iCategory = cur_cat;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   212
				aRun[runs].iStart = run_start;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   213
				aRun[runs].iLength = run_end - run_start;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   214
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   215
			
662fa7de7023 201024_05
hgs
parents:
diff changeset
   216
			runs++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   217
			run_start = run_end;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   218
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   219
662fa7de7023 201024_05
hgs
parents:
diff changeset
   220
		p++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   221
		run_end++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   222
662fa7de7023 201024_05
hgs
parents:
diff changeset
   223
		// adjust 'p' and 'run_end'
662fa7de7023 201024_05
hgs
parents:
diff changeset
   224
		if (IsSupplementary(pc))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   225
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   226
			p++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   227
			run_end++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   228
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   229
662fa7de7023 201024_05
hgs
parents:
diff changeset
   230
		cur_cat = new_cat;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   231
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   232
662fa7de7023 201024_05
hgs
parents:
diff changeset
   233
	if (aRun && runs < aMaxRuns)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   234
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   235
		aRun[runs].iCategory = cur_cat;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   236
		aRun[runs].iStart = run_start;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   237
		aRun[runs].iLength = run_end - run_start;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   238
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   239
662fa7de7023 201024_05
hgs
parents:
diff changeset
   240
	return runs + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   241
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   242
662fa7de7023 201024_05
hgs
parents:
diff changeset
   243
662fa7de7023 201024_05
hgs
parents:
diff changeset
   244
EXPORT_C TInt TBidirectionalState::ReorderText(const TText* aText,TInt aLength,TBool aParRightToLeft,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   245
											   TText*& aNewText)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   246
/** Reorders text according to the Unicode Bidirectional Reordering algorithm.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   247
662fa7de7023 201024_05
hgs
parents:
diff changeset
   248
Reorders the input text from logical order (which may be bidirectional) to 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   249
display order (strictly left to right).
662fa7de7023 201024_05
hgs
parents:
diff changeset
   250
662fa7de7023 201024_05
hgs
parents:
diff changeset
   251
@param aText The input text in logical order.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   252
@param aLength The length of the input text.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   253
@param aParRightToLeft ETrue if the default directionality of the text to be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   254
re-ordered is right-to-left.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   255
@param aNewText Returns the re-ordered text. If the text did not need re-ordering, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   256
or if there was an error, aText will be returned. Otherwise, ownership of 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   257
a newly allocated buffer will be returned to the caller. This buffer must 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   258
be deleted with delete[] (or CleanupArrayDeletePushL()) and not delete (or 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   259
CleanupStack::PushL()).
662fa7de7023 201024_05
hgs
parents:
diff changeset
   260
@return A system-wide error value if there has been an error; KErrNone if there 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   261
has not. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   262
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   263
	aNewText = const_cast<TText*>(aText);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   264
	if (aLength < 2)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   265
		return KErrNone;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   266
662fa7de7023 201024_05
hgs
parents:
diff changeset
   267
	int error = KErrNone;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   268
	TBidirectionalState::TRunInfo run_info;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   269
	run_info.iDirection = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   270
	run_info.iIndex = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   271
	run_info.iStart = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   272
	run_info.iLength = aLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   273
	TBidirectionalState::TRunInfo* run_info_array = &run_info;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   274
	TBidirectionalState::TRunInfo* allocated_run_info_array = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   275
	int runs = GenerateBdRunArray(aText, aLength, run_info_array, 1);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   276
	if (runs > 1)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   277
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   278
		allocated_run_info_array = new TBidirectionalState::TRunInfo[runs];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   279
		if (allocated_run_info_array)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   280
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   281
			run_info_array = allocated_run_info_array;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   282
			GenerateBdRunArray(aText, aLength, run_info_array, runs);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   283
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   284
		else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   285
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   286
			// the run cannot be allocated: stick with our single l-to-r run
662fa7de7023 201024_05
hgs
parents:
diff changeset
   287
			error = KErrNoMemory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   288
			runs = 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   289
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   290
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   291
	if (error == KErrNone)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   292
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   293
		TBidirectionalState state;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   294
		state.ReorderLine(run_info_array, runs, ETrue, ETrue, aParRightToLeft,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   295
			TChar::EOtherNeutral, TChar::EOtherNeutral);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   296
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   297
662fa7de7023 201024_05
hgs
parents:
diff changeset
   298
	// If there was only one run and it's left-to-right, we've finished.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   299
	if (!allocated_run_info_array && run_info.iDirection == 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   300
		return error;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   301
662fa7de7023 201024_05
hgs
parents:
diff changeset
   302
	// Reorder the text into a new buffer.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   303
	TText* buffer = new TText[aLength];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   304
	if (!buffer)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   305
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   306
		delete [] allocated_run_info_array;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   307
		return KErrNoMemory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   308
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   309
	const TBidirectionalState::TRunInfo* r = run_info_array;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   310
	TText* dest = buffer;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   311
	for (int i = 0; i < runs; i++, r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   312
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   313
		const TText* source = &aText[r->iStart];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   314
		int length = r->iLength;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   315
		Mem::Copy(dest,source,length * sizeof(TText));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   316
		if (r->iDirection)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   317
			ReverseGroups(dest,length);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   318
		dest += length;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   319
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   320
662fa7de7023 201024_05
hgs
parents:
diff changeset
   321
	delete [] allocated_run_info_array;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   322
	aNewText = buffer;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   323
	return KErrNone;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   324
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   325
662fa7de7023 201024_05
hgs
parents:
diff changeset
   326
662fa7de7023 201024_05
hgs
parents:
diff changeset
   327
EXPORT_C TBidirectionalState::TBidirectionalState()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   328
/** Standard constructor. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   329
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   330
	Reset();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   331
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   332
662fa7de7023 201024_05
hgs
parents:
diff changeset
   333
662fa7de7023 201024_05
hgs
parents:
diff changeset
   334
/** Reorders a line of text and updates the bidirectional state for the next line.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   335
662fa7de7023 201024_05
hgs
parents:
diff changeset
   336
@param aRunInfo An array of objects representing runs of characters with the 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   337
same bidirectional category. Any number of characters can be combined into 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   338
a run if they have the same category, except for the categories TChar::EEuropeanNumberSeparator 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   339
and TChar::ECommonNumberSeparator, which should be put into single-character 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   340
runs because the reordering logic depends on this.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   341
@param aRuns Number of 'run info' objects.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   342
@param aParStart Tells the function whether the line is the first line of a 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   343
paragraph.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   344
@param aParEnd Tells the function whether the line is the last line of a paragraph.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   345
@param aParRightToLeft ETrue if the default directionality of the text to be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   346
re-ordered is right-to-left.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   347
@param aNextCategory The category of the character immediately after the end 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   348
of the line. This is ignored if aParEnd is ETrue.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   349
@param aNextStrongCategory The category of the first strong character (one 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   350
of the categories ELeftToRight, ELeftToRightEmbedding, ELeftToRightOverride, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   351
ERightToLeft, ERightToLeftArabic, ERightToLeftEmbedding or ERightToLeftOverride) 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   352
after the end of the line. This is ignored if aParEnd is ETrue.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   353
@param aVisualEndIsAmbiguous EFalse if the logical end of this line is at the
662fa7de7023 201024_05
hgs
parents:
diff changeset
   354
visual end and the logical beginning of the next line is at the visual beginning.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   355
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   356
EXPORT_C void TBidirectionalState::ReorderLine(TRunInfo* aRunInfo, TInt aRuns,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   357
	TBool aParStart, TBool aParEnd, TBool aParRightToLeft,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   358
	TChar::TBdCategory aNextCategory, TChar::TBdCategory aNextStrongCategory,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   359
	TBool& aVisualEndIsAmbiguous)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   360
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   361
	ReorderLine(aRunInfo, aRuns, aParStart, aParEnd, aParRightToLeft,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   362
		aNextCategory, aNextStrongCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   363
	if (iStackLevel  != 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   364
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   365
		aVisualEndIsAmbiguous = ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   366
		return;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   367
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   368
	TCategory nextCat = CharToBdCat(aNextCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   369
	TCategory nextStrong = CharToBdCat(aNextStrongCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   370
	const TUint KAllStrongLeftToRight =
662fa7de7023 201024_05
hgs
parents:
diff changeset
   371
		ELeftToRight | ELeftToRightEmbedding | ELeftToRightOverride;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   372
	const TUint KAllStrongRightToLeft =
662fa7de7023 201024_05
hgs
parents:
diff changeset
   373
		ERightToLeft | ERightToLeftArabic | ERightToLeftEmbedding | ERightToLeftOverride;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   374
	if (aParRightToLeft)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   375
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   376
		// Ambiguous if any of the surrounding categories are strongly left-to-right
662fa7de7023 201024_05
hgs
parents:
diff changeset
   377
		aVisualEndIsAmbiguous =
662fa7de7023 201024_05
hgs
parents:
diff changeset
   378
			(iPreviousStrongCategory | iPreviousCategory | nextCat | nextStrong)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   379
			& KAllStrongLeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   380
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   381
	else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   382
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   383
		// Ambiguous if any of the surrounding categories are strongly right-to-left
662fa7de7023 201024_05
hgs
parents:
diff changeset
   384
		aVisualEndIsAmbiguous =
662fa7de7023 201024_05
hgs
parents:
diff changeset
   385
			(iPreviousStrongCategory | iPreviousCategory | nextCat | nextStrong)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   386
			& KAllStrongRightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   387
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   388
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   389
/** Reorders a line of text and updates the bidirectional state for the next line.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   390
662fa7de7023 201024_05
hgs
parents:
diff changeset
   391
@param aRunInfo An array of objects representing runs of characters with the 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   392
same bidirectional category. Any number of characters can be combined into 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   393
a run if they have the same category, except for the categories TChar::EEuropeanNumberSeparator 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   394
and TChar::ECommonNumberSeparator, which should be put into single-character 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   395
runs because the reordering logic depends on this.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   396
@param aRuns Number of 'run info' objects.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   397
@param aParStart Tells the function whether the line is the first line of a 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   398
paragraph.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   399
@param aParEnd Tells the function whether the line is the last line of a paragraph.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   400
@param aParRightToLeft ETrue if the default directionality of the text to be 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   401
re-ordered is right-to-left.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   402
@param aNextCategory The category of the character immediately after the end 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   403
of the line. This is ignored if aParEnd is ETrue.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   404
@param aNextStrongCategory The category of the first strong character (one 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   405
of the categories ELeftToRight, ELeftToRightEmbedding, ELeftToRightOverride, 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   406
ERightToLeft, ERightToLeftArabic, ERightToLeftEmbedding or ERightToLeftOverride) 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   407
after the end of the line. This is ignored if aParEnd is ETrue. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   408
EXPORT_C void TBidirectionalState::ReorderLine(TRunInfo* aRunInfo, TInt aRuns,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   409
	TBool aParStart, TBool aParEnd, TBool aParRightToLeft,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   410
	TChar::TBdCategory aNextCategory, TChar::TBdCategory aNextStrongCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   411
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   412
	// Reset if this is a new paragraph.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   413
	if (aParStart)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   414
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   415
		Reset();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   416
		iPreviousCategory = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   417
		if (aParRightToLeft)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   418
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   419
			iStack[0].iEmbeddingLevel = 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   420
			iPreviousStrongCategory = ERightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   421
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   422
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   423
662fa7de7023 201024_05
hgs
parents:
diff changeset
   424
	// Initialise the context object.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   425
	TReorderContext context;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   426
	context.iRunInfo = aRunInfo;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   427
	context.iRuns = aRuns;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   428
	context.iLastStrongCategory = iPreviousStrongCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   429
	if (aParEnd)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   430
		context.iNextCategory = context.iNextStrongCategory = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   431
	else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   432
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   433
		context.iNextCategory = CharToBdCat(aNextCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   434
		context.iNextStrongCategory = CharToBdCat(aNextStrongCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   435
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   436
662fa7de7023 201024_05
hgs
parents:
diff changeset
   437
	// Initialise output data and find out what categories are present so that unnecessary steps can be skipped.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   438
	context.iCategories = iPreviousCategory | context.iNextCategory | context.iNextStrongCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   439
	for (TInt i = 0; i != aRuns; ++i)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   440
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   441
		aRunInfo[i].iEmbeddingLevel = iStack[0].iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   442
		aRunInfo[i].iDirection = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   443
		aRunInfo[i].iIndex = i;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   444
		aRunInfo[i].iCategory = UintToBdCat(aRunInfo[i].iCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   445
		context.iCategories |= aRunInfo[i].iCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   446
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   447
662fa7de7023 201024_05
hgs
parents:
diff changeset
   448
	// Do nothing if no right-to-left material is present.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   449
	if (aRuns == 0 ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   450
		(iStackLevel == 0 && iStack[0].iEmbeddingLevel == 0 &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
   451
		 !(context.iCategories & (ERightToLeftGroup | EBdControlsGroup))))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   452
		return;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   453
662fa7de7023 201024_05
hgs
parents:
diff changeset
   454
	// Perform the bidirectional algorithm.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   455
	if ((context.iCategories & EBdControlsGroup) ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
   456
		State().iOverrideState != ENoOverrideState)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   457
		HandleBdControls(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   458
	ResolveWeakTypesW1W2W3(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   459
	ResolveWeakTypesW4W5W6(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   460
	ResolveWeakTypesW7(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   461
	if (context.iCategories & EOtherNeutral)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   462
		ResolveNeutralTypes(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   463
	ResolveImplicitLevels(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   464
	PrepareForNextLine(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   465
	ReorderRuns(context);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   466
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   467
662fa7de7023 201024_05
hgs
parents:
diff changeset
   468
662fa7de7023 201024_05
hgs
parents:
diff changeset
   469
void TBidirectionalState::PrepareForNextLine(const TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   470
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   471
Fold context information back into TBidirectionalState.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   472
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   473
*/	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   474
   {
662fa7de7023 201024_05
hgs
parents:
diff changeset
   475
	if (aContext.iRuns != 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   476
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   477
		iPreviousCategory = static_cast<TCategory>(
662fa7de7023 201024_05
hgs
parents:
diff changeset
   478
			aContext.iRunInfo[aContext.iRuns - 1].iCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   479
		iPreviousStrongCategory = aContext.iLastStrongCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   480
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   481
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   482
662fa7de7023 201024_05
hgs
parents:
diff changeset
   483
662fa7de7023 201024_05
hgs
parents:
diff changeset
   484
void TBidirectionalState::HandleBdControls(TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   485
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   486
Handle LRO, RLO, LRE, RLE and PDF. After this phase, these categories will no
662fa7de7023 201024_05
hgs
parents:
diff changeset
   487
longer be found.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   488
662fa7de7023 201024_05
hgs
parents:
diff changeset
   489
This corresponds to Unicode(3.2) Bidirectional Algorithm phases X1-X7.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   490
Phase X8 is not required as the run is assumed to be all in one paragraph.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   491
Phases X9-X10 are implicit in other functions.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   492
662fa7de7023 201024_05
hgs
parents:
diff changeset
   493
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   494
*/	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   495
   {
662fa7de7023 201024_05
hgs
parents:
diff changeset
   496
	aContext.iCategories = iPreviousCategory | aContext.iNextCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   497
	for (TInt i = 0; i != aContext.iRuns; ++i)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   498
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   499
		TRunInfo* r = aContext.iRunInfo + i;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   500
		TCategory nextCatInLine = i < aContext.iRuns - 1?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   501
			(TCategory)(r[1].iCategory) : ENoCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   502
662fa7de7023 201024_05
hgs
parents:
diff changeset
   503
		TBool was_pdf = FALSE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   504
		if (r->iCategory & EBdControlsGroup)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   505
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   506
			if (r->iCategory == EPopDirectionalFormat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   507
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   508
				if (iStackLevel > 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   509
					{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   510
					was_pdf = TRUE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   511
					r->iEmbeddingLevel = State().iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   512
					if (nextCatInLine == State().iStartCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   513
						// Ignore POP-PUSH pair with nothing between.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   514
						// This is surely wrong? Perhaps it is a hack to
662fa7de7023 201024_05
hgs
parents:
diff changeset
   515
						// help other parts of the algorithm. Must investigate.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   516
						// TPB.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   517
						r->iCategory = r[1].iCategory = EBoundaryNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   518
					else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   519
						{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   520
						r->iCategory = Pop();
662fa7de7023 201024_05
hgs
parents:
diff changeset
   521
						}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   522
					}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   523
				else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   524
					r->iCategory = EBoundaryNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   525
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   526
			else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   527
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   528
				// Category is LRE, RLE, LRO or RLO.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   529
				if (nextCatInLine == EPopDirectionalFormat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   530
					// Ignore PUSH-POP pair with nothing between.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   531
					r->iCategory = r[1].iCategory = EBoundaryNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   532
				else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   533
					r->iCategory = Push(static_cast<TCategory>(r->iCategory));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   534
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   535
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   536
662fa7de7023 201024_05
hgs
parents:
diff changeset
   537
		if (!was_pdf)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   538
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   539
			switch (State().iOverrideState)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   540
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   541
				case ELeftToRightOverrideState:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   542
					r->iCategory = ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   543
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   544
				case ERightToLeftOverrideState:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   545
					r->iCategory = ERightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   546
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   547
				default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   548
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   549
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   550
			r->iEmbeddingLevel = State().iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   551
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   552
		if (r->iCategory & EStrongGroup)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   553
			aContext.iLastStrongCategory = static_cast<TCategory>(r->iCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   554
		aContext.iCategories |= r->iCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   555
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   556
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   557
662fa7de7023 201024_05
hgs
parents:
diff changeset
   558
662fa7de7023 201024_05
hgs
parents:
diff changeset
   559
void TBidirectionalState::ResolveWeakTypesW1W2W3(TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   560
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   561
Unicode(3.2) Bidirectional Algorithm phases W1, W2 and W3.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   562
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   563
*/	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   564
    {
662fa7de7023 201024_05
hgs
parents:
diff changeset
   565
	if (!(aContext.iCategories
662fa7de7023 201024_05
hgs
parents:
diff changeset
   566
		& (ENonSpacingMark | ERightToLeftArabic | EEuropeanNumber)))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   567
		return;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   568
662fa7de7023 201024_05
hgs
parents:
diff changeset
   569
	TRunInfo* endOfRuns = aContext.iRunInfo + aContext.iRuns;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   570
	TCategory prev_cat = iPreviousCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   571
	TBool european_to_arabic_number = iPreviousStrongCategory == ERightToLeftArabic;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   572
662fa7de7023 201024_05
hgs
parents:
diff changeset
   573
	aContext.iCategories = iPreviousCategory | aContext.iNextCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   574
	for (TRunInfo* r = aContext.iRunInfo; r != endOfRuns; r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   575
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   576
		switch (r->iCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   577
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   578
			case ENonSpacingMark:					// non-spacing marks change to the previous category
662fa7de7023 201024_05
hgs
parents:
diff changeset
   579
				r->iCategory = prev_cat;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   580
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   581
			case ELeftToRight:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   582
				european_to_arabic_number = EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   583
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   584
			case ERightToLeft:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   585
				european_to_arabic_number = EFalse;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   586
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   587
			case ERightToLeftArabic:				// Arabic letters change to R
662fa7de7023 201024_05
hgs
parents:
diff changeset
   588
				european_to_arabic_number = ETrue;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   589
				r->iCategory = ERightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   590
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   591
			case EEuropeanNumber:				    // European numbers change to Arabic if last strong category was R
662fa7de7023 201024_05
hgs
parents:
diff changeset
   592
				if (european_to_arabic_number)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   593
					r->iCategory = EArabicNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   594
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   595
			default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   596
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   597
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   598
		aContext.iCategories |= r->iCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   599
		prev_cat = static_cast<TCategory>(r->iCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   600
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   601
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   602
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   603
This phase removes categories NSM, AL, ES, ET, CS, BS, S, WS and BN, leaving
662fa7de7023 201024_05
hgs
parents:
diff changeset
   604
only L, R, EN, AN and ON.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   605
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   606
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   607
void TBidirectionalState::ResolveWeakTypesW4W5W6(TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   608
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   609
	int i;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   610
	TRunInfo* r;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   611
	TCategory prev_cat = iPreviousCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   612
	TCategory next_cat = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   613
662fa7de7023 201024_05
hgs
parents:
diff changeset
   614
	// Phase P0b.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   615
	prev_cat = iPreviousCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   616
	if (aContext.iCategories & EBoundaryNeutral)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   617
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   618
		for (i = 0, aContext.iCategories = iPreviousCategory | aContext.iNextCategory, r = aContext.iRunInfo;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   619
			 i < aContext.iRuns;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   620
			 i++, aContext.iCategories |= r->iCategory, r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   621
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   622
			if (r->iCategory == EBoundaryNeutral)		// runs of boundary neutrals change to EN, ET or AN if adjacent to
662fa7de7023 201024_05
hgs
parents:
diff changeset
   623
				{										// one of these, otherwise to ON
662fa7de7023 201024_05
hgs
parents:
diff changeset
   624
				int end = i + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   625
				while (end < aContext.iRuns && aContext.iRunInfo[end].iCategory == EBoundaryNeutral)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   626
					end++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   627
				next_cat = end < aContext.iRuns ? (TCategory)(aContext.iRunInfo[end].iCategory) : aContext.iNextCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   628
				TCategory c = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   629
				if (prev_cat == EEuropeanNumber || next_cat == EEuropeanNumber)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   630
					c = EEuropeanNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   631
				else if (prev_cat == EEuropeanNumberTerminator || next_cat == EEuropeanNumberTerminator)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   632
					c = EEuropeanNumberTerminator;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   633
				else if (prev_cat == EArabicNumber || next_cat == EArabicNumber)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   634
					c = EArabicNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   635
				for (int j = i; j < end; j++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   636
					aContext.iRunInfo[j].iCategory = c;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   637
				i = end - 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   638
				r = &aContext.iRunInfo[i];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   639
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   640
			prev_cat = (TCategory)r->iCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   641
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   642
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   643
662fa7de7023 201024_05
hgs
parents:
diff changeset
   644
	// Phase P1.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   645
	prev_cat = iPreviousCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   646
	if (aContext.iCategories & (EEuropeanNumberSeparator | ECommonNumberSeparator))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   647
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   648
		for (i = 0, aContext.iCategories = iPreviousCategory | aContext.iNextCategory, r = aContext.iRunInfo;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   649
			 i < aContext.iRuns;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   650
			 i++, aContext.iCategories |= r->iCategory, r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   651
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   652
			next_cat = i < aContext.iRuns - 1 ? (TCategory)(r[1].iCategory) : aContext.iNextCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   653
			switch (r->iCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   654
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   655
				case EEuropeanNumberSeparator:			// European separators change to EN if between two ENs, else to ON
662fa7de7023 201024_05
hgs
parents:
diff changeset
   656
					if (prev_cat == EEuropeanNumber && next_cat == EEuropeanNumber)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   657
						r->iCategory = EEuropeanNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   658
					else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   659
						r->iCategory = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   660
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   661
				case ECommonNumberSeparator:			// CSs change to EN or AN if between two of the same, else to ON
662fa7de7023 201024_05
hgs
parents:
diff changeset
   662
					if (prev_cat == EEuropeanNumber && next_cat == EEuropeanNumber)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   663
						r->iCategory = EEuropeanNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   664
					else if (prev_cat == EArabicNumber && next_cat == EArabicNumber)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   665
						r->iCategory = EArabicNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   666
					else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   667
						r->iCategory = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   668
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   669
				default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   670
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   671
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   672
			prev_cat = (TCategory)r->iCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   673
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   674
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   675
662fa7de7023 201024_05
hgs
parents:
diff changeset
   676
	/*
662fa7de7023 201024_05
hgs
parents:
diff changeset
   677
	Phase L1: tabs, whitespace before tabs, and trailing whitespace, is set to the base embedding level.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   678
	We ought to do this just before the final reordering, but the whitespace and segment separator
662fa7de7023 201024_05
hgs
parents:
diff changeset
   679
	categories have disappeared by then so we use the sentinel value 255 which tells
662fa7de7023 201024_05
hgs
parents:
diff changeset
   680
	ResolveImplicitLevels what to do.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   681
	*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   682
	TBool demote_whitespace = TRUE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   683
	for (i = aContext.iRuns - 1, r = &aContext.iRunInfo[i]; i >= 0; i--, r--)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   684
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   685
		switch (r->iCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   686
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   687
			case EWhitespace:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   688
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   689
			case ESegmentSeparator:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   690
				demote_whitespace = TRUE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   691
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   692
			default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   693
				demote_whitespace = FALSE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   694
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   695
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   696
		if (demote_whitespace)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   697
			r->iEmbeddingLevel = 255;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   698
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   699
662fa7de7023 201024_05
hgs
parents:
diff changeset
   700
	// Phases P2 and P3.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   701
	prev_cat = iPreviousCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   702
	if (aContext.iCategories & (EEuropeanNumberTerminator | ESegmentSeparator | EWhitespace))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   703
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   704
		for (i = 0, aContext.iCategories = iPreviousCategory | aContext.iNextCategory, r = aContext.iRunInfo;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   705
			 i < aContext.iRuns;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   706
			 i++, aContext.iCategories |= r->iCategory, r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   707
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   708
			next_cat = i < aContext.iRuns - 1 ? (TCategory)(r[1].iCategory) : aContext.iNextCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   709
			switch (r->iCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   710
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   711
				case EEuropeanNumberTerminator:			// runs of ETs change to ENs if next to an EN, else to ON
662fa7de7023 201024_05
hgs
parents:
diff changeset
   712
					{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   713
					int end = i + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   714
					while (end < aContext.iRuns && aContext.iRunInfo[end].iCategory == EEuropeanNumberTerminator)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   715
						end++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   716
					next_cat = end < aContext.iRuns ? (TCategory)(aContext.iRunInfo[end].iCategory) : aContext.iNextCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   717
					TCategory c = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   718
					if (prev_cat == EEuropeanNumber || next_cat == EEuropeanNumber)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   719
						c = EEuropeanNumber;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   720
					for (int j = i; j < end; j++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   721
						aContext.iRunInfo[j].iCategory = c;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   722
					i = end - 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   723
					r = &aContext.iRunInfo[i];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   724
					}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   725
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   726
				case ESegmentSeparator:					// S and WS change to ON
662fa7de7023 201024_05
hgs
parents:
diff changeset
   727
				case EWhitespace:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   728
					r->iCategory = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   729
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   730
				default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   731
					break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   732
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   733
			prev_cat = (TCategory)r->iCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   734
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   735
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   736
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   737
662fa7de7023 201024_05
hgs
parents:
diff changeset
   738
void TBidirectionalState::ResolveWeakTypesW7(TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   739
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   740
	if (!(aContext.iCategories & EEuropeanNumber))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   741
		return;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   742
662fa7de7023 201024_05
hgs
parents:
diff changeset
   743
	TCategory prev_strong_cat = iPreviousStrongCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   744
662fa7de7023 201024_05
hgs
parents:
diff changeset
   745
	aContext.iCategories = iPreviousCategory | aContext.iNextCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   746
	TRunInfo* endOfRuns = aContext.iRunInfo + aContext.iRuns;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   747
	for (TRunInfo* r = aContext.iRunInfo; r != endOfRuns; r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   748
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   749
		switch (r->iCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   750
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   751
			case ELeftToRight:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   752
				prev_strong_cat = ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   753
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   754
			case ERightToLeft:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   755
				prev_strong_cat = ERightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   756
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   757
			case EEuropeanNumber: 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   758
				if (prev_strong_cat == ELeftToRight)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   759
					r->iCategory = ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   760
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   761
			default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   762
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   763
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   764
		aContext.iCategories |= r->iCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   765
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   766
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   767
662fa7de7023 201024_05
hgs
parents:
diff changeset
   768
662fa7de7023 201024_05
hgs
parents:
diff changeset
   769
662fa7de7023 201024_05
hgs
parents:
diff changeset
   770
void TBidirectionalState::DeneutralizeRuns(TRunInfo* aStart, TRunInfo* aEnd,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   771
	TCategory aStartCategory, TCategory aEndCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   772
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   773
Turn all ON (Other Neutral) into non-neutrals according to the rules N1 and N2.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   774
@param aStart The start of the run array to be altered.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   775
@param aEnd One past the end of the run array to be altered.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   776
@param aStartCategory
662fa7de7023 201024_05
hgs
parents:
diff changeset
   777
	The last non-neutral before the run, must be ELeftToRight or ERightToLeft.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   778
@param aEndCategory
662fa7de7023 201024_05
hgs
parents:
diff changeset
   779
	The first non-neutral after the run, must be ELeftToRight or ERightToLeft.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   780
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   781
*/	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   782
	// if sandwiched by the same category, neutrals become that.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   783
	if (aStartCategory == aEndCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   784
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   785
		for (; aStart != aEnd; ++aStart)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   786
			aStart->iCategory = aStartCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   787
		return;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   788
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   789
	// otherwise look at the embedding level in each case
662fa7de7023 201024_05
hgs
parents:
diff changeset
   790
	for (; aStart != aEnd; ++aStart)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   791
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   792
		aStart->iCategory = aStart->iEmbeddingLevel & 1?
662fa7de7023 201024_05
hgs
parents:
diff changeset
   793
			ERightToLeft : ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   794
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   795
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   796
662fa7de7023 201024_05
hgs
parents:
diff changeset
   797
662fa7de7023 201024_05
hgs
parents:
diff changeset
   798
void TBidirectionalState::ResolveNeutralTypes(TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   799
	/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   800
This phase removes the ON (Other Neutral) category, leaving only L, R, EN, and
662fa7de7023 201024_05
hgs
parents:
diff changeset
   801
AN; no need to update aContext.iCategories.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   802
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   803
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
   804
    {
662fa7de7023 201024_05
hgs
parents:
diff changeset
   805
	// Really we should find if any number intervenes, but this would require
662fa7de7023 201024_05
hgs
parents:
diff changeset
   806
	// a BC break.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   807
	TCategory prevNonNeutral = iPreviousStrongCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   808
	if (prevNonNeutral & ELeftToRightGroup)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   809
		prevNonNeutral = ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   810
	else if (prevNonNeutral & ERightToLeftGroup)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   811
		prevNonNeutral = ERightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   812
	TRunInfo *prevNonNeutralRun = aContext.iRunInfo;	// one past the last non-neutral found
662fa7de7023 201024_05
hgs
parents:
diff changeset
   813
	TRunInfo *endOfRuns = aContext.iRunInfo + aContext.iRuns;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   814
662fa7de7023 201024_05
hgs
parents:
diff changeset
   815
	// All neutrals have now been changed to ON; change them to L or R depending on context.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   816
	for (TRunInfo *p = aContext.iRunInfo; p != endOfRuns; ++p)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   817
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   818
		TCategory nonNeutral = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   819
		switch (p->iCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   820
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   821
			case ELeftToRight:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   822
				nonNeutral = ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   823
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   824
			case ERightToLeft:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   825
				nonNeutral = ERightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   826
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   827
			case EArabicNumber:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   828
			case EEuropeanNumber: 
662fa7de7023 201024_05
hgs
parents:
diff changeset
   829
				nonNeutral = ERightToLeft;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   830
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   831
			default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   832
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   833
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   834
		if (nonNeutral != EOtherNeutral)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   835
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   836
			if (p != prevNonNeutralRun)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   837
				DeneutralizeRuns(prevNonNeutralRun, p,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   838
					prevNonNeutral, nonNeutral);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   839
			prevNonNeutral = nonNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   840
			prevNonNeutralRun = p + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   841
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   842
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   843
	DeneutralizeRuns(prevNonNeutralRun, endOfRuns, prevNonNeutral,
662fa7de7023 201024_05
hgs
parents:
diff changeset
   844
		aContext.iNextStrongCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   845
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   846
662fa7de7023 201024_05
hgs
parents:
diff changeset
   847
662fa7de7023 201024_05
hgs
parents:
diff changeset
   848
void TBidirectionalState::ResolveImplicitLevels(TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   849
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   850
Phases I1 and I2.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   851
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   852
*/	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   853
	int i;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   854
	TRunInfo* r;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   855
	for (i = 0, r = aContext.iRunInfo; i < aContext.iRuns; i++, r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   856
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   857
		if (r->iEmbeddingLevel == 255) // sentinel indicating this is a tab or segment-final whitespace
662fa7de7023 201024_05
hgs
parents:
diff changeset
   858
			r->iEmbeddingLevel = iStack[0].iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   859
		else switch (r->iCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   860
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   861
			case ELeftToRight:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   862
				if (r->iEmbeddingLevel & 1)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   863
					r->iEmbeddingLevel++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   864
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   865
			case ERightToLeft:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   866
				if (!(r->iEmbeddingLevel & 1))
662fa7de7023 201024_05
hgs
parents:
diff changeset
   867
					r->iEmbeddingLevel++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   868
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   869
			case EEuropeanNumber: case EArabicNumber:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   870
				if (r->iEmbeddingLevel & 1)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   871
					r->iEmbeddingLevel++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   872
				else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   873
					r->iEmbeddingLevel += 2;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   874
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   875
			default:
662fa7de7023 201024_05
hgs
parents:
diff changeset
   876
				break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   877
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   878
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   879
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   880
662fa7de7023 201024_05
hgs
parents:
diff changeset
   881
662fa7de7023 201024_05
hgs
parents:
diff changeset
   882
void TBidirectionalState::ReorderRuns(TReorderContext& aContext)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   883
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
   884
Phase L2.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   885
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
   886
*/	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   887
	// Find the highest level and lowest odd level.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   888
	int i;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   889
	TRunInfo* r;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   890
	int highest = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   891
	int lowest_odd = EMaxLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   892
	int level = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   893
	for (i = 0, r = aContext.iRunInfo; i < aContext.iRuns; i++, r++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   894
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   895
		level = r->iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   896
		if (level > highest)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   897
			highest = level;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   898
		if ((level & 1) && level < lowest_odd)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   899
			lowest_odd = level;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   900
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   901
662fa7de7023 201024_05
hgs
parents:
diff changeset
   902
	// From the highest level to the lowest odd level, reverse any run at that level or higher.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   903
	for (level = highest; level >= lowest_odd; level--)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   904
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   905
		int run_start = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   906
		r = aContext.iRunInfo;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   907
		while (run_start < aContext.iRuns)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   908
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   909
			while (run_start < aContext.iRuns && r->iEmbeddingLevel < level)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   910
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   911
				run_start++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   912
				r++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   913
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   914
			int run_end = run_start;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   915
			while (run_end < aContext.iRuns && r->iEmbeddingLevel >= level)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   916
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   917
				r->iDirection = !r->iDirection;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   918
				run_end++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   919
				r++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   920
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   921
			TRunInfo* p = &aContext.iRunInfo[run_start];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   922
			TRunInfo* q = &aContext.iRunInfo[run_end - 1];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   923
			while (p < q)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   924
				{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   925
				TRunInfo temp = *p;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   926
				*p = *q;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   927
				*q = temp;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   928
				p++;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   929
				q--;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   930
				}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   931
			run_start = run_end;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   932
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   933
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   934
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   935
662fa7de7023 201024_05
hgs
parents:
diff changeset
   936
662fa7de7023 201024_05
hgs
parents:
diff changeset
   937
TBidirectionalState::TCategory TBidirectionalState::Push(TCategory aStartCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   938
/** @internalComponent */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   939
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   940
	TInt rightToLeftFlag = (static_cast<TInt>(aStartCategory)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   941
		& ERightToLeftGroup)? 1 : 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   942
	TInt oldLevel = State().iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   943
	TInt newLevel = oldLevel + 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   944
	// And add an extra one if the bottom bit is not correct.
662fa7de7023 201024_05
hgs
parents:
diff changeset
   945
	newLevel += (newLevel & 1) ^ rightToLeftFlag;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   946
662fa7de7023 201024_05
hgs
parents:
diff changeset
   947
	if (EMaxExplicitLevel < newLevel)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   948
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   949
		if (oldLevel == 60)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   950
			++iPushesBeyond60;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   951
		else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   952
			++iPushesBeyond61;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   953
		return EBoundaryNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   954
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   955
662fa7de7023 201024_05
hgs
parents:
diff changeset
   956
	++iStackLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   957
	TStackItem& state = iStack[iStackLevel];
662fa7de7023 201024_05
hgs
parents:
diff changeset
   958
	state.iEmbeddingLevel = static_cast<TUint8>(newLevel);
662fa7de7023 201024_05
hgs
parents:
diff changeset
   959
	state.iOverrideState = static_cast<TOverrideState>(aStartCategory
662fa7de7023 201024_05
hgs
parents:
diff changeset
   960
		& (ELeftToRightOverride | ERightToLeftOverride));
662fa7de7023 201024_05
hgs
parents:
diff changeset
   961
	state.iStartCategory = aStartCategory;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   962
662fa7de7023 201024_05
hgs
parents:
diff changeset
   963
	return rightToLeftFlag? ERightToLeft : ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   964
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   965
662fa7de7023 201024_05
hgs
parents:
diff changeset
   966
662fa7de7023 201024_05
hgs
parents:
diff changeset
   967
TBidirectionalState::TCategory TBidirectionalState::Pop()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   968
/** @internalComponent */	
662fa7de7023 201024_05
hgs
parents:
diff changeset
   969
   {
662fa7de7023 201024_05
hgs
parents:
diff changeset
   970
	__ASSERT_DEBUG(0 < iStackLevel, User::Invariant());
662fa7de7023 201024_05
hgs
parents:
diff changeset
   971
	TInt level = State().iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   972
	if (level < 60)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   973
		--iStackLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   974
	else if (iPushesBeyond61 != 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   975
		--iPushesBeyond61;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   976
	else if (level == 61)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   977
		--iStackLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   978
	else if (iPushesBeyond60)
662fa7de7023 201024_05
hgs
parents:
diff changeset
   979
		--iPushesBeyond60;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   980
	else
662fa7de7023 201024_05
hgs
parents:
diff changeset
   981
		--iStackLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   982
	return (level & 1)? ERightToLeft : ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   983
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   984
662fa7de7023 201024_05
hgs
parents:
diff changeset
   985
662fa7de7023 201024_05
hgs
parents:
diff changeset
   986
EXPORT_C void TBidirectionalState::Reset()
662fa7de7023 201024_05
hgs
parents:
diff changeset
   987
/** Sets the object to its default 'start of paragraph' state. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
   988
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
   989
	iStackLevel = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   990
	iPushesBeyond60 = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   991
	iPushesBeyond61 = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   992
	iStack[0].iEmbeddingLevel = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   993
	iStack[0].iOverrideState = ENoOverrideState;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   994
	iStack[0].iStartCategory = EOtherNeutral;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   995
	iPreviousCategory = ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   996
	iPreviousStrongCategory = ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
   997
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
   998
662fa7de7023 201024_05
hgs
parents:
diff changeset
   999
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1000
EXPORT_C TBool TBidirectionalState::IsDefault() const
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1001
/** Returns Gets the default 'start of paragraph' state.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1002
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1003
@return ETrue if the object is in its default 'start of paragraph' state. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1004
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1005
	return iStackLevel == 0 &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1006
		   iStack[0].iEmbeddingLevel == 0 &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1007
		   iStack[0].iOverrideState == ENoOverrideState &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1008
		   iStack[0].iStartCategory == EOtherNeutral &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1009
		   iPreviousCategory == ELeftToRight &&
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1010
		   iPreviousStrongCategory == ELeftToRight;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1011
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1012
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1013
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1014
EXPORT_C TBool TBidirectionalState::operator==(const TBidirectionalState& aState) const
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1015
/** Return ETrue if two bidirectional states are identical.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1016
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1017
@param aState A bidirectional state.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1018
@return ETrue if two bidirectional states are identical. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1019
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1020
	if (iPreviousCategory != aState.iPreviousCategory ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1021
		iPreviousStrongCategory != aState.iPreviousStrongCategory ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1022
		iStackLevel != aState.iStackLevel)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1023
		return FALSE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1024
	const TStackItem* p = iStack;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1025
	const TStackItem* q = aState.iStack;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1026
	for (int i = 0; i <= iStackLevel; i++, p++, q++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1027
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1028
		if (p->iStartCategory != q->iStartCategory ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1029
			p->iOverrideState != q->iOverrideState ||
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1030
			p->iEmbeddingLevel != q->iEmbeddingLevel)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1031
			return FALSE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1032
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1033
	return TRUE;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1034
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1035
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1036
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1037
TInt TBidirectionalState::CatToNumber(TInt aCat)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1038
/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1039
Finds the highest bit set in the input. Used to convert
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1040
TBidirectionalState::TCategory into TChar::TBdCategory.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1041
@param aCat a TBidirectionalState::TCategory.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1042
@return The equivalent TChar::TBdCategory.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1043
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1044
*/	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1045
	TInt shifts = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1046
	TInt bits = 32;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1047
	TInt mask = ~0L;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1048
	while (bits != 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1049
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1050
		bits >>= 1;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1051
		mask <<= bits;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1052
		if ((aCat & mask) == 0)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1053
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1054
			aCat <<= bits;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1055
			shifts += bits;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1056
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1057
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1058
	return 31 - shifts;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1059
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1060
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1061
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1062
EXPORT_C void TBidirectionalState::ExternalizeL(RWriteStream& aDest)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1063
/** Serializes a bidirectional state to an output stream.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1064
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1065
@param aDest An output stream. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1066
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1067
	//+ put the prev cat, prev strong cat and stack levels in one number?
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1068
	// Write the previous category and previous strong category.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1069
	aDest.WriteInt8L(CatToNumber(iPreviousCategory));
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1070
	aDest.WriteInt8L(CatToNumber(iPreviousStrongCategory));
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1071
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1072
	// Write the number of stack levels
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1073
	aDest.WriteInt8L(iStackLevel);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1074
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1075
	/*
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1076
	Write each stack level as a single number: 5 bits for the start category, 2 for the override state,
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1077
	6 for the embedding level.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1078
	*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1079
	for (int i = 0; i <= iStackLevel; i++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1080
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1081
		TInt x = CatToNumber(iStack[i].iStartCategory);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1082
		if (iStack[i].iOverrideState == ELeftToRightOverrideState)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1083
			{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1084
			x |= (KBidirectionalStateOverrideStreamValueLeftToRight << 5);	
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1085
			}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1086
        else if (iStack[i].iOverrideState == ERightToLeftOverrideState)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1087
        	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1088
        	x |= (KBidirectionalStateOverrideStreamValueRightToLeft << 5); 	
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1089
        	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1090
       	x |= ((TInt)iStack[i].iEmbeddingLevel << 7);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1091
		aDest.WriteInt16L(x);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1092
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1093
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1094
	TInt level = State().iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1095
	if (60 <= level)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1096
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1097
		aDest.WriteInt8L(iPushesBeyond60);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1098
		aDest.WriteInt8L(iPushesBeyond61);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1099
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1100
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1101
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1102
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1103
EXPORT_C void TBidirectionalState::InternalizeL(RReadStream& aSource)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1104
/** Reads a bidirectional state from an input stream, translating it from its serialized 
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1105
form.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1106
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1107
@param aSource A source stream. */
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1108
	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1109
	// Read the previous category and the previous strong category.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1110
	TInt x = aSource.ReadInt8L();
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1111
	iPreviousCategory = (TCategory)(1 << x);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1112
	x = aSource.ReadInt8L();
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1113
	iPreviousStrongCategory = (TCategory)(1 << x);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1114
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1115
	// Read the number of stack levels.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1116
	iStackLevel = aSource.ReadInt8L();
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1117
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1118
	// Read the stack levels.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1119
	for (int i = 0; i <= iStackLevel; i++)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1120
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1121
		x = aSource.ReadInt16L();
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1122
		iStack[i].iStartCategory = (TCategory)(1 << (x & 0x1F));
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1123
		switch ((x >> 5) & 3)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1124
        	{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1125
    	case KBidirectionalStateOverrideStreamValueLeftToRight: 
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1126
    		iStack[i].iOverrideState = ELeftToRightOverrideState;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1127
    		break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1128
    	case KBidirectionalStateOverrideStreamValueRightToLeft:
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1129
    		iStack[i].iOverrideState = ERightToLeftOverrideState; 
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1130
    		break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1131
    	case KBidirectionalStateOverrideStreamValueNone:
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1132
    	default: iStack[i].iOverrideState = ENoOverrideState; break;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1133
        	};
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1134
		iStack[i].iEmbeddingLevel = (TUint8)(x >> 7);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1135
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1136
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1137
	TInt level = State().iEmbeddingLevel;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1138
	if (60 <= level)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1139
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1140
		iPushesBeyond60 = aSource.ReadInt8L();
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1141
		iPushesBeyond61 = aSource.ReadInt8L();
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1142
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1143
	else
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1144
		{
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1145
		iPushesBeyond60 = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1146
		iPushesBeyond61 = 0;
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1147
		}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1148
	}
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1149
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1150
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1151
TBidirectionalState::TBidirectionalState(TChar::TBdCategory aPrevCat,
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1152
	TChar::TBdCategory aPrevStrongCat,
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1153
	TBool aParRightToLeft)
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1154
	/**
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1155
Constructor suitable for test code.
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1156
@internalComponent
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1157
*/
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1158
    {
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1159
	Reset();
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1160
	iPreviousCategory = CharToBdCat(aPrevCat);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1161
	iPreviousStrongCategory = CharToBdCat(aPrevStrongCat);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1162
	iStack[0].iEmbeddingLevel = (TUint8) (aParRightToLeft? 1 : 0);
662fa7de7023 201024_05
hgs
parents:
diff changeset
  1163
	}