2 * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.symbianfoundation.org/legal/licencesv10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
15 * Definitions for bidirectional text reordering.
34 class TBidirectionalState
36 The bidirectional state class.
37 This class contains functions that implement the Unicode Bidirectional Algorithm,
38 which changes text from logical order to display order for the correct display
39 of right-to-left scripts, like Arabic and Hebrew. A TBidirectionalState object
40 carries the embedding level and stack from one line to the next. On construction
41 it is in its 'start of paragraph' state.
50 Information about a run of characters with the same bidirectional
53 An array of these representing a line is passed into, and reordered by,
60 /** Category of a run of text: passed to ReorderLine(); these are
61 passed in as TChar::TBdCategory values but are modified for internal
64 /** Embedding level of this run: used internally by ReorderLine(). */
65 TUint8 iEmbeddingLevel;
66 /** Resolved direction of this run: 0 for left to right, 1 for right
69 /** Index of this run after reordering. */
71 /** Start of text; returned by ReorderText(). */
73 /** Length of text; returned by ReorderText(). */
77 IMPORT_C TBidirectionalState();
78 IMPORT_C void ReorderLine(TRunInfo* aRunInfo,TInt aRuns,TBool aParStart,TBool aParEnd,TBool aParRightToLeft,
79 TChar::TBdCategory aNextCategory,TChar::TBdCategory aNextStrongCategory,
80 TBool& aVisualEndIsAmbiguous);
81 IMPORT_C void ReorderLine(TRunInfo* aRunInfo,TInt aRuns,TBool aParStart,TBool aParEnd,TBool aParRightToLeft,
82 TChar::TBdCategory aNextCategory,TChar::TBdCategory aNextStrongCategory);
83 IMPORT_C static TInt ReorderText(const TText* aText,TInt aLength,TBool aParRightToLeft,TText*& aNewText);
84 IMPORT_C static void ReverseGroups(TText* aStart,TInt aLength);
85 IMPORT_C void Reset();
86 IMPORT_C TBool IsDefault() const;
87 IMPORT_C TBool operator==(const TBidirectionalState& aState) const;
88 IMPORT_C void ExternalizeL(RWriteStream& aDest);
89 IMPORT_C void InternalizeL(RReadStream& aSource);
90 TBool ParRightToLeft() const { return iStack[0].iEmbeddingLevel & 1; }
93 // Bidirectional categories coded as bit flags
96 ELeftToRight = 1 << TChar::ELeftToRight,
97 ELeftToRightEmbedding = 1 << TChar::ELeftToRightEmbedding,
98 ELeftToRightOverride = 1 << TChar::ELeftToRightOverride,
99 ERightToLeft = 1 << TChar::ERightToLeft,
100 ERightToLeftArabic = 1 << TChar::ERightToLeftArabic,
101 ERightToLeftEmbedding = 1 << TChar::ERightToLeftEmbedding,
102 ERightToLeftOverride = 1 << TChar::ERightToLeftOverride,
103 EPopDirectionalFormat = 1 << TChar::EPopDirectionalFormat,
104 EEuropeanNumber = 1 << TChar::EEuropeanNumber,
105 EEuropeanNumberSeparator = 1 << TChar::EEuropeanNumberSeparator,
106 EEuropeanNumberTerminator = 1 << TChar::EEuropeanNumberTerminator,
107 EArabicNumber = 1 << TChar::EArabicNumber,
108 ECommonNumberSeparator = 1 << TChar::ECommonNumberSeparator,
109 ENonSpacingMark = 1 << TChar::ENonSpacingMark,
110 EBoundaryNeutral = 1 << TChar::EBoundaryNeutral,
111 EParagraphSeparator = 1 << TChar::EParagraphSeparator,
112 ESegmentSeparator = 1 << TChar::ESegmentSeparator,
113 EWhitespace = 1 << TChar::EWhitespace,
114 EOtherNeutral = 1 << TChar::EOtherNeutral,
117 EBdControlsGroup = ELeftToRightEmbedding | ERightToLeftEmbedding |
118 ELeftToRightOverride | ERightToLeftOverride | EPopDirectionalFormat,
119 ELeftToRightGroup = ELeftToRight | EEuropeanNumber | ELeftToRightOverride | ELeftToRightEmbedding,
120 ERightToLeftGroup = ERightToLeft | EArabicNumber | ERightToLeftArabic | ERightToLeftOverride |
121 ERightToLeftEmbedding,
122 EStrongGroup = ELeftToRightEmbedding | ERightToLeftEmbedding
123 | ELeftToRightOverride | ERightToLeftOverride
124 | ELeftToRight | ERightToLeft | ERightToLeftArabic,
131 EMaxExplicitLevel = 61,
138 ENoOverrideState = 0,
139 ELeftToRightOverrideState = ELeftToRightOverride,
140 ERightToLeftOverrideState = ERightToLeftOverride
146 TUint8 iEmbeddingLevel; // embedding level
147 TOverrideState iOverrideState; // directional override state
148 TCategory iStartCategory; // category that started this level; EOtherNeutral if none
152 /** The information needed during line reordering.
153 @internalComponent */
154 class TReorderContext
157 void SetNextCategory(TChar::TBdCategory aCat);
158 void SetNextStrongCategory(TChar::TBdCategory aCat);
160 /** Category at start of next line, or ON if at the end of the
162 TCategory iNextCategory;
163 /** Which of L, R or AL appears first in the remainder of the
164 paragraph, or ON if none. */
165 TCategory iNextStrongCategory;
166 /** The run array for this line. */
168 /** The length of iRunInfo. */
170 /** Bitmap of categories currently present in iRunInfo. */
172 /** Found by the algorithm to set iPreviousStrongCategory. */
173 TCategory iLastStrongCategory;
177 static TInt GenerateBdRunArray(const TText* aText, TInt aLength,
178 TBidirectionalState::TRunInfo* aRun, TInt aMaxRuns);
181 const TStackItem& State() const { return iStack[iStackLevel]; }
182 TCategory Push(TCategory aStartCategory);
186 TBidirectionalState(TChar::TBdCategory aPrevCat,
187 TChar::TBdCategory aPrevStrongCat, TBool aParRightToLeft);
188 void HandleBdControls(TReorderContext& aContext);
189 void ResolveWeakTypesW1W2W3(TReorderContext& aContext);
190 void ResolveWeakTypesW4W5W6(TReorderContext& aContext);
191 void ResolveWeakTypesW7(TReorderContext& aContext);
192 void ResolveNeutralTypes(TReorderContext& aContext);
193 void ResolveImplicitLevels(TReorderContext& aContext);
194 void PrepareForNextLine(const TReorderContext& aContext);
195 void ReorderRuns(TReorderContext& aContext);
196 static TInt CatToNumber(TInt aCat);
197 static TCategory CharToBdCat(TChar::TBdCategory aCat);
198 static TCategory UintToBdCat(TUint aCat);
199 static void DeneutralizeRuns(TRunInfo* aStart, TRunInfo* aEnd,
200 TCategory aStartCategory, TCategory aEndCategory);
202 TCategory iPreviousCategory; // category at end of last line, or EStartOfParagraph if at start of par
203 TCategory iPreviousStrongCategory; // L or R; derived from embedding level if at start of par
204 TInt16 iStackLevel; // current stack level
205 TInt8 iPushesBeyond60; // number of times Push called with iStackLevel == 60 and Left-To-Right category
206 TInt8 iPushesBeyond61; // number of times Push called with iStackLevel == 61
207 TStackItem iStack[EMaxStackLevels]; // the stack of embedding levels