001: /*
002: *******************************************************************************
003: * Copyright (C) 1998-2005, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: *
007: * Created on Dec 09, 2003
008: *
009: *******************************************************************************
010: */
011: package com.ibm.icu.dev.tool.layout;
012:
013: import java.io.PrintStream;
014: import java.util.Vector;
015:
016: public class ThaiStateTable {
017: static Vector stateTable = null;
018: static int nextState = 0;
019:
020: private final static int newState() {
021: ThaiStateTransition[] stateRow = new ThaiStateTransition[ThaiCharacterClasses.cCount];
022:
023: for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
024: stateRow[c] = null;
025: }
026:
027: stateTable.addElement(stateRow);
028:
029: return nextState++;
030: }
031:
032: private final static boolean isLegalHere(int state, char pairAction) {
033: switch (pairAction) {
034: case 'A':
035: return state == 0;
036:
037: case 'C':
038: case 'D':
039: case 'E':
040: case 'F':
041: case 'G':
042: case 'H':
043: return true;
044:
045: case 'R':
046: case 'S':
047: return false;
048: }
049:
050: return false;
051: }
052:
053: private final static boolean composesWithAnything(int charClass) {
054: for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
055: char action = ThaiCharacterClasses.getPairAction(charClass,
056: c);
057:
058: if (action >= 'C' && action <= 'I') {
059: return true;
060: }
061: }
062:
063: return false;
064: }
065:
066: private final static void fixNextStates() {
067: ThaiStateTransition[] groundState = (ThaiStateTransition[]) stateTable
068: .elementAt(0);
069:
070: for (int s = 1; s < stateTable.size(); s += 1) {
071: ThaiStateTransition[] state = (ThaiStateTransition[]) stateTable
072: .elementAt(s);
073:
074: for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
075: ThaiStateTransition transition = state[c];
076:
077: if (transition.getNextState() == 0) {
078: transition.setNextState(groundState[c]
079: .getNextState());
080: }
081: }
082: }
083: }
084:
085: private final static int addState(int prevClass, int prevPrevClass) {
086: int state = newState();
087: ThaiStateTransition[] stateRow = (ThaiStateTransition[]) stateTable
088: .elementAt(state);
089:
090: for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
091: char pairAction = ThaiCharacterClasses.getPairAction(
092: prevClass, c);
093: int nextState = 0;
094:
095: switch (pairAction) {
096: case 'G':
097: if (prevClass == ThaiCharacterClasses.NIK
098: && prevPrevClass == ThaiCharacterClasses.AV1) {
099: pairAction = 'R';
100: } else if (prevPrevClass != ThaiCharacterClasses.COA) {
101: pairAction = 'C';
102: }
103: break;
104:
105: case 'E':
106: if (prevPrevClass == ThaiCharacterClasses.COA) {
107: pairAction = 'F';
108: }
109: break;
110:
111: case 'I':
112: if (prevClass == ThaiCharacterClasses.TON
113: && (prevPrevClass < ThaiCharacterClasses.CON || prevPrevClass > ThaiCharacterClasses.COD)) {
114: pairAction = 'S';
115: } else {
116: pairAction = 'A';
117: }
118: break;
119:
120: default:
121: break;
122: }
123:
124: if (c != prevClass && isLegalHere(state, pairAction)
125: && composesWithAnything(c)) {
126: nextState = addState(c, prevClass);
127: }
128:
129: stateRow[c] = new ThaiStateTransition(nextState, pairAction);
130: }
131:
132: return state;
133: }
134:
135: static {
136: stateTable = new Vector();
137:
138: addState(ThaiCharacterClasses.NON, ThaiCharacterClasses.NON);
139:
140: fixNextStates();
141: }
142:
143: public static ThaiStateTransition getTransition(int state,
144: int currClass) {
145: ThaiStateTransition[] row = (ThaiStateTransition[]) stateTable
146: .elementAt(state);
147:
148: return row[currClass];
149: }
150:
151: private static String header0 = "const ThaiShaping::StateTransition ThaiShaping::thaiStateTable[][ThaiShaping::classCount] = {";
152:
153: private static String header1 = " //+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+";
154:
155: private static String header2 = " //| N C C C L F F F B B B T A A A N A A A |\n"
156: + " //| O O O O V V V V V V D O D D D I V V V |\n"
157: + " //| N N A D O 1 2 3 1 2 I N 1 2 3 K 1 2 3 |";
158:
159: public static void writeStateTable(PrintStream output) {
160: System.out.print("Writing state table...");
161:
162: output.println(header0);
163: output.println(header1);
164: output.println(header2);
165: output.println(header1);
166:
167: for (int state = 0; state < stateTable.size(); state += 1) {
168: ThaiStateTransition[] row = (ThaiStateTransition[]) stateTable
169: .elementAt(state);
170:
171: output.print(" /*");
172:
173: if (state < 10) {
174: output.print("0");
175: }
176:
177: output.print(state);
178:
179: output.print("*/ {");
180:
181: for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
182: row[c].write(output);
183:
184: if (c < ThaiCharacterClasses.cCount - 1) {
185: output.print(", ");
186: }
187: }
188:
189: output.print("}");
190:
191: if (state < stateTable.size() - 1) {
192: output.print(",");
193: }
194:
195: output.println();
196: }
197:
198: output.println("};\n");
199:
200: System.out.println(" done.");
201: }
202: }
|