graphicsdeviceinterface/gdi/sgdi/FontIndic.cpp
changeset 183 6a1564a2f3e6
parent 168 2bd88482bfe5
child 194 18f84489a694
equal deleted inserted replaced
168:2bd88482bfe5 183:6a1564a2f3e6
     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