summaryrefslogtreecommitdiff
path: root/Build/source/libs/graphite/src/segment/TestPasses.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/graphite/src/segment/TestPasses.cpp')
-rw-r--r--Build/source/libs/graphite/src/segment/TestPasses.cpp1005
1 files changed, 1005 insertions, 0 deletions
diff --git a/Build/source/libs/graphite/src/segment/TestPasses.cpp b/Build/source/libs/graphite/src/segment/TestPasses.cpp
new file mode 100644
index 00000000000..a85e6c56207
--- /dev/null
+++ b/Build/source/libs/graphite/src/segment/TestPasses.cpp
@@ -0,0 +1,1005 @@
+/*--------------------------------------------------------------------*//*: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: TestPasses.cpp
+Responsibility: Sharon Correll
+Last reviewed: Not yet.
+
+Description:
+ Hard-coded passes 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
+//:>********************************************************************************************
+
+/*----------------------------------------------------------------------------------------------
+ For release version.
+----------------------------------------------------------------------------------------------*/
+#ifndef _DEBUG
+
+bool GrLineBreakPass::RunTestRules(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ return false;
+}
+
+bool GrSubPass::RunTestRules(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ return false;
+}
+
+bool GrPosPass::RunTestRules(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ return false;
+}
+
+#endif // !_DEBUG
+
+
+#ifdef _DEBUG
+
+/*----------------------------------------------------------------------------------------------
+ Set up a table manager for testing.
+----------------------------------------------------------------------------------------------*/
+void GrTableManager::SetUpTest(std::wstring stuRendBehavior)
+{
+ if (stuRendBehavior == L"NoRules")
+ {
+ m_cpass = 2;
+ m_cpassLB = 0;
+ m_ipassPos1 = 1;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrPosPass(1);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"JustReorder" || stuRendBehavior == "RightToLeftLayout")
+ {
+ m_cpass = 4;
+ m_cpassLB = 0;
+ m_ipassPos1 = 3;
+ m_fBidi = true;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrBidiPass(2);
+ m_prgppass[3] = new GrPosPass(3);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpReverseNumbersTest();
+ m_prgppass[2]->SetUpTestData();
+ m_prgppass[3]->SetUpTestData();
+
+ m_prgppass[2]->SetTopDirLevel(TopDirectionLevel());
+ }
+ else if (stuRendBehavior == L"CrossLineContext")
+ {
+ m_cpass = 4;
+ m_cpassLB = 1;
+ m_ipassPos1 = 3;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrLineBreakPass(1);
+ m_prgppass[2] = new GrSubPass(2);
+ m_prgppass[3] = new GrPosPass(3);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpCrossLineContextTest();
+ m_prgppass[2]->SetUpCrossLineContextTest();
+ m_prgppass[3]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"Reprocess")
+ {
+ m_cpass = 6;
+ m_cpassLB = 1;
+ m_ipassPos1 = 5;
+ m_fBidi = true;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrLineBreakPass(1);
+ m_prgppass[2] = new GrSubPass(2);
+ m_prgppass[3] = new GrSubPass(3);
+ m_prgppass[4] = new GrBidiPass(4);
+ m_prgppass[5] = new GrPosPass(5);
+
+ m_prgppass[0]->SetUpTestData(); // glyph-gen pass
+ m_prgppass[1]->SetUpReprocessTest(); // line-break pass
+ m_prgppass[2]->SetUpReverseNumbersTest(); // sub pass 1
+ m_prgppass[3]->SetUpReprocessTest(); // sub pass 2
+ m_prgppass[4]->SetUpTestData(); // bidi pass
+ m_prgppass[5]->SetUpTestData(); // pos pass
+
+ m_prgppass[4]->SetTopDirLevel(TopDirectionLevel());
+ }
+ else if (stuRendBehavior == L"LineEdgeContext")
+ {
+ m_cpass = 4;
+ m_cpassLB = 0;
+ m_ipassPos1 = 3;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrSubPass(2);
+ m_prgppass[3] = new GrPosPass(3);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpLineEdgeContextTest(1);
+ m_prgppass[2]->SetUpLineEdgeContextTest(2);
+ m_prgppass[3]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"BidiAlgorithm")
+ {
+ m_cpass = 4;
+ m_cpassLB = 0;
+ m_ipassPos1 = 3;
+ m_fBidi = true;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrBidiPass(2);
+ m_prgppass[3] = new GrPosPass(3);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpBidiAlgorithmTest();
+ m_prgppass[2]->SetUpBidiAlgorithmTest();
+ m_prgppass[3]->SetUpTestData();
+
+ m_prgppass[2]->SetTopDirLevel(TopDirectionLevel());
+ }
+ else if (stuRendBehavior == L"PseudoGlyphs")
+ {
+ m_cpass = 3;
+ m_cpassLB = 0;
+ m_ipassPos1 = 2;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrPosPass(2);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpPseudoGlyphsTest();
+ m_prgppass[2]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"SimpleFSM")
+ {
+ m_cpass = 3;
+ m_cpassLB = 0;
+ m_ipassPos1 = 2;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrPosPass(2);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpSimpleFSMTest();
+ m_prgppass[2]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"RuleAction")
+ {
+ m_cpass = 3;
+ m_cpassLB = 0;
+ m_ipassPos1 = 2;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrPosPass(2);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpRuleActionTest();
+ m_prgppass[2]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"RuleAction2")
+ {
+ m_cpass = 6;
+ m_cpassLB = 0;
+ m_ipassPos1 = 5;
+ m_fBidi = true;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrSubPass(2);
+ m_prgppass[3] = new GrSubPass(3);
+ m_prgppass[4] = new GrBidiPass(4);
+ m_prgppass[5] = new GrPosPass(5);
+
+ m_prgppass[0]->SetUpTestData(); // glyph-gen pass
+ m_prgppass[1]->SetUpRuleAction2Test(); // sub pass 1
+ m_prgppass[2]->SetUpRuleAction2Test(); // sub pass 2
+ m_prgppass[3]->SetUpRuleAction2Test(); // sub pass 3
+ m_prgppass[4]->SetUpTestData(); // bidi pass
+ m_prgppass[5]->SetUpTestData(); // pos pass
+
+ m_prgppass[4]->SetTopDirLevel(TopDirectionLevel());
+ }
+ else if (stuRendBehavior == L"Assoc")
+ {
+ m_cpass = 5;
+ m_cpassLB = 1;
+ m_ipassPos1 = 4;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrLineBreakPass(1);
+ m_prgppass[2] = new GrSubPass(2);
+ m_prgppass[3] = new GrSubPass(3);
+ m_prgppass[4] = new GrPosPass(4);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpAssocTest();
+ m_prgppass[2]->SetUpAssocTest();
+ m_prgppass[3]->SetUpAssocTest();
+ m_prgppass[4]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"Assoc2")
+ {
+ m_cpass = 3;
+ m_cpassLB = 0;
+ m_ipassPos1 = 2;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrPosPass(2);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpAssoc2Test();
+ m_prgppass[2]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"DefaultAssoc")
+ {
+ m_cpass = 3;
+ m_cpassLB = 0;
+ m_ipassPos1 = 2;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrPosPass(2);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpDefaultAssocTest();
+ m_prgppass[2]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"BidiNumbers")
+ {
+ m_cpass = 4;
+ m_cpassLB = 0;
+ m_ipassPos1 = 3;
+ m_fBidi = true;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrBidiPass(2);
+ m_prgppass[3] = new GrPosPass(3);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpBidiNumbersTest();
+ m_prgppass[2]->SetUpBidiNumbersTest();
+ m_prgppass[3]->SetUpTestData();
+
+ m_prgppass[2]->SetTopDirLevel(TopDirectionLevel());
+ }
+ else if (stuRendBehavior == L"Feature")
+ {
+ m_cpass = 3;
+ m_cpassLB = 0;
+ m_ipassPos1 = 2;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrPosPass(2);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpFeatureTest();
+ m_prgppass[2]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"Ligatures")
+ {
+ m_cpass = 4;
+ m_cpassLB = 1;
+ m_ipassPos1 = 3;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrLineBreakPass(1);
+ m_prgppass[2] = new GrSubPass(2);
+ m_prgppass[3] = new GrPosPass(3);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpLigatureTest();
+ m_prgppass[2]->SetUpLigatureTest();
+ m_prgppass[3]->SetUpTestData();
+ }
+ else if (stuRendBehavior == L"Ligatures2")
+ {
+ m_cpass = 4;
+ m_cpassLB = 1;
+ m_ipassPos1 = 3;
+ m_fBidi = false;
+
+ m_prgppass = new GrPass*[m_cpass];
+ m_prgppass[0] = new GrGlyphGenPass(0);
+ m_prgppass[1] = new GrSubPass(1);
+ m_prgppass[2] = new GrSubPass(2);
+ m_prgppass[3] = new GrPosPass(3);
+
+ m_prgppass[0]->SetUpTestData();
+ m_prgppass[1]->SetUpLigature2Test();
+ m_prgppass[2]->SetUpLigature2Test();
+ m_prgppass[3]->SetUpTestData();
+ }
+ else
+ Assert(false);
+
+ m_engst.m_prgpsstrm = new GrSlotStream*[m_cpass];
+ for (int ipass = 0; ipass < m_cpass; ++ipass)
+ m_engst.m_prgpsstrm[ipass] = new GrSlotStream(ipass);
+}
+
+
+/*----------------------------------------------------------------------------------------------
+ Set the pass variables that normally will be read from the ECF.
+----------------------------------------------------------------------------------------------*/
+
+void GrPass::SetUpTestData()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 2;
+ m_nMaxRuleLoop = 2;
+}
+
+//void GrBidiPass::SetUpTestData()
+//{
+// m_nMaxRuleContext = m_nMaxChunk = 1;
+// m_nMaxRuleLoop = 2;
+//}
+
+/*----------------------------------------------------------------------------------------------
+ Call the appropriate test function.
+----------------------------------------------------------------------------------------------*/
+
+bool GrLineBreakPass::RunTestRules(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ if (m_staBehavior == "Reprocess")
+ return RunReprocessTest(ptman, psstrmInput, psstrmOutput);
+ else if (m_staBehavior == "CrossLineContext")
+ return RunCrossLineContextTest(ptman, psstrmInput, psstrmOutput);
+ else
+ return false;
+}
+
+bool GrSubPass::RunTestRules(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ if (m_staBehavior == "ReverseNumbers")
+ return RunReverseNumbersTest(ptman, psstrmInput, psstrmOutput);
+ else if (m_staBehavior == "CrossLineContext")
+ return RunCrossLineContextTest(ptman, psstrmInput, psstrmOutput);
+ else if (m_staBehavior == "Reprocess")
+ return RunReprocessTest(ptman, psstrmInput, psstrmOutput);
+ else if (m_staBehavior == "LineEdgeContext")
+ return RunLineEdgeContextTest(ptman, psstrmInput, psstrmOutput);
+ else if (m_staBehavior == "BidiAlgorithm")
+ return RunBidiAlgorithmTest(ptman, psstrmInput, psstrmOutput);
+ else if (m_staBehavior == "PseudoGlyphs")
+ return RunPseudoGlyphsTest(ptman, psstrmInput, psstrmOutput);
+ else if (m_staBehavior == "BidiNumbers")
+ return RunBidiNumbersTest(ptman, psstrmInput, psstrmOutput);
+ else
+ return false;
+}
+
+bool GrPosPass::RunTestRules(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ return false;
+}
+
+/*----------------------------------------------------------------------------------------------
+ A substitution pass that causes numbers to be reversed. Used by both the JustReorder test
+ and the Reprocess test.
+----------------------------------------------------------------------------------------------*/
+
+void GrSubPass::SetUpReverseNumbersTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 1;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "ReverseNumbers";
+}
+
+bool GrSubPass::RunReverseNumbersTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ data16 chw0;
+
+ // clsDigit { dir = DIR_RIGHT };
+ if (psstrmInput->SlotsPending() >= 1)
+ {
+ bool fRtl = ptman->RightToLeft();
+ chw0 = psstrmInput->Peek(0)->GlyphID();
+ if ((chw0 >= '0') && (chw0 <= '9'))
+ {
+ GrSlotState * pslot0 = psstrmInput->NextGet();
+// GrFeatureValues fval0;
+// pslot0->GetFeatureValues(&fval0);
+
+ GrSlotState * pslotNew;
+ ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
+ pslotNew->SetDirectionality(fRtl ? kdircArabNum : kdircR);
+ pslotNew->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew);
+
+ return true;
+ }
+ else
+ {
+ GrSlotState * pslot0 = psstrmInput->NextGet();
+// GrFeatureValues fval0;
+// pslot0->GetFeatureValues(&fval0);
+
+ GrSlotState * pslotNew;
+ ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
+ if (chw0 == 32)
+ pslotNew->SetDirectionality(kdircWhiteSpace);
+ else if (chw0 == '.')
+ pslotNew->SetDirectionality(kdircComSep);
+ else
+ pslotNew->SetDirectionality(fRtl ? kdircR : kdircL);
+ pslotNew->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew);
+
+ return true;
+ }
+ }
+ else
+ return false;
+}
+
+/*----------------------------------------------------------------------------------------------
+ A substitution pass that will do some hard-coded actions resulting in cross-line-boundary
+ contextuals.
+----------------------------------------------------------------------------------------------*/
+void GrEngine::SetUpCrossLineContextTest()
+{
+ m_fLineBreak = true;
+ m_cchwPreXlbContext = 2;
+ m_cchwPostXlbContext = 0;
+}
+
+void GrLineBreakPass::SetUpCrossLineContextTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 1;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "CrossLineContext";
+}
+
+void GrSubPass::SetUpCrossLineContextTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 3;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "CrossLineContext";
+}
+
+bool GrLineBreakPass::RunCrossLineContextTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ // '=' { break = intra };
+ if ((psstrmInput->SlotsPending() >= 1) &&
+ (psstrmInput->Peek(0)->GlyphID() == 61))
+ {
+ GrSlotState * pslotNew0;
+ ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew0);
+ pslotNew0->SetBreakWeight(int(klbHyphenBreak));
+ psstrmOutput->NextPut(pslotNew0);
+
+ psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+bool GrSubPass::RunCrossLineContextTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ // any '=' _ _ > any '=' '=':2 any:1 / _ _ # _ _
+ if ((psstrmInput->SlotsPending() >= 3) &&
+ (psstrmInput->Peek(1)->GlyphID() == 61) &&
+ (psstrmInput->Peek(2)->GlyphID() == ptman->LBGlyphID()))
+ {
+ GrSlotState * pslot0 = psstrmInput->Peek(0);
+ GrSlotState * pslot1 = psstrmInput->Peek(1);
+ gid16 chw0 = pslot0->GlyphID();
+// GrFeatureValues fval0;
+// pslot0->GetFeatureValues(&fval0);
+// GrFeatureValues fval1;
+// pslot1->GetFeatureValues(&fval1);
+
+ // copy the first 3 slots
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ // insert 2 more
+ GrSlotState * pslot3;
+ ptman->NewSlot(61, pslot1, NULL, m_ipass, &pslot3);
+ pslot3->Associate(pslot1);
+ psstrmOutput->NextPut(pslot3);
+
+ GrSlotState * pslot4;
+ ptman->NewSlot(chw0, pslot0, NULL, m_ipass, &pslot4);
+ pslot4->Associate(pslot0);
+ psstrmOutput->NextPut(pslot4);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+/*----------------------------------------------------------------------------------------------
+ Line break and substitution passes that cause intra-pass reprocessing (ie, the ^ mechanism).
+----------------------------------------------------------------------------------------------*/
+
+void GrLineBreakPass::SetUpReprocessTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 2;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "Reprocess";
+}
+
+bool GrLineBreakPass::RunReprocessTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ gid16 chw;
+
+ // '^' {lb=2} / _ lc
+ if ((psstrmInput->SlotsPending() >=2) &&
+ (psstrmInput->Peek(0)->GlyphID() == '^') &&
+ (((chw = psstrmInput->Peek(1)->GlyphID()) >= 'a') &&
+ (chw <= 'z')))
+ {
+ GrSlotState * pslotNew0;
+ ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew0);
+ pslotNew0->SetBreakWeight(int(klbHyphenBreak));
+ psstrmOutput->NextPut(pslotNew0);
+
+ psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
+void GrSubPass::SetUpReprocessTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 3;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "Reprocess";
+}
+
+bool GrSubPass::RunReprocessTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ gid16 chw;
+ gid16 chwLB = ptman->LBGlyphID();
+
+ // symbol > @2 {dir = DIR_ARABNUMBER} / any {dir != DIR_LEFT} ^ _
+ if ((psstrmInput->SlotsPending() >= 2) &&
+ (psstrmInput->Peek(0)->Directionality() != kdircL) &&
+ (((chw = psstrmInput->Peek(1)->GlyphID()) == '@') ||
+ (chw == '@') || (chw == '$') || (chw == '%') ||
+ (chw == '^') || (chw == '&') || (chw == '*')))
+ {
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+ GrSlotState * pslotNew1;
+ ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew1);
+ pslotNew1->SetDirectionality(kdircArabNum);
+ psstrmOutput->NextPut(pslotNew1);
+
+ psstrmOutput->SetPosForNextRule(-1, psstrmInput, false);
+
+ return true;
+ }
+
+ // '^' lc > @1 uc
+ else if ((psstrmInput->SlotsPending() >= 2) &&
+ (psstrmInput->Peek(0)->GlyphID() == '^') &&
+ (((chw = psstrmInput->Peek(1)->GlyphID()) >= 'a') &&
+ (chw <= 'z')))
+ {
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ gid16 chwNew = chw - 'a' + 'A';
+ GrSlotState * pslotNew1;
+ ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew1);
+ pslotNew1->SetGlyphID(chwNew);
+ psstrmOutput->NextPut(pslotNew1);
+
+ psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
+
+ return true;
+ }
+
+ // '^' lc > @1 uc / _ # _
+ else if ((psstrmInput->SlotsPending() >= 3) &&
+ (psstrmInput->Peek(0)->GlyphID() == '^') &&
+ (psstrmInput->Peek(1)->IsLineBreak(chwLB)) &&
+ (((chw = psstrmInput->Peek(2)->GlyphID()) >= 'a') &&
+ (chw <= 'z')))
+ {
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ gid16 chwNew = chw - 'a' + 'A';
+ GrSlotState * pslotNew1;
+ ptman->NewSlotCopy(psstrmInput->NextGet(), m_ipass, &pslotNew1);
+ pslotNew1->SetGlyphID(chwNew);
+ psstrmOutput->NextPut(pslotNew1);
+
+ psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
+
+ return true;
+ }
+
+ else
+ return false;
+}
+
+
+/*----------------------------------------------------------------------------------------------
+ Substitution passes that create contextual forms at the line breaks; also a cross-line-
+ boundary contextual.
+----------------------------------------------------------------------------------------------*/
+
+void GrSubPass::SetUpLineEdgeContextTest(int ipass)
+{
+ m_nMaxRuleContext = (ipass == 2)? 5: 2;
+ m_nMaxChunk = m_nMaxRuleContext;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "LineEdgeContext";
+}
+
+bool GrSubPass::RunLineEdgeContextTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ gid16 chwLB = ptman->LBGlyphID();
+
+ // any _ _ > @1 '-' '-' / _ _ _ #
+ if ((m_ipass == 1) &&
+ (psstrmInput->SlotsPending() >= 2) &&
+ (psstrmInput->Peek(1)->IsLineBreak(chwLB)))
+ {
+ GrSlotState * pslot0 = psstrmInput->Peek(0);
+// GrFeatureValues fval;
+// pslot0->GetFeatureValues(&fval);
+
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ GrSlotState * pslotNew1;
+ ptman->NewSlot('-', pslot0, NULL, m_ipass, &pslotNew1);
+ pslotNew1->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew1);
+
+ GrSlotState * pslotNew2;
+ ptman->NewSlot('-', pslot0, NULL, m_ipass, &pslotNew2);
+ pslotNew2->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew2);
+
+ return true;
+ }
+
+ // _ _ any > '+' '+' @4 / # _ _ _
+ else if ((m_ipass == 1) &&
+ (psstrmInput->SlotsPending() >= 2) &&
+ (psstrmInput->Peek(0)->IsLineBreak(chwLB)))
+ {
+ GrSlotState * pslot2 = psstrmInput->Peek(1);
+// GrFeatureValues fval;
+// pslot2->GetFeatureValues(&fval);
+
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ GrSlotState * pslotNew0;
+ ptman->NewSlot('+', pslot2, NULL, m_ipass, &pslotNew0);
+ pslotNew0->Associate(pslot2);
+ psstrmOutput->NextPut(pslotNew0);
+
+ GrSlotState * pslotNew1;
+ ptman->NewSlot('+', pslot2, NULL, m_ipass, &pslotNew1);
+ pslotNew1->Associate(pslot2);
+ psstrmOutput->NextPut(pslotNew1);
+
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ return true;
+ }
+
+ // '-' '-' '+' '+' > @1 _ _ @4 / _ _ # _ _
+ else if ((m_ipass == 2) &&
+ (psstrmInput->SlotsPending() >= 5) &&
+ (psstrmInput->Peek(0)->GlyphID() == '-') &&
+ (psstrmInput->Peek(1)->GlyphID() == '-') &&
+ (psstrmInput->Peek(2)->IsLineBreak(chwLB)) &&
+ (psstrmInput->Peek(3)->GlyphID() == '+') &&
+ (psstrmInput->Peek(4)->GlyphID() == '+'))
+ {
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+ psstrmInput->Skip(1);
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+ psstrmInput->Skip(1);
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ return true;
+ }
+
+ else
+ return false;
+}
+
+/*----------------------------------------------------------------------------------------------
+ Substitution passes that do something special with pseudo glyphs.
+----------------------------------------------------------------------------------------------*/
+
+void GrSubPass::SetUpPseudoGlyphsTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 3;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "PseudoGlyphs";
+}
+
+bool GrSubPass::RunPseudoGlyphsTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ gid16 chwLB = ptman->LBGlyphID();
+
+ // pseudo > uppercase / _ ' '
+ if ((psstrmInput->SlotsPending() >= 2) &&
+ (psstrmInput->Peek(0)->GlyphID() > 1000) && // pseudo
+ (psstrmInput->Peek(1)->GlyphID() == 32))
+ {
+ GrSlotState * pslot0 = psstrmInput->NextGet();
+// GrFeatureValues fval;
+// pslot0->GetFeatureValues(&fval);
+
+ GrSlotState * pslotNew;
+ ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
+ pslotNew->SetGlyphID(pslot0->GlyphID() - 1000);
+ pslotNew->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew);
+
+ psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
+
+ return true;
+ }
+
+ // pseudo > uppercase / _ |
+ // pseudo > uppercase / _ #
+ else if ((psstrmInput->SlotsPending() <= 2) &&
+ (psstrmInput->Peek(0)->GlyphID() > 1000) && // pseudo
+ (psstrmInput->SlotsPending() < 2 || psstrmInput->Peek(1)->GlyphID() == 35))
+ {
+ GrSlotState * pslot0 = psstrmInput->NextGet();
+// GrFeatureValues fval;
+// pslot0->GetFeatureValues(&fval);
+
+ GrSlotState * pslotNew;
+ ptman->NewSlotCopy(pslot0, m_ipass, &pslotNew);
+ pslotNew->SetGlyphID(pslot0->GlyphID() - 1000);
+ pslotNew->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew);
+
+ psstrmOutput->SetPosForNextRule(0, psstrmInput, false);
+
+ return true;
+ }
+
+ // pseudo any _ > lowercase:1 @2 @1 / _ _ ^ _;
+ else if ((psstrmInput->SlotsPending() >= 3) &&
+ (psstrmInput->Peek(0)->GlyphID() > 1000)) // pseudo
+ {
+ GrSlotState * pslot0 = psstrmInput->NextGet();
+// GrFeatureValues fval;
+// pslot0->GetFeatureValues(&fval);
+
+ GrSlotState * pslotNew0;
+ ptman->NewSlot(pslot0->GlyphID()-1000-65+97, pslot0, NULL, m_ipass, &pslotNew0);
+ pslotNew0->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew0);
+
+ psstrmOutput->CopyOneSlotFrom(psstrmInput);
+
+ GrSlotState * pslotNew2;
+ ptman->NewSlot(pslot0->GlyphID(), pslot0, NULL, m_ipass, &pslotNew2);
+ pslotNew2->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew2);
+
+ psstrmOutput->SetPosForNextRule(-1, psstrmInput, false);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+/*----------------------------------------------------------------------------------------------
+ Substitution pass that tests reversing numbers.
+----------------------------------------------------------------------------------------------*/
+void GrSubPass::SetUpBidiNumbersTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 1;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "BidiNumbers";
+}
+
+bool GrSubPass::RunBidiNumbersTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ gid16 chw0;
+
+ // clsDigit > clsDigit { dir = DIR_ARABNUMBER };
+ if ((psstrmInput->SlotsPending() >= 1) &&
+ (((chw0 = psstrmInput->Peek(0)->GlyphID()) >= '0' && chw0 <= '9') ||
+ (chw0 >= 'A' && chw0 <= 'Z') || (chw0 >= 'a' && chw0 <= 'z')))
+ {
+ GrSlotState * pslot0 = psstrmInput->NextGet();
+// GrFeatureValues fval0;
+// pslot0->GetFeatureValues(&fval0);
+
+ GrSlotState * pslotNew;
+ ptman->NewSlot(chw0, pslot0, NULL, m_ipass, &pslotNew);
+ if (chw0 >= '0' && chw0 <= '9')
+ pslotNew->SetDirectionality(kdircArabNum);
+ else // a-z and A-Z
+ pslotNew->SetDirectionality(kdircR);
+ pslotNew->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+void GrBidiPass::SetUpBidiNumbersTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 1;
+ m_nMaxRuleLoop = 2;
+ m_nTopDirection = 1;
+}
+
+/*----------------------------------------------------------------------------------------------
+ Substitution pass that tests the bidi algorithm thoroughly.
+----------------------------------------------------------------------------------------------*/
+void GrSubPass::SetUpBidiAlgorithmTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 1;
+ m_nMaxRuleLoop = 2;
+ m_staBehavior = "BidiAlgorithm";
+}
+
+bool GrSubPass::RunBidiAlgorithmTest(GrTableManager * ptman,
+ GrSlotStream * psstrmInput, GrSlotStream * psstrmOutput)
+{
+ gid16 chw0;
+
+ if (psstrmInput->SlotsPending() >= 1)
+ {
+ chw0 = psstrmInput->Peek(0)->GlyphID();
+
+ DirCode dircNew;
+
+ if (chw0 >= '0' && chw0 <= '9')
+ dircNew = kdircEuroNum;
+ else if (chw0 >= 'a' && chw0 <= 'z')
+ dircNew = kdircL;
+ else if (chw0 >= 'A' && chw0 <= 'M')
+ dircNew = kdircR;
+ else if (chw0 >= 'N' && chw0 <= 'T')
+ dircNew = kdircRArab;
+ else if (chw0 >= 'U' && chw0 <= 'Z')
+ dircNew = kdircArabNum;
+ else if (chw0 == '$' || chw0 == '%')
+ dircNew = kdircEuroTerm;
+ else if (chw0 == '.' || chw0 == '*' || chw0 == '+')
+ dircNew = kdircEuroSep;
+ else if (chw0 == '@')
+ dircNew = kdircComSep;
+ else if (chw0 == '_' || chw0 == '=')
+ dircNew = kdircNeutral;
+ else if (chw0 == ':')
+ dircNew = kdircNSM;
+ else
+ return false;
+
+ GrSlotState * pslot0 = psstrmInput->NextGet();
+// GrFeatureValues fval0;
+// pslot0->GetFeatureValues(&fval0);
+
+ GrSlotState * pslotNew;
+ ptman->NewSlot(chw0, pslot0, NULL, m_ipass, &pslotNew);
+ pslotNew->SetDirectionality(dircNew);
+ pslotNew->Associate(pslot0);
+ psstrmOutput->NextPut(pslotNew);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+void GrBidiPass::SetUpBidiAlgorithmTest()
+{
+ m_nMaxRuleContext = m_nMaxChunk = 1;
+ m_nMaxRuleLoop = 2;
+ m_nTopDirection = 0;
+}
+
+
+#endif // _DEBUG
+
+} // namespace gr
+
+#endif // OLD_TEST_STUFF
+
+//:End Ignore