Home | History | Annotate | Download | only in layout
      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