diff --git a/Terminal.Gui/Text/TextFormatter.cs b/Terminal.Gui/Text/TextFormatter.cs index db13b5930..a9956ca51 100644 --- a/Terminal.Gui/Text/TextFormatter.cs +++ b/Terminal.Gui/Text/TextFormatter.cs @@ -287,13 +287,13 @@ public class TextFormatter Rune [] runes = linesFormatted [line].ToRunes (); runes = Direction switch - { - TextDirection.RightLeft_BottomTop => runes.Reverse ().ToArray (), - TextDirection.RightLeft_TopBottom => runes.Reverse ().ToArray (), - TextDirection.BottomTop_LeftRight => runes.Reverse ().ToArray (), - TextDirection.BottomTop_RightLeft => runes.Reverse ().ToArray (), - _ => runes - }; + { + TextDirection.RightLeft_BottomTop => runes.Reverse ().ToArray (), + TextDirection.RightLeft_TopBottom => runes.Reverse ().ToArray (), + TextDirection.BottomTop_LeftRight => runes.Reverse ().ToArray (), + TextDirection.BottomTop_RightLeft => runes.Reverse ().ToArray (), + _ => runes + }; // When text is justified, we lost left or right, so we use the direction to align. @@ -304,7 +304,7 @@ public class TextFormatter { if (isVertical) { - int runesWidth = GetWidestLineLength (linesFormatted, line, TabWidth); + int runesWidth = GetColumnsRequiredForVerticalText (linesFormatted, tabWidth: TabWidth); x = screen.Right - runesWidth; CursorPosition = screen.Width - runesWidth + (_hotKeyPos > -1 ? _hotKeyPos : 0); } @@ -320,7 +320,7 @@ public class TextFormatter if (isVertical) { int runesWidth = line > 0 - ? GetWidestLineLength (linesFormatted, 0, line, TabWidth) + ? GetColumnsRequiredForVerticalText (linesFormatted, TabWidth) : 0; x = screen.Left + runesWidth; } @@ -335,7 +335,7 @@ public class TextFormatter { if (isVertical) { - int runesWidth = GetWidestLineLength (linesFormatted, line, TabWidth); + int runesWidth = GetColumnsRequiredForVerticalText (linesFormatted, TabWidth); x = screen.Left + line + (screen.Width - runesWidth) / 2; CursorPosition = (screen.Width - runesWidth) / 2 + (_hotKeyPos > -1 ? _hotKeyPos : 0); @@ -700,48 +700,48 @@ public class TextFormatter public static bool IsHorizontalDirection (TextDirection textDirection) { return textDirection switch - { - TextDirection.LeftRight_TopBottom => true, - TextDirection.LeftRight_BottomTop => true, - TextDirection.RightLeft_TopBottom => true, - TextDirection.RightLeft_BottomTop => true, - _ => false - }; + { + TextDirection.LeftRight_TopBottom => true, + TextDirection.LeftRight_BottomTop => true, + TextDirection.RightLeft_TopBottom => true, + TextDirection.RightLeft_BottomTop => true, + _ => false + }; } /// Check if it is a vertical direction public static bool IsVerticalDirection (TextDirection textDirection) { return textDirection switch - { - TextDirection.TopBottom_LeftRight => true, - TextDirection.TopBottom_RightLeft => true, - TextDirection.BottomTop_LeftRight => true, - TextDirection.BottomTop_RightLeft => true, - _ => false - }; + { + TextDirection.TopBottom_LeftRight => true, + TextDirection.TopBottom_RightLeft => true, + TextDirection.BottomTop_LeftRight => true, + TextDirection.BottomTop_RightLeft => true, + _ => false + }; } /// Check if it is Left to Right direction public static bool IsLeftToRight (TextDirection textDirection) { return textDirection switch - { - TextDirection.LeftRight_TopBottom => true, - TextDirection.LeftRight_BottomTop => true, - _ => false - }; + { + TextDirection.LeftRight_TopBottom => true, + TextDirection.LeftRight_BottomTop => true, + _ => false + }; } /// Check if it is Top to Bottom direction public static bool IsTopToBottom (TextDirection textDirection) { return textDirection switch - { - TextDirection.TopBottom_LeftRight => true, - TextDirection.TopBottom_RightLeft => true, - _ => false - }; + { + TextDirection.TopBottom_LeftRight => true, + TextDirection.TopBottom_RightLeft => true, + _ => false + }; } // TODO: Move to StringExtensions? @@ -1122,21 +1122,21 @@ public class TextFormatter case ' ': return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length); case '\t': - { - length += tabWidth + 1; - - if (length == tabWidth && tabWidth > cWidth) { - return to + 1; - } + length += tabWidth + 1; - if (length > cWidth && tabWidth > cWidth) - { - return to; - } + if (length == tabWidth && tabWidth > cWidth) + { + return to + 1; + } - return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length); - } + if (length > cWidth && tabWidth > cWidth) + { + return to; + } + + return GetNextWhiteSpace (to + 1, cWidth, out incomplete, length); + } default: to++; @@ -1145,11 +1145,11 @@ public class TextFormatter } return cLength switch - { - > 0 when to < runes.Count && runes [to].Value != ' ' && runes [to].Value != '\t' => from, - > 0 when to < runes.Count && (runes [to].Value == ' ' || runes [to].Value == '\t') => from, - _ => to - }; + { + > 0 when to < runes.Count && runes [to].Value != ' ' && runes [to].Value != '\t' => from, + > 0 when to < runes.Count && (runes [to].Value == ' ' || runes [to].Value == '\t') => from, + _ => to + }; } if (start < text.GetRuneCount ()) @@ -1580,29 +1580,28 @@ public class TextFormatter } /// - /// Returns the number of columns in the widest line in the list based on the and - /// the . + /// Returns the number of columns required to render oriented vertically. /// /// /// This API will return incorrect results if the text includes glyphs who's width is dependent on surrounding /// glyphs (e.g. Arabic). /// /// The lines. - /// The start index. - /// The length. + /// The line in the list to start with (any lines before will be ignored). + /// The number of lines to process (if less than lines.Count, any lines after will be ignored). /// The number of columns used for a tab. - /// The maximum characters width. - public static int GetWidestLineLength ( + /// The width required. + public static int GetColumnsRequiredForVerticalText ( List lines, - int startIndex = -1, - int length = -1, + int startLine = -1, + int linesCount = -1, int tabWidth = 0 ) { var max = 0; - for (int i = startIndex == -1 ? 0 : startIndex; - i < (length == -1 ? lines.Count : startIndex + length); + for (int i = startLine == -1 ? 0 : startLine; + i < (linesCount == -1 ? lines.Count : startLine + linesCount); i++) { string runes = lines [i]; diff --git a/Terminal.Gui/View/ViewText.cs b/Terminal.Gui/View/ViewText.cs index 96c33e56e..eb98e8e13 100644 --- a/Terminal.Gui/View/ViewText.cs +++ b/Terminal.Gui/View/ViewText.cs @@ -334,7 +334,7 @@ public partial class View switch (TextFormatter.IsVerticalDirection (TextDirection)) { case true: - int colWidth = TextFormatter.GetWidestLineLength (new List { TextFormatter.Text }, 0, 1); + int colWidth = TextFormatter.GetColumnsRequiredForVerticalText (new List { TextFormatter.Text }, 0, 1); // TODO: v2 - This uses frame.Width; it should only use Viewport if (_frame.Width < colWidth diff --git a/UnitTests/Text/TextFormatterTests.cs b/UnitTests/Text/TextFormatterTests.cs index 6f16a2215..afc3a956d 100644 --- a/UnitTests/Text/TextFormatterTests.cs +++ b/UnitTests/Text/TextFormatterTests.cs @@ -1,5 +1,6 @@ using System.Text; using Xunit.Abstractions; +using static Terminal.Gui.SpinnerStyle; // Alias Console to MockConsole so we don't accidentally use Console @@ -961,30 +962,43 @@ ssb Assert.Equal (1, TextFormatter.GetMaxColsForWidth (text, 1)); } + [Theory] + [InlineData (new [] { "0123456789" }, 1)] + [InlineData (new [] { "Hello World" }, 1)] + [InlineData (new [] { "Hello", "World" }, 2)] + [InlineData (new [] { "こんにちは", "世界" }, 4)] + public void GetColumnsRequiredForVerticalText_List_GetsWidth (IEnumerable text, int expectedWidth) + { + Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ())); + + } + + [Theory] + [InlineData (new [] { "Hello World" }, 1, 0, 1, 1)] [InlineData (new [] { "Hello", "World" }, 2, 1, 1, 1)] [InlineData (new [] { "こんにちは", "世界" }, 4, 1, 1, 2)] - public void GetWidestLineLength_List_Simple_And_Wide_Runes ( + public void GetColumnsRequiredForVerticalText_List_Simple_And_Wide_Runes ( IEnumerable text, - int width, + int expectedWidth, int index, int length, - int indexWidth + int expectedIndexWidth ) { - Assert.Equal (width, TextFormatter.GetWidestLineLength (text.ToList ())); - Assert.Equal (indexWidth, TextFormatter.GetWidestLineLength (text.ToList (), index, length)); + Assert.Equal (expectedWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList ())); + Assert.Equal (expectedIndexWidth, TextFormatter.GetColumnsRequiredForVerticalText (text.ToList (), index, length)); } [Fact] - public void GetWidestLineLength_List_With_Combining_Runes () + public void GetColumnsRequiredForVerticalText_List_With_Combining_Runes () { List text = new () { "Les Mis", "e\u0328\u0301", "rables" }; - Assert.Equal (1, TextFormatter.GetWidestLineLength (text, 1, 1)); + Assert.Equal (1, TextFormatter.GetColumnsRequiredForVerticalText (text, 1, 1)); } [Fact] - public void GetWidestLineLength_With_Combining_Runes () + public void GetColumnsRequiredForVerticalText_With_Combining_Runes () { var text = "Les Mise\u0328\u0301rables"; Assert.Equal (1, TextFormatter.GetWidestLineLength (text, 1, 1));