1 /* |
|
2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0"" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 // CAknFepInlineTextDecorator class |
|
30 // |
|
31 #include <aknenv.h> |
|
32 |
|
33 #include "AknFepInlineTextDecorator.h" |
|
34 #include "AknFepManager.h" |
|
35 |
|
36 #ifdef _DEBUG |
|
37 #include "AknFepPanic.h" |
|
38 #endif |
|
39 |
|
40 void CAknFepInlineTextDecorator::DecorateInlineText( |
|
41 const TDesC& aInlineText, |
|
42 TDes& aDecoratedText, |
|
43 TInt& aPositionOfInsertionPointInInlineText, |
|
44 TChar aPreviousCharacter, |
|
45 TBool aRTLParagraph, |
|
46 TBool aInputDirectionIsRTL) |
|
47 { |
|
48 DecorateNeutralCharacters(aInlineText, aDecoratedText, aPositionOfInsertionPointInInlineText, |
|
49 aPreviousCharacter, aRTLParagraph, aInputDirectionIsRTL); |
|
50 } |
|
51 |
|
52 /** |
|
53 * This routine performs a consolidation of directional markers in the region around text being committed. |
|
54 * It returns EFalse if no change has been made to the buffer. |
|
55 */ |
|
56 TBool CAknFepInlineTextDecorator::ResolveDecoratedText( |
|
57 TDes& aDecoratedTextPlusSurroundings, |
|
58 TCursorSelection aDecoratedTextSpan) |
|
59 { |
|
60 TBool needsResolving(EFalse); // Return value |
|
61 |
|
62 // Note that this is a copy of a part of the buffer and that aNewTextSpan is relative to this |
|
63 // new buffer, not the whole text buffer. |
|
64 // aNewTextSpan must fit within the descriptor; that is from 0 to length-1 |
|
65 // But remember that span is a span; indices refer to positions between characters. 0 is position just before 0 |
|
66 // 1 is a position between 0 and character 1. |
|
67 __ASSERT_DEBUG(aDecoratedTextSpan.LowerPos() >= 0, |
|
68 AknFepPanic(EAknFepPanicCharPosOutOfRange) ); |
|
69 __ASSERT_DEBUG(aDecoratedTextSpan.HigherPos() <= aDecoratedTextPlusSurroundings.Length(), |
|
70 AknFepPanic(EAknFepPanicCharPosOutOfRange) ); |
|
71 |
|
72 // Examine the decorated text for real content |
|
73 TBool cont = EFalse; |
|
74 TInt ii = 0; |
|
75 for (ii = aDecoratedTextSpan.LowerPos(); ii < aDecoratedTextSpan.HigherPos(); ii++) |
|
76 { |
|
77 if (!CharacterIsDirectionalMarker(aDecoratedTextPlusSurroundings[ii])) |
|
78 cont = ETrue; |
|
79 } |
|
80 // if all we have entered are directional markers we want |
|
81 // to keep them so do nothing and return |
|
82 if (!cont) |
|
83 return needsResolving; // Uses initialized value of return value. Please maintain. |
|
84 |
|
85 ii = 0; |
|
86 while (ii < aDecoratedTextPlusSurroundings.Length()) |
|
87 { |
|
88 TChar prevCh = ENullChar; |
|
89 if (ii > 0) |
|
90 prevCh = aDecoratedTextPlusSurroundings[ii-1]; |
|
91 TChar ch = aDecoratedTextPlusSurroundings[ii]; |
|
92 TChar nextCh = ENullChar; |
|
93 if (ii < aDecoratedTextPlusSurroundings.Length()-1) |
|
94 nextCh = aDecoratedTextPlusSurroundings[ii+1]; |
|
95 |
|
96 if (CharacterIsDirectionalMarker(ch)) |
|
97 { |
|
98 // Remove a marker if : |
|
99 // |
|
100 // 1. previous character is strong and has the same directionality |
|
101 // 2. next character is a marker of the same type (remove both) |
|
102 // 3. next character is strong and has the same directionality |
|
103 // |
|
104 if (CharactersHaveSameStrongDirection(ch, prevCh)) |
|
105 { |
|
106 aDecoratedTextPlusSurroundings.Delete(ii, ESingleCharacter); |
|
107 ii--; |
|
108 needsResolving = ETrue; |
|
109 } |
|
110 else if (CharacterIsDirectionalMarker(nextCh) && CharactersHaveSameStrongDirection(ch, nextCh)) |
|
111 { |
|
112 aDecoratedTextPlusSurroundings.Delete(ii, ETwoCharacters); |
|
113 ii--; |
|
114 needsResolving = ETrue; |
|
115 } |
|
116 else if (CharactersHaveSameStrongDirection(ch, nextCh)) |
|
117 { |
|
118 aDecoratedTextPlusSurroundings.Delete(ii, ESingleCharacter); |
|
119 ii--; |
|
120 needsResolving = ETrue; |
|
121 } |
|
122 } |
|
123 ii++; |
|
124 } |
|
125 return needsResolving; |
|
126 } |
|
127 |
|
128 |
|
129 TBool CAknFepInlineTextDecorator::CharacterIsDirectionalMarker(TChar aChar) |
|
130 { |
|
131 return (aChar == ELeftToRightMark || aChar == ERightToLeftMark); |
|
132 } |
|
133 |
|
134 TBool CAknFepInlineTextDecorator::CharacterIsStrongLeftToRight(TChar aChar) |
|
135 { |
|
136 return (aChar.GetBdCategory() == TChar::ELeftToRight || |
|
137 aChar == ELeftToRightMark); |
|
138 } |
|
139 |
|
140 TBool CAknFepInlineTextDecorator::CharacterIsStrongRightToLeft(TChar aChar) |
|
141 { |
|
142 return ((aChar.GetBdCategory() == TChar::ERightToLeft) || |
|
143 (aChar.GetBdCategory() == TChar::ERightToLeftArabic) || |
|
144 aChar == ERightToLeftMark); |
|
145 } |
|
146 |
|
147 TBool CAknFepInlineTextDecorator::CharactersHaveSameStrongDirection(TChar aCh1, TChar aCh2) |
|
148 { |
|
149 return ((CharacterIsStrongLeftToRight(aCh1) && CharacterIsStrongLeftToRight(aCh2)) || |
|
150 (CharacterIsStrongRightToLeft(aCh1) && CharacterIsStrongRightToLeft(aCh2))); |
|
151 } |
|
152 |
|
153 TBool CAknFepInlineTextDecorator::CharacterIsWeaklyDirectional(TChar aChar) |
|
154 { |
|
155 return ((aChar.GetBdCategory() == TChar::EEuropeanNumber) || |
|
156 (aChar.GetBdCategory() == TChar::EEuropeanNumberSeparator) || |
|
157 (aChar.GetBdCategory() == TChar::EEuropeanNumberTerminator) || |
|
158 (aChar.GetBdCategory() == TChar::EArabicNumber) || |
|
159 (aChar.GetBdCategory() == TChar::ECommonNumberSeparator)); |
|
160 } |
|
161 |
|
162 TBool CAknFepInlineTextDecorator::CharacterIsSeparator(TChar aChar) |
|
163 { |
|
164 return ((aChar.GetBdCategory() == TChar::EParagraphSeparator) || |
|
165 (aChar.GetBdCategory() == TChar::ESegmentSeparator)); |
|
166 } |
|
167 |
|
168 TBool CAknFepInlineTextDecorator::CharacterIsNeutral(TChar aChar) |
|
169 { |
|
170 return ((aChar.GetBdCategory() == TChar::EWhitespace) || |
|
171 (aChar.GetBdCategory() == TChar::EOtherNeutral)); |
|
172 } |
|
173 |
|
174 void CAknFepInlineTextDecorator::DecorateNeutralCharacters( |
|
175 const TDesC& aInlineText, |
|
176 TDes& aDecoratedText, |
|
177 TInt& aPositionOfInsertionPointInInlineText, |
|
178 TChar aPreviousCharacter, |
|
179 TBool aRTLParagraph, |
|
180 TBool aInputDirectionIsRTL) |
|
181 { |
|
182 |
|
183 TChar curCh; |
|
184 TChar prevCh = aPreviousCharacter; |
|
185 TBuf<ESingleCharacter> insertBuf(ESingleCharacter); |
|
186 |
|
187 for (TInt ii = 0; ii < aInlineText.Length(); ii++) |
|
188 { |
|
189 curCh = aInlineText[ii]; |
|
190 aDecoratedText.Append(curCh); |
|
191 |
|
192 if (CharacterIsNeutral(curCh)) |
|
193 { |
|
194 // mark the neutral character with appropriate direction markers if : |
|
195 // |
|
196 // 1. the input mode (lang) is opposed to the paragraph direction and |
|
197 // previous character is not neutral |
|
198 // 2. the input mode (lang) is opposed to the previous char direction |
|
199 // (=> charcater is entered inside existing block) |
|
200 // |
|
201 // Note that we need to increment the insertion point by 2 if the |
|
202 // markers are inserted before it |
|
203 // |
|
204 if ((aInputDirectionIsRTL && !aRTLParagraph && !CharacterIsNeutral(prevCh)) || |
|
205 (aInputDirectionIsRTL && CharacterIsStrongLeftToRight(prevCh))) |
|
206 { // mark neutral with RLM |
|
207 insertBuf[0]=ERightToLeftMark; |
|
208 aDecoratedText.Insert(aDecoratedText.Length() -1, insertBuf); |
|
209 aDecoratedText.Append(insertBuf); |
|
210 |
|
211 if (aPositionOfInsertionPointInInlineText > ii) |
|
212 aPositionOfInsertionPointInInlineText+=ETwoCharacters; |
|
213 } |
|
214 |
|
215 else if ((!aInputDirectionIsRTL && aRTLParagraph && !CharacterIsNeutral(prevCh)) || |
|
216 (!aInputDirectionIsRTL && CharacterIsStrongRightToLeft(prevCh))) |
|
217 { // mark neutral with LRM |
|
218 insertBuf[0]=ELeftToRightMark; |
|
219 aDecoratedText.Insert(aDecoratedText.Length() -1, insertBuf); |
|
220 aDecoratedText.Append(insertBuf); |
|
221 |
|
222 if (aPositionOfInsertionPointInInlineText > ii) |
|
223 aPositionOfInsertionPointInInlineText+=ETwoCharacters; |
|
224 } |
|
225 } |
|
226 prevCh = curCh; |
|
227 } |
|
228 } |
|
229 |
|