diff options
Diffstat (limited to 'Build/source/libs/graphite-engine/src/segment/TestFSM.cpp')
-rw-r--r-- | Build/source/libs/graphite-engine/src/segment/TestFSM.cpp | 3416 |
1 files changed, 3416 insertions, 0 deletions
diff --git a/Build/source/libs/graphite-engine/src/segment/TestFSM.cpp b/Build/source/libs/graphite-engine/src/segment/TestFSM.cpp new file mode 100644 index 00000000000..6dad1dc9dc8 --- /dev/null +++ b/Build/source/libs/graphite-engine/src/segment/TestFSM.cpp @@ -0,0 +1,3416 @@ +/*--------------------------------------------------------------------*//*:Ignore this sentence. +Copyright (C) 1999, 2001 SIL International. All rights reserved. + +Distributable under the terms of either the Common Public License or the +GNU Lesser General Public License, as specified in the LICENSING.txt file. + +File: TestFSM.cpp +Responsibility: Sharon Correll +Last reviewed: Not yet. + +Description: + Hard-coded FSMs for test procedures. +-------------------------------------------------------------------------------*//*:End Ignore*/ + +//:Ignore + +//:>******************************************************************************************** +//:> Include files +//:>******************************************************************************************** +#include "Main.h" + +#ifdef _MSC_VER +#pragma hdrstop +#endif +#undef THIS_FILE +DEFINE_THIS_FILE + +#ifdef OLD_TEST_STUFF + +//:>******************************************************************************************** +//:> Forward declarations +//:>******************************************************************************************** + +//:>******************************************************************************************** +//:> Local Constants and static variables +//:>******************************************************************************************** + +namespace gr +{ + +//:>******************************************************************************************** +//:> Methods +//:>******************************************************************************************** + +#ifndef _DEBUG + +bool GrLineBreakPass::RunTestRules(GrTableManager * ptman, int ruln, + GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput) +{ + return false; +} + +bool GrSubPass::RunTestRules(GrTableManager * ptman, int ruln, + GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput) +{ + return false; +} + +bool GrPosPass::RunTestRules(GrTableManager * ptman, int ruln, + GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput) +{ + return false; +} +#endif // !_DEBUG + + +#ifdef _DEBUG + +/*---------------------------------------------------------------------------------------------- + Call the appropriate test function. +----------------------------------------------------------------------------------------------*/ + +bool GrLineBreakPass::RunTestRules(GrTableManager * ptman, int ruln, + GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput) +{ + return false; +} + +bool GrSubPass::RunTestRules(GrTableManager * ptman, int ruln, + GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput) +{ + if (m_staBehavior == "SimpleFSM") + return RunSimpleFSMTest(ptman, ruln, psstrmInput, psstrmOutput); + else if (m_staBehavior == "RuleAction") + return false; + else if (m_staBehavior == "RuleAction2") + return false; + else if (m_staBehavior == "Assoc") + return false; + else + return false; +} + +bool GrPosPass::RunTestRules(GrTableManager * ptman, int ruln, + GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput) +{ + return false; +} + + +/*---------------------------------------------------------------------------------------------- + A simple FSM. + + Rules: + r1. clsCons clsVowel clsDiacrAcute + r2. clsCons clsVowelAE clsDiacr + r3. clsCons clsVowelI + r4. clsCons clsVowelI clsDiacrGrave + r5. clsCons clsVowelI clsDiacr + + Machine classes: + mcCons: b,c,d / f,g,h / j,k,l,m,n / p,q,r,s,t / v,w,x,y,z + mcVae: a 97/ e 101 + mcVi: i 105 + mcVou: o 111 / u 117 + mcDa: acute '/' 47 + mcDg: grave '\' 92 + mcDct: other diacritics-circumflex '^' 94 / tilde '~' 126 + + + FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | mcCons mcVae mcVi mcVou mcDa mcDg mcDct + --------------------------------------------------------------------------- + T NA s0 | s1 + | - - - - - - - + T NA s1 | s2 s4 s3 + | - - - - - - - + T NA s2 | s5 s6 s6 + | - - - - - - - + T NA s3 | s10 + | - - - - - - - + T A s4 | s7 s8 s9 + | - - - - - - - + F A s5 | + | - - - - - - - + F A s6 | + | - - - - - - - + F A s7 | + | - - - - - - - + F A s8 | + | - - - - - - - + F A s9 | + | - - - - - - - + F A s10 | + | - - - - - - - + + Rules Matched: + s4: r3 + s5: r1, r2 + s6: r2 + s7: r1, r5 + s8: r4, r5 + s9: r5 + s10: r1 + +----------------------------------------------------------------------------------------------*/ + +void GrSubPass::SetUpSimpleFSMTest() +{ + m_nMaxRuleContext = m_nMaxChunk = 3; + m_nMaxRuleLoop = 2; + m_staBehavior = "SimpleFSM"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpSimpleFSMTest(); +} + +void GrFSM::SetUpSimpleFSMTest() +{ + // Create machine class ranges. + m_cmcr = 14; + m_prgmcr = new GrFSMClassRange[14]; + m_prgmcr[0].m_chwFirst = 47; // forward slash (acute): mcDa + m_prgmcr[0].m_chwLast = 47; + m_prgmcr[0].m_col = 4; + + m_prgmcr[1].m_chwFirst = 92; // backslash: mcDg + m_prgmcr[1].m_chwLast = 92; + m_prgmcr[1].m_col = 5; + + m_prgmcr[2].m_chwFirst = 94; // caret: mcDct + m_prgmcr[2].m_chwLast = 94; + m_prgmcr[2].m_col = 6; + + m_prgmcr[3].m_chwFirst = 97; // a: mcVae + m_prgmcr[3].m_chwLast = 97; + m_prgmcr[3].m_col = 1; + + m_prgmcr[4].m_chwFirst = 98; // b - d: mcCons + m_prgmcr[4].m_chwLast = 100; + m_prgmcr[4].m_col = 0; + + m_prgmcr[5].m_chwFirst = 101; // e: mcVae + m_prgmcr[5].m_chwLast = 101; + m_prgmcr[5].m_col = 1; + + m_prgmcr[6].m_chwFirst = 102; // f - h: mcCons + m_prgmcr[6].m_chwLast = 104; + m_prgmcr[6].m_col = 0; + + m_prgmcr[7].m_chwFirst = 105; // i: mcVi + m_prgmcr[7].m_chwLast = 105; + m_prgmcr[7].m_col = 2; + + m_prgmcr[8].m_chwFirst = 106; // j - n: mcCons + m_prgmcr[8].m_chwLast = 110; + m_prgmcr[8].m_col = 0; + + m_prgmcr[9].m_chwFirst = 111; // o: mcVou + m_prgmcr[9].m_chwLast = 111; + m_prgmcr[9].m_col = 3; + + m_prgmcr[10].m_chwFirst = 112; // p - t: mcCons + m_prgmcr[10].m_chwLast = 116; + m_prgmcr[10].m_col = 0; + + m_prgmcr[11].m_chwFirst = 117; // u: mcVou + m_prgmcr[11].m_chwLast = 117; + m_prgmcr[11].m_col = 3; + + m_prgmcr[12].m_chwFirst = 118; // v - z: mcCons + m_prgmcr[12].m_chwLast = 122; + m_prgmcr[12].m_col = 0; + + m_prgmcr[13].m_chwFirst = 126; // tilde: mcDct + m_prgmcr[13].m_chwLast = 126; + m_prgmcr[13].m_col = 6; + + m_dimcrInit = 8; // (max power of 2 <= m_cmcr); + m_cLoop = 3; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 11; + m_crowNonAcpt = 4; + m_crowFinal = 6; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 7; + + // Set up transition table. + m_prgrowTransitions = new short[35]; // 35 = (m_crow-m_crowFinal) * m_ccol + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 2; *psn++ = 4; *psn++ = 3; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5; *psn++ = 6; *psn++ = 6; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =10; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 8; *psn++ = 9; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[10]; // 10 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[7+1]; // 7 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s4: r3 + m_prgrulnMatched[0] = 3; + + m_prgirulnMin[1] = 1; // s5: r1, r2 + m_prgrulnMatched[1] = 1; + m_prgrulnMatched[2] = 2; + + m_prgirulnMin[2] = 3; // s6: r2 + m_prgrulnMatched[3] = 2; + + m_prgirulnMin[3] = 4; // s7: r1, r5 + m_prgrulnMatched[4] = 1; + m_prgrulnMatched[5] = 5; + + m_prgirulnMin[4] = 6; // s8: r4, r5 + m_prgrulnMatched[6] = 4; + m_prgrulnMatched[7] = 5; + + m_prgirulnMin[5] = 8; // s9: r5 + m_prgrulnMatched[8] = 5; + + m_prgirulnMin[6] = 9; // s10: r1 + m_prgrulnMatched[9] = 1; + + m_prgirulnMin[7] = 10; +} + + +/*---------------------------------------------------------------------------------------------- + The "rule" does something silly: just inserts *'s--the number equals the number of the + rule. +----------------------------------------------------------------------------------------------*/ +bool GrSubPass::RunSimpleFSMTest(GrTableManager * ptman, int ruln, GrSlotStream * psstrmInput, + GrSlotStream * psstrmOutput) +{ + int cslotMatched = (ruln == 3)? 2: 3; + + GrSlotState * pslot0 = psstrmInput->Peek(0); + + for (int islot = 0; islot < cslotMatched; islot++) + psstrmOutput->CopyOneSlotFrom(psstrmInput); + + for (islot = 0; islot < ruln; islot++) + { + GrSlotState * pslot; + ptman->NewSlot('*', pslot0, NULL, m_ipass, &pslot); + pslot->Associate(pslot0); + psstrmOutput->NextPut(pslot); + } + + return true; +} + + +/*---------------------------------------------------------------------------------------------- + A simple set of rules with actions. + + Rules: + r0. clsDigit gSlash clsDigit _ > @3 _ @1 gTilde; // tilde = 126 + r1. _ clsDigit gBackSlash clsDigit > gDollar @4 _ @2; // dollar sign = 36 + + Machine classes: + mcDigit: '0' - '9' 48 - 57 + mcSlash: '/' 47 + mcBSlash: '\' 92 + + + FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | clsDig mcSlash mcBSlash + ------------------------------------------------------ + T NA s0 | s1 + | - - - + T NA s1 | s2 s3 + | - - - + T NA s2 | s4 + | - - - + T NA s3 | s5 + | - - - + F A s4 | + | - - - + F A s5 | + | - - - + + Rules Matched: + s4: r0 + s5: r1 + +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpRuleActionTest() +{ + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpRuleActionTest(); +} + +void GrClassTable::SetUpRuleActionTest() +{ + m_ccls = 2; // number of classes + m_cclsLinear = 2; // number of classes in linear format + + m_prgchwBIGGlyphList = new data16[100]; + + m_prgichwOffsets = new data16[2+1]; + + gid16 * pchw = m_prgchwBIGGlyphList; + + // Output class 0: tilde + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(126)); // '~' + + // Output class 1: dollar + m_prgichwOffsets[1] = 1; + *pchw++ = msbf(data16(36)); // '$' + + m_prgichwOffsets[2] = 2; +} + +void GrSubPass::SetUpRuleActionTest() +{ + m_nMaxRuleContext = m_nMaxChunk = 3; + m_nMaxRuleLoop = 2; + m_staBehavior = "RuleAction"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpRuleActionTest(); + + m_crul = 2; + + // Set up constraint code--succeed trivially. + m_prgbConstraintBlock = new byte[3]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopPushByte; *pb++ = 1; // Push true + *pb++ = kopPopRet; // PopAndRet + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + m_prgibConstraintStart[1] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[30]; + pb = m_prgbActionBlock; + + // Rule 1: clsDigit gSlash clsDigit _ > @3 _ @1 gTilde; + + *pb++ = kopPutCopy; *pb++ = 2; // PutCopy 2 + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopPutCopy; *pb++ = -2; // PutCopy -2 + *pb++ = kopNext; // Next + *pb++ = kopInsert; // Insert + *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0 ('~' = 126) + *pb++ = kopNext; // Next + *pb++ = kopPushByte; *pb++ = 0; // Push 0 + *pb++ = kopPopRet; // PopAndRet + + // Rule 2: _ clsDigit gBackSlash clsDigit > gDollar @4 _ @2; + + *pb++ = kopInsert; // Insert + *pb++ = kopPutGlyph8bitObs; *pb++ = 1; // PutGlyph 1 ('$' = 36) + *pb++ = kopNext; // Next + *pb++ = kopPutCopy; *pb++ = 2; // PutCopy 2 + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopPutCopy; *pb++ = -2; // PutCopy -2 + *pb++ = kopNext; // Next + *pb++ = kopPushByte; *pb++ = 0; // Push 0 + *pb++ = kopPopRet; // PopAndRet + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 15; +} + +void GrFSM::SetUpRuleActionTest() +{ + // Create machine class ranges. + m_cmcr = 3; + m_prgmcr = new GrFSMClassRange[3]; + m_prgmcr[0].m_chwFirst = 47; // forward slash: mcSlash + m_prgmcr[0].m_chwLast = 47; + m_prgmcr[0].m_col = 1; + + m_prgmcr[1].m_chwFirst = 48; // 0 - 9: mcDigit + m_prgmcr[1].m_chwLast = 57; + m_prgmcr[1].m_col = 0; + + m_prgmcr[2].m_chwFirst = 92; // backslash + m_prgmcr[2].m_chwLast = 92; + m_prgmcr[2].m_col = 2; + + + m_dimcrInit = 2; // (max power of 2 <= m_cmcr); + m_cLoop = 1; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 6; + m_crowNonAcpt = 4; + m_crowFinal = 2; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 3; + + // Set up transition table. + m_prgrowTransitions = new short[12]; // 12 = (m_crow-m_crowFinal) * m_ccol + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 2; *psn++ = 3; + *psn++ = 4; *psn++ = 0; *psn++ = 0; + *psn++ = 5; *psn++ = 0; *psn++ = 0; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[2+1]; // 2 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s4: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; // s5: r1 + m_prgrulnMatched[1] = 1; + + m_prgirulnMin[2] = 2; +} + +/*---------------------------------------------------------------------------------------------- + A more complicated set of rules with actions. + + PASS 1: + r0. clsDigit > @1 {dir = DIR_RIGHT} / ^ _ {dir == DIR_LEFT}; + r1. clsSpecial > @2 {dir = DIR_ARABNUMBER} / clsDigit {dir != DIR_LEFT} ^ _; + r2. clsSpecial > @2 {dir = @1.dir} / clsSpecial ^ _; + + Pass 1 machine classes: + mcDigit: '0' - '9' 48 - 57 + mcSpecial: '-', '_', '=', '~' 45, 95, 61, 126 + + Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | mcDigit mcSpecial + ------------------------------------------ + T NA s0 | s2 s1 + | - _ + T NA s1 | s4 + | - - + T A s2 | s3 + | - - + F A s3 | + | - - + F A s4 | + | - - + + Rules Matched: + s2: r0 + s3: r1 + s4: r2 + + PASS 2: + r0. clsVowel gCaret > clsCirumVowel _; + r1. clsVowel gSlash > _ clsAcuteVowel$1; + + Pass 2 machine classes: + mcVowel + mcCaret: '^' 94 + mcSlash: '/' 47 + + + Pass 2 FSM: + | mcVowel mcCaret mcSlash + ----------------------------------------------------- + T NA s0 | s1 + | - _ + T NA s1 | s2 s3 + | - - + F A s2 | + | - - + F A s3 | + | - - + + Rules matched: + s2: r0 + s3: r1 + + + PASS 3: + r0. clsLeft > clsRight {dir = @1.dir} / _ clsDir {dir==DIR_RIGHT}; + r1. clsRight > clsLeft {dir = @1.dir} / clsDir {dir==DIR_RIGHT} _; + + Pass 3 machine classes: + mcDir: (clsDigit, clsSpecial) + mcLeft: '(', '[', '{' 40, 91, 123 + mcRight: ')', ']', '}' 41, 93, 125 + + Pass 3 FSM: + | mcDir mcLeft mcRight + ----------------------------------------------------- + T NA s0 | s2 s1 + | - _ + T NA s1 | s3 + | - - + T NA s2 | s4 + | - - + F A s3 | + | - - + F A s4 | + | - - + + Rules matched: + s3: r0 + s4: r1 + + +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpRuleAction2Test() +{ + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpRuleAction2Test(); +} + +void GrClassTable::SetUpRuleAction2Test() +{ + m_ccls = 7; // number of classes + m_cclsLinear = 4; // number of classes in linear format + + m_prgchwBIGGlyphList = new data16[70]; + + m_prgichwOffsets = new data16[7+1]; + + data16 * pchw = m_prgchwBIGGlyphList; + + // Output class 0: clsCirumVowel + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(226)); // a + *pchw++ = msbf(data16(234)); // e + *pchw++ = msbf(data16(238)); // i + *pchw++ = msbf(data16(244)); // o + *pchw++ = msbf(data16(251)); // u + *pchw++ = msbf(data16(194)); // A + *pchw++ = msbf(data16(202)); // E + *pchw++ = msbf(data16(206)); // I + *pchw++ = msbf(data16(212)); // O + *pchw++ = msbf(data16(219)); // U + + // Output class 1: clsAcuteVowel + m_prgichwOffsets[1] = 10; + *pchw++ = msbf(data16(225)); // a + *pchw++ = msbf(data16(233)); // e + *pchw++ = msbf(data16(237)); // i + *pchw++ = msbf(data16(243)); // o + *pchw++ = msbf(data16(250)); // u + *pchw++ = msbf(data16(193)); // A + *pchw++ = msbf(data16(201)); // E + *pchw++ = msbf(data16(205)); // I + *pchw++ = msbf(data16(211)); // O + *pchw++ = msbf(data16(218)); // U + + // Output class 2: clsLeft + m_prgichwOffsets[2] = 10 + 10; + *pchw++ = msbf(data16(40)); // ( + *pchw++ = msbf(data16(91)); // [ + *pchw++ = msbf(data16(123)); // { + + // Output class 3: clsRight + m_prgichwOffsets[3] = 20 + 3; + *pchw++ = msbf(data16(41)); // ) + *pchw++ = msbf(data16(93)); // ] + *pchw++ = msbf(data16(125)); // } + + // Input class 4: clsVowel + m_prgichwOffsets[4] = 23 + 3; // 26 + *pchw++ = msbf(data16(10)); + *pchw++ = msbf(data16(8)); *pchw++ = msbf(data16(3)); *pchw++ = msbf(data16(10-8)); + *pchw++ = msbf(data16(65)); *pchw++ = msbf(data16(5)); // A + *pchw++ = msbf(data16(69)); *pchw++ = msbf(data16(6)); // E + *pchw++ = msbf(data16(73)); *pchw++ = msbf(data16(7)); // I + *pchw++ = msbf(data16(79)); *pchw++ = msbf(data16(8)); // O + *pchw++ = msbf(data16(85)); *pchw++ = msbf(data16(9)); // U + *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(0)); // a + *pchw++ = msbf(data16(101)); *pchw++ = msbf(data16(1)); // e + *pchw++ = msbf(data16(105)); *pchw++ = msbf(data16(2)); // i + *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(3)); // o + *pchw++ = msbf(data16(117)); *pchw++ = msbf(data16(4)); // u + + // Input class 5: clsLeft + m_prgichwOffsets[5] = 26 + 4 + 10*2; // 50 + *pchw++ = msbf(data16(3)); + *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2)); + *pchw++ = msbf(data16(40)); *pchw++ = msbf(data16(0)); // ( + *pchw++ = msbf(data16(91)); *pchw++ = msbf(data16(1)); // [ + *pchw++ = msbf(data16(123)); *pchw++ = msbf(data16(2)); // { + + // Input class 6: clsRight + m_prgichwOffsets[6] = 50 + 4 + 3*2; // 60 + *pchw++ = msbf(data16(3)); + *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2)); + *pchw++ = msbf(data16(41)); *pchw++ = msbf(data16(0)); // ) + *pchw++ = msbf(data16(93)); *pchw++ = msbf(data16(1)); // ] + *pchw++ = msbf(data16(125)); *pchw++ = msbf(data16(2)); // } + + m_prgichwOffsets[7] = 60 + 4 + 3*2; // 70 +} + +void GrSubPass::SetUpRuleAction2Test() +{ + if (m_ipass == 1) + { + m_nMaxRuleContext = m_nMaxChunk = 2; + m_nMaxRuleLoop = 5; + m_staBehavior = "RuleAction2"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpRuleAction2Test(m_ipass); + + m_crul = 3; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1 + 10 + 10]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0 + *pb++ = kopPushSlotAttr; *pb++= kslatDir; // PushSlotAttr dir 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = kdircL; // Push DIR_LEFT + *pb++ = kopEqual; // Equal + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0 + *pb++ = kopPushSlotAttr; *pb++= kslatDir; // PushSlotAttr dir 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = kdircL; // Push DIR_LEFT + *pb++ = kopNotEq; // NotEqual + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 1; + m_prgibConstraintStart[1] = 11; + m_prgibConstraintStart[2] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[10 + 11 + 12]; + pb = m_prgbActionBlock; + + // Rule 0: clsDigit > @1 {dir = DIR_RIGHT} / ^ _ {dir == DIR_LEFT}; + + *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0 + *pb++ = kopPushByte; *pb++ = kdircR; // PushByte DIR_RIGHT + *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir + *pb++ = kopNext; // Next + *pb++ = kopPushByte; *pb++ = -1; // Push -1 + *pb++ = kopPopRet; // PopAndRet + + // Rule 1: clsSpecial > @2 {dir = DIR_ARABNUMBER} / clsDigit {dir != DIR_LEFT} ^ _; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0 + *pb++ = kopPushByte; *pb++ = kdircArabNum; // Push DIR_ARABNUMBER + *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir + *pb++ = kopNext; // Next + *pb++ = kopPushByte; *pb++ = -1; // Push -1 + *pb++ = kopPopRet; // PopAndRet + + // Rule 2: clsSpecial > @2 {dir = @1.dir} / clsSpecial ^ _; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0 + *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir -1 + *pb++ = -1; + *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir + *pb++ = kopNext; // Next + *pb++ = kopPushByte; *pb++ = -1; // Push -1 + *pb++ = kopPopRet; // PopAndRet + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 10; + m_prgibActionStart[2] = 10 + 11; + } + else if (m_ipass == 2) + { + m_nMaxRuleContext = m_nMaxChunk = 2; + m_nMaxRuleLoop = 3; + m_staBehavior = "RuleAction2"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpRuleAction2Test(m_ipass); + + m_crul = 2; + + // Set up constraint code--succeed trivially. + m_prgbConstraintBlock = new byte[1]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + m_prgibConstraintStart[1] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[16]; + pb = m_prgbActionBlock; + + // Rule 0: clsVowel gCaret > clsCirumVowel _; + + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsVowel clsCircumVowel + *pb++ = 4; *pb++ = 0; + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: clsVowel gSlash > _ clsAcuteVowel$1; + + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopPutSubs8bitObs; *pb++ = -1; // PutSubs -1 clsVowel clsAcuteVowel + *pb++ = 4; *pb++ = 1; + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 8; + } + else if (m_ipass == 3) + { + m_nMaxRuleContext = m_nMaxChunk = 2; + m_nMaxRuleLoop = 3; + m_staBehavior = "RuleAction2"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpRuleAction2Test(m_ipass); + + m_crul = 2; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1 + 10 + 10]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + *pb++ = kopCntxtItem; *pb++ = 1; // ContextItem 1 + *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = kdircR; // Push DIR_RIGHT + *pb++ = kopEqual; // Equal + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0 + *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = kdircR; // Push DIR_RIGHT + *pb++ = kopEqual; // Equal + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 1; + m_prgibConstraintStart[1] = 1 + 10; + + // Set up rule action code. + m_prgbActionBlock = new byte[23]; + pb = m_prgbActionBlock; + + // Rule 0: clsLeft > clsRight {dir = @1.dir} / _ clsDir {dir == DIR_RIGHT}; + + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsLeft clsRight + *pb++ = 5; *pb++ = 3; + *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir 1 + *pb++ = 1; + *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: clsRight > clsLeft {dir = @1.dir} / clsDir {dir == DIR_RIGHT} _; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsRight clsLeft + *pb++ = 6; *pb++ = 2; + *pb++ = kopPushSlotAttr;*pb++ = kslatDir; // PushSlotAttr dir -1 + *pb++ = -1; + *pb++ = kopAttrSet; *pb++ = kslatDir; // AttrSet dir + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 11; + } +} + + +void GrFSM::SetUpRuleAction2Test(int ipass) +{ + if (ipass == 1) + { + // Create machine class ranges. + m_cmcr = 5; + m_prgmcr = new GrFSMClassRange[5]; + m_prgmcr[0].m_chwFirst = 45; // hyphen + m_prgmcr[0].m_chwLast = 45; + m_prgmcr[0].m_col = 1; + + m_prgmcr[1].m_chwFirst = 48; // 0 - 9: mcDigit + m_prgmcr[1].m_chwLast = 57; + m_prgmcr[1].m_col = 0; + + m_prgmcr[2].m_chwFirst = 61; // equals sign + m_prgmcr[2].m_chwLast = 61; + m_prgmcr[2].m_col = 1; + + m_prgmcr[3].m_chwFirst = 95; // underscore + m_prgmcr[3].m_chwLast = 95; + m_prgmcr[3].m_col = 1; + + m_prgmcr[4].m_chwFirst = 126; // tilde + m_prgmcr[4].m_chwLast = 126; + m_prgmcr[4].m_col = 1; + + m_dimcrInit = 4; // (max power of 2 <= m_cmcr); + m_cLoop = 2; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 5; + m_crowNonAcpt = 2; + m_crowFinal = 2; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 2; + + // Set up transition table. + m_prgrowTransitions = new short[6]; // 6 = (m_crow-m_crowFinal) * m_ccol + short * psn = m_prgrowTransitions; + *psn++ = 2; *psn++ = 1; + *psn++ = 0; *psn++ = 4; + *psn++ = 0; *psn++ = 3; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s2: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; // s3: r1 + m_prgrulnMatched[1] = 1; + + m_prgirulnMin[2] = 2; // s3: r2 + m_prgrulnMatched[2] = 2; + + m_prgirulnMin[3] = 3; + } + else if (ipass == 2) + { + // Create machine class ranges. + m_cmcr = 12; + m_prgmcr = new GrFSMClassRange[12]; + m_prgmcr[0].m_chwFirst = 47; // slash + m_prgmcr[0].m_chwLast = 47; + m_prgmcr[0].m_col = 2; + + m_prgmcr[1].m_chwFirst = 65; // A + m_prgmcr[1].m_chwLast = 65; + m_prgmcr[1].m_col = 0; + + m_prgmcr[2].m_chwFirst = 69; // E + m_prgmcr[2].m_chwLast = 69; + m_prgmcr[2].m_col = 0; + + m_prgmcr[3].m_chwFirst = 73; // I + m_prgmcr[3].m_chwLast = 73; + m_prgmcr[3].m_col = 0; + + m_prgmcr[4].m_chwFirst = 79; // O + m_prgmcr[4].m_chwLast = 79; + m_prgmcr[4].m_col = 0; + + m_prgmcr[5].m_chwFirst = 85; // U + m_prgmcr[5].m_chwLast = 85; + m_prgmcr[5].m_col = 0; + + m_prgmcr[6].m_chwFirst = 94; // caret + m_prgmcr[6].m_chwLast = 94; + m_prgmcr[6].m_col = 1; + + m_prgmcr[7].m_chwFirst = 97; // a + m_prgmcr[7].m_chwLast = 97; + m_prgmcr[7].m_col = 0; + + m_prgmcr[8].m_chwFirst = 101; // e + m_prgmcr[8].m_chwLast = 101; + m_prgmcr[8].m_col = 0; + + m_prgmcr[9].m_chwFirst = 105; // i + m_prgmcr[9].m_chwLast = 105; + m_prgmcr[9].m_col = 0; + + m_prgmcr[10].m_chwFirst = 111; // o + m_prgmcr[10].m_chwLast = 111; + m_prgmcr[10].m_col = 0; + + m_prgmcr[11].m_chwFirst = 117; // u + m_prgmcr[11].m_chwLast = 117; + m_prgmcr[11].m_col = 0; + + m_dimcrInit = 8; // (max power of 2 <= m_cmcr); + m_cLoop = 3; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 4; + m_crowNonAcpt = 2; + m_crowFinal = 2; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 3; + + // Set up transition table. + m_prgrowTransitions = new short[6]; // 6 = (m_crow-m_crowFinal) * m_ccol + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 2; *psn++ = 3; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[2+1]; // 2 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s1: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; // s2: r1 + m_prgrulnMatched[1] = 1; + + m_prgirulnMin[2] = 2; + } + else if (ipass == 3) + { + // Create machine class ranges. + m_cmcr = 11; + m_prgmcr = new GrFSMClassRange[11]; + m_prgmcr[0].m_chwFirst = 40; // ( + m_prgmcr[0].m_chwLast = 40; + m_prgmcr[0].m_col = 1; + + m_prgmcr[1].m_chwFirst = 41; // ) + m_prgmcr[1].m_chwLast = 41; + m_prgmcr[1].m_col = 2; + + m_prgmcr[2].m_chwFirst = 45; // hyphen + m_prgmcr[2].m_chwLast = 45; + m_prgmcr[2].m_col = 0; + + m_prgmcr[3].m_chwFirst = 48; // 0 - 9: mcDigit + m_prgmcr[3].m_chwLast = 57; + m_prgmcr[3].m_col = 0; + + m_prgmcr[4].m_chwFirst = 61; // = + m_prgmcr[4].m_chwLast = 61; + m_prgmcr[4].m_col = 0; + + m_prgmcr[5].m_chwFirst = 91; // [ + m_prgmcr[5].m_chwLast = 91; + m_prgmcr[5].m_col = 1; + + m_prgmcr[6].m_chwFirst = 93; // ] + m_prgmcr[6].m_chwLast = 93; + m_prgmcr[6].m_col = 2; + + m_prgmcr[7].m_chwFirst = 95; // underscore + m_prgmcr[7].m_chwLast = 95; + m_prgmcr[7].m_col = 0; + + m_prgmcr[8].m_chwFirst = 123; // { + m_prgmcr[8].m_chwLast = 123; + m_prgmcr[8].m_col = 1; + + m_prgmcr[9].m_chwFirst = 125; // } + m_prgmcr[9].m_chwLast = 125; + m_prgmcr[9].m_col = 2; + + m_prgmcr[10].m_chwFirst = 126; // tilde + m_prgmcr[10].m_chwLast = 126; + m_prgmcr[10].m_col = 0; + + m_dimcrInit = 8; // (max power of 2 <= m_cmcr); + m_cLoop = 3; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 5; + m_crowNonAcpt = 3; + m_crowFinal = 2; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 3; + + // Set up transition table. + m_prgrowTransitions = new short[9]; // 9 = (m_crow-m_crowFinal) * m_ccol + short * psn = m_prgrowTransitions; + *psn++ = 2; *psn++ = 1; *psn++ = 0; + *psn++ = 3; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 4; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[2+1]; // 2 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s3: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; // s4: r1 + m_prgrulnMatched[1] = 1; + + m_prgirulnMin[2] = 2; + } +} + + +/*---------------------------------------------------------------------------------------------- + Tests of various kinds of assocations. + + PASS 1 (line-break): + r0. gX / # _ ^ ; // do nothing + r1. gX {break = -2}; + + Pass 1 machine classes: + mcX: 'x' 120 + mcLB: 35 + + Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | gX gLB + -------------------------------- + T NA s0 | s2 s1 + | + T NA s1 | s3 + | + F A s2 | + | + F A s3 | + + + Rules Matched: + s2: r1 + s3: r0 + + + + PASS 2: + r0. clsOA clsE > clsELig:(1 2) _; + r1. clsLC _ _ gX > @1 @5 @1 @5 / _ _ # {break==2} _ _ ; + r2. _ clsFraction _ > clsNumerator:2 gSlash:2 clsDenom:2; + + Pass 2 machine classes: + mcOA: O A 79 65 + mcOAlc: o a 111 97 + mcE E e 69 101 + mcFraction: 188 189 190 + mcX: x 120 + mcLCother + mcLB: 35 + + + Pass 2 FSM: mcLC + | mcOA mcOAlc mcE mcElc other mcX mcFractn mcLB + ----------------------------------------------------------------------------------------- + T NA s0 | s1 s2 s4 s3 s3 s6 + | - - - - - - - + T NA s1 | s7 + | - - - - - - - + T NA s2 | s7 s5 + | - - - - - - - + T NA s3 | s5 + | - - - - - - - + T NA s4 | s5 + | - - - - - - - + T NA s5 | s8 + | - - - - - - - + F A s6 | + | - - - - - - + F A s7 | + | - - - - - - + F A s8 | + | - - - - - - + + Rules matched: + s6: r2 + s7: r0 + s8: r1 + + + PASS 3: + r0. _ > gHyphen / _ # {break == 2} ^; + + Pass 3 machine classes: + mcLB: 35 + + Pass 3 FSM: + + | gLB + -------------------------------- + T NA s0 | s1 + | + F A s1 | + | + + Rules Matched: + s1: r0 +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpAssocTest() +{ + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpAssocTest(); + + m_fLineBreak = true; + m_cchwPreXlbContext = 1; + m_cchwPostXlbContext = 1; +} + +void GrClassTable::SetUpAssocTest() +{ + m_ccls = 11; // number of classes + m_cclsLinear = 5; // number of classes in linear format (output classes) + + m_prgchwBIGGlyphList = new data16[143]; + + m_prgichwOffsets = new data16[m_ccls+1]; + + data16 * pchw = m_prgchwBIGGlyphList; + + // Output class 0: clsELig + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(140)); // OE + *pchw++ = msbf(data16(198)); // AE + *pchw++ = msbf(data16(156)); // oe + *pchw++ = msbf(data16(230)); // ae + + // Output class 1: clsNumerator + m_prgichwOffsets[1] = 4; + *pchw++ = msbf(data16(49)); // 1 + *pchw++ = msbf(data16(49)); // 1 + *pchw++ = msbf(data16(51)); // 3 + + // Output class 2: clsDenom + m_prgichwOffsets[2] = 4 + 3; + *pchw++ = msbf(data16(52)); // 4 + *pchw++ = msbf(data16(50)); // 2 + *pchw++ = msbf(data16(52)); // 4 + + // Output class 3: gSlash + m_prgichwOffsets[3] = 7 + 3; + *pchw++ = msbf(data16(47)); // '/' + + // Output class 4: gHyphen + m_prgichwOffsets[4] = 10 + 1; + *pchw++ = msbf(data16(45)); // '-' + + // Input class 5: clsOA + m_prgichwOffsets[5] = 11 + 1; + *pchw++ = msbf(data16(4)); + *pchw++ = msbf(data16(4)); *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(0)); + *pchw++ = msbf(data16(65)); *pchw++ = msbf(data16(1)); // A + *pchw++ = msbf(data16(79)); *pchw++ = msbf(data16(0)); // O + *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(3)); // a + *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(2)); // o + + // Input class 6: clsE + m_prgichwOffsets[6] = 12 + 4 + 4*2; // 24 + *pchw++ = msbf(data16(3)); + *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2)); + *pchw++ = msbf(data16(40)); *pchw++ = msbf(data16(0)); // E + *pchw++ = msbf(data16(91)); *pchw++ = msbf(data16(1)); // e + + // Input class 7: clsLC + m_prgichwOffsets[7] = 24 + 4 + 2*2; // 32 + *pchw++ = msbf(data16(26)); + *pchw++ = msbf(data16(16)); *pchw++ = msbf(data16(4)); *pchw++ = msbf(data16(26-16)); + for (int i = 0; i < 26; ++i) + { + *pchw++ = msbf(data16(97+i)); *pchw++ = msbf(data16(i)); + } + + // Input class 8: gX + m_prgichwOffsets[8] = 32 + 4 + 26*2; // 88 + *pchw++ = msbf(data16(1)); + *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(0)); *pchw++ = msbf(data16(0)); + *pchw++ = msbf(data16(120)); *pchw++ = msbf(data16(0)); + + // Input class 9: clsFraction + m_prgichwOffsets[9] = 88 + 4 + 1*2; // 127 + *pchw++ = msbf(data16(3)); + *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2)); + *pchw++ = msbf(data16(188)); *pchw++ = msbf(data16(0)); // 1/4 + *pchw++ = msbf(data16(189)); *pchw++ = msbf(data16(1)); // 1/2 + *pchw++ = msbf(data16(190)); *pchw++ = msbf(data16(2)); // 3/4 + + // Input class 10: # + m_prgichwOffsets[10] = 127 + 4 + 3*2; // 137 + *pchw++ = msbf(data16(1)); + *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(0)); *pchw++ = msbf(data16(0)); + *pchw++ = msbf(data16(35)); *pchw++ = msbf(data16(0)); // 1/4 + + m_prgichwOffsets[11] = 137 + 4 + 1*2; // 143 +} + +void GrLineBreakPass::SetUpAssocTest() +{ + m_nMaxRuleContext = m_nMaxChunk = 1; + m_nMaxRuleLoop = 5; + m_staBehavior = "Assoc"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpAssocTest(m_ipass); + + m_crul = 2; + + // Set up constraint code--succeed trivially. + m_prgbConstraintBlock = new byte[1]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + m_prgibConstraintStart[1] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[7 + 8]; + pb = m_prgbActionBlock; + + // Rule 0: gX / # _ ^ ; // do nothing + + *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0 + *pb++ = kopNext; // Next + *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: gX {break = -2}; + + *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0 + *pb++ = kopPushByte; *pb++ = -2; // PushByte -2 + *pb++ = kopAttrSet; *pb++ = kslatBreak; // AttrSet breakweight + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 7; +} + +void GrSubPass::SetUpAssocTest() +{ + if (m_ipass == 2) + { + m_nMaxRuleContext = m_nMaxChunk = 3; + m_nMaxRuleLoop = 5; + m_staBehavior = "Assoc"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpAssocTest(m_ipass); + + m_crul = 3; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1 + 10]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + *pb++ = kopCntxtItem; *pb++ = 1; // ContextItem 1 + *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = 2; // Push 2 + *pb++ = kopEqual; // Equal + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + m_prgibConstraintStart[1] = 1; + m_prgibConstraintStart[2] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[12 + 12 + 22]; + pb = m_prgbActionBlock; + + // Rule 0: clsOA clsE > clsELig:(1 2) _ ; + + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsOA clsELig + *pb++ = 5; *pb++ = 0; + *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1 + *pb++ = 0; *pb++ = 1; + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: clsLC _ _ gX > @1 @5 @1 @5 / _ _ # {break==2} _ _ ; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutCopy; *pb++ = 2; // PutCopy 2 + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext - line break + *pb++ = kopInsert; // Insert + *pb++ = kopPutCopy; *pb++ = -1; // PutCopy -1 + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopRetZero; // RetZero + + // Rule 2: _ clsFraction _ > clsNumerator:2 gSlash:2 clsDenom:2; + + *pb++ = kopInsert; // Insert + *pb++ = kopPutSubs8bitObs; *pb++ = 1; // PutSubs 1 clsFraction clsNumerator + *pb++ = 9; *pb++ = 1; + *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 1 + *pb++ = 1; + *pb++ = kopNext; // Next + *pb++ = kopPutGlyph8bitObs; *pb++ = 3; // PutGlyph gSlash + *pb++ = kopNext; // Next + *pb++ = kopInsert; // Insert + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 clsFraction clsDenom + *pb++ = 9; *pb++ = 2; + *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 0 + *pb++ = 0; + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 12; + m_prgibActionStart[2] = 12 + 12; + } + else if (m_ipass == 3) + { + m_nMaxRuleContext = m_nMaxChunk = 1; + m_nMaxRuleLoop = 3; + m_staBehavior = "Assoc"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpAssocTest(m_ipass); + + m_crul = 1; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1 + 10]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + *pb++ = kopCntxtItem; *pb++ = 0; // ContextItem 0 + *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = 2; // Push 2 + *pb++ = kopEqual; // Equal + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 1; + + m_prgbActionBlock = new byte[7]; + pb = m_prgbActionBlock; + + // Rule 0: _ > gHyphen / _ # {break == 2} ^; + + *pb++ = kopInsert; // Insert + *pb++ = kopPutGlyph8bitObs; *pb++ = 4; // PutGlyph 4 ('-' = 45) + *pb++ = kopNext; // Next + *pb++ = kopPushByte; *pb++ = 1; // Push 1 + *pb++ = kopPopRet; // PopAndRet + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + } + else + Assert(false); +} + + +void GrFSM::SetUpAssocTest(int ipass) +{ + if (ipass == 1) + { + // Create machine class ranges. + m_cmcr = 2; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 35; // # + m_prgmcr[0].m_chwLast = 35; + m_prgmcr[0].m_col = 1; + + m_prgmcr[1].m_chwFirst = 120; // x + m_prgmcr[1].m_chwLast = 120; + m_prgmcr[1].m_col = 0; + + m_dimcrInit = 2; // (max power of 2 <= m_cmcr); + m_cLoop = 1; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 4; + m_crowNonAcpt = 2; + m_crowFinal = 2; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 2; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 4 + short * psn = m_prgrowTransitions; + *psn++ = 2; *psn++ = 1; + *psn++ = 3; *psn++ = 0; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1]; + + m_prgirulnMin[0] = 0; // s2: r1 + m_prgrulnMatched[0] = 1; + + m_prgirulnMin[1] = 1; // s3: r0 + m_prgrulnMatched[1] = 0; + + m_prgirulnMin[2] = 2; + } + else if (ipass == 2) + { + // Create machine class ranges. + m_cmcr = 13; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 35; // # + m_prgmcr[0].m_chwLast = 35; + m_prgmcr[0].m_col = 7; + + m_prgmcr[1].m_chwFirst = 65; // A + m_prgmcr[1].m_chwLast = 65; + m_prgmcr[1].m_col = 0; + + m_prgmcr[2].m_chwFirst = 69; // E + m_prgmcr[2].m_chwLast = 69; + m_prgmcr[2].m_col = 2; + + m_prgmcr[3].m_chwFirst = 79; // O + m_prgmcr[3].m_chwLast = 79; + m_prgmcr[3].m_col = 0; + + m_prgmcr[4].m_chwFirst = 97; // a + m_prgmcr[4].m_chwLast = 97; + m_prgmcr[4].m_col = 1; + + m_prgmcr[5].m_chwFirst = 98; // b - d + m_prgmcr[5].m_chwLast = 100; + m_prgmcr[5].m_col = 4; + + m_prgmcr[6].m_chwFirst = 101; // e + m_prgmcr[6].m_chwLast = 101; + m_prgmcr[6].m_col = 3; + + m_prgmcr[7].m_chwFirst = 102; // f - n + m_prgmcr[7].m_chwLast = 110; + m_prgmcr[7].m_col = 4; + + m_prgmcr[8].m_chwFirst = 111; // o + m_prgmcr[8].m_chwLast = 111; + m_prgmcr[8].m_col = 1; + + m_prgmcr[9].m_chwFirst = 112; // p - w + m_prgmcr[9].m_chwLast = 119; + m_prgmcr[9].m_col = 4; + + m_prgmcr[10].m_chwFirst = 120; // x + m_prgmcr[10].m_chwLast = 120; + m_prgmcr[10].m_col = 5; + + m_prgmcr[11].m_chwFirst = 121; // y - z + m_prgmcr[11].m_chwLast = 122; + m_prgmcr[11].m_col = 4; + + m_prgmcr[12].m_chwFirst = 188; // 1/4, 1/2, 3/4 + m_prgmcr[12].m_chwLast = 190; + m_prgmcr[12].m_col = 6; + + + m_dimcrInit = 8; // (max power of 2 <= m_cmcr); + m_cLoop = 3; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 9; + m_crowNonAcpt = 6; + m_crowFinal = 3; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 8; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 48 + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 2; *psn++ = 0; *psn++ = 4; *psn++ = 3; *psn++ = 3; *psn++ = 6; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 5; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 8; *psn++ = 0; *psn++ = 0; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s6: r2 + m_prgrulnMatched[0] = 2; + + m_prgirulnMin[1] = 1; // s7: r0 + m_prgrulnMatched[1] = 0; + + m_prgirulnMin[2] = 2; // s8: r1 + m_prgrulnMatched[2] = 1; + + m_prgirulnMin[3] = 3; + } + else if (ipass == 3) + { + // Create machine class ranges. + m_cmcr = 1; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 35; // # + m_prgmcr[0].m_chwLast = 35; + m_prgmcr[0].m_col = 0; + + m_dimcrInit = 1; // (max power of 2 <= m_cmcr); + m_cLoop = 0; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 2; + m_crowNonAcpt = 1; + m_crowFinal = 1; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 1; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 1 + short * psn = m_prgrowTransitions; + *psn++ = 1; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[1]; // 1 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1]; + + m_prgirulnMin[0] = 0; // s1: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; + } +} + + +/*---------------------------------------------------------------------------------------------- + Second batch of association tests. + + PASS 1: + r0. clsSymbol _ > _ @1 / _ gNumber gHyphen # gNumber _; + r1. clsSymbol _ > _ @1 / _ gHyphen # _; + r2. _ clsSymbol > @6 _ / _ gNumber gHyphen # gNumber _; + r3. _ clsSymbol > @4 _ / _ gHyphen # _; + r4. clsLeft _ > @1 clsRight$1:1 / _ clsLetter gHyphen # _ gSpace; + r5. clsLeft _ > @1 clsRight$1:1 / _ clsLetter gHyphen # clsLetter _ gSpace; + r6. clsLeft _ > @1 clsRight$1:1 / _ clsLetter _ gSpace; + r7. clsLeft _ > @1 clsRight$1:1 / _ clsLetter clsLetter _ gSpace; + + Pass 1 machine classes: + mcSym: @, $, %, & 64, 36, 37, 38 + mcNum: 48-57 + mcHyphen: 45 + mcSpace: 32 + mcLet: 97-122 + mcLeft: ( [ { 40, 91, 123 + mcRight: ) ] } 41, 93, 125 + + Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | mcSym mcNum mcHyph mcSpace mcLet mcLeft mcLB + ---------------------------------------------------------------------------------- + T NA s0 | s1 s2 s3 s4 + | + T NA s1 | s5 s6 + | + T NA s2 | s7 + | + T NA s3 | s8 + | + T NA s4 | s9 + | + T NA s5 | s10 + | + T NA s6 | s18 + | + T NA s7 | s11 + | + T NA s8 | s19 + | + T NA s9 | s12 s20 s13 + | + T NA s10 | s14 + | + T NA s11 | s15 + | + T NA s12 | s16 + | + T NA s13 | s21 + | + T NA s14 | s22 + | + T NA s15 | s23 + | + T NA s16 | s24 s17 + | + T NA s17 | s25 + | + F A s18 | + | + F A s19 | + | + F A s20 | + | + F A s21 | + | + F A s22 | + | + F A s23 | + | + F A s24 | + | + F A s25 | + + + Rules Matched: + s18: r1 + s19: r3 + s20: r6 + s21: r7 + s22: r0 + s23: r2 + s24: r4 + s25: r5 +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpAssoc2Test() +{ + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpAssoc2Test(); + + m_fLineBreak = true; + m_cchwPreXlbContext = 3; + m_cchwPostXlbContext = 2; +} + +void GrClassTable::SetUpAssoc2Test() +{ + m_ccls = 2; // number of classes + m_cclsLinear = 1; // number of classes in linear format (output classes) + + m_prgchwBIGGlyphList = new data16[13]; + + m_prgichwOffsets = new data16[m_ccls+1]; + + data16 * pchw = m_prgchwBIGGlyphList; + + // Output class 0: clsRight + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(41)); // ) + *pchw++ = msbf(data16(93)); // ] + *pchw++ = msbf(data16(125)); // } + + // Input class 1: clsLeft + m_prgichwOffsets[1] = 3; + *pchw++ = msbf(data16(3)); + *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(1)); *pchw++ = msbf(data16(3-2)); + *pchw++ = msbf(data16(40)); *pchw++ = msbf(data16(0)); // ( + *pchw++ = msbf(data16(91)); *pchw++ = msbf(data16(1)); // [ + *pchw++ = msbf(data16(123)); *pchw++ = msbf(data16(2)); // { + + m_prgichwOffsets[2] = 3 + 4 + 3*2; // 13 +} + +void GrSubPass::SetUpAssoc2Test() +{ + m_nMaxRuleContext = m_nMaxChunk = 6; + m_nMaxRuleLoop = 5; + m_staBehavior = "Assoc2"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpAssoc2Test(m_ipass); + + m_crul = 8; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + m_prgibConstraintStart[1] = 0; + m_prgibConstraintStart[2] = 0; + m_prgibConstraintStart[3] = 0; + m_prgibConstraintStart[4] = 0; + m_prgibConstraintStart[5] = 0; + m_prgibConstraintStart[6] = 0; + m_prgibConstraintStart[7] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[11 + 9 + 11 + 9 + 14 + 15 + 12 + 13]; + pb = m_prgbActionBlock; + + // Rule 0: clsSymbol _ > _ @1 / _ gNumber gHyphen # gNumber _; + + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutCopy; *pb++ = -4; // PutCopy -4 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: clsSymbol _ > _ @1 / _ gHyphen # _; + + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutCopy; *pb++ = -2; // PutCopy -2 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 2: _ clsSymbol > @6 _ / _ gNumber gHyphen # gNumber _; + + *pb++ = kopInsert; // Insert + *pb++ = kopPutCopy; *pb++ = 5; // PutCopy 5 + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 3: _ clsSymbol > @4 _ / _ gHyphen # _; + + *pb++ = kopInsert; // Insert + *pb++ = kopPutCopy; *pb++ = 3; // PutCopy 3 + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 4: clsLeft _ > @1 clsRight$1 / _ clsLetter gHyphen # _ gSpace; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutSubs8bitObs; *pb++ = -3; // PutSubs -3 1 0 + *pb++ = 1; *pb++ = 0; + *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -3 + *pb++ = -3; + *pb++ = kopNext; // Next; + *pb++ = kopRetZero; // RetZero + + // Rule 5: clsLeft _ > @1 clsRight$1 / _ clsLetter gHyphen # clsLetter _ gSpace; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutSubs8bitObs; *pb++ = -4; // PutSubs -4 1 0 + *pb++ = 1; *pb++ = 0; + *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -4 + *pb++ = -4; + *pb++ = kopNext; // Next; + *pb++ = kopRetZero; // RetZero + + // Rule 6: clsLeft _ > @1 clsRight$1 / _ clsLetter _ gSpace; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutSubs8bitObs; *pb++ = -1; // PutSubs -1 1 0 + *pb++ = 1; *pb++ = 0; + *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -1 + *pb++ = -1; + *pb++ = kopNext; // Next; + *pb++ = kopRetZero; // RetZero + + // Rule 7: clsLeft _ > @1 clsRight$1 / _ clsLetter clsLetter _ gSpace; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutSubs8bitObs; *pb++ = -2; // PutSubs -2 1 0 + *pb++ = 1; *pb++ = 0; + *pb++ = kopAssoc; *pb++ = 1; // Assoc 1 -2 + *pb++ = -2; + *pb++ = kopNext; // Next; + *pb++ = kopRetZero; // RetZero + + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 11; + m_prgibActionStart[2] = 11 + 9; + m_prgibActionStart[3] = 20 + 11; + m_prgibActionStart[4] = 31 + 9; + m_prgibActionStart[5] = 40 + 14; + m_prgibActionStart[6] = 54 + 15; + m_prgibActionStart[7] = 69 + 12; +} + + +void GrFSM::SetUpAssoc2Test(int ipass) +{ + // Create machine class ranges. + m_cmcr = 10; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 32; // space + m_prgmcr[0].m_chwLast = 32; + m_prgmcr[0].m_col = 3; + + m_prgmcr[1].m_chwFirst = 35; // # + m_prgmcr[1].m_chwLast = 35; + m_prgmcr[1].m_col = 6; + + m_prgmcr[2].m_chwFirst = 36; // $, %, & + m_prgmcr[2].m_chwLast = 38; + m_prgmcr[2].m_col = 0; + + m_prgmcr[3].m_chwFirst = 40; // ( + m_prgmcr[3].m_chwLast = 40; + m_prgmcr[3].m_col = 5; + + m_prgmcr[4].m_chwFirst = 45; // - + m_prgmcr[4].m_chwLast = 45; + m_prgmcr[4].m_col = 2; + + m_prgmcr[5].m_chwFirst = 48; // 0 - 9 + m_prgmcr[5].m_chwLast = 57; + m_prgmcr[5].m_col = 1; + + m_prgmcr[6].m_chwFirst = 64; // @ + m_prgmcr[6].m_chwLast = 64; + m_prgmcr[6].m_col = 0; + + m_prgmcr[7].m_chwFirst = 91; // [ + m_prgmcr[7].m_chwLast = 91; + m_prgmcr[7].m_col = 5; + + m_prgmcr[8].m_chwFirst = 97; // a - z + m_prgmcr[8].m_chwLast = 122; + m_prgmcr[8].m_col = 4; + + m_prgmcr[9].m_chwFirst = 123; // { + m_prgmcr[9].m_chwLast = 123; + m_prgmcr[9].m_col = 5; + + + m_dimcrInit = 8; // (max power of 2 <= m_cmcr); + m_cLoop = 3; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 26; + m_crowNonAcpt = 18; + m_crowFinal = 8; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 7; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 126 + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 2; *psn++ = 3; *psn++ = 0; *psn++ = 0; *psn++ = 4; *psn++ = 0; + *psn++ = 0; *psn++ = 5; *psn++ = 6; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 8; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 9; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ =10; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =18; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =11; + *psn++ =19; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ =12; *psn++ =20; *psn++ =13; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =14; + *psn++ = 0; *psn++ =15; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =16; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =21; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ =22; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ =23; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =24; *psn++ =17; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ =25; *psn++ = 0; *psn++ = 0; *psn++ = 0; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[8]; // 3 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1]; + + m_prgirulnMin[0] = 0; // s18: r1 + m_prgrulnMatched[0] = 1; + + m_prgirulnMin[1] = 1; // s19: r3 + m_prgrulnMatched[1] = 3; + + m_prgirulnMin[2] = 2; // s20: r6 + m_prgrulnMatched[2] = 6; + + m_prgirulnMin[3] = 3; // s21: r7 + m_prgrulnMatched[3] = 7; + + m_prgirulnMin[4] = 4; // s22: r0 + m_prgrulnMatched[4] = 0; + + m_prgirulnMin[5] = 5; // s23: r2 + m_prgrulnMatched[5] = 2; + + m_prgirulnMin[6] = 6; // s24: r4 + m_prgrulnMatched[6] = 4; + + m_prgirulnMin[7] = 7; // s25: r5 + m_prgrulnMatched[7] = 5; + + m_prgirulnMin[8] = 8; +} + +/*---------------------------------------------------------------------------------------------- + Test of default associations + + PASS 1: + r0. gDollar _ > @1 gEquals; + r1. gAtSign > _ ; + + Pass 1 machine classes: + mcDollar: $ 36 + mcAt: @ 64 + + Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | mcDollar mcAt + -------------------------------------- + T NA s0 | s1 s2 + | + F A s1 | + | + F A s2 | + + + Rules Matched: + s1: r0 + s2: r1 +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpDefaultAssocTest() +{ + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpDefaultAssocTest(); +} + +void GrClassTable::SetUpDefaultAssocTest() +{ + m_ccls = 1; // number of classes + m_cclsLinear = 1; // number of classes in linear format + + m_prgchwBIGGlyphList = new data16[1]; + + m_prgichwOffsets = new data16[m_ccls+1]; + + data16 * pchw = m_prgchwBIGGlyphList; + + // Output class 0: gEquals + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(61)); + + m_prgichwOffsets[1] = 1; +} + +void GrSubPass::SetUpDefaultAssocTest() +{ + m_nMaxRuleContext = m_nMaxChunk = 1; + m_nMaxRuleLoop = 5; + m_staBehavior = "DefaultAssoc"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpDefaultAssocTest(); + + m_crul = 2; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + m_prgibConstraintStart[1] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[6 + 3]; + pb = m_prgbActionBlock; + + // Rule 0: gDollar _ > @1 gEquals; + + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopInsert; // Insert + *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: gAtSign > _ ; + + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 6; +} + + +void GrFSM::SetUpDefaultAssocTest() +{ + // Create machine class ranges. + m_cmcr = 2; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 36; // $ + m_prgmcr[0].m_chwLast = 36; + m_prgmcr[0].m_col = 0; + + m_prgmcr[1].m_chwFirst = 64; // @ + m_prgmcr[1].m_chwLast = 64; + m_prgmcr[1].m_col = 1; + + + m_dimcrInit = 2; // (max power of 2 <= m_cmcr); + m_cLoop = 1; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 3; + m_crowNonAcpt = 1; + m_crowFinal = 2; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 2; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 2 + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 2; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[2]; // 2 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1]; + + m_prgirulnMin[0] = 0; // s1: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; // s2: r1 + m_prgrulnMatched[1] = 1; + + m_prgirulnMin[2] = 2; +} + +/*---------------------------------------------------------------------------------------------- + Test of features. The ID of "theFeature" == 234, its index is 0. The default value is 1. + + PASS 1: + if (theFeature == 0) // * -> $ + r0. gAsterisk > gDollar ; + else if (theFeature == 1) // * -> % + r1. gAsterisk > gPercent ; + else // * -> @ + r2. gAsterisk > gAt ; + + Pass 1 machine classes: + mcAsterisk: * 42 + + Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | mcAsterisk + -------------------------------- + T NA s0 | s1 + | + F A s1 | + + + Rules Matched: + s1: r0, r1, r2 +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpFeatureTest() +{ + AddFeature(234, 0, 1, 1); + + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpFeatureTest(); +} + +void GrClassTable::SetUpFeatureTest() +{ + m_ccls = 4; // number of classes + m_cclsLinear = 4; // number of classes in linear format + + m_prgchwBIGGlyphList = new data16[4]; + + m_prgichwOffsets = new data16[m_ccls + 1]; + + data16 * pchw = m_prgchwBIGGlyphList; + + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(36)); // $ + + m_prgichwOffsets[1] = 1; + *pchw++ = msbf(data16(37)); // % + + m_prgichwOffsets[2] = 2; + *pchw++ = msbf(data16(64)); // @ + + m_prgichwOffsets[3] = 3; + *pchw++ = msbf(data16(42)); // * + + m_prgichwOffsets[4] = 4; +} + +void GrSubPass::SetUpFeatureTest() +{ + m_nMaxRuleContext = m_nMaxChunk = 1; + m_nMaxRuleLoop = 5; + m_staBehavior = "Feature"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpFeatureTest(); + + m_crul = 3; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1 + 6 + 12 + 12]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; + + // (theFeature == 0) + *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0 + *pb++ = kopPushByte; *pb++ = 0; // PushByte 0 + *pb++ = kopEqual; // Equal + *pb++ = kopPopRet; // PopAndRet + + // (theFeature != 0 && theFeature == 1) + *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0 + *pb++ = kopPushByte; *pb++ = 0; // PushByte 0 + *pb++ = kopNotEq; // NotEq + *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0 + *pb++ = kopPushByte; *pb++ = 1; // PushByte 1 + *pb++ = kopEqual; // Equal + *pb++ = kopAnd; // And + *pb++ = kopPopRet; // PopAndRet + + // (theFeature != 0 && theFeature != 1) + *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0 + *pb++ = kopPushByte; *pb++ = 0; // PushByte 0 + *pb++ = kopNotEq; // NotEq + *pb++ = kopPushFeat; *pb++ = 0; // PushFeat 0 + *pb++ = kopPushByte; *pb++ = 1; // PushByte 1 + *pb++ = kopNotEq; // NotEq + *pb++ = kopAnd; // And + *pb++ = kopPopRet; // PopAndRet + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 1; + m_prgibConstraintStart[1] = 1 + 6; + m_prgibConstraintStart[2] = 1 + 6 + 12; + + // Set up rule action code. + m_prgbActionBlock = new byte[4 + 4 + 4]; + pb = m_prgbActionBlock; + + // Rule 0: gAsterisk > gDollar ; + + *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: gAsterisk > gPercent ; + + *pb++ = kopPutGlyph8bitObs; *pb++ = 1; // PutGlyph 1 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 2: gAsterisk > gAt ; + + *pb++ = kopPutGlyph8bitObs; *pb++ = 2; // PutGlyph 2 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 4; + m_prgibActionStart[2] = 4 + 4; +} + + +void GrFSM::SetUpFeatureTest() +{ + // Create machine class ranges. + m_cmcr = 1; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 42; // * + m_prgmcr[0].m_chwLast = 42; + m_prgmcr[0].m_col = 0; + + + m_dimcrInit = 1; // (max power of 2 <= m_cmcr); + m_cLoop = 0; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 2; + m_crowNonAcpt = 1; + m_crowFinal = 1; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 1; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 1 + short * psn = m_prgrowTransitions; + *psn++ = 1; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1]; + + m_prgirulnMin[0] = 0; // s1: r0, r1, r2 + m_prgrulnMatched[0] = 0; + m_prgrulnMatched[1] = 1; + m_prgrulnMatched[2] = 2; + + m_prgirulnMin[1] = 3; +} + + +/*---------------------------------------------------------------------------------------------- + Tests of ligatures and components. + + PASS 1 (line-break): + r0. clsLetter { break = 2 } + + Pass 1 machine classes: + mcLetter: a - z 97 - 122 + + Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | clsLetter + -------------------------------- + T NA s0 | s1 + | + F A s1 | + + + Rules Matched: + s1: r0 + + + PASS 2 (substitution): + r0. gX gY gZ > gCapX:(1 2 4) { comp {X.ref=@1; Y.ref=@2; Z.ref=@4 }} _ _ + / _ _ # {break==2} _; + r1. gX gY gZ > _ _ gCapZ:(1 3 4) { comp {X.ref=@1; Y.ref=@3; Z.ref=@4 }} + / _ # {break==2} _ _; + r2. gX gY gZ > _ gCapY:(1 2 3) { comp {X.ref=@1; Y.ref=@2; Z.ref=@3 }} gPlus; + + Pass 2 machine classes: + mcX: x 120 + mcY: y 121 + mcZ: z 122 + mcLB: 35 + + + Pass 2 FSM: + | mcX mcY mcZ mcLB + ---------------------------------------------------- + T NA s0 | s1 + | - - - + T NA s1 | s2 s3 + | - - - + T NA s2 | s6 s4 + | - - - + T NA s3 | s5 + | - - - + T NA s4 | s7 + | - - - + T NA s5 | s8 + | - - - + F A s6 | + | - - - + F A s7 | + | - - - + F A s8 | + | - - - + + Rules matched: + s6: r2 + s7: r0 + s8: r1 +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpLigatureTest() +{ + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpLigatureTest(); + + m_pgtbl = new GrGlyphTable(); + m_pgtbl->SetUpLigatureTest(); + + m_fLineBreak = true; + m_cchwPreXlbContext = 2; + m_cchwPostXlbContext = 2; +} + +void GrClassTable::SetUpLigatureTest() +{ + m_ccls = 7; // number of classes + m_cclsLinear = 7; // number of classes in linear format (all classes are single-item) + + m_prgchwBIGGlyphList = new data16[7]; + + m_prgichwOffsets = new data16[m_ccls+1]; + + data16 * pchw = m_prgchwBIGGlyphList; + + // Class 0: gCapX + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(88)); // X + + // Class 1: gCapY + m_prgichwOffsets[1] = 1; + *pchw++ = msbf(data16(89)); // Y + + // Class 2: gCapZ + m_prgichwOffsets[2] = 2; + *pchw++ = msbf(data16(90)); // Z + + // Class 3: gPlus + m_prgichwOffsets[3] = 3; + *pchw++ = msbf(data16(43)); // + + + // Class 4: gX + m_prgichwOffsets[4] = 4; + *pchw++ = msbf(data16(120)); // x + + // Class 5: gY + m_prgichwOffsets[5] = 5; + *pchw++ = msbf(data16(121)); // y + + // Class 6: gZ + m_prgichwOffsets[6] = 6; + *pchw++ = msbf(data16(122)); // z + + m_prgichwOffsets[7] = 7; +} + +void GrGlyphTable::SetUpLigatureTest() +{ + SetNumberOfGlyphs(128); + SetNumberOfStyles(1); + + GrGlyphSubTable * pgstbl = new GrGlyphSubTable(); + Assert(pgstbl); + + pgstbl->Initialize(1, 0, 128, 10, 4); + SetSubTable(0, pgstbl); + + SetNumberOfComponents(4); // comp.w, comp.x, comp.y, comp.z + + pgstbl->SetUpLigatureTest(); +} + +/*********************************************************************************************** + TODO: This method is BROKEN because m_prgibBIGAttrValues has been changed. It is no + longer a data16 *. The Gloc table can contain 16-bit or 32-bit entries and must be + accessed accordingly. +***********************************************************************************************/ +void GrGlyphSubTable::SetUpLigatureTest() +{ + m_nAttrIDLim = 20; + + m_pgatbl = new GrGlyphAttrTable(); + m_pgatbl->Initialize(0, 102); + + for (int i = 0; i < 88; i++) + m_prgibBIGAttrValues[i] = (byte)msbf(data16(0)); + + m_prgibBIGAttrValues[88] = (byte)msbf(data16(0)); + m_prgibBIGAttrValues[89] = (byte)msbf(data16(34)); + m_prgibBIGAttrValues[90] = (byte)msbf(data16(68)); + + for (i = 91; i < 128; i++) + m_prgibBIGAttrValues[i] = (byte)msbf(data16(102)); + + m_pgatbl->SetUpLigatureTest(); +} + +void GrGlyphAttrTable::SetUpLigatureTest() +{ + // Glyph 88 'X' (2 runs; offset = 0): + // 0 = 0 comp.w undefined + // 1 = 8 comp.x: (0,0, 25,100) + // 2 = 12 comp.y: (25,0, 75,100) + // 3 = 16 comp.z: (75,0, 100,100) + // 4-7 = 0 comp.w box corners + // 8 = 100 comp.x. top + // 9 = 0 bottom + // 10= 0 left + // 11= 25 right + // 12= 100 comp.y. top + // 13= 0 bottom + // 14= 25 left + // 15= 75 right + // 16= 100 comp.z. top + // 17= 0 bottom + // 18= 75 left + // 19= 100 right + // + // Glyph 89 (2 runs; offset = 34): + // 0 = 0 comp.w undefined + // 1 = 8 comp.x: (0,0, 33,100) + // 2 = 12 comp.y: (33,0, 67,100) + // 3 = 16 comp.z: (67,0, 100,100) + // 4-7 = 0 comp.w box corners + // 8 = 100 comp.x. top + // 9 = 0 bottom + // 10= 0 left + // 11= 33 right + // 12= 100 comp.y. top + // 13= 0 bottom + // 14= 33 left + // 15= 67 right + // 16= 100 comp.z. top + // 17= 0 bottom + // 18= 67 left + // 19= 100 right + // + // Glyph 90 (2 runs; offset = 68): + // 0 = 0 comp.w undefined + // 1 = 8 comp.x: (0,0, 10,100) + // 2 = 12 comp.y: (10,0, 90,100) + // 3 = 16 comp.z: (90,0, 100,100) + // 4-7 = 0 comp.w box corners + // 8 = 100 comp.x. top + // 9 = 0 bottom + // 10= 0 left + // 11= 10 right + // 12= 100 comp.y. top + // 13= 0 bottom + // 14= 10 left + // 15= 90 right + // 16= 100 comp.z. top + // 17= 0 bottom + // 18= 90 left + // 19= 100 right + + byte * pbBIG = m_prgbBIGEntries; + + GrGlyphAttrRun gatrun; + + // Glyph 88 'X' + gatrun.m_bMinAttrID = 1; + gatrun.m_cAttrs = 3; + gatrun.m_rgchwBIGValues[0] = msbf(data16(8)); + gatrun.m_rgchwBIGValues[1] = msbf(data16(12)); + gatrun.m_rgchwBIGValues[2] = msbf(data16(16)); + memcpy(pbBIG, &gatrun, 8); // 8 = 3*2 + 2 + pbBIG += 8; + gatrun.m_bMinAttrID = 8; // comp.x.top + gatrun.m_cAttrs = 12; + gatrun.m_rgchwBIGValues[0] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[1] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[2] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[3] = msbf(data16(25)); + gatrun.m_rgchwBIGValues[4] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[5] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[6] = msbf(data16(25)); + gatrun.m_rgchwBIGValues[7] = msbf(data16(75)); + gatrun.m_rgchwBIGValues[8] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[9] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[10] = msbf(data16(75)); + gatrun.m_rgchwBIGValues[11] = msbf(data16(100)); + memcpy(pbBIG, &gatrun, 26); // 26 = 12*2 + 2 + pbBIG += 26; + + // Glyph 89 'Y' + gatrun.m_bMinAttrID = 1; + gatrun.m_cAttrs = 3; + gatrun.m_rgchwBIGValues[0] = msbf(data16(8)); + gatrun.m_rgchwBIGValues[1] = msbf(data16(12)); + gatrun.m_rgchwBIGValues[2] = msbf(data16(16)); + memcpy(pbBIG, &gatrun, 8); // 8 = 3*2 + 2 + pbBIG += 8; + gatrun.m_bMinAttrID = 8; // comp.x.top + gatrun.m_cAttrs = 12; + gatrun.m_rgchwBIGValues[0] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[1] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[2] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[3] = msbf(data16(33)); + gatrun.m_rgchwBIGValues[4] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[5] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[6] = msbf(data16(33)); + gatrun.m_rgchwBIGValues[7] = msbf(data16(67)); + gatrun.m_rgchwBIGValues[8] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[9] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[10] = msbf(data16(67)); + gatrun.m_rgchwBIGValues[11] = msbf(data16(100)); + memcpy(pbBIG, &gatrun, 26); // 26 = 12*2 + 2 + pbBIG += 26; + + // Glyph 90 'Z' + gatrun.m_bMinAttrID = 1; + gatrun.m_cAttrs = 3; + gatrun.m_rgchwBIGValues[0] = msbf(data16(8)); + gatrun.m_rgchwBIGValues[1] = msbf(data16(12)); + gatrun.m_rgchwBIGValues[2] = msbf(data16(16)); + memcpy(pbBIG, &gatrun, 8); // 8 = 3*2 + 2 + pbBIG += 8; + gatrun.m_bMinAttrID = 8; // comp.x.top + gatrun.m_cAttrs = 12; + gatrun.m_rgchwBIGValues[0] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[1] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[2] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[3] = msbf(data16(10)); + gatrun.m_rgchwBIGValues[4] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[5] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[6] = msbf(data16(10)); + gatrun.m_rgchwBIGValues[7] = msbf(data16(90)); + gatrun.m_rgchwBIGValues[8] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[9] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[10] = msbf(data16(90)); + gatrun.m_rgchwBIGValues[11] = msbf(data16(100)); + memcpy(pbBIG, &gatrun, 26); // 26 = 12*2 + 2 + pbBIG += 26; + + Assert(pbBIG == m_prgbBIGEntries + 102); +} + +void GrLineBreakPass::SetUpLigatureTest() +{ + m_nMaxRuleContext = m_nMaxChunk = 1; + m_nMaxRuleLoop = 5; + m_staBehavior = "Ligatures"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpLigatureTest(m_ipass); + + m_crul = 1; + + // Set up constraint code--succeed trivially. + m_prgbConstraintBlock = new byte[1]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[8]; + pb = m_prgbActionBlock; + + // Rule 0: clsLetter { break = 2 } + + *pb++ = kopPutCopy; *pb++ = 0; // PutCopy 0 + *pb++ = kopPushByte; *pb++ = 2; // PushByte 2 + *pb++ = kopAttrSet; *pb++ = kslatBreak; // AttrSet breakweight + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; +} + +void GrSubPass::SetUpLigatureTest() +{ + if (m_ipass == 2) + { + m_nMaxRuleContext = m_nMaxChunk = 4; + m_nMaxRuleLoop = 5; + m_staBehavior = "Ligatures"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpLigatureTest(m_ipass); + + m_crul = 3; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1 + 10 + 10]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + *pb++ = kopCntxtItem; *pb++ = 2; // ContextItem 2 + *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = 2; // Push 2 + *pb++ = kopEqual; // Equal + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + *pb++ = kopCntxtItem; *pb++ = 1; // ContextItem 1 + *pb++ = kopPushSlotAttr;*pb++ = kslatBreak; // PushSlotAttr break 0 + *pb++ = 0; + *pb++ = kopPushByte; *pb++ = 2; // Push 2 + *pb++ = kopEqual; // Equal + *pb++ = kopOr; // Or + *pb++ = kopPopRet; // PopAndRet + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 1; + m_prgibConstraintStart[1] = 11; + m_prgibConstraintStart[2] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[29 + 29 + 29]; + pb = m_prgbActionBlock; + + // Rule 0: gX gY gZ > gCapX:(1 2 4) { comp {X.ref=@1; Y.ref=@2; Z.ref=@4 }} _ _ + // / _ _ # {break==2} _; + + *pb++ = kopPutGlyph8bitObs; *pb++ = 0; // PutGlyph 0 (gCapX) + *pb++ = kopAssoc; *pb++ = 3; // Assoc 3 0 1 3 + *pb++ = 0; *pb++ = 1; *pb++ = 3; + *pb++ = kopPushByte; *pb++ = 0; // Push 0 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref x + *pb++ = kslatCompRef; *pb++ = 1; + *pb++ = kopPushByte; *pb++ = 1; // Push 1 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref y + *pb++ = kslatCompRef; *pb++ = 2; + *pb++ = kopPushByte; *pb++ = 3; // Push 3 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref z + *pb++ = kslatCompRef; *pb++ = 3; + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: gX gY gZ > _ _ gCapZ:(1 3 4) { comp {X.ref=@1; Y.ref=@3; Z.ref=@4 }} + // / _ # {break==2} _ _; + + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopCopyNext; // CopyNext + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopPutGlyph8bitObs; *pb++ = 2; // PutGlyph 2 (gCapZ) + *pb++ = kopAssoc; *pb++ = 3; // Assoc 3 -3 -1 0 + *pb++ = -3; *pb++ = -1; *pb++ = 0; + *pb++ = kopPushByte; *pb++ = -3; // Push -3 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref x + *pb++ = kslatCompRef; *pb++ = 1; + *pb++ = kopPushByte; *pb++ = -1; // Push -1 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref y + *pb++ = kslatCompRef; *pb++ = 2; + *pb++ = kopPushByte; *pb++ = 0; // Push 0 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref z + *pb++ = kslatCompRef; *pb++ = 3; + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 2: gX gY gZ > _ gCapY:(1 2 3) { comp {X.ref=@1; Y.ref=@2; Z.ref=@3 }} gPlus; + + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopPutGlyph8bitObs; *pb++ = 1; // PutGlyph 1 (gCapY) + *pb++ = kopAssoc; *pb++ = 3; // Assoc 3 -1 0 1 + *pb++ = -1; *pb++ = 0; *pb++ = 1; + *pb++ = kopPushByte; *pb++ = -1; // Push -1 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref x + *pb++ = kslatCompRef; *pb++ = 1; + *pb++ = kopPushByte; *pb++ = 0; // Push 0 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref y + *pb++ = kslatCompRef; *pb++ = 2; + *pb++ = kopPushByte; *pb++ = 1; // Push 1 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot comp_ref z + *pb++ = kslatCompRef; *pb++ = 3; + *pb++ = kopNext; // Next + *pb++ = kopPutGlyph8bitObs; *pb++ = 3; // PutGlyph 3 (gPlus) + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 29; + m_prgibActionStart[2] = 29 + 29; + } + else + Assert(false); +} + + +void GrFSM::SetUpLigatureTest(int ipass) +{ + if (ipass == 1) + { + // Create machine class ranges. + m_cmcr = 1; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 97; // a - z + m_prgmcr[0].m_chwLast = 122; + m_prgmcr[0].m_col = 0; + + m_dimcrInit = 1; // (max power of 2 <= m_cmcr); + m_cLoop = 0; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 2; + m_crowNonAcpt = 1; + m_crowFinal = 1; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 1; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 1 + short * psn = m_prgrowTransitions; + *psn++ = 1; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[1]; // 1 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[m_crow - m_crowNonAcpt + 1]; + + m_prgirulnMin[0] = 0; // s1: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; + } + else if (ipass == 2) + { + // Create machine class ranges. + m_cmcr = 4; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 35; // # + m_prgmcr[0].m_chwLast = 35; + m_prgmcr[0].m_col = 3; + + m_prgmcr[1].m_chwFirst = 120; // x + m_prgmcr[1].m_chwLast = 120; + m_prgmcr[1].m_col = 0; + + m_prgmcr[2].m_chwFirst = 121; // y + m_prgmcr[2].m_chwLast = 121; + m_prgmcr[2].m_col = 1; + + m_prgmcr[3].m_chwFirst = 122; // z + m_prgmcr[3].m_chwLast = 123; + m_prgmcr[3].m_col = 2; + + + m_dimcrInit = 4; // (max power of 2 <= m_cmcr); + m_cLoop = 2; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 9; + m_crowNonAcpt = 6; + m_crowFinal = 3; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 4; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 24 + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 0; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 2; *psn++ = 0; *psn++ = 3; + *psn++ = 0; *psn++ = 0; *psn++ = 6; *psn++ = 4; + *psn++ = 0; *psn++ = 5; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 7; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 8; *psn++ = 0; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s6: r2 + m_prgrulnMatched[0] = 2; + + m_prgirulnMin[1] = 1; // s7: r0 + m_prgrulnMatched[1] = 0; + + m_prgirulnMin[2] = 2; // s8: r1 + m_prgrulnMatched[2] = 1; + + m_prgirulnMin[3] = 3; + } +} + + +/*---------------------------------------------------------------------------------------------- + Tests of ligatures and components where the components are modified glyphs. + + PASS 1: + r0. gX gI > @2 @1; + r1. clsPlainVowel gAcute > clsVowelAcute:(1 2) _; + r2. clsPlainVowel gGrave > clsVowelGrave:(1 2) _; + + Pass 1 machine classes: + mcX: x 120 + mcI: i 105 + mcPV: a e o u 97 101 111 117 + mcAcute: / 47 + mcGrave: \ 92 + + Pass 1 FSM: (T=transition, F=final, A=accepting, NA=non-accepting) + + | mcX mcPV mcI mcAcute mcGrave + --------------------------------------------------------------- + T NA s0 | s1 s2 s2 + | - - - - + T NA s1 | s3 + | - - - - + T NA s2 | s4 s5 + | - - - - + F A s3 | + | - - - - + F A s4 | + | - - - - + F A s5 | + | - - - - + + + Rules Matched: + s3: r0 + s4: r1 + s5: r2 + + + PASS 2: + r0. clsVowel gI > clsCapVowel:(1 2) { comp {v.ref = @1; i.ref = @2}} _; + + Pass 2 machine classes: + mcV: 97 101 111 117 + 224 225 232 233 236 237 242 243 249 250 + mcI: i 105 + + + Pass 2 FSM: + | mcV mcI + ---------------------------------------------------- + T NA s0 | s1 s1 + | - + T NA s1 | s2 + | - + F A s2 | + | - + + Rules matched: + s2: r0 +----------------------------------------------------------------------------------------------*/ +void GrEngine::SetUpLigature2Test() +{ + if (m_pctbl) + delete m_pctbl; + + m_pctbl = new GrClassTable(); + m_pctbl->SetUpLigature2Test(); + + m_pgtbl = new GrGlyphTable(); + m_pgtbl->SetUpLigature2Test(); +} + +void GrClassTable::SetUpLigature2Test() +{ + m_ccls = 5; // number of classes + m_cclsLinear = 3; // number of classes in linear format + + m_prgchwBIGGlyphList = new data16[73]; + + m_prgichwOffsets = new data16[m_ccls+1]; + + data16 * pchw = m_prgchwBIGGlyphList; + + // Output class 0: clsVowelAcute + m_prgichwOffsets[0] = 0; + *pchw++ = msbf(data16(225)); // a-acute + *pchw++ = msbf(data16(233)); // e-acute + *pchw++ = msbf(data16(237)); // i-acute + *pchw++ = msbf(data16(243)); // o-acute + *pchw++ = msbf(data16(250)); // u-acute + + // Output class 1: clsVowelGrave + m_prgichwOffsets[1] = 5; + *pchw++ = msbf(data16(224)); // a-grave + *pchw++ = msbf(data16(232)); // e-grave + *pchw++ = msbf(data16(236)); // i-grave + *pchw++ = msbf(data16(242)); // o-grave + *pchw++ = msbf(data16(249)); // u-grave + + // Output class 2: clsCapVowel + m_prgichwOffsets[2] = 5 + 5; // 10 + *pchw++ = msbf(data16(65)); // A + *pchw++ = msbf(data16(69)); // E + *pchw++ = msbf(data16(73)); // I + *pchw++ = msbf(data16(79)); // O + *pchw++ = msbf(data16(85)); // U + *pchw++ = msbf(data16(193)); // A-acute + *pchw++ = msbf(data16(201)); // E-acute + *pchw++ = msbf(data16(205)); // I-acute + *pchw++ = msbf(data16(211)); // O-acute + *pchw++ = msbf(data16(218)); // U-acute + *pchw++ = msbf(data16(192)); // A-grave + *pchw++ = msbf(data16(200)); // E-grave + *pchw++ = msbf(data16(204)); // I-grave + *pchw++ = msbf(data16(210)); // O-grave + *pchw++ = msbf(data16(217)); // U-grave + + // Input class 3: clsPlainVowel + m_prgichwOffsets[3] = 10 + 15; // 25 + *pchw++ = msbf(data16(5)); + *pchw++ = msbf(data16(4)); *pchw++ = msbf(data16(2)); *pchw++ = msbf(data16(5-4)); + *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(0)); // a + *pchw++ = msbf(data16(101)); *pchw++ = msbf(data16(1)); // e + *pchw++ = msbf(data16(105)); *pchw++ = msbf(data16(2)); // i + *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(3)); // o + *pchw++ = msbf(data16(117)); *pchw++ = msbf(data16(4)); // u + + // Input class 4: clsVowel + m_prgichwOffsets[4] = 25 + 4+(5*2); // 39 + *pchw++ = msbf(data16(15)); + *pchw++ = msbf(data16(8)); *pchw++ = msbf(data16(3)); *pchw++ = msbf(data16(15-8)); + *pchw++ = msbf(data16(97)); *pchw++ = msbf(data16(0)); // a + *pchw++ = msbf(data16(101)); *pchw++ = msbf(data16(1)); // e + *pchw++ = msbf(data16(105)); *pchw++ = msbf(data16(2)); // i + *pchw++ = msbf(data16(111)); *pchw++ = msbf(data16(3)); // o + *pchw++ = msbf(data16(117)); *pchw++ = msbf(data16(4)); // u + *pchw++ = msbf(data16(224)); *pchw++ = msbf(data16(10)); // a-grave + *pchw++ = msbf(data16(225)); *pchw++ = msbf(data16(5)); // a-acute + *pchw++ = msbf(data16(232)); *pchw++ = msbf(data16(11)); // e-grave + *pchw++ = msbf(data16(233)); *pchw++ = msbf(data16(6)); // e-acute + *pchw++ = msbf(data16(236)); *pchw++ = msbf(data16(12)); // i-grave + *pchw++ = msbf(data16(237)); *pchw++ = msbf(data16(7)); // i-acute + *pchw++ = msbf(data16(242)); *pchw++ = msbf(data16(13)); // o-grave + *pchw++ = msbf(data16(243)); *pchw++ = msbf(data16(8)); // o-acute + *pchw++ = msbf(data16(249)); *pchw++ = msbf(data16(14)); // u-grave + *pchw++ = msbf(data16(250)); *pchw++ = msbf(data16(9)); // u-acute + + m_prgichwOffsets[5] = 39 + 4+(15*2); // 73 +} + +void GrGlyphTable::SetUpLigature2Test() +{ + SetNumberOfGlyphs(256); + SetNumberOfStyles(1); + + GrGlyphSubTable * pgstbl = new GrGlyphSubTable(); + Assert(pgstbl); + + pgstbl->Initialize(1, 0, 256, 10, 4); + SetSubTable(0, pgstbl); + + SetNumberOfComponents(2); // comp.base, comp.i + + pgstbl->SetUpLigature2Test(); +} + +/*********************************************************************************************** + TODO: This method is BROKEN because m_prgibBIGAttrValues has been changed. It is no + longer a data16 *. The Gloc table can contain 16-bit or 32-bit entries and must be + accessed accordingly. +***********************************************************************************************/ +void GrGlyphSubTable::SetUpLigature2Test() +{ + m_nAttrIDLim = 10; + + m_pgatbl = new GrGlyphAttrTable(); + m_pgatbl->Initialize(0, 330); + + for (int i = 0; i <= 65; i++) // A + m_prgibBIGAttrValues[i] = (byte)msbf(data16(0)); + + for (i = 66; i <= 69; i++) // E + m_prgibBIGAttrValues[i] = (byte)msbf(data16(22)); + + for (i = 70; i <= 73; i++) // I + m_prgibBIGAttrValues[i] = (byte)msbf(data16(44)); + + for (i = 74; i <= 79; i++) // O + m_prgibBIGAttrValues[i] = (byte)msbf(data16(66)); + + for (i = 80; i <= 85; i++) // U + m_prgibBIGAttrValues[i] = (byte)msbf(data16(88)); + + for (i = 86; i <= 192; i++) // A-grave + m_prgibBIGAttrValues[i] = (byte)msbf(data16(110)); + + m_prgibBIGAttrValues[193] = (byte)msbf(data16(132)); // A-acute + + for (i = 194; i <= 200; i++) // E-grave + m_prgibBIGAttrValues[i] = (byte)msbf(data16(154)); + + m_prgibBIGAttrValues[201] = (byte)msbf(data16(176)); // E-acute + + for (i = 202; i <= 204; i++) // I-grave + m_prgibBIGAttrValues[i] = (byte)msbf(data16(198)); + + m_prgibBIGAttrValues[205] = (byte)msbf(data16(220)); // I-acute + + for (i = 206; i <= 210; i++) // O-grave + m_prgibBIGAttrValues[i] = (byte)msbf(data16(242)); + + m_prgibBIGAttrValues[211] = (byte)msbf(data16(264)); // O-acute + + for (i = 212; i <= 217; i++) // U-grave + m_prgibBIGAttrValues[i] = (byte)msbf(data16(286)); + + m_prgibBIGAttrValues[218] = (byte)msbf(data16(308)); // O-acute + + for (i = 219; i < 256; i++) + m_prgibBIGAttrValues[i] = (byte)msbf(data16(330)); + + m_pgatbl->SetUpLigature2Test(); +} + +void GrGlyphAttrTable::SetUpLigature2Test() +{ + // All ligatures have the following defined: + // + // 0 = 2 comp.base (0,30, 100,100) + // 1 = 6 comp.i (0,0, 100,30) + // 2= 100 comp.base.top + // 3= 30 bottom + // 4= 0 left + // 5= 100 right + // 6 = 30 comp.i.top + // 7 = 0 bottom + // 8= 0 left + // 9= 100 right + + byte * pbBIG = m_prgbBIGEntries; + + GrGlyphAttrRun gatrun; + + for (int i = 0; i < 15; i++) + { + gatrun.m_bMinAttrID = 0; + gatrun.m_cAttrs = 10; + gatrun.m_rgchwBIGValues[0] = msbf(data16(2)); + gatrun.m_rgchwBIGValues[1] = msbf(data16(6)); + gatrun.m_rgchwBIGValues[2] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[3] = msbf(data16(30)); + gatrun.m_rgchwBIGValues[4] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[5] = msbf(data16(100)); + gatrun.m_rgchwBIGValues[6] = msbf(data16(30)); + gatrun.m_rgchwBIGValues[7] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[8] = msbf(data16(0)); + gatrun.m_rgchwBIGValues[9] = msbf(data16(100)); + memcpy(pbBIG, &gatrun, 22); // 22 = 10*2 + 2 + pbBIG += 22; + } + + Assert(pbBIG == m_prgbBIGEntries + (22 * 15)); +} + +void GrSubPass::SetUpLigature2Test() +{ + if (m_ipass == 1) + { + m_nMaxRuleContext = m_nMaxChunk = 2; + m_nMaxRuleLoop = 5; + m_staBehavior = "Ligatures2"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpLigature2Test(m_ipass); + + m_crul = 3; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + m_prgibConstraintStart[1] = 0; + m_prgibConstraintStart[2] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[7 + 12 + 12]; + pb = m_prgbActionBlock; + + // Rule 0: gX gI > @2 @1; + + *pb++ = kopPutCopy; *pb++ = 1; // PutCopy 1 + *pb++ = kopNext; // Next + *pb++ = kopPutCopy; *pb++ = -1; // PutCopy -1 + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 1: clsPlainVowel gAcute > clsVowelAcute:(1 2) _; + + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 3 0 + *pb++ = 3; *pb++ = 0; + *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1 + *pb++ = 0; *pb++ = 1; + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + // Rule 2: clsPlainVowel gGrave > clsVowelGrave:(1 2) _; + + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 3 1 + *pb++ = 3; *pb++ = 1; + *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1 + *pb++ = 0; *pb++ = 1; + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + m_prgibActionStart[1] = 7; + m_prgibActionStart[2] = 7 + 12; + } + else if (m_ipass == 2) + { + m_nMaxRuleContext = m_nMaxChunk = 2; + m_nMaxRuleLoop = 5; + m_staBehavior = "Ligatures2"; + + m_pfsm = new GrFSM(); + Assert(m_pfsm); + m_pfsm->SetUpLigature2Test(m_ipass); + + m_crul = 1; + + // Set up constraint code. + m_prgbConstraintBlock = new byte[1]; + byte * pb = m_prgbConstraintBlock; + *pb++ = kopRetTrue; // RetTrue + + m_prgibConstraintStart = new data16[m_crul]; + m_prgibConstraintStart[0] = 0; + + // Set up rule action code. + m_prgbActionBlock = new byte[7 + 12 + 12]; + pb = m_prgbActionBlock; + + // Rule 0: clsVowel gI > clsCapVowel:(1 2) { comp {v.ref = @1; i.ref = @2}} _; + + *pb++ = kopPutSubs8bitObs; *pb++ = 0; // PutSubs 0 4 2 + *pb++ = 4; *pb++ = 2; + *pb++ = kopAssoc; *pb++ = 2; // Assoc 2 0 1 + *pb++ = 0; *pb++ = 1; + *pb++ = kopPushByte; *pb++ = 0; // Push 0 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot compRef v + *pb++ = kslatCompRef; *pb++ = 0; + *pb++ = kopPushByte; *pb++ = 1; // Push 1 + *pb++ = kopIAttrSetSlot; // IAttrSetSlot compRef i + *pb++ = kslatCompRef; *pb++ = 1; + *pb++ = kopNext; // Next + *pb++ = kopDelete; // Delete + *pb++ = kopNext; // Next + *pb++ = kopRetZero; // RetZero + + m_prgibActionStart = new data16[m_crul]; + m_prgibActionStart[0] = 0; + } + else + Assert(false); +} + + +void GrFSM::SetUpLigature2Test(int ipass) +{ + if (ipass == 1) + { + // Create machine class ranges. + m_cmcr = 8; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 47; // acute + m_prgmcr[0].m_chwLast = 47; + m_prgmcr[0].m_col = 3; + + m_prgmcr[1].m_chwFirst = 92; // grave + m_prgmcr[1].m_chwLast = 92; + m_prgmcr[1].m_col = 4; + + m_prgmcr[2].m_chwFirst = 97; // a + m_prgmcr[2].m_chwLast = 97; + m_prgmcr[2].m_col = 1; + + m_prgmcr[3].m_chwFirst = 101; // e + m_prgmcr[3].m_chwLast = 101; + m_prgmcr[3].m_col = 1; + + m_prgmcr[4].m_chwFirst = 105; // i + m_prgmcr[4].m_chwLast = 105; + m_prgmcr[4].m_col = 2; + + m_prgmcr[5].m_chwFirst = 111; // o + m_prgmcr[5].m_chwLast = 111; + m_prgmcr[5].m_col = 1; + + m_prgmcr[6].m_chwFirst = 117; // u + m_prgmcr[6].m_chwLast = 117; + m_prgmcr[6].m_col = 1; + + m_prgmcr[7].m_chwFirst = 120; // x + m_prgmcr[7].m_chwLast = 120; + m_prgmcr[7].m_col = 0; + + m_dimcrInit = 8; // (max power of 2 <= m_cmcr); + m_cLoop = 3; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 6; + m_crowNonAcpt = 3; + m_crowFinal = 3; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 5; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 15 + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 2; *psn++ = 2; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 3; *psn++ = 0; *psn++ = 0; + *psn++ = 0; *psn++ = 0; *psn++ = 0; *psn++ = 4; *psn++ = 5; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[3]; // 3 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[3+1]; // 3 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s3: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; // s4: r1 + m_prgrulnMatched[1] = 1; + + m_prgirulnMin[2] = 2; // s5: r2 + m_prgrulnMatched[2] = 2; + + m_prgirulnMin[3] = 3; + } + else if (ipass == 2) + { + // Create machine class ranges. + m_cmcr = 10; + m_prgmcr = new GrFSMClassRange[m_cmcr]; + m_prgmcr[0].m_chwFirst = 97; // a + m_prgmcr[0].m_chwLast = 97; + m_prgmcr[0].m_col = 0; + + m_prgmcr[1].m_chwFirst = 101; // e + m_prgmcr[1].m_chwLast = 101; + m_prgmcr[1].m_col = 0; + + m_prgmcr[2].m_chwFirst = 105; // i + m_prgmcr[2].m_chwLast = 105; + m_prgmcr[2].m_col = 1; + + m_prgmcr[3].m_chwFirst = 111; // o + m_prgmcr[3].m_chwLast = 111; + m_prgmcr[3].m_col = 0; + + m_prgmcr[4].m_chwFirst = 117; // u + m_prgmcr[4].m_chwLast = 117; + m_prgmcr[4].m_col = 0; + + m_prgmcr[5].m_chwFirst = 224; // a-grave, a-acute + m_prgmcr[5].m_chwLast = 225; + m_prgmcr[5].m_col = 0; + + m_prgmcr[6].m_chwFirst = 232; // e-grave, e-acute + m_prgmcr[6].m_chwLast = 233; + m_prgmcr[6].m_col = 0; + + m_prgmcr[7].m_chwFirst = 236; // i-grave, i-acute + m_prgmcr[7].m_chwLast = 237; + m_prgmcr[7].m_col = 0; + + m_prgmcr[8].m_chwFirst = 242; // o-grave, o-acute + m_prgmcr[8].m_chwLast = 243; + m_prgmcr[8].m_col = 0; + + m_prgmcr[9].m_chwFirst = 249; // u-grave, u-acute + m_prgmcr[9].m_chwLast = 250; + m_prgmcr[9].m_col = 0; + + + m_dimcrInit = 8; // (max power of 2 <= m_cmcr); + m_cLoop = 3; // log2(max power of 2 <= m_cmcr); + m_imcrStart = m_cmcr - m_dimcrInit; + + + m_crow = 3; + m_crowNonAcpt = 2; + m_crowFinal = 1; + m_rowFinalMin = m_crow - m_crowFinal; + m_ccol = 2; + + // Set up transition table. + m_prgrowTransitions = new short[(m_crow-m_crowFinal) * m_ccol]; // 4 + short * psn = m_prgrowTransitions; + *psn++ = 1; *psn++ = 1; + *psn++ = 0; *psn++ = 2; + + // Set up matched-rules tables. + m_prgrulnMatched = new data16[1]; // 1 = sum of rules matched for each accepting state + m_prgirulnMin = new data16[1+1]; // 1 = m_crow - m_crowNonAcpt + + m_prgirulnMin[0] = 0; // s2: r0 + m_prgrulnMatched[0] = 0; + + m_prgirulnMin[1] = 1; + } +} + +#endif // _DEBUG + +} // namespace gr + +#endif // OLD_TEST_STUFF + +//:End Ignore |