1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textbase/sgdi/FontIndic.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,434 @@
1.4 +// Copyright (c) 2005-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +/**
1.20 + @file
1.21 + @internalComponent
1.22 +*/
1.23 +
1.24 +//#include <gdi.h>
1.25 +#include <DisplayMode.h>
1.26 +#include "FontIndic.h"
1.27 +//#include <textbase.h>
1.28 +#include "GlyphSel.h"
1.29 +#include "ShapeInfo.h"
1.30 +#include "gdiinline.inl"
1.31 +
1.32 +// State machine for determining syllable boundaries.
1.33 +// Key: D = Dependent vowel. V = Virama. N = Nukta
1.34 +// I = Independent Vowel. S = Candrabindu/Anusvara/Visarga
1.35 +// C = Consonant. J = zero-width joiner. X = Other
1.36 +// A = Addak (double the following constant)
1.37 +enum TSyllableState
1.38 + {
1.39 + EReject = -1,
1.40 + // Begin + I: add and move to IndependentVowel
1.41 + // Begin + C: add and move to Consonant
1.42 + // Begin + V/N/D/S/J/X: add and close syllable
1.43 + EBegin = 0,
1.44 + // Consonant + D: add and move to ConsonantVowel
1.45 + // Consonant + N: add
1.46 + // Consonant + V: add and move to Virama
1.47 + // Consonant + S: add and close syllable
1.48 + // Consonant + C/I/J/X: close syllable
1.49 + EConsonant = 1,
1.50 + // Consonant2 + D: add and move to ConsonantVowel
1.51 + // Consonant2 + N: add
1.52 + // Consonant2 + V: add and move to Virama2
1.53 + // Consonant2 + S: add and close syllable
1.54 + // Consonant2 + C/I/J/X: close syllable
1.55 + EConsonant2 = 2,
1.56 + // Consonant3 + D: add and move to ConsonantVowel
1.57 + // Consonant3 + N: add
1.58 + // Consonant3 + V: add and move to Virama3
1.59 + // Consonant3 + S: add and close syllable
1.60 + // Consonant3 + C/I/J/X: close syllable
1.61 + EConsonant3 = 3,
1.62 + // Consonant + D: add and move to ConsonantVowel
1.63 + // Consonant + N: add
1.64 + // Consonant + V: add and close syllable
1.65 + // Consonant + S: add and close syllable
1.66 + // Consonant + C/I/J/X: close syllable
1.67 + EConsonant4 = 4,
1.68 + // IndependentVowel + S: add
1.69 + // IndependentVowel + D/V/N/I/C/J/X: close syllable
1.70 + EIndependentVowel = 5,
1.71 + // Virama + C: add and move to Consonant
1.72 + // Virama + J: add and close syllable
1.73 + // Virama + N/V/D/I/S/X: close syllable
1.74 + EVirama = 6,
1.75 + // Virama2 + C: add and move to Consonant3
1.76 + // Virama2 + J: add and close syllable
1.77 + // Virama2 + N/V/D/I/S/X: close syllable
1.78 + EVirama2 = 7,
1.79 + // Virama3 + C: add and move to Consonant4
1.80 + // Virama3 + J: add and close syllable
1.81 + // Virama3 + N/V/D/I/S/X: close syllable
1.82 + EVirama3 = 8,
1.83 + // Virama4 + J: add and close syllable
1.84 + // Virama4 + CN/V/D/I/S/X: close syllable
1.85 + EVirama4 = 9,
1.86 + // ConsonantVowel + S: add
1.87 + // ConsonantVowel + D/V/N/I/C/J/X: close syllable
1.88 + EConsonantVowel = 10,
1.89 + // NuktaConsonant + D/V: add
1.90 + // NuktaConsonant + S/N/I/C/J/X: close syllable
1.91 + ENuktaConsonant = 11,
1.92 + // NuktaConsonant + D/V: add
1.93 + // NuktaConsonant + S/N/I/C/J/X: close syllable
1.94 + ENuktaConsonant2 = 12,
1.95 + // NuktaConsonant + D/V: add
1.96 + // NuktaConsonant + S/N/I/C/J/X: close syllable
1.97 + ENuktaConsonant3 = 13,
1.98 + // NuktaConsonant + D: add
1.99 + // NuktaConsonant + V/S/N/I/C/J/X: close syllable
1.100 + ENuktaConsonant4 = 14,
1.101 + // IndependentVowelA + CANDRA E: add
1.102 + // IndependentVowelA + anything else: close syllable
1.103 + EIndependentVowelA = 15,
1.104 + // ZeroWidthJoinerC + V: add
1.105 + // ZeroWidthJoinerC + C/S/N/I/J/X/D: close syllable
1.106 + EZeroWidthJoinerC = 16,
1.107 + // ZeroWidthJoinerA + CANDRA E: add
1.108 + // ZeroWidthJoinerA +anything else: close syllable
1.109 + EZeroWidthJoinerA = 17,
1.110 + // ZeroWidthJoinerV + C/N: add
1.111 + // ZeroWidthJoinerV + anything else: close syllable
1.112 + EZeroWidthJoinerV = 18,
1.113 + // ZeroWidthJoinerV2 + C/N: add
1.114 + // ZeroWidthJoinerV2 + anything else: close syllable
1.115 + EZeroWidthJoinerV2 = 19,
1.116 + // ZeroWidthJoinerV3 + C/N: add
1.117 + // ZeroWidthJoinerV3 + anything else: close syllable
1.118 + EZeroWidthJoinerV3 =20,
1.119 + // EKannadaRa + C/N/V/ZWJ(C): add
1.120 + EKannadaRa = 21,
1.121 + // ESplitVowel1 + SV2: add and close syllable
1.122 + // ESPlitVowel1 + anything else: close syllable
1.123 + ESplitVowel1 = 22,
1.124 + //EGurBearerA + EIndicCodeGurDependentVowelA: add and move to EIndependentVowel
1.125 + //EGurBearerA + modifier: add and close syllable
1.126 + //EGurBearerA + anything else: close syllable
1.127 + EGurBearerA = 23,
1.128 + //EGurBearerU + EIndicCodeGurDependentVowelU: add and move to EIndependentVowel
1.129 + //EGurBearerU + anything else: close syllable
1.130 + EGurBearerU = 24,
1.131 + //EGurBearerI + EIndicCodeGurDependentVowelI: add and move to EIndependentVowel
1.132 + //EGurBearerI + anything else: close syllable
1.133 + EGurBearerI = 25,
1.134 +
1.135 + EConsonantMalaChillu = 26,
1.136 + EConsonantMalaChillu2 = 27,
1.137 + EConsonantMalaChillu3 = 28,
1.138 + EViramaMalaChillu = 29,
1.139 + EViramaMalaChillu2 = 30,
1.140 + EViramaMalaChillu3 = 31,
1.141 + EConsonantMalaChilluNA = 32,
1.142 + EConsonantMalaChilluNA2 = 33,
1.143 + EConsonantMalaChilluNA3 = 34,
1.144 + EViramaMalaChilluNA = 35,
1.145 + EViramaMalaChilluNA2 = 36,
1.146 + EViramaMalaChilluNA3 = 37,
1.147 + EZeroWidthJoinerMalaChilluNA = 38,
1.148 + EZeroWidthJoinerMalaChilluNA2 = 39,
1.149 + EZeroWidthJoinerMalaChilluNA3 = 40,
1.150 + // Add and close acceptances go here.
1.151 + EAccept = 41
1.152 + };
1.153 +
1.154 +/** Defines the transitions for a state machine for determining syllable
1.155 +boundaries. The machine starts in state 0. On receiving a character of type t
1.156 +while in state s, moves to state KStateResponse[s][t]. */
1.157 +const TSyllableState KStateResponse[42][24] =
1.158 + {
1.159 + // EBegin -- nothing added yet
1.160 + {EAccept, EAccept, EIndependentVowel, EConsonant, EAccept, EAccept, EAccept, EAccept, ENuktaConsonant, EIndependentVowelA, EAccept, EKannadaRa, EAccept, EAccept, EAccept, EGurBearerA, EGurBearerU, EGurBearerI, EAccept, EAccept, EAccept, EConsonantMalaChillu,EConsonantMalaChilluNA,EConsonant},
1.161 + // EConsonant -- seen a consonant either at the start or after virama
1.162 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, ENuktaConsonant, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.163 + // EConsonant2 -- seen a consonant after virama
1.164 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama2, ENuktaConsonant2, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.165 + // EConsonant3 -- seen a consonant after virama2
1.166 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama3, ENuktaConsonant3, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.167 + // EConsonant4 -- seen a consonant after virama3
1.168 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama4, ENuktaConsonant4, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.169 + // EIndependentVowel -- possibly nasalized. I haven't bothered to distinguish between
1.170 + // nasalization and visarga.
1.171 + {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
1.172 + // EVirama -- just seen a virama in a legal context. Must be consonant or ZWJ next
1.173 + {EReject, EReject, EReject, EConsonant2, EReject, EReject, EReject, EZeroWidthJoinerV, ENuktaConsonant2, EReject, EReject, EConsonant2, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
1.174 + // EVirama2 -- just seen a virama in a legal context. Must be consonant2
1.175 + {EReject, EReject, EReject, EConsonant3, EReject, EReject, EReject, EZeroWidthJoinerV2, ENuktaConsonant3, EReject, EReject, EConsonant3, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
1.176 + // EVirama3 -- just seen a virama in a legal context. Must be consonant3
1.177 + {EReject, EReject, EReject, EConsonant4, EReject, EReject, EReject, EZeroWidthJoinerV3, ENuktaConsonant4, EReject, EReject, EConsonant4, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonant4,EConsonant4,EConsonant4},
1.178 + // EVirama4 -- just seen a virama in a legal context. Must be consonant4
1.179 + {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
1.180 + // EConsonantVowel -- Just seen a consonant with matra. Can only nasalize or visarg
1.181 + {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
1.182 + // ENuktaConsonant -- Just seen a consonant with Nukta. Can only accept a dependant vowel or a Virama at this stage.
1.183 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.184 + // ENuktaConsonant2 -- Just seen a consonant with Nukta after a virama.
1.185 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama2, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.186 + // ENuktaConsonant3 -- Just seen a consonant with Nukta after Virama2.
1.187 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama3, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.188 + // ENuktaConsonant4 -- Just seen a consonant with Nukta after Virama3.
1.189 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama4, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.190 + // EIndependentVowelA -- Special case Devanagari independent vowel
1.191 + {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EZeroWidthJoinerA, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.192 + // EZeroWidthJoinerC -- Just seen a ZWJ after a consonant
1.193 + {EReject, EReject, EReject, EReject, EReject, EVirama, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
1.194 + // EZeroWidthJoinerA -- Just seen a ZWJ after the dependent Vowel A
1.195 + {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
1.196 + // EZeroWidthJoinerV -- Just seen the ZWJ after the first pair of consonant + virama
1.197 + {EReject, EAccept, EReject, EConsonant2, EReject, EReject, EReject, EReject, ENuktaConsonant2, EReject, EReject, EConsonant2, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
1.198 + // EZeroWidthJoinerV2 -- Just seen the ZWJ after consonant + virama + consonant + virama
1.199 + {EReject, EAccept, EReject, EConsonant3, EReject, EReject, EReject, EReject, ENuktaConsonant3, EReject, EReject, EConsonant3, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
1.200 + // EZeroWidthJoinerV3 -- Just seen the ZWJ after consonant + virama + consonant + virama + consonant + virama
1.201 + {EReject, EAccept, EReject, EConsonant4, EReject, EReject, EReject, EReject, ENuktaConsonant4, EReject, EReject, EConsonant4, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonant4,EConsonant4,EConsonant4},
1.202 + // EKannadaRa -- Special case consonant
1.203 + {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, ENuktaConsonant, EZeroWidthJoinerC, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject},
1.204 + // ESplitVowel1 -- Just seen a consonant with first part of a split vowel. Can only nasalize, visarg or add second part of splt vowel
1.205 + {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject},
1.206 + // EGurBearerA -- Just seen a dependent Vowel EIndicCodeGurDependentVowelA and modifier
1.207 + {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject, EReject, EReject,EReject,EReject},
1.208 + // EGurBearerU -- Just seen a dependent Vowel EIndicCodeGurDependentVowelU
1.209 + {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject, EReject,EReject,EReject},
1.210 + // EGurBearerI -- Just seen a dependent Vowel EIndicCodeGurDependentVowelI
1.211 + {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject,EReject,EReject},
1.212 +
1.213 + {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
1.214 + {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu2,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
1.215 + {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu3,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
1.216 + {EReject,EReject,EReject,EConsonant2,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
1.217 + {EReject,EReject,EReject,EConsonant3,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
1.218 + {EReject,EReject,EReject,EConsonant4,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4,EConsonant4,EConsonant4},
1.219 + {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
1.220 + {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA2,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
1.221 + {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA3,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject},
1.222 + {EReject,EReject,EReject,EConsonant2,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2},
1.223 + {EReject,EReject,EReject,EConsonant3,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA2,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3},
1.224 + {EReject,EReject,EReject,EConsonant4,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA3,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4,EConsonant4,EConsonant4},
1.225 + {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant2},
1.226 + {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant3},
1.227 + {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4},
1.228 +
1.229 + // EAccept -- this one is added but anything further is rejected
1.230 + {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject}
1.231 + };
1.232 +
1.233 +TIndicCodeType CodeType(TInt aCode, const TIndicCodeMapping aCodeMap[], TInt aMapLen)
1.234 + {
1.235 + TInt start = 0;
1.236 + TInt end = aMapLen - 1;
1.237 + while (start != end)
1.238 + {
1.239 + const TInt mid = (start + end + 1) >> 1;
1.240 + if (aCodeMap[mid].iFirstCodeInRange <= aCode)
1.241 + start = mid;
1.242 + else
1.243 + end = mid - 1;
1.244 + }
1.245 + return static_cast<TIndicCodeType>(aCodeMap[start].iCodeType);
1.246 + }
1.247 +
1.248 +const TText16* SyllableEnd(const TText16* aCurrentPosition,
1.249 + const TText16* aEnd, const TIndicCodeMapping aCodeMap[], TInt aMapLen)
1.250 + {
1.251 + TSyllableState state = EBegin;
1.252 + while (aCurrentPosition != aEnd)
1.253 + {
1.254 + const TIndicCodeType ct = CodeType(*aCurrentPosition, aCodeMap, aMapLen);
1.255 + state = KStateResponse[state][ct];
1.256 + if (state == EReject)
1.257 + return aCurrentPosition;
1.258 + ++aCurrentPosition;
1.259 + }
1.260 + return aCurrentPosition;
1.261 + }
1.262 +
1.263 +/**
1.264 +Common function for all Indic scripts.
1.265 +Performs the shaping operation on Indic script text up to KMaxTextToShape.
1.266 +*/
1.267 +TInt IndicShapingProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo,
1.268 + const TIndicCodeMapping aCodeMap[], TInt aMapLen, const TUint aHighChar,
1.269 + const TUint aLowChar, const TUint32 aScript, const TUint32 aLang)
1.270 + {
1.271 + const TText16* startCharacter = aGss.iParam.iText.Ptr();
1.272 + const TText16* endCharacter = startCharacter + aGss.iParam.iText.Length();
1.273 + const TText16* currentCharacter = aGss.iText.CurrentPosition();
1.274 + TInt currentPosition = currentCharacter - startCharacter;
1.275 +
1.276 + // Do some new shaping
1.277 +
1.278 + // First close the existing RShapeInfo
1.279 + if(aShapeInfo.IsOpen())
1.280 + aShapeInfo.Close();
1.281 +
1.282 + // Find the end of Indic text whilst limiting the amount of text to be shaped to
1.283 + // KMaxTextToShape. When finding the end of end position of the text to be shaped,
1.284 + // include numerals, punctuations and other control characters.
1.285 + const TText16* endIndic = currentCharacter;
1.286 + TChar endIndicChar = *endIndic;
1.287 + while((endIndic <= endCharacter || endIndic - currentCharacter <= KMaxTextToShape) &&
1.288 + ((*endIndic >= aLowChar && *endIndic <= aHighChar) ||
1.289 + ((endIndicChar.IsDigit() || endIndicChar.IsPunctuation()) && !QuoteOrBracketPair(*endIndic))))
1.290 + {
1.291 + if (endIndic == endCharacter || endIndic - currentCharacter > KMaxTextToShape)
1.292 + break;
1.293 + endIndic = SyllableEnd(endIndic, endCharacter, aCodeMap, aMapLen);
1.294 + endIndicChar = *endIndic;
1.295 + }
1.296 +
1.297 + TInt endPosForShaping = endIndic - startCharacter;
1.298 +
1.299 + //Now shape from current position to the end of Hindi
1.300 + return aShapeInfo.Open(aGss.iFont, aGss.iParam.iText,
1.301 + currentPosition, endPosForShaping, aScript, aLang);
1.302 + }
1.303 +
1.304 +/**
1.305 +Common function for all Indic scripts. Adds the shaped glyphs to the glyph cluster.
1.306 +This function is called regardless of whether shaping was done or skipped in this
1.307 +iteration of the Default Process
1.308 +*/
1.309 +TBool IndicPostShapingProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo,
1.310 + TInt aCurrPos, TInt aSyllEndPos, const TText16* aSyllableEnd)
1.311 + {
1.312 + // Now get all the shaped values
1.313 + // Get the number of glyphs, glyphs, positions and indices after shaping.
1.314 + TInt numGlyphs = aShapeInfo.GlyphCount();
1.315 + const TInt32* glyph = aShapeInfo.Glyphs();
1.316 + const RShapeInfo::TPoint16* position = aShapeInfo.GlyphPositions();
1.317 + const TInt16* indices = aShapeInfo.Indices();
1.318 + TPoint origin;
1.319 +
1.320 + // Shift the indices and positions until the current poisition is reached. This done so that the
1.321 + // origin can be set back to the original co-ordinates at the start of this Hindi text
1.322 + while (*indices < aCurrPos)
1.323 + {
1.324 + position++;
1.325 + indices++;
1.326 + }
1.327 + // Set the origin back by subtracting the current position co-ordinates from the current pen position
1.328 + origin.iX = aGss.iParam.iPen.iX - position->iX;
1.329 + origin.iY = aGss.iParam.iPen.iY - position->iY;
1.330 +
1.331 + // No re-initialise the indices and positions to start appending the glyphs to clusters from the beginning
1.332 + indices = aShapeInfo.Indices();
1.333 + position = aShapeInfo.GlyphPositions();
1.334 +
1.335 + // Now do some post shaping syllable chopping
1.336 + for (TInt i = 0; i < numGlyphs; i++, glyph++, position++, indices++)
1.337 + {
1.338 + if(*indices >= aSyllEndPos)
1.339 + break;
1.340 + if(*indices >= aCurrPos && *indices < aSyllEndPos)
1.341 + {
1.342 + aGss.iParam.iPen.iX = origin.iX + position->iX;
1.343 + aGss.iParam.iPen.iY = origin.iY + position->iY;
1.344 +
1.345 + //Just skip the non-existing glyph and continue handling other glyphs if AppendGlyphToCluster return false.
1.346 + // The "continue" statement is for avoiding the potential risk of handling the non-existing glyph.
1.347 + if (!aGss.AppendGlyphToCluster(0x80000000UL | *glyph))
1.348 + continue;
1.349 + }
1.350 + }
1.351 +
1.352 + // We'll do pen advance ourselves, thanks.
1.353 + aGss.iPen = TGlyphSelectionState::EPenAdvance_No;
1.354 + aGss.iParam.iPen.iX = origin.iX + position->iX;
1.355 + aGss.iParam.iPen.iY = origin.iY + position->iY;
1.356 + aGss.iClusterState = TGlyphSelectionState::EGClusterComplete;
1.357 + aGss.iText.SetCurrentPosition(aSyllableEnd);
1.358 + return ETrue;
1.359 + }
1.360 +
1.361 +/**
1.362 +Common function for all Indic scripts.
1.363 +Performs shaping and Rasterizing operation on Indic script text
1.364 +*/
1.365 +TBool DoProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo, const TIndicScriptProcessorParameters& aScriptSpecificParameters){
1.366 + const TText16* startCharacter = aGss.iParam.iText.Ptr();
1.367 + const TText16* endCharacter = startCharacter + aGss.iParam.iText.Length();
1.368 + const TText16* currentCharacter = aGss.iText.CurrentPosition();
1.369 + TInt currentPosition = currentCharacter - startCharacter;
1.370 +
1.371 + // Get the logical end of the syllable from the input text. We will use this later to chop
1.372 + // syllables from the glyph values we get.
1.373 + const TText16* syllableEnd = SyllableEnd(currentCharacter, endCharacter, aScriptSpecificParameters.iCodeMap,
1.374 + aScriptSpecificParameters.iMapLen);
1.375 + TInt syllableEndPos = syllableEnd - startCharacter;
1.376 +
1.377 + TInt ret = KErrNone;
1.378 + if(currentPosition >= aShapeInfo.EndOfShapedText())
1.379 + ret = IndicShapingProcess(aGss, aShapeInfo, aScriptSpecificParameters.iCodeMap, aScriptSpecificParameters.iMapLen,
1.380 + aScriptSpecificParameters.iUCHigh, aScriptSpecificParameters.iUCLow, aScriptSpecificParameters.iScriptCode, aScriptSpecificParameters.iLanguageCode);
1.381 +
1.382 + // If an RShapeInfo could not be opened, call the default process
1.383 + if (ret != KErrNone)
1.384 + return GlyphSelector_Default::Process(aGss, aShapeInfo);
1.385 +
1.386 + // Now call the post shaping process to add glyphs to the glyph cluster
1.387 + return IndicPostShapingProcess(aGss, aShapeInfo, currentPosition, syllableEndPos, syllableEnd);
1.388 +}
1.389 +
1.390 +/*************************************************** D E V A N A G A R I ***************************************************/
1.391 +TBool GlyphSelector_Devanagari::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
1.392 + {
1.393 + return DoProcess(aGss, aShapeInfo, KIndicDevParameters);
1.394 + }
1.395 +
1.396 +/***************************************************** K A N N A D A ******************************************************/
1.397 +TBool GlyphSelector_Kannada::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
1.398 + {
1.399 + return DoProcess(aGss, aShapeInfo, KIndicKanParameters);
1.400 + }
1.401 +
1.402 +/***************************************************** G U J A R A T I ******************************************************/
1.403 +TBool GlyphSelector_Gujarati::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
1.404 + {
1.405 + return DoProcess(aGss, aShapeInfo, KIndicGujParameters);
1.406 + }
1.407 +
1.408 +/***************************************************** B E N G A L I ******************************************************/
1.409 +TBool GlyphSelector_Bengali::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
1.410 + {
1.411 + return DoProcess(aGss, aShapeInfo, KIndicBenParameters);
1.412 + }
1.413 +
1.414 +/***************************************************** T A M I L ******************************************************/
1.415 +TBool GlyphSelector_Tamil::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
1.416 + {
1.417 + return DoProcess(aGss, aShapeInfo, KIndicTamParameters);
1.418 + }
1.419 +
1.420 +/***************************************************** T E L U G U ******************************************************/
1.421 +TBool GlyphSelector_Telugu::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
1.422 + {
1.423 + return DoProcess(aGss, aShapeInfo, KIndicTelParameters);
1.424 + }
1.425 +
1.426 +/***************************************************** G U R M U K H I ******************************************************/
1.427 +TBool GlyphSelector_Gurmukhi::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)\
1.428 + {
1.429 + return DoProcess(aGss, aShapeInfo, KIndicGurParameters);
1.430 + }
1.431 +
1.432 +/***************************************************** M A L A Y A L A M ******************************************************/
1.433 +TBool GlyphSelector_Malayalam::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)
1.434 + {
1.435 + return DoProcess(aGss, aShapeInfo, KIndicMalParameters);
1.436 + }
1.437 +