|
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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include "FontIndic.h" |
|
22 #include <gdi.h> |
|
23 #include "GlyphSel.h" |
|
24 #include "ShapeInfo.h" |
|
25 #include "gdiinline.inl" |
|
26 |
|
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) |
|
32 enum TSyllableState |
|
33 { |
|
34 EReject = -1, |
|
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 |
|
38 EBegin = 0, |
|
39 // Consonant + D: add and move to ConsonantVowel |
|
40 // Consonant + N: add |
|
41 // Consonant + V: add and move to Virama |
|
42 // Consonant + S: add and close syllable |
|
43 // Consonant + C/I/J/X: close syllable |
|
44 EConsonant = 1, |
|
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 |
|
50 EConsonant2 = 2, |
|
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 |
|
56 EConsonant3 = 3, |
|
57 // Consonant + D: add and move to ConsonantVowel |
|
58 // Consonant + N: add |
|
59 // Consonant + V: add and close syllable |
|
60 // Consonant + S: add and close syllable |
|
61 // Consonant + C/I/J/X: close syllable |
|
62 EConsonant4 = 4, |
|
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 |
|
69 EVirama = 6, |
|
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 |
|
73 EVirama2 = 7, |
|
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 |
|
77 EVirama3 = 8, |
|
78 // Virama4 + J: add and close syllable |
|
79 // Virama4 + CN/V/D/I/S/X: close syllable |
|
80 EVirama4 = 9, |
|
81 // ConsonantVowel + S: add |
|
82 // ConsonantVowel + D/V/N/I/C/J/X: close syllable |
|
83 EConsonantVowel = 10, |
|
84 // NuktaConsonant + D/V: add |
|
85 // NuktaConsonant + S/N/I/C/J/X: close syllable |
|
86 ENuktaConsonant = 11, |
|
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 |
|
115 EKannadaRa = 21, |
|
116 // ESplitVowel1 + SV2: add and close syllable |
|
117 // ESPlitVowel1 + anything else: close syllable |
|
118 ESplitVowel1 = 22, |
|
119 //EGurBearerA + EIndicCodeGurDependentVowelA: add and move to EIndependentVowel |
|
120 //EGurBearerA + modifier: add and close syllable |
|
121 //EGurBearerA + anything else: close syllable |
|
122 EGurBearerA = 23, |
|
123 //EGurBearerU + EIndicCodeGurDependentVowelU: add and move to EIndependentVowel |
|
124 //EGurBearerU + anything else: close syllable |
|
125 EGurBearerU = 24, |
|
126 //EGurBearerI + EIndicCodeGurDependentVowelI: add and move to EIndependentVowel |
|
127 //EGurBearerI + anything else: close syllable |
|
128 EGurBearerI = 25, |
|
129 |
|
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. |
|
146 EAccept = 41 |
|
147 }; |
|
148 |
|
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] = |
|
153 { |
|
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}, |
|
207 |
|
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}, |
|
223 |
|
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} |
|
226 }; |
|
227 |
|
228 TIndicCodeType CodeType(TInt aCode, const TIndicCodeMapping aCodeMap[], TInt aMapLen) |
|
229 { |
|
230 TInt start = 0; |
|
231 TInt end = aMapLen - 1; |
|
232 while (start != end) |
|
233 { |
|
234 const TInt mid = (start + end + 1) >> 1; |
|
235 if (aCodeMap[mid].iFirstCodeInRange <= aCode) |
|
236 start = mid; |
|
237 else |
|
238 end = mid - 1; |
|
239 } |
|
240 return static_cast<TIndicCodeType>(aCodeMap[start].iCodeType); |
|
241 } |
|
242 |
|
243 const TText16* SyllableEnd(const TText16* aCurrentPosition, |
|
244 const TText16* aEnd, const TIndicCodeMapping aCodeMap[], TInt aMapLen) |
|
245 { |
|
246 TSyllableState state = EBegin; |
|
247 while (aCurrentPosition != aEnd) |
|
248 { |
|
249 const TIndicCodeType ct = CodeType(*aCurrentPosition, aCodeMap, aMapLen); |
|
250 state = KStateResponse[state][ct]; |
|
251 if (state == EReject) |
|
252 return aCurrentPosition; |
|
253 ++aCurrentPosition; |
|
254 } |
|
255 return aCurrentPosition; |
|
256 } |
|
257 |
|
258 /** |
|
259 Common function for all Indic scripts. |
|
260 Performs the shaping operation on Indic script text up to KMaxTextToShape. |
|
261 */ |
|
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) |
|
265 { |
|
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; |
|
270 |
|
271 // Do some new shaping |
|
272 |
|
273 // First close the existing RShapeInfo |
|
274 if(aShapeInfo.IsOpen()) |
|
275 aShapeInfo.Close(); |
|
276 |
|
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)))) |
|
285 { |
|
286 if (endIndic == endCharacter || endIndic - currentCharacter > KMaxTextToShape) |
|
287 break; |
|
288 endIndic = SyllableEnd(endIndic, endCharacter, aCodeMap, aMapLen); |
|
289 endIndicChar = *endIndic; |
|
290 } |
|
291 |
|
292 TInt endPosForShaping = endIndic - startCharacter; |
|
293 |
|
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); |
|
297 } |
|
298 |
|
299 /** |
|
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 |
|
303 */ |
|
304 TBool IndicPostShapingProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo, |
|
305 TInt aCurrPos, TInt aSyllEndPos, const TText16* aSyllableEnd) |
|
306 { |
|
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(); |
|
313 TPoint origin; |
|
314 |
|
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) |
|
318 { |
|
319 position++; |
|
320 indices++; |
|
321 } |
|
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; |
|
325 |
|
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(); |
|
329 |
|
330 // Now do some post shaping syllable chopping |
|
331 for (TInt i = 0; i < numGlyphs; i++, glyph++, position++, indices++) |
|
332 { |
|
333 if(*indices >= aSyllEndPos) |
|
334 break; |
|
335 if(*indices >= aCurrPos && *indices < aSyllEndPos) |
|
336 { |
|
337 aGss.iParam.iPen.iX = origin.iX + position->iX; |
|
338 aGss.iParam.iPen.iY = origin.iY + position->iY; |
|
339 |
|
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)) |
|
343 continue; |
|
344 } |
|
345 } |
|
346 |
|
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); |
|
353 return ETrue; |
|
354 } |
|
355 |
|
356 /** |
|
357 Common function for all Indic scripts. |
|
358 Performs shaping and Rasterizing operation on Indic script text |
|
359 */ |
|
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; |
|
365 |
|
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; |
|
371 |
|
372 TInt ret = KErrNone; |
|
373 if(currentPosition >= aShapeInfo.EndOfShapedText()) |
|
374 ret = IndicShapingProcess(aGss, aShapeInfo, aScriptSpecificParameters.iCodeMap, aScriptSpecificParameters.iMapLen, |
|
375 aScriptSpecificParameters.iUCHigh, aScriptSpecificParameters.iUCLow, aScriptSpecificParameters.iScriptCode, aScriptSpecificParameters.iLanguageCode); |
|
376 |
|
377 // If an RShapeInfo could not be opened, call the default process |
|
378 if (ret != KErrNone) |
|
379 return GlyphSelector_Default::Process(aGss, aShapeInfo); |
|
380 |
|
381 // Now call the post shaping process to add glyphs to the glyph cluster |
|
382 return IndicPostShapingProcess(aGss, aShapeInfo, currentPosition, syllableEndPos, syllableEnd); |
|
383 } |
|
384 |
|
385 /*************************************************** D E V A N A G A R I ***************************************************/ |
|
386 TBool GlyphSelector_Devanagari::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) |
|
387 { |
|
388 return DoProcess(aGss, aShapeInfo, KIndicDevParameters); |
|
389 } |
|
390 |
|
391 /***************************************************** K A N N A D A ******************************************************/ |
|
392 TBool GlyphSelector_Kannada::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) |
|
393 { |
|
394 return DoProcess(aGss, aShapeInfo, KIndicKanParameters); |
|
395 } |
|
396 |
|
397 /***************************************************** G U J A R A T I ******************************************************/ |
|
398 TBool GlyphSelector_Gujarati::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) |
|
399 { |
|
400 return DoProcess(aGss, aShapeInfo, KIndicGujParameters); |
|
401 } |
|
402 |
|
403 /***************************************************** B E N G A L I ******************************************************/ |
|
404 TBool GlyphSelector_Bengali::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) |
|
405 { |
|
406 return DoProcess(aGss, aShapeInfo, KIndicBenParameters); |
|
407 } |
|
408 |
|
409 /***************************************************** T A M I L ******************************************************/ |
|
410 TBool GlyphSelector_Tamil::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) |
|
411 { |
|
412 return DoProcess(aGss, aShapeInfo, KIndicTamParameters); |
|
413 } |
|
414 |
|
415 /***************************************************** T E L U G U ******************************************************/ |
|
416 TBool GlyphSelector_Telugu::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) |
|
417 { |
|
418 return DoProcess(aGss, aShapeInfo, KIndicTelParameters); |
|
419 } |
|
420 |
|
421 /***************************************************** G U R M U K H I ******************************************************/ |
|
422 TBool GlyphSelector_Gurmukhi::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)\ |
|
423 { |
|
424 return DoProcess(aGss, aShapeInfo, KIndicGurParameters); |
|
425 } |
|
426 |
|
427 /***************************************************** M A L A Y A L A M ******************************************************/ |
|
428 TBool GlyphSelector_Malayalam::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) |
|
429 { |
|
430 return DoProcess(aGss, aShapeInfo, KIndicMalParameters); |
|
431 } |
|
432 |