os/graphics/graphicsdeviceinterface/gdi/sgdi/FontIndic.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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