sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @internalComponent sl@0: */ sl@0: sl@0: #include "FontIndic.h" sl@0: #include sl@0: #include "GlyphSel.h" sl@0: #include "ShapeInfo.h" sl@0: #include "gdiinline.inl" sl@0: sl@0: // State machine for determining syllable boundaries. sl@0: // Key: D = Dependent vowel. V = Virama. N = Nukta sl@0: // I = Independent Vowel. S = Candrabindu/Anusvara/Visarga sl@0: // C = Consonant. J = zero-width joiner. X = Other sl@0: // A = Addak (double the following constant) sl@0: enum TSyllableState sl@0: { sl@0: EReject = -1, sl@0: // Begin + I: add and move to IndependentVowel sl@0: // Begin + C: add and move to Consonant sl@0: // Begin + V/N/D/S/J/X: add and close syllable sl@0: EBegin = 0, sl@0: // Consonant + D: add and move to ConsonantVowel sl@0: // Consonant + N: add sl@0: // Consonant + V: add and move to Virama sl@0: // Consonant + S: add and close syllable sl@0: // Consonant + C/I/J/X: close syllable sl@0: EConsonant = 1, sl@0: // Consonant2 + D: add and move to ConsonantVowel sl@0: // Consonant2 + N: add sl@0: // Consonant2 + V: add and move to Virama2 sl@0: // Consonant2 + S: add and close syllable sl@0: // Consonant2 + C/I/J/X: close syllable sl@0: EConsonant2 = 2, sl@0: // Consonant3 + D: add and move to ConsonantVowel sl@0: // Consonant3 + N: add sl@0: // Consonant3 + V: add and move to Virama3 sl@0: // Consonant3 + S: add and close syllable sl@0: // Consonant3 + C/I/J/X: close syllable sl@0: EConsonant3 = 3, sl@0: // Consonant + D: add and move to ConsonantVowel sl@0: // Consonant + N: add sl@0: // Consonant + V: add and close syllable sl@0: // Consonant + S: add and close syllable sl@0: // Consonant + C/I/J/X: close syllable sl@0: EConsonant4 = 4, sl@0: // IndependentVowel + S: add sl@0: // IndependentVowel + D/V/N/I/C/J/X: close syllable sl@0: EIndependentVowel = 5, sl@0: // Virama + C: add and move to Consonant sl@0: // Virama + J: add and close syllable sl@0: // Virama + N/V/D/I/S/X: close syllable sl@0: EVirama = 6, sl@0: // Virama2 + C: add and move to Consonant3 sl@0: // Virama2 + J: add and close syllable sl@0: // Virama2 + N/V/D/I/S/X: close syllable sl@0: EVirama2 = 7, sl@0: // Virama3 + C: add and move to Consonant4 sl@0: // Virama3 + J: add and close syllable sl@0: // Virama3 + N/V/D/I/S/X: close syllable sl@0: EVirama3 = 8, sl@0: // Virama4 + J: add and close syllable sl@0: // Virama4 + CN/V/D/I/S/X: close syllable sl@0: EVirama4 = 9, sl@0: // ConsonantVowel + S: add sl@0: // ConsonantVowel + D/V/N/I/C/J/X: close syllable sl@0: EConsonantVowel = 10, sl@0: // NuktaConsonant + D/V: add sl@0: // NuktaConsonant + S/N/I/C/J/X: close syllable sl@0: ENuktaConsonant = 11, sl@0: // NuktaConsonant + D/V: add sl@0: // NuktaConsonant + S/N/I/C/J/X: close syllable sl@0: ENuktaConsonant2 = 12, sl@0: // NuktaConsonant + D/V: add sl@0: // NuktaConsonant + S/N/I/C/J/X: close syllable sl@0: ENuktaConsonant3 = 13, sl@0: // NuktaConsonant + D: add sl@0: // NuktaConsonant + V/S/N/I/C/J/X: close syllable sl@0: ENuktaConsonant4 = 14, sl@0: // IndependentVowelA + CANDRA E: add sl@0: // IndependentVowelA + anything else: close syllable sl@0: EIndependentVowelA = 15, sl@0: // ZeroWidthJoinerC + V: add sl@0: // ZeroWidthJoinerC + C/S/N/I/J/X/D: close syllable sl@0: EZeroWidthJoinerC = 16, sl@0: // ZeroWidthJoinerA + CANDRA E: add sl@0: // ZeroWidthJoinerA +anything else: close syllable sl@0: EZeroWidthJoinerA = 17, sl@0: // ZeroWidthJoinerV + C/N: add sl@0: // ZeroWidthJoinerV + anything else: close syllable sl@0: EZeroWidthJoinerV = 18, sl@0: // ZeroWidthJoinerV2 + C/N: add sl@0: // ZeroWidthJoinerV2 + anything else: close syllable sl@0: EZeroWidthJoinerV2 = 19, sl@0: // ZeroWidthJoinerV3 + C/N: add sl@0: // ZeroWidthJoinerV3 + anything else: close syllable sl@0: EZeroWidthJoinerV3 =20, sl@0: // EKannadaRa + C/N/V/ZWJ(C): add sl@0: EKannadaRa = 21, sl@0: // ESplitVowel1 + SV2: add and close syllable sl@0: // ESPlitVowel1 + anything else: close syllable sl@0: ESplitVowel1 = 22, sl@0: //EGurBearerA + EIndicCodeGurDependentVowelA: add and move to EIndependentVowel sl@0: //EGurBearerA + modifier: add and close syllable sl@0: //EGurBearerA + anything else: close syllable sl@0: EGurBearerA = 23, sl@0: //EGurBearerU + EIndicCodeGurDependentVowelU: add and move to EIndependentVowel sl@0: //EGurBearerU + anything else: close syllable sl@0: EGurBearerU = 24, sl@0: //EGurBearerI + EIndicCodeGurDependentVowelI: add and move to EIndependentVowel sl@0: //EGurBearerI + anything else: close syllable sl@0: EGurBearerI = 25, sl@0: sl@0: EConsonantMalaChillu = 26, sl@0: EConsonantMalaChillu2 = 27, sl@0: EConsonantMalaChillu3 = 28, sl@0: EViramaMalaChillu = 29, sl@0: EViramaMalaChillu2 = 30, sl@0: EViramaMalaChillu3 = 31, sl@0: EConsonantMalaChilluNA = 32, sl@0: EConsonantMalaChilluNA2 = 33, sl@0: EConsonantMalaChilluNA3 = 34, sl@0: EViramaMalaChilluNA = 35, sl@0: EViramaMalaChilluNA2 = 36, sl@0: EViramaMalaChilluNA3 = 37, sl@0: EZeroWidthJoinerMalaChilluNA = 38, sl@0: EZeroWidthJoinerMalaChilluNA2 = 39, sl@0: EZeroWidthJoinerMalaChilluNA3 = 40, sl@0: // Add and close acceptances go here. sl@0: EAccept = 41 sl@0: }; sl@0: sl@0: /** Defines the transitions for a state machine for determining syllable sl@0: boundaries. The machine starts in state 0. On receiving a character of type t sl@0: while in state s, moves to state KStateResponse[s][t]. */ sl@0: const TSyllableState KStateResponse[42][24] = sl@0: { sl@0: // EBegin -- nothing added yet sl@0: {EAccept, EAccept, EIndependentVowel, EConsonant, EAccept, EAccept, EAccept, EAccept, ENuktaConsonant, EIndependentVowelA, EAccept, EKannadaRa, EAccept, EAccept, EAccept, EGurBearerA, EGurBearerU, EGurBearerI, EAccept, EAccept, EAccept, EConsonantMalaChillu,EConsonantMalaChilluNA,EConsonant}, sl@0: // EConsonant -- seen a consonant either at the start or after virama sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, ENuktaConsonant, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // EConsonant2 -- seen a consonant after virama sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama2, ENuktaConsonant2, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // EConsonant3 -- seen a consonant after virama2 sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama3, ENuktaConsonant3, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // EConsonant4 -- seen a consonant after virama3 sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama4, ENuktaConsonant4, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // EIndependentVowel -- possibly nasalized. I haven't bothered to distinguish between sl@0: // nasalization and visarga. sl@0: {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject}, sl@0: // EVirama -- just seen a virama in a legal context. Must be consonant or ZWJ next sl@0: {EReject, EReject, EReject, EConsonant2, EReject, EReject, EReject, EZeroWidthJoinerV, ENuktaConsonant2, EReject, EReject, EConsonant2, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2}, sl@0: // EVirama2 -- just seen a virama in a legal context. Must be consonant2 sl@0: {EReject, EReject, EReject, EConsonant3, EReject, EReject, EReject, EZeroWidthJoinerV2, ENuktaConsonant3, EReject, EReject, EConsonant3, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3}, sl@0: // EVirama3 -- just seen a virama in a legal context. Must be consonant3 sl@0: {EReject, EReject, EReject, EConsonant4, EReject, EReject, EReject, EZeroWidthJoinerV3, ENuktaConsonant4, EReject, EReject, EConsonant4, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonant4,EConsonant4,EConsonant4}, sl@0: // EVirama4 -- just seen a virama in a legal context. Must be consonant4 sl@0: {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject}, sl@0: // EConsonantVowel -- Just seen a consonant with matra. Can only nasalize or visarg sl@0: {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject}, sl@0: // ENuktaConsonant -- Just seen a consonant with Nukta. Can only accept a dependant vowel or a Virama at this stage. sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // ENuktaConsonant2 -- Just seen a consonant with Nukta after a virama. sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama2, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // ENuktaConsonant3 -- Just seen a consonant with Nukta after Virama2. sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama3, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // ENuktaConsonant4 -- Just seen a consonant with Nukta after Virama3. sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama4, EReject, EReject, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // EIndependentVowelA -- Special case Devanagari independent vowel sl@0: {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EZeroWidthJoinerA, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // EZeroWidthJoinerC -- Just seen a ZWJ after a consonant sl@0: {EReject, EReject, EReject, EReject, EReject, EVirama, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject}, sl@0: // EZeroWidthJoinerA -- Just seen a ZWJ after the dependent Vowel A sl@0: {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject}, sl@0: // EZeroWidthJoinerV -- Just seen the ZWJ after the first pair of consonant + virama sl@0: {EReject, EAccept, EReject, EConsonant2, EReject, EReject, EReject, EReject, ENuktaConsonant2, EReject, EReject, EConsonant2, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2}, sl@0: // EZeroWidthJoinerV2 -- Just seen the ZWJ after consonant + virama + consonant + virama sl@0: {EReject, EAccept, EReject, EConsonant3, EReject, EReject, EReject, EReject, ENuktaConsonant3, EReject, EReject, EConsonant3, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3}, sl@0: // EZeroWidthJoinerV3 -- Just seen the ZWJ after consonant + virama + consonant + virama + consonant + virama sl@0: {EReject, EAccept, EReject, EConsonant4, EReject, EReject, EReject, EReject, ENuktaConsonant4, EReject, EReject, EConsonant4, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonant4,EConsonant4,EConsonant4}, sl@0: // EKannadaRa -- Special case consonant sl@0: {EReject, EAccept, EReject, EReject, EConsonantVowel, EVirama, ENuktaConsonant, EZeroWidthJoinerC, EReject, EReject, EConsonantVowel, EReject, ESplitVowel1, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EConsonantVowel, EReject,EReject,EReject}, sl@0: // ESplitVowel1 -- Just seen a consonant with first part of a split vowel. Can only nasalize, visarg or add second part of splt vowel sl@0: {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EConsonantVowel, EConsonantVowel, EReject, EReject, EReject, EReject, EReject, EReject, EReject,EReject,EReject}, sl@0: // EGurBearerA -- Just seen a dependent Vowel EIndicCodeGurDependentVowelA and modifier sl@0: {EReject, EAccept, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject, EReject, EReject,EReject,EReject}, sl@0: // EGurBearerU -- Just seen a dependent Vowel EIndicCodeGurDependentVowelU sl@0: {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject, EReject,EReject,EReject}, sl@0: // EGurBearerI -- Just seen a dependent Vowel EIndicCodeGurDependentVowelI sl@0: {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EIndependentVowel, EReject,EReject,EReject}, sl@0: sl@0: {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject}, sl@0: {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu2,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject}, sl@0: {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChillu3,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject}, sl@0: {EReject,EReject,EReject,EConsonant2,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2}, sl@0: {EReject,EReject,EReject,EConsonant3,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3}, sl@0: {EReject,EReject,EReject,EConsonant4,EReject,EReject,EReject,EAccept,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4,EConsonant4,EConsonant4}, sl@0: {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject}, sl@0: {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA2,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject}, sl@0: {EReject,EAccept,EReject,EReject,EConsonantVowel,EViramaMalaChilluNA3,EReject,EReject,EReject,EReject,EReject,EReject,ESplitVowel1,EConsonantVowel,EConsonantVowel,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject}, sl@0: {EReject,EReject,EReject,EConsonant2,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu2,EConsonantMalaChilluNA2,EConsonant2}, sl@0: {EReject,EReject,EReject,EConsonant3,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA2,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonantMalaChillu3,EConsonantMalaChilluNA3,EConsonant3}, sl@0: {EReject,EReject,EReject,EConsonant4,EReject,EReject,EReject,EZeroWidthJoinerMalaChilluNA3,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4,EConsonant4,EConsonant4}, sl@0: {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant2}, sl@0: {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant3}, sl@0: {EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EReject,EConsonant4}, sl@0: sl@0: // EAccept -- this one is added but anything further is rejected sl@0: {EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject, EReject} sl@0: }; sl@0: sl@0: TIndicCodeType CodeType(TInt aCode, const TIndicCodeMapping aCodeMap[], TInt aMapLen) sl@0: { sl@0: TInt start = 0; sl@0: TInt end = aMapLen - 1; sl@0: while (start != end) sl@0: { sl@0: const TInt mid = (start + end + 1) >> 1; sl@0: if (aCodeMap[mid].iFirstCodeInRange <= aCode) sl@0: start = mid; sl@0: else sl@0: end = mid - 1; sl@0: } sl@0: return static_cast(aCodeMap[start].iCodeType); sl@0: } sl@0: sl@0: const TText16* SyllableEnd(const TText16* aCurrentPosition, sl@0: const TText16* aEnd, const TIndicCodeMapping aCodeMap[], TInt aMapLen) sl@0: { sl@0: TSyllableState state = EBegin; sl@0: while (aCurrentPosition != aEnd) sl@0: { sl@0: const TIndicCodeType ct = CodeType(*aCurrentPosition, aCodeMap, aMapLen); sl@0: state = KStateResponse[state][ct]; sl@0: if (state == EReject) sl@0: return aCurrentPosition; sl@0: ++aCurrentPosition; sl@0: } sl@0: return aCurrentPosition; sl@0: } sl@0: sl@0: /** sl@0: Common function for all Indic scripts. sl@0: Performs the shaping operation on Indic script text up to KMaxTextToShape. sl@0: */ sl@0: TInt IndicShapingProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo, sl@0: const TIndicCodeMapping aCodeMap[], TInt aMapLen, const TUint aHighChar, sl@0: const TUint aLowChar, const TUint32 aScript, const TUint32 aLang) sl@0: { sl@0: const TText16* startCharacter = aGss.iParam.iText.Ptr(); sl@0: const TText16* endCharacter = startCharacter + aGss.iParam.iText.Length(); sl@0: const TText16* currentCharacter = aGss.iText.CurrentPosition(); sl@0: TInt currentPosition = currentCharacter - startCharacter; sl@0: sl@0: // Do some new shaping sl@0: sl@0: // First close the existing RShapeInfo sl@0: if(aShapeInfo.IsOpen()) sl@0: aShapeInfo.Close(); sl@0: sl@0: // Find the end of Indic text whilst limiting the amount of text to be shaped to sl@0: // KMaxTextToShape. When finding the end of end position of the text to be shaped, sl@0: // include numerals, punctuations and other control characters. sl@0: const TText16* endIndic = currentCharacter; sl@0: TChar endIndicChar = *endIndic; sl@0: while((endIndic <= endCharacter || endIndic - currentCharacter <= KMaxTextToShape) && sl@0: ((*endIndic >= aLowChar && *endIndic <= aHighChar) || sl@0: ((endIndicChar.IsDigit() || endIndicChar.IsPunctuation()) && !QuoteOrBracketPair(*endIndic)))) sl@0: { sl@0: if (endIndic == endCharacter || endIndic - currentCharacter > KMaxTextToShape) sl@0: break; sl@0: endIndic = SyllableEnd(endIndic, endCharacter, aCodeMap, aMapLen); sl@0: endIndicChar = *endIndic; sl@0: } sl@0: sl@0: TInt endPosForShaping = endIndic - startCharacter; sl@0: sl@0: //Now shape from current position to the end of Hindi sl@0: return aShapeInfo.Open(aGss.iFont, aGss.iParam.iText, sl@0: currentPosition, endPosForShaping, aScript, aLang); sl@0: } sl@0: sl@0: /** sl@0: Common function for all Indic scripts. Adds the shaped glyphs to the glyph cluster. sl@0: This function is called regardless of whether shaping was done or skipped in this sl@0: iteration of the Default Process sl@0: */ sl@0: TBool IndicPostShapingProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo, sl@0: TInt aCurrPos, TInt aSyllEndPos, const TText16* aSyllableEnd) sl@0: { sl@0: // Now get all the shaped values sl@0: // Get the number of glyphs, glyphs, positions and indices after shaping. sl@0: TInt numGlyphs = aShapeInfo.GlyphCount(); sl@0: const TInt32* glyph = aShapeInfo.Glyphs(); sl@0: const RShapeInfo::TPoint16* position = aShapeInfo.GlyphPositions(); sl@0: const TInt16* indices = aShapeInfo.Indices(); sl@0: TPoint origin; sl@0: sl@0: // Shift the indices and positions until the current poisition is reached. This done so that the sl@0: // origin can be set back to the original co-ordinates at the start of this Hindi text sl@0: while (*indices < aCurrPos) sl@0: { sl@0: position++; sl@0: indices++; sl@0: } sl@0: // Set the origin back by subtracting the current position co-ordinates from the current pen position sl@0: origin.iX = aGss.iParam.iPen.iX - position->iX; sl@0: origin.iY = aGss.iParam.iPen.iY - position->iY; sl@0: sl@0: // No re-initialise the indices and positions to start appending the glyphs to clusters from the beginning sl@0: indices = aShapeInfo.Indices(); sl@0: position = aShapeInfo.GlyphPositions(); sl@0: sl@0: // Now do some post shaping syllable chopping sl@0: for (TInt i = 0; i < numGlyphs; i++, glyph++, position++, indices++) sl@0: { sl@0: if(*indices >= aSyllEndPos) sl@0: break; sl@0: if(*indices >= aCurrPos && *indices < aSyllEndPos) sl@0: { sl@0: aGss.iParam.iPen.iX = origin.iX + position->iX; sl@0: aGss.iParam.iPen.iY = origin.iY + position->iY; sl@0: sl@0: //Just skip the non-existing glyph and continue handling other glyphs if AppendGlyphToCluster return false. sl@0: // The "continue" statement is for avoiding the potential risk of handling the non-existing glyph. sl@0: if (!aGss.AppendGlyphToCluster(0x80000000UL | *glyph)) sl@0: continue; sl@0: } sl@0: } sl@0: sl@0: // We'll do pen advance ourselves, thanks. sl@0: aGss.iPen = TGlyphSelectionState::EPenAdvance_No; sl@0: aGss.iParam.iPen.iX = origin.iX + position->iX; sl@0: aGss.iParam.iPen.iY = origin.iY + position->iY; sl@0: aGss.iClusterState = TGlyphSelectionState::EGClusterComplete; sl@0: aGss.iText.SetCurrentPosition(aSyllableEnd); sl@0: return ETrue; sl@0: } sl@0: sl@0: /** sl@0: Common function for all Indic scripts. sl@0: Performs shaping and Rasterizing operation on Indic script text sl@0: */ sl@0: TBool DoProcess(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo, const TIndicScriptProcessorParameters& aScriptSpecificParameters){ sl@0: const TText16* startCharacter = aGss.iParam.iText.Ptr(); sl@0: const TText16* endCharacter = startCharacter + aGss.iParam.iText.Length(); sl@0: const TText16* currentCharacter = aGss.iText.CurrentPosition(); sl@0: TInt currentPosition = currentCharacter - startCharacter; sl@0: sl@0: // Get the logical end of the syllable from the input text. We will use this later to chop sl@0: // syllables from the glyph values we get. sl@0: const TText16* syllableEnd = SyllableEnd(currentCharacter, endCharacter, aScriptSpecificParameters.iCodeMap, sl@0: aScriptSpecificParameters.iMapLen); sl@0: TInt syllableEndPos = syllableEnd - startCharacter; sl@0: sl@0: TInt ret = KErrNone; sl@0: if(currentPosition >= aShapeInfo.EndOfShapedText()) sl@0: ret = IndicShapingProcess(aGss, aShapeInfo, aScriptSpecificParameters.iCodeMap, aScriptSpecificParameters.iMapLen, sl@0: aScriptSpecificParameters.iUCHigh, aScriptSpecificParameters.iUCLow, aScriptSpecificParameters.iScriptCode, aScriptSpecificParameters.iLanguageCode); sl@0: sl@0: // If an RShapeInfo could not be opened, call the default process sl@0: if (ret != KErrNone) sl@0: return GlyphSelector_Default::Process(aGss, aShapeInfo); sl@0: sl@0: // Now call the post shaping process to add glyphs to the glyph cluster sl@0: return IndicPostShapingProcess(aGss, aShapeInfo, currentPosition, syllableEndPos, syllableEnd); sl@0: } sl@0: sl@0: /*************************************************** D E V A N A G A R I ***************************************************/ sl@0: TBool GlyphSelector_Devanagari::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicDevParameters); sl@0: } sl@0: sl@0: /***************************************************** K A N N A D A ******************************************************/ sl@0: TBool GlyphSelector_Kannada::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicKanParameters); sl@0: } sl@0: sl@0: /***************************************************** G U J A R A T I ******************************************************/ sl@0: TBool GlyphSelector_Gujarati::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicGujParameters); sl@0: } sl@0: sl@0: /***************************************************** B E N G A L I ******************************************************/ sl@0: TBool GlyphSelector_Bengali::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicBenParameters); sl@0: } sl@0: sl@0: /***************************************************** T A M I L ******************************************************/ sl@0: TBool GlyphSelector_Tamil::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicTamParameters); sl@0: } sl@0: sl@0: /***************************************************** T E L U G U ******************************************************/ sl@0: TBool GlyphSelector_Telugu::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicTelParameters); sl@0: } sl@0: sl@0: /***************************************************** G U R M U K H I ******************************************************/ sl@0: TBool GlyphSelector_Gurmukhi::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo)\ sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicGurParameters); sl@0: } sl@0: sl@0: /***************************************************** M A L A Y A L A M ******************************************************/ sl@0: TBool GlyphSelector_Malayalam::Process(TGlyphSelectionState& aGss, RShapeInfo& aShapeInfo) sl@0: { sl@0: return DoProcess(aGss, aShapeInfo, KIndicMalParameters); sl@0: } sl@0: