internal void PrintCaseInfo(Bidi bidi, String src, String dst) { int length = bidi.GetProcessedLength(); sbyte[] levels = bidi.GetLevels(); char[] levelChars = new char[length]; sbyte lev; int runCount = bidi.CountRuns(); Errcontln("========================================"); Errcontln("Processed length: " + length); for (int i = 0; i < length; i++) { lev = levels[i]; if (lev < 0) { levelChars[i] = '-'; } else if (lev < columns.Length) { levelChars[i] = columns[lev]; } else { levelChars[i] = '+'; } } Errcontln("Levels: " + ILOG.J2CsMapping.Util.StringUtil.NewString(levelChars)); Errcontln("Source: " + src); Errcontln("Result: " + dst); Errcontln("Direction: " + bidi.GetDirection()); Errcontln("paraLevel: " + bidi.GetParaLevel().ToString()); Errcontln("reorderingMode: " + ModeToString(bidi.GetReorderingMode())); Errcontln("reorderingOptions: " + SpOptionsToString(bidi.GetReorderingOptions())); Errcont("Runs: " + runCount + " => logicalStart.length/level: "); for (int i_0 = 0; i_0 < runCount; i_0++) { BidiRun run; run = bidi.GetVisualRun(i_0); Errcont(" " + run.GetStart() + "." + run.GetLength() + "/" + run.GetEmbeddingLevel()); } Errcont("\n"); }
public void TestFailureRecovery2() { Logln("\nEntering TestFailureRecovery\n"); Bidi bidi = new Bidi(); try { bidi.SetPara("abc", (sbyte)(IBM.ICU.Text.Bidi.LEVEL_DEFAULT_LTR - 1), null); Errln("Bidi.setPara did not fail when passed too big para level"); } catch (ArgumentException e) { Logln("OK: Got exception for bidi.setPara(..., Bidi.LEVEL_DEFAULT_LTR - 1, ...)" + " as expected: " + e.Message); } try { bidi.SetPara("abc", (sbyte)(-1), null); Errln("Bidi.setPara did not fail when passed negative para level"); } catch (ArgumentException e_0) { Logln("OK: Got exception for bidi.setPara(..., -1, ...)" + " as expected: " + e_0.Message); } try { IBM.ICU.Text.Bidi.WriteReverse(null, 0); Errln("Bidi.writeReverse did not fail when passed a null string"); } catch (ArgumentException e_1) { Logln("OK: Got exception for Bidi.writeReverse(null) as expected: " + e_1.Message); } bidi = new Bidi(); try { bidi.SetLine(0, 1); Errln("bidi.setLine did not fail when called before valid setPara()"); } catch (InvalidOperationException e_2) { Logln("OK: Got exception for Bidi.setLine(0, 1) as expected: " + e_2.Message); } try { bidi.GetDirection(); Errln("bidi.getDirection did not fail when called before valid setPara()"); } catch (InvalidOperationException e_3) { Logln("OK: Got exception for Bidi.getDirection() as expected: " + e_3.Message); } bidi.SetPara("abc", IBM.ICU.Text.Bidi.LTR, null); try { bidi.GetLevelAt(3); Errln("bidi.getLevelAt did not fail when called with bad argument"); } catch (ArgumentException e_4) { Logln("OK: Got exception for Bidi.getLevelAt(3) as expected: " + e_4.Message); } try { bidi = new Bidi(-1, 0); Errln("Bidi constructor did not fail when called with bad argument"); } catch (ArgumentException e_5) { Logln("OK: Got exception for Bidi(-1,0) as expected: " + e_5.Message); } bidi = new Bidi(2, 1); try { bidi.SetPara("abc", IBM.ICU.Text.Bidi.LTR, null); Errln("setPara did not fail when called with text too long"); } catch (Exception e_6) { Logln("OK: Got exception for setPara(\"abc\") as expected: " + e_6.Message); } try { bidi.SetPara("=2", IBM.ICU.Text.Bidi.RTL, null); bidi.CountRuns(); Errln("countRuns did not fail when called for too many runs"); } catch (Exception e_7) { Logln("OK: Got exception for countRuns as expected: " + e_7.Message); } int rm = bidi.GetReorderingMode(); bidi.SetReorderingMode(IBM.ICU.Text.Bidi.REORDER_DEFAULT - 1); if (rm != bidi.GetReorderingMode()) { Errln("setReorderingMode with bad argument #1 should have no effect"); } bidi.SetReorderingMode(9999); if (rm != bidi.GetReorderingMode()) { Errln("setReorderingMode with bad argument #2 should have no effect"); } /* Try a surrogate char */ bidi = new Bidi(); bidi.SetPara("\uD800\uDC00", IBM.ICU.Text.Bidi.RTL, null); if (bidi.GetDirection() != IBM.ICU.Text.Bidi.MIXED) { Errln("getDirection for 1st surrogate char should be MIXED"); } sbyte[] levels = new sbyte[] { 6, 5, 4 }; try { bidi.SetPara("abc", (sbyte)5, levels); Errln("setPara did not fail when called with bad levels"); } catch (ArgumentException e_8) { Logln("OK: Got exception for setPara(..., levels) as expected: " + e_8.Message); } Logln("\nExiting TestFailureRecovery\n"); }
private void DoMisc() { /* Miscellaneous tests to exercize less popular code paths */ Bidi bidi = new Bidi(120, 66), bidiLine; AssertEquals("\nwriteReverse should return an empty string", "", IBM.ICU.Text.Bidi.WriteReverse("", 0)); bidi.SetPara("", IBM.ICU.Text.Bidi.LTR, null); AssertEquals("\nwriteReordered should return an empty string", "", bidi.WriteReordered(0)); bidi.SetPara("abc", IBM.ICU.Text.Bidi.LTR, null); AssertEquals("\ngetRunStart should return 0", 0, bidi.GetRunStart(0)); AssertEquals("\ngetRunLimit should return 3", 3, bidi.GetRunLimit(0)); bidi.SetPara("abc ", IBM.ICU.Text.Bidi.RTL, null); bidiLine = bidi.SetLine(0, 6); for (int i = 3; i < 6; i++) { AssertEquals("\nTrailing space at " + i + " should get paragraph level", IBM.ICU.Text.Bidi.RTL, bidiLine.GetLevelAt(i)); } bidi.SetPara("abc def", IBM.ICU.Text.Bidi.RTL, null); bidiLine = bidi.SetLine(0, 6); for (int i_0 = 3; i_0 < 6; i_0++) { AssertEquals("\nTrailing space at " + i_0 + " should get paragraph level", IBM.ICU.Text.Bidi.RTL, bidiLine.GetLevelAt(i_0)); } bidi.SetPara("abcdefghi ", IBM.ICU.Text.Bidi.RTL, null); bidiLine = bidi.SetLine(0, 6); for (int i_1 = 3; i_1 < 6; i_1++) { AssertEquals("\nTrailing char at " + i_1 + " should get level 2", 2, bidiLine.GetLevelAt(i_1)); } bidi.SetReorderingOptions(IBM.ICU.Text.Bidi.OPTION_REMOVE_CONTROLS); bidi.SetPara("\u200eabc def", IBM.ICU.Text.Bidi.RTL, null); bidiLine = bidi.SetLine(0, 6); AssertEquals("\nWrong result length", 5, bidiLine.GetResultLength()); bidi.SetPara("abcdefghi", IBM.ICU.Text.Bidi.LTR, null); bidiLine = bidi.SetLine(0, 6); AssertEquals("\nWrong direction #1", IBM.ICU.Text.Bidi.LTR, bidiLine.GetDirection()); bidi.SetPara("", IBM.ICU.Text.Bidi.LTR, null); sbyte[] levels = bidi.GetLevels(); AssertEquals("\nWrong number of level elements", 0, levels.Length); AssertEquals("\nWrong number of runs #1", 0, bidi.CountRuns()); bidi.SetPara(" ", IBM.ICU.Text.Bidi.RTL, null); bidiLine = bidi.SetLine(0, 6); AssertEquals("\nWrong number of runs #2", 1, bidiLine.CountRuns()); bidi.SetPara("a\u05d0 bc", IBM.ICU.Text.Bidi.RTL, null); bidiLine = bidi.SetLine(0, 6); AssertEquals("\nWrong direction #2", IBM.ICU.Text.Bidi.MIXED, bidi.GetDirection()); AssertEquals("\nWrong direction #3", IBM.ICU.Text.Bidi.MIXED, bidiLine.GetDirection()); AssertEquals("\nWrong number of runs #3", 2, bidiLine.CountRuns()); int[] map = IBM.ICU.Text.Bidi.ReorderLogical(null); AssertTrue("\nWe should have got a null map #1", map == null); map = IBM.ICU.Text.Bidi.ReorderLogical(new sbyte[] { 0, 99, 99 }); AssertTrue("\nWe should have got a null map #2", map == null); map = IBM.ICU.Text.Bidi.ReorderVisual(null); AssertTrue("\nWe should have got a null map #3", map == null); map = IBM.ICU.Text.Bidi.InvertMap(null); AssertTrue("\nWe should have got a null map #4", map == null); map = IBM.ICU.Text.Bidi.InvertMap(new int[] { 0, 1, -1, 5, 4 }); AssertTrue("\nUnexpected inverted Map", ILOG.J2CsMapping.Collections.Arrays.Equals(map, new int[] { 0, 1, -1, -1, 4, 3 })); bidi.SetPara("", IBM.ICU.Text.Bidi.LTR, null); map = bidi.GetLogicalMap(); AssertTrue("\nMap should have length==0 #1", map.Length == 0); map = bidi.GetVisualMap(); AssertTrue("\nMap should have length==0 #2", map.Length == 0); /* test BidiRun.toString and allocation of run memory > 1 */ bidi.SetPara("abc", IBM.ICU.Text.Bidi.LTR, null); AssertEquals("\nWrong run display", "BidiRun 0 - 3 @ 0", bidi .GetLogicalRun(0).ToString()); /* test REMOVE_BIDI_CONTROLS together with DO_MIRRORING */ bidi.SetPara("abc\u200e", IBM.ICU.Text.Bidi.LTR, null); String xout = bidi.WriteReordered(IBM.ICU.Text.Bidi.REMOVE_BIDI_CONTROLS | IBM.ICU.Text.Bidi.DO_MIRRORING); AssertEquals("\nWrong result #1", "abc", xout); /* test inverse Bidi with marks and contextual orientation */ bidi.SetReorderingMode(IBM.ICU.Text.Bidi.REORDER_INVERSE_LIKE_DIRECT); bidi.SetReorderingOptions(IBM.ICU.Text.Bidi.OPTION_INSERT_MARKS); bidi.SetPara("", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #2", "", xout); bidi.SetPara(" ", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #3", " ", xout); bidi.SetPara("abc", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #4", "abc", xout); bidi.SetPara("\u05d0\u05d1", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #5", "\u05d1\u05d0", xout); bidi.SetPara("abc \u05d0\u05d1", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #6", "\u05d1\u05d0 abc", xout); bidi.SetPara("\u05d0\u05d1 abc", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #7", "\u200fabc \u05d1\u05d0", xout); bidi.SetPara("\u05d0\u05d1 abc .-=", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #8", "\u200f=-. abc \u05d1\u05d0", xout); bidi.OrderParagraphsLTR(true); bidi.SetPara("\n\r \n\rabc\n\u05d0\u05d1\rabc \u05d2\u05d3\n\r" + "\u05d4\u05d5 abc\n\u05d6\u05d7 abc .-=\r\n" + "-* \u05d8\u05d9 abc .-=", IBM.ICU.Text.Bidi.LEVEL_DEFAULT_RTL, null); xout = bidi.WriteReordered(0); AssertEquals( "\nWrong result #9", "\n\r \n\rabc\n\u05d1\u05d0\r\u05d3\u05d2 abc\n\r" + "\u200fabc \u05d5\u05d4\n\u200f=-. abc \u05d7\u05d6\r\n" + "\u200f=-. abc \u05d9\u05d8 *-", xout); bidi.SetPara("\u05d0 \t", IBM.ICU.Text.Bidi.LTR, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #10", "\u05D0\u200e \t", xout); bidi.SetPara("\u05d0 123 \t\u05d1 123 \u05d2", IBM.ICU.Text.Bidi.LTR, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #11", "\u05d0 \u200e123\u200e \t\u05d2 123 \u05d1", xout); bidi.SetPara("\u05d0 123 \u0660\u0661 ab", IBM.ICU.Text.Bidi.LTR, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #12", "\u05d0 \u200e123 \u200e\u0660\u0661 ab", xout); bidi.SetPara("ab \t", IBM.ICU.Text.Bidi.RTL, null); xout = bidi.WriteReordered(0); AssertEquals("\nWrong result #13", "\u200f\t ab", xout); /* check exceeding para level */ bidi = new Bidi(); bidi.SetPara("A\u202a\u05d0\u202aC\u202c\u05d1\u202cE", (sbyte)(IBM.ICU.Text.Bidi.MAX_EXPLICIT_LEVEL - 1), null); AssertEquals("\nWrong level at index 2", 61, bidi.GetLevelAt(2)); /* check 1-char runs with RUNS_ONLY */ bidi.SetReorderingMode(IBM.ICU.Text.Bidi.REORDER_RUNS_ONLY); bidi.SetPara("a \u05d0 b \u05d1 c \u05d2 d ", IBM.ICU.Text.Bidi.LTR, null); AssertEquals("\nWrong number of runs #4", 14, bidi.CountRuns()); }
private void _testReordering(Bidi bidi, int testNumber) { int[] logicalMap1; int[] logicalMap2; int[] logicalMap3; int[] visualMap1; int[] visualMap2; int[] visualMap3; int[] visualMap4 = new int[MAXLEN]; sbyte[] levels; int i, length = bidi.GetLength(), destLength = bidi.GetResultLength(); int runCount, visualIndex, logicalIndex = -1, logicalStart, runLength; bool odd; if (length <= 0) { return; } /* get the logical and visual maps from the object */ logicalMap1 = bidi.GetLogicalMap(); if (logicalMap1 == null) { Errln("getLogicalMap in test " + testNumber + " is null"); logicalMap1 = new int[0]; } visualMap1 = bidi.GetVisualMap(); if (visualMap1 == null) { Errln("getVisualMap() in test " + testNumber + " is null"); visualMap1 = new int[0]; } /* invert them both */ visualMap2 = IBM.ICU.Text.Bidi.InvertMap(logicalMap1); logicalMap2 = IBM.ICU.Text.Bidi.InvertMap(visualMap1); /* get them from the levels array, too */ levels = bidi.GetLevels(); if (levels == null || levels.Length != length) { Errln("getLevels() in test " + testNumber + " failed"); } logicalMap3 = IBM.ICU.Text.Bidi.ReorderLogical(levels); visualMap3 = IBM.ICU.Text.Bidi.ReorderVisual(levels); /* get the visual map from the runs, too */ try { runCount = bidi.CountRuns(); } catch (InvalidOperationException e) { Errln("countRuns() in test " + testNumber + " failed"); runCount = 0; } Logln("\n---- " + runCount + " runs"); visualIndex = 0; BidiRun run; for (i = 0; i < runCount; ++i) { run = bidi.GetVisualRun(i); if (run == null) { Errln("null visual run encountered at index " + i + ", in test " + testNumber); continue; } odd = run.IsOddRun(); logicalStart = run.GetStart(); runLength = run.GetLength(); Log("(" + ((run.IsOddRun()) ? "R" : "L")); Log(" @" + run.GetStart() + '[' + run.GetLength() + "])\n"); if (!odd) { do /* LTR */ { visualMap4[visualIndex++] = logicalStart++; } while (--runLength > 0); } else { logicalStart += runLength; /* logicalLimit */ do /* RTL */ { visualMap4[visualIndex++] = --logicalStart; } while (--runLength > 0); } } Log("\n"); /* print all the maps */ Logln("logical maps:"); for (i = 0; i < length; ++i) { Log(logicalMap1[i] + " "); } Log("\n"); for (i = 0; i < length; ++i) { Log(logicalMap2[i] + " "); } Log("\n"); for (i = 0; i < length; ++i) { Log(logicalMap3[i] + " "); } Log("\nvisual maps:\n"); for (i = 0; i < destLength; ++i) { Log(visualMap1[i] + " "); } Log("\n"); for (i = 0; i < destLength; ++i) { Log(visualMap2[i] + " "); } Log("\n"); for (i = 0; i < length; ++i) { Log(visualMap3[i] + " "); } Log("\n"); for (i = 0; i < length; ++i) { Log(visualMap4[i] + " "); } Log("\n"); /* * check that the indexes are the same between these and * Bidi.getLogical/VisualIndex() */ for (i = 0; i < length; ++i) { if (logicalMap1[i] != logicalMap2[i]) { Errln("Error in tests[" + testNumber + "]: (logicalMap1[" + i + "] == " + logicalMap1[i] + ") != (logicalMap2[" + i + "] == " + logicalMap2[i] + ")"); } if (logicalMap1[i] != logicalMap3[i]) { Errln("Error in tests[" + testNumber + "]: (logicalMap1[" + i + "] == " + logicalMap1[i] + ") != (logicalMap3[" + i + "] == " + logicalMap3[i] + ")"); } if (visualMap1[i] != visualMap2[i]) { Errln("Error in tests[" + testNumber + "]: (visualMap1[" + i + "] == " + visualMap1[i] + ") != (visualMap2[" + i + "] == " + visualMap2[i] + ")"); } if (visualMap1[i] != visualMap3[i]) { Errln("Error in tests[" + testNumber + "]: (visualMap1[" + i + "] == " + visualMap1[i] + ") != (visualMap3[" + i + "] == " + visualMap3[i] + ")"); } if (visualMap1[i] != visualMap4[i]) { Errln("Error in tests[" + testNumber + "]: (visualMap1[" + i + "] == " + visualMap1[i] + ") != (visualMap4[" + i + "] == " + visualMap4[i] + ")"); } try { visualIndex = bidi.GetVisualIndex(i); } catch (Exception e_0) { Errln("Bidi.getVisualIndex(" + i + ") failed in tests[" + testNumber + "]"); } if (logicalMap1[i] != visualIndex) { Errln("Error in tests[" + testNumber + "]: (logicalMap1[" + i + "] == " + logicalMap1[i] + ") != (Bidi.getVisualIndex(" + i + ") == " + visualIndex + ")"); } try { logicalIndex = bidi.GetLogicalIndex(i); } catch (Exception e_1) { Errln("Bidi.getLogicalIndex(" + i + ") failed in tests[" + testNumber + "]"); } if (visualMap1[i] != logicalIndex) { Errln("Error in tests[" + testNumber + "]: (visualMap1[" + i + "] == " + visualMap1[i] + ") != (Bidi.getLogicalIndex(" + i + ") == " + logicalIndex + ")"); } } }
private void DoTest(Bidi bidi, int testNumber, TestData test, int lineStart, bool countRunsFirst) { short[] dirProps = test.dirProps; byte[] levels = test.levels; int[] visualMap = test.visualMap; int i, len = bidi.GetLength(), logicalIndex = -1, runCount = 0; sbyte level, level2; if (countRunsFirst) { Logln("Calling Bidi.countRuns() first."); try { runCount = bidi.CountRuns(); } catch (InvalidOperationException e) { Errln("Bidi.countRuns(test[" + testNumber + "]) failed"); } } else { Logln("Calling Bidi.getLogicalMap() first."); } _testReordering(bidi, testNumber); for (i = 0; i < len; ++i) { Logln(i + " " + bidi.GetLevelAt(i) + " " + levelString + IBM.ICU.Charset.TestData.dirPropNames[dirProps[lineStart + i]] + " " + bidi.GetVisualIndex(i)); } Log("\n-----levels:"); for (i = 0; i < len; ++i) { if (i > 0) { Log(","); } Log(" " + bidi.GetLevelAt(i)); } Log("\n--reordered:"); for (i = 0; i < len; ++i) { if (i > 0) { Log(","); } Log(" " + bidi.GetVisualIndex(i)); } Log("\n"); AssertEquals( "\nFailure in Bidi.getDirection(test[" + testNumber + "])", test.direction, bidi.GetDirection()); AssertEquals( "\nFailure in Bidi.getParaLevel(test[" + testNumber + "])", test.resultLevel, bidi.GetParaLevel()); for (i = 0; i < len; ++i) { AssertEquals("\nFailure in Bidi.getLevelAt(" + i + ") in test[" + testNumber + "]", levels[i], bidi.GetLevelAt(i)); } for (i = 0; i < len; ++i) { try { logicalIndex = bidi.GetVisualIndex(i); } catch (Exception th) { Errln("Bidi.getVisualIndex(" + i + ") in test[" + testNumber + "] failed"); } if (visualMap[i] != logicalIndex) { AssertEquals("\nFailure in Bidi.getVisualIndex(" + i + ") in test[" + testNumber + "])", visualMap[i], logicalIndex); } } if (!countRunsFirst) { try { runCount = bidi.CountRuns(); } catch (InvalidOperationException e_0) { Errln("Bidi.countRuns(test[" + testNumber + "]) failed"); } } BidiRun run; for (logicalIndex = 0; logicalIndex < len;) { level = bidi.GetLevelAt(logicalIndex); run = bidi.GetLogicalRun(logicalIndex); logicalIndex = run.GetLimit(); level2 = run.GetEmbeddingLevel(); AssertEquals("Logical " + run.ToString() + " in test[" + testNumber + "]: wrong level", level, level2); if (--runCount < 0) { Errln("Bidi.getLogicalRun(test[" + testNumber + "]): wrong number of runs compared to Bidi.countRuns() = " + bidi.CountRuns()); } } if (runCount != 0) { Errln("Bidi.getLogicalRun(test[" + testNumber + "]): wrong number of runs compared to Bidi.countRuns() = " + bidi.CountRuns()); } Log("\n\n"); }
static internal String WriteReordered(Bidi bidi, int options) { int run, runCount; StringBuilder dest; char[] text = bidi.text; runCount = bidi.CountRuns(); /* * Option "insert marks" implies Bidi.INSERT_LRM_FOR_NUMERIC if the * reordering mode (checked below) is appropriate. */ if ((bidi.reorderingOptions & IBM.ICU.Text.Bidi.OPTION_INSERT_MARKS) != 0) { options |= IBM.ICU.Text.Bidi.INSERT_LRM_FOR_NUMERIC; options &= ~IBM.ICU.Text.Bidi.REMOVE_BIDI_CONTROLS; } /* * Option "remove controls" implies Bidi.REMOVE_BIDI_CONTROLS and * cancels Bidi.INSERT_LRM_FOR_NUMERIC. */ if ((bidi.reorderingOptions & IBM.ICU.Text.Bidi.OPTION_REMOVE_CONTROLS) != 0) { options |= IBM.ICU.Text.Bidi.REMOVE_BIDI_CONTROLS; options &= ~IBM.ICU.Text.Bidi.INSERT_LRM_FOR_NUMERIC; } /* * If we do not perform the "inverse Bidi" algorithm, then we don't need * to insert any LRMs, and don't need to test for it. */ if ((bidi.reorderingMode != IBM.ICU.Text.Bidi.REORDER_INVERSE_NUMBERS_AS_L) && (bidi.reorderingMode != IBM.ICU.Text.Bidi.REORDER_INVERSE_LIKE_DIRECT) && (bidi.reorderingMode != IBM.ICU.Text.Bidi.REORDER_INVERSE_FOR_NUMBERS_SPECIAL) && (bidi.reorderingMode != IBM.ICU.Text.Bidi.REORDER_RUNS_ONLY)) { options &= ~IBM.ICU.Text.Bidi.INSERT_LRM_FOR_NUMERIC; } dest = new StringBuilder( ((options & IBM.ICU.Text.Bidi.INSERT_LRM_FOR_NUMERIC) != 0) ? bidi.length * 2 : bidi.length); /* * Iterate through all visual runs and copy the run text segments to the * destination, according to the options. * * The tests for where to insert LRMs ignore the fact that there may be * BN codes or non-BMP code points at the beginning and end of a run; * they may insert LRMs unnecessarily but the tests are faster this way * (this would have to be improved for UTF-8). */ if ((options & IBM.ICU.Text.Bidi.OUTPUT_REVERSE) == 0) { /* forward output */ if ((options & IBM.ICU.Text.Bidi.INSERT_LRM_FOR_NUMERIC) == 0) { /* do not insert Bidi controls */ for (run = 0; run < runCount; ++run) { BidiRun bidiRun = bidi.GetVisualRun(run); if (bidiRun.IsEvenRun()) { dest.Append(DoWriteForward(text, bidiRun.start, bidiRun.limit, options & ~IBM.ICU.Text.Bidi.DO_MIRRORING)); } else { dest.Append(DoWriteReverse(text, bidiRun.start, bidiRun.limit, options)); } } } else { /* insert Bidi controls for "inverse Bidi" */ sbyte[] dirProps = bidi.dirProps; char uc; int markFlag; for (run = 0; run < runCount; ++run) { BidiRun bidiRun_0 = bidi.GetVisualRun(run); markFlag = 0; /* check if something relevant in insertPoints */ markFlag = bidi.runs[run].insertRemove; if (markFlag < 0) /* bidi controls count */ { markFlag = 0; } if (bidiRun_0.IsEvenRun()) { if (bidi.IsInverse() && dirProps[bidiRun_0.start] != IBM.ICU.Text.Bidi.L) { markFlag |= IBM.ICU.Text.Bidi.LRM_BEFORE; } if ((markFlag & IBM.ICU.Text.Bidi.LRM_BEFORE) != 0) { uc = LRM_CHAR; } else if ((markFlag & IBM.ICU.Text.Bidi.RLM_BEFORE) != 0) { uc = RLM_CHAR; } else { uc = ((Char)0); } if (uc != 0) { dest.Append(uc); } dest.Append(DoWriteForward(text, bidiRun_0.start, bidiRun_0.limit, options & ~IBM.ICU.Text.Bidi.DO_MIRRORING)); if (bidi.IsInverse() && dirProps[bidiRun_0.limit - 1] != IBM.ICU.Text.Bidi.L) { markFlag |= IBM.ICU.Text.Bidi.LRM_AFTER; } if ((markFlag & IBM.ICU.Text.Bidi.LRM_AFTER) != 0) { uc = LRM_CHAR; } else if ((markFlag & IBM.ICU.Text.Bidi.RLM_AFTER) != 0) { uc = RLM_CHAR; } else { uc = ((Char)0); } if (uc != 0) { dest.Append(uc); } } else /* RTL run */ { if (bidi.IsInverse() && !bidi.TestDirPropFlagAt(MASK_R_AL, bidiRun_0.limit - 1)) { markFlag |= IBM.ICU.Text.Bidi.RLM_BEFORE; } if ((markFlag & IBM.ICU.Text.Bidi.LRM_BEFORE) != 0) { uc = LRM_CHAR; } else if ((markFlag & IBM.ICU.Text.Bidi.RLM_BEFORE) != 0) { uc = RLM_CHAR; } else { uc = ((Char)0); } if (uc != 0) { dest.Append(uc); } dest.Append(DoWriteReverse(text, bidiRun_0.start, bidiRun_0.limit, options)); if (bidi.IsInverse() && (MASK_R_AL & IBM.ICU.Text.Bidi .DirPropFlag(dirProps[bidiRun_0.start])) == 0) { markFlag |= IBM.ICU.Text.Bidi.RLM_AFTER; } if ((markFlag & IBM.ICU.Text.Bidi.LRM_AFTER) != 0) { uc = LRM_CHAR; } else if ((markFlag & IBM.ICU.Text.Bidi.RLM_AFTER) != 0) { uc = RLM_CHAR; } else { uc = ((Char)0); } if (uc != 0) { dest.Append(uc); } } } } } else { /* reverse output */ if ((options & IBM.ICU.Text.Bidi.INSERT_LRM_FOR_NUMERIC) == 0) { /* do not insert Bidi controls */ for (run = runCount; --run >= 0;) { BidiRun bidiRun_1 = bidi.GetVisualRun(run); if (bidiRun_1.IsEvenRun()) { dest.Append(DoWriteReverse(text, bidiRun_1.start, bidiRun_1.limit, options & ~IBM.ICU.Text.Bidi.DO_MIRRORING)); } else { dest.Append(DoWriteForward(text, bidiRun_1.start, bidiRun_1.limit, options)); } } } else { /* insert Bidi controls for "inverse Bidi" */ sbyte[] dirProps_2 = bidi.dirProps; for (run = runCount; --run >= 0;) { /* reverse output */ BidiRun bidiRun_3 = bidi.GetVisualRun(run); if (bidiRun_3.IsEvenRun()) { if (dirProps_2[bidiRun_3.limit - 1] != IBM.ICU.Text.Bidi.L) { dest.Append(LRM_CHAR); } dest.Append(DoWriteReverse(text, bidiRun_3.start, bidiRun_3.limit, options & ~IBM.ICU.Text.Bidi.DO_MIRRORING)); if (dirProps_2[bidiRun_3.start] != IBM.ICU.Text.Bidi.L) { dest.Append(LRM_CHAR); } } else { if ((MASK_R_AL & IBM.ICU.Text.Bidi .DirPropFlag(dirProps_2[bidiRun_3.start])) == 0) { dest.Append(RLM_CHAR); } dest.Append(DoWriteForward(text, bidiRun_3.start, bidiRun_3.limit, options)); if ((MASK_R_AL & IBM.ICU.Text.Bidi .DirPropFlag(dirProps_2[bidiRun_3.limit - 1])) == 0) { dest.Append(RLM_CHAR); } } } } } return(dest.ToString()); }