1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html#License 3 /* 4 ******************************************************************************* 5 * Copyright (C) 1998-2008, International Business Machines Corporation and * 6 * others. All Rights Reserved. * 7 ******************************************************************************* 8 * 9 * Created on Dec 09, 2003 10 * 11 ******************************************************************************* 12 */ 13 package com.ibm.icu.dev.tool.layout; 14 15 import java.io.PrintStream; 16 import java.util.Vector; 17 18 public class ThaiStateTable 19 { 20 static Vector stateTable = null; 21 static int nextState = 0; 22 23 private final static int newState() 24 { 25 ThaiStateTransition[] stateRow = new ThaiStateTransition[ThaiCharacterClasses.cCount]; 26 27 for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) { 28 stateRow[c] = null; 29 } 30 31 stateTable.addElement(stateRow); 32 33 return nextState++; 34 } 35 36 private final static boolean isLegalHere(int state, char pairAction) 37 { 38 switch (pairAction) { 39 case 'A': 40 return state == 0; 41 42 case 'C': 43 case 'D': 44 case 'E': 45 case 'F': 46 case 'G': 47 case 'H': 48 return true; 49 50 case 'R': 51 case 'S': 52 return false; 53 } 54 55 return false; 56 } 57 58 private final static boolean composesWithAnything(int charClass) 59 { 60 for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) { 61 char action = ThaiCharacterClasses.getPairAction(charClass, c); 62 63 if (action >= 'C' && action <= 'I') { 64 return true; 65 } 66 } 67 68 return false; 69 } 70 71 private final static void fixNextStates() 72 { 73 ThaiStateTransition[] groundState = (ThaiStateTransition[]) stateTable.elementAt(0); 74 75 for (int s = 1; s < stateTable.size(); s += 1) { 76 ThaiStateTransition[] state = (ThaiStateTransition[]) stateTable.elementAt(s); 77 78 for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) { 79 ThaiStateTransition transition = state[c]; 80 81 if (transition.getNextState() == 0) { 82 transition.setNextState(groundState[c].getNextState()); 83 } 84 } 85 } 86 } 87 88 private final static int addState(int prevClass, int prevPrevClass) 89 { 90 int state = newState(); 91 ThaiStateTransition[] stateRow = (ThaiStateTransition[]) stateTable.elementAt(state); 92 93 for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) { 94 char pairAction = ThaiCharacterClasses.getPairAction(prevClass, c); 95 int nextSt = 0; 96 97 switch (pairAction) { 98 case 'G': 99 if (prevClass == ThaiCharacterClasses.NIK && 100 prevPrevClass == ThaiCharacterClasses.AV1) { 101 pairAction = 'R'; 102 } else if (prevPrevClass != ThaiCharacterClasses.COA) { 103 pairAction = 'C'; 104 } 105 break; 106 107 case 'E': 108 if (prevPrevClass == ThaiCharacterClasses.COA) { 109 pairAction = 'F'; 110 } 111 break; 112 113 case 'I': 114 if (prevClass == ThaiCharacterClasses.TON && 115 (prevPrevClass < ThaiCharacterClasses.CON || 116 prevPrevClass > ThaiCharacterClasses.COD)) { 117 pairAction = 'S'; 118 } else { 119 pairAction = 'A'; 120 } 121 break; 122 123 default: 124 break; 125 } 126 127 if (c != prevClass && isLegalHere(state, pairAction) && composesWithAnything(c)) { 128 nextSt = addState(c, prevClass); 129 } 130 131 stateRow[c] = new ThaiStateTransition(nextSt, pairAction); 132 } 133 134 return state; 135 } 136 137 static 138 { 139 stateTable = new Vector(); 140 141 addState(ThaiCharacterClasses.NON, ThaiCharacterClasses.NON); 142 143 fixNextStates(); 144 } 145 146 public static ThaiStateTransition getTransition(int state, int currClass) 147 { 148 ThaiStateTransition[] row = (ThaiStateTransition[]) stateTable.elementAt(state); 149 150 return row[currClass]; 151 } 152 153 private static String header0 = 154 "const ThaiShaping::StateTransition ThaiShaping::thaiStateTable[][ThaiShaping::classCount] = {"; 155 156 private static String header1 = 157 " //+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+"; 158 159 private static String header2 = 160 " //| N C C C L F F F B B B T A A A N A A A |\n" + 161 " //| O O O O V V V V V V D O D D D I V V V |\n" + 162 " //| N N A D O 1 2 3 1 2 I N 1 2 3 K 1 2 3 |"; 163 164 public static void writeStateTable(PrintStream output) 165 { 166 System.out.print("Writing state table..."); 167 168 output.println(header0); 169 output.println(header1); 170 output.println(header2); 171 output.println(header1); 172 173 for (int state = 0; state < stateTable.size(); state += 1) { 174 ThaiStateTransition[] row = (ThaiStateTransition[]) stateTable.elementAt(state); 175 176 output.print(" /*"); 177 178 if (state < 10) { 179 output.print("0"); 180 } 181 182 output.print(state); 183 184 output.print("*/ {"); 185 186 for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) { 187 row[c].write(output); 188 189 if (c < ThaiCharacterClasses.cCount - 1) { 190 output.print(", "); 191 } 192 } 193 194 output.print("}"); 195 196 if (state < stateTable.size() - 1) { 197 output.print(","); 198 } 199 200 output.println(); 201 } 202 203 output.println("};\n"); 204 205 System.out.println(" done."); 206 } 207 } 208