blob: 935f1c8a3a0b297c3de6edbff40b4e641fe1ce14 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1998-2008, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 09, 2003
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.PrintStream;
import java.util.Vector;
public class ThaiStateTable
{
static Vector stateTable = null;
static int nextState = 0;
private final static int newState()
{
ThaiStateTransition[] stateRow = new ThaiStateTransition[ThaiCharacterClasses.cCount];
for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
stateRow[c] = null;
}
stateTable.addElement(stateRow);
return nextState++;
}
private final static boolean isLegalHere(int state, char pairAction)
{
switch (pairAction) {
case 'A':
return state == 0;
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
return true;
case 'R':
case 'S':
return false;
}
return false;
}
private final static boolean composesWithAnything(int charClass)
{
for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
char action = ThaiCharacterClasses.getPairAction(charClass, c);
if (action >= 'C' && action <= 'I') {
return true;
}
}
return false;
}
private final static void fixNextStates()
{
ThaiStateTransition[] groundState = (ThaiStateTransition[]) stateTable.elementAt(0);
for (int s = 1; s < stateTable.size(); s += 1) {
ThaiStateTransition[] state = (ThaiStateTransition[]) stateTable.elementAt(s);
for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
ThaiStateTransition transition = state[c];
if (transition.getNextState() == 0) {
transition.setNextState(groundState[c].getNextState());
}
}
}
}
private final static int addState(int prevClass, int prevPrevClass)
{
int state = newState();
ThaiStateTransition[] stateRow = (ThaiStateTransition[]) stateTable.elementAt(state);
for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
char pairAction = ThaiCharacterClasses.getPairAction(prevClass, c);
int nextSt = 0;
switch (pairAction) {
case 'G':
if (prevClass == ThaiCharacterClasses.NIK &&
prevPrevClass == ThaiCharacterClasses.AV1) {
pairAction = 'R';
} else if (prevPrevClass != ThaiCharacterClasses.COA) {
pairAction = 'C';
}
break;
case 'E':
if (prevPrevClass == ThaiCharacterClasses.COA) {
pairAction = 'F';
}
break;
case 'I':
if (prevClass == ThaiCharacterClasses.TON &&
(prevPrevClass < ThaiCharacterClasses.CON ||
prevPrevClass > ThaiCharacterClasses.COD)) {
pairAction = 'S';
} else {
pairAction = 'A';
}
break;
default:
break;
}
if (c != prevClass && isLegalHere(state, pairAction) && composesWithAnything(c)) {
nextSt = addState(c, prevClass);
}
stateRow[c] = new ThaiStateTransition(nextSt, pairAction);
}
return state;
}
static
{
stateTable = new Vector();
addState(ThaiCharacterClasses.NON, ThaiCharacterClasses.NON);
fixNextStates();
}
public static ThaiStateTransition getTransition(int state, int currClass)
{
ThaiStateTransition[] row = (ThaiStateTransition[]) stateTable.elementAt(state);
return row[currClass];
}
private static String header0 =
"const ThaiShaping::StateTransition ThaiShaping::thaiStateTable[][ThaiShaping::classCount] = {";
private static String header1 =
" //+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+";
private static String header2 =
" //| N C C C L F F F B B B T A A A N A A A |\n" +
" //| O O O O V V V V V V D O D D D I V V V |\n" +
" //| N N A D O 1 2 3 1 2 I N 1 2 3 K 1 2 3 |";
public static void writeStateTable(PrintStream output)
{
System.out.print("Writing state table...");
output.println(header0);
output.println(header1);
output.println(header2);
output.println(header1);
for (int state = 0; state < stateTable.size(); state += 1) {
ThaiStateTransition[] row = (ThaiStateTransition[]) stateTable.elementAt(state);
output.print(" /*");
if (state < 10) {
output.print("0");
}
output.print(state);
output.print("*/ {");
for (int c = 0; c < ThaiCharacterClasses.cCount; c += 1) {
row[c].write(output);
if (c < ThaiCharacterClasses.cCount - 1) {
output.print(", ");
}
}
output.print("}");
if (state < stateTable.size() - 1) {
output.print(",");
}
output.println();
}
output.println("};\n");
System.out.println(" done.");
}
}