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