First public contribution.
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
21 #include "FontIndic.h"
24 #include "ShapeInfo.h"
25 #include "gdiinline.inl"
27 // State machine for determining syllable boundaries.
28 // Key: D = Dependent vowel. V = Virama. N = Nukta
29 // I = Independent Vowel. S = Candrabindu/Anusvara/Visarga
30 // C = Consonant. J = zero-width joiner. X = Other
31 // A = Addak (double the following constant)
35 // Begin + I: add and move to IndependentVowel
36 // Begin + C: add and move to Consonant
37 // Begin + V/N/D/S/J/X: add and close syllable
39 // Consonant + D: add and move to ConsonantVowel
41 // Consonant + V: add and move to Virama
42 // Consonant + S: add and close syllable
43 // Consonant + C/I/J/X: close syllable
45 // Consonant2 + D: add and move to ConsonantVowel
46 // Consonant2 + N: add
47 // Consonant2 + V: add and move to Virama2
48 // Consonant2 + S: add and close syllable
49 // Consonant2 + C/I/J/X: close syllable
51 // Consonant3 + D: add and move to ConsonantVowel
52 // Consonant3 + N: add
53 // Consonant3 + V: add and move to Virama3
54 // Consonant3 + S: add and close syllable
55 // Consonant3 + C/I/J/X: close syllable
57 // Consonant + D: add and move to ConsonantVowel
59 // Consonant + V: add and close syllable
60 // Consonant + S: add and close syllable
61 // Consonant + C/I/J/X: close syllable
63 // IndependentVowel + S: add
64 // IndependentVowel + D/V/N/I/C/J/X: close syllable
65 EIndependentVowel = 5,
66 // Virama + C: add and move to Consonant
67 // Virama + J: add and close syllable
68 // Virama + N/V/D/I/S/X: close syllable
70 // Virama2 + C: add and move to Consonant3
71 // Virama2 + J: add and close syllable
72 // Virama2 + N/V/D/I/S/X: close syllable
74 // Virama3 + C: add and move to Consonant4
75 // Virama3 + J: add and close syllable
76 // Virama3 + N/V/D/I/S/X: close syllable
78 // Virama4 + J: add and close syllable
79 // Virama4 + CN/V/D/I/S/X: close syllable
81 // ConsonantVowel + S: add
82 // ConsonantVowel + D/V/N/I/C/J/X: close syllable
84 // NuktaConsonant + D/V: add
85 // NuktaConsonant + S/N/I/C/J/X: close syllable
87 // NuktaConsonant + D/V: add
88 // NuktaConsonant + S/N/I/C/J/X: close syllable
89 ENuktaConsonant2 = 12,
90 // NuktaConsonant + D/V: add
91 // NuktaConsonant + S/N/I/C/J/X: close syllable
92 ENuktaConsonant3 = 13,
93 // NuktaConsonant + D: add
94 // NuktaConsonant + V/S/N/I/C/J/X: close syllable
95 ENuktaConsonant4 = 14,
96 // IndependentVowelA + CANDRA E: add
97 // IndependentVowelA + anything else: close syllable
98 EIndependentVowelA = 15,
99 // ZeroWidthJoinerC + V: add
100 // ZeroWidthJoinerC + C/S/N/I/J/X/D: close syllable
101 EZeroWidthJoinerC = 16,
102 // ZeroWidthJoinerA + CANDRA E: add
103 // ZeroWidthJoinerA +anything else: close syllable
104 EZeroWidthJoinerA = 17,
105 // ZeroWidthJoinerV + C/N: add
106 // ZeroWidthJoinerV + anything else: close syllable
107 EZeroWidthJoinerV = 18,
108 // ZeroWidthJoinerV2 + C/N: add
109 // ZeroWidthJoinerV2 + anything else: close syllable
110 EZeroWidthJoinerV2 = 19,
111 // ZeroWidthJoinerV3 + C/N: add
112 // ZeroWidthJoinerV3 + anything else: close syllable
113 EZeroWidthJoinerV3 =20,
114 // EKannadaRa + C/N/V/ZWJ(C): add
116 // ESplitVowel1 + SV2: add and close syllable
117 // ESPlitVowel1 + anything else: close syllable
119 //EGurBearerA + EIndicCodeGurDependentVowelA: add and move to EIndependentVowel
120 //EGurBearerA + modifier: add and close syllable
121 //EGurBearerA + anything else: close syllable
123 //EGurBearerU + EIndicCodeGurDependentVowelU: add and move to EIndependentVowel
124 //EGurBearerU + anything else: close syllable
126 //EGurBearerI + EIndicCodeGurDependentVowelI: add and move to EIndependentVowel
127 //EGurBearerI + anything else: close syllable
130 EConsonantMalaChillu = 26,
131 EConsonantMalaChillu2 = 27,
132 EConsonantMalaChillu3 = 28,
133 EViramaMalaChillu = 29,
134 EViramaMalaChillu2 = 30,
135 EViramaMalaChillu3 = 31,
136 EConsonantMalaChilluNA = 32,
137 EConsonantMalaChilluNA2 = 33,
138 EConsonantMalaChilluNA3 = 34,
139 EViramaMalaChilluNA = 35,
140 EViramaMalaChilluNA2 = 36,
141 EViramaMalaChilluNA3 = 37,
142 EZeroWidthJoinerMalaChilluNA = 38,
143 EZeroWidthJoinerMalaChilluNA2 = 39,
144 EZeroWidthJoinerMalaChilluNA3 = 40,
145 // Add and close acceptances go here.
149 /** Defines the transitions for a state machine for determining syllable
150 boundaries. The machine starts in state 0. On receiving a character of type t
151 while in state s, moves to state KStateResponse[s][t]. */
152 const TSyllableState KStateResponse[42][24] =
154 // EBegin -- nothing added yet
155 {EAccept, EAccept, EIndependentVowel, EConsonant, EAccept, EAccept, EAccept, EAccept, ENuktaConsonant, EIndependentVowelA, EAccept, EKannadaRa, EAccept, EAccept, EAccept, EGurBearerA, EGurBearerU, EGurBearerI, EAccept, EAccept, EAccept, EConsonantMalaChillu,EConsonantMalaChilluNA,EConsonant},
156 // EConsonant -- seen a consonant either at the start or after virama
157 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, ENuktaConsonant, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
158 // EConsonant2 -- seen a consonant after virama
159 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama2, ENuktaConsonant2, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
160 // EConsonant3 -- seen a consonant after virama2
161 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama3, ENuktaConsonant3, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
162 // EConsonant4 -- seen a consonant after virama3
163 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama4, ENuktaConsonant4, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
164 // EIndependentVowel -- possibly nasalized. I haven't bothered to distinguish between
165 // nasalization and visarga.
166 {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
167 // EVirama -- just seen a virama in a legal context. Must be consonant or ZWJ next
168 {EReject, EReject, EReject, EConsonant2, EReject, EReject, EReject, EZeroWidthJoinerV, ENuktaConsonant2, EReject, EReject, EConsonant2, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
169 // EVirama2 -- just seen a virama in a legal context. Must be consonant2
170 {EReject, EReject, EReject, EConsonant3, EReject, EReject, EReject, EZeroWidthJoinerV2, ENuktaConsonant3, EReject, EReject, EConsonant3, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
171 // EVirama3 -- just seen a virama in a legal context. Must be consonant3
172 {EReject, EReject, EReject, EConsonant4, EReject, EReject, EReject, EZeroWidthJoinerV3, ENuktaConsonant4, EReject, EReject, EConsonant4, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonant4,EConsonant4,EConsonant4},
173 // EVirama4 -- just seen a virama in a legal context. Must be consonant4
174 {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
175 // EConsonantVowel -- Just seen a consonant with matra. Can only nasalize or visarg
176 {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
177 // ENuktaConsonant -- Just seen a consonant with Nukta. Can only accept a dependant vowel or a Virama at this stage.
178 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
179 // ENuktaConsonant2 -- Just seen a consonant with Nukta after a virama.
180 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama2, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
181 // ENuktaConsonant3 -- Just seen a consonant with Nukta after Virama2.
182 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama3, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
183 // ENuktaConsonant4 -- Just seen a consonant with Nukta after Virama3.
184 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama4, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
185 // EIndependentVowelA -- Special case Devanagari independent vowel
186 {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EZeroWidthJoinerA, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
187 // EZeroWidthJoinerC -- Just seen a ZWJ after a consonant
188 {EReject, EReject, EReject, EReject, EReject, EVirama, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
189 // EZeroWidthJoinerA -- Just seen a ZWJ after the dependent Vowel A
190 {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
191 // EZeroWidthJoinerV -- Just seen the ZWJ after the first pair of consonant + virama
192 {EReject, EAccept, EReject, EConsonant2, EReject, EReject, EReject, EReject, ENuktaConsonant2, EReject, EReject, EConsonant2, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
193 // EZeroWidthJoinerV2 -- Just seen the ZWJ after consonant + virama + consonant + virama
194 {EReject, EAccept, EReject, EConsonant3, EReject, EReject, EReject, EReject, ENuktaConsonant3, EReject, EReject, EConsonant3, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
195 // EZeroWidthJoinerV3 -- Just seen the ZWJ after consonant + virama + consonant + virama + consonant + virama
196 {EReject, EAccept, EReject, EConsonant4, EReject, EReject, EReject, EReject, ENuktaConsonant4, EReject, EReject, EConsonant4, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonant4,EConsonant4,EConsonant4},
197 // EKannadaRa -- Special case consonant
198 {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, ENuktaConsonant, EZeroWidthJoinerC, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
199 // ESplitVowel1 -- Just seen a consonant with first part of a split vowel. Can only nasalize, visarg or add second part of splt vowel
200 {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
201 // EGurBearerA -- Just seen a dependent Vowel EIndicCodeGurDependentVowelA and modifier
202 {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject, EReject, EReject,EReject,EReject},
203 // EGurBearerU -- Just seen a dependent Vowel EIndicCodeGurDependentVowelU
204 {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject, EReject,EReject,EReject},
205 // EGurBearerI -- Just seen a dependent Vowel EIndicCodeGurDependentVowelI
206 {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject,EReject,EReject},
208 {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
209 {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu2,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
210 {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu3,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
211 {EReject,EReject,EReject,EConsonant2,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
212 {EReject,EReject,EReject,EConsonant3,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
213 {EReject,EReject,EReject,EConsonant4,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4,EConsonant4,EConsonant4},
214 {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
215 {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA2,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
216 {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA3,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
217 {EReject,EReject,EReject,EConsonant2,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
218 {EReject,EReject,EReject,EConsonant3,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA2,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
219 {EReject,EReject,EReject,EConsonant4,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA3,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4,EConsonant4,EConsonant4},
220 {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant2},
221 {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant3},
222 {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4},
224 // EAccept -- this one is added but anything further is rejected
225 {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject}
228 TIndicCodeType CodeType(TInt aCode, const TIndicCodeMapping aCodeMap[], TInt aMapLen)
231 TInt end = aMapLen - 1;
234 const TInt mid = (start + end + 1) >> 1;
235 if (aCodeMap[mid].iFirstCodeInRange <= aCode)
240 return static_cast<TIndicCodeType>(aCodeMap[start].iCodeType);
243 const TText16* SyllableEnd(const TText16* aCurrentPosition,
244 const TText16* aEnd, const TIndicCodeMapping aCodeMap[], TInt aMapLen)
246 TSyllableState state = EBegin;
247 while (aCurrentPosition != aEnd)
249 const TIndicCodeType ct = CodeType(*aCurrentPosition, aCodeMap, aMapLen);
250 state = KStateResponse[state][ct];
251 if (state == EReject)
252 return aCurrentPosition;
255 return aCurrentPosition;
259 Common function for all Indic scripts.
260 Performs the shaping operation on Indic script text up to KMaxTextToShape.
262 TInt IndicShapingProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo,
263 const TIndicCodeMapping aCodeMap[], TInt aMapLen, const TUint aHighChar,
264 const TUint aLowChar, const TUint32 aScript, const TUint32 aLang)
266 const TText16* startCharacter = aGss.iParam.iText.Ptr();
267 const TText16* endCharacter = startCharacter + aGss.iParam.iText.Length();
268 const TText16* currentCharacter = aGss.iText.CurrentPosition();
269 TInt currentPosition = currentCharacter - startCharacter;
271 // Do some new shaping
273 // First close the existing RShapeInfo
274 if(aShapeInfo.IsOpen())
277 // Find the end of Indic text whilst limiting the amount of text to be shaped to
278 // KMaxTextToShape. When finding the end of end position of the text to be shaped,
279 // include numerals, punctuations and other control characters.
280 const TText16* endIndic = currentCharacter;
281 TChar endIndicChar = *endIndic;
282 while((endIndic <= endCharacter || endIndic - currentCharacter <= KMaxTextToShape) &&
283 ((*endIndic >= aLowChar && *endIndic <= aHighChar) ||
284 ((endIndicChar.IsDigit() || endIndicChar.IsPunctuation()) && !QuoteOrBracketPair(*endIndic))))
286 if (endIndic == endCharacter || endIndic - currentCharacter > KMaxTextToShape)
288 endIndic = SyllableEnd(endIndic, endCharacter, aCodeMap, aMapLen);
289 endIndicChar = *endIndic;
292 TInt endPosForShaping = endIndic - startCharacter;
294 //Now shape from current position to the end of Hindi
295 return aShapeInfo.Open(aGss.iFont, aGss.iParam.iText,
296 currentPosition, endPosForShaping, aScript, aLang);
300 Common function for all Indic scripts. Adds the shaped glyphs to the glyph cluster.
301 This function is called regardless of whether shaping was done or skipped in this
302 iteration of the Default Process
304 TBool IndicPostShapingProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo,
305 TInt aCurrPos, TInt aSyllEndPos, const TText16* aSyllableEnd)
307 // Now get all the shaped values
308 // Get the number of glyphs, glyphs, positions and indices after shaping.
309 TInt numGlyphs = aShapeInfo.GlyphCount();
310 const TInt32* glyph = aShapeInfo.Glyphs();
311 const RShapeInfo::TPoint16* position = aShapeInfo.GlyphPositions();
312 const TInt16* indices = aShapeInfo.Indices();
315 // Shift the indices and positions until the current poisition is reached. This done so that the
316 // origin can be set back to the original co-ordinates at the start of this Hindi text
317 while (*indices < aCurrPos)
322 // Set the origin back by subtracting the current position co-ordinates from the current pen position
323 origin.iX = aGss.iParam.iPen.iX - position->iX;
324 origin.iY = aGss.iParam.iPen.iY - position->iY;
326 // No re-initialise the indices and positions to start appending the glyphs to clusters from the beginning
327 indices = aShapeInfo.Indices();
328 position = aShapeInfo.GlyphPositions();
330 // Now do some post shaping syllable chopping
331 for (TInt i = 0; i < numGlyphs; i++, glyph++, position++, indices++)
333 if(*indices >= aSyllEndPos)
335 if(*indices >= aCurrPos && *indices < aSyllEndPos)
337 aGss.iParam.iPen.iX = origin.iX + position->iX;
338 aGss.iParam.iPen.iY = origin.iY + position->iY;
340 //Just skip the non-existing glyph and continue handling other glyphs if AppendGlyphToCluster return false.
341 // The "continue" statement is for avoiding the potential risk of handling the non-existing glyph.
342 if (!aGss.AppendGlyphToCluster(0x80000000UL | *glyph))
347 // We'll do pen advance ourselves, thanks.
348 aGss.iPen = TGlyphSelectionState::EPenAdvance_No;
349 aGss.iParam.iPen.iX = origin.iX + position->iX;
350 aGss.iParam.iPen.iY = origin.iY + position->iY;
351 aGss.iClusterState = TGlyphSelectionState::EGClusterComplete;
352 aGss.iText.SetCurrentPosition(aSyllableEnd);
357 Common function for all Indic scripts.
358 Performs shaping and Rasterizing operation on Indic script text
360 TBool DoProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo, const TIndicScriptProcessorParameters& aScriptSpecificParameters){
361 const TText16* startCharacter = aGss.iParam.iText.Ptr();
362 const TText16* endCharacter = startCharacter + aGss.iParam.iText.Length();
363 const TText16* currentCharacter = aGss.iText.CurrentPosition();
364 TInt currentPosition = currentCharacter - startCharacter;
366 // Get the logical end of the syllable from the input text. We will use this later to chop
367 // syllables from the glyph values we get.
368 const TText16* syllableEnd = SyllableEnd(currentCharacter, endCharacter, aScriptSpecificParameters.iCodeMap,
369 aScriptSpecificParameters.iMapLen);
370 TInt syllableEndPos = syllableEnd - startCharacter;
373 if(currentPosition >= aShapeInfo.EndOfShapedText())
374 ret = IndicShapingProcess(aGss, aShapeInfo, aScriptSpecificParameters.iCodeMap, aScriptSpecificParameters.iMapLen,
375 aScriptSpecificParameters.iUCHigh, aScriptSpecificParameters.iUCLow, aScriptSpecificParameters.iScriptCode, aScriptSpecificParameters.iLanguageCode);
377 // If an RShapeInfo could not be opened, call the default process
379 return GlyphSelector_Default::Process(aGss, aShapeInfo);
381 // Now call the post shaping process to add glyphs to the glyph cluster
382 return IndicPostShapingProcess(aGss, aShapeInfo, currentPosition, syllableEndPos, syllableEnd);
385 /*************************************************** D E V A N A G A R I ***************************************************/
386 TBool GlyphSelector_Devanagari::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
388 return DoProcess(aGss, aShapeInfo, KIndicDevParameters);
391 /***************************************************** K A N N A D A ******************************************************/
392 TBool GlyphSelector_Kannada::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
394 return DoProcess(aGss, aShapeInfo, KIndicKanParameters);
397 /***************************************************** G U J A R A T I ******************************************************/
398 TBool GlyphSelector_Gujarati::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
400 return DoProcess(aGss, aShapeInfo, KIndicGujParameters);
403 /***************************************************** B E N G A L I ******************************************************/
404 TBool GlyphSelector_Bengali::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
406 return DoProcess(aGss, aShapeInfo, KIndicBenParameters);
409 /***************************************************** T A M I L ******************************************************/
410 TBool GlyphSelector_Tamil::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
412 return DoProcess(aGss, aShapeInfo, KIndicTamParameters);
415 /***************************************************** T E L U G U ******************************************************/
416 TBool GlyphSelector_Telugu::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
418 return DoProcess(aGss, aShapeInfo, KIndicTelParameters);
421 /***************************************************** G U R M U K H I ******************************************************/
422 TBool GlyphSelector_Gurmukhi::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)\
424 return DoProcess(aGss, aShapeInfo, KIndicGurParameters);
427 /***************************************************** M A L A Y A L A M ******************************************************/
428 TBool GlyphSelector_Malayalam::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
430 return DoProcess(aGss, aShapeInfo, KIndicMalParameters);