public static int GetCellLength(RenderContext context, char rune) { if (context.LegacyConsole) { // Is it represented by a single byte? // In that case we don't have to calculate the // actual cell width. if (context.Encoding.GetByteCount(new[] { rune }) == 1) { return(1); } } // TODO: We need to figure out why Segment.SplitLines fails // if we let wcwidth (which returns -1 instead of 1) // calculate the size for new line characters. // That is correct from a Unicode perspective, but the // algorithm was written before wcwidth was added and used // to work with string length and not cell length. if (rune == '\n') { return(1); } return(UnicodeCalculator.GetWidth(rune)); }
public void Test_Favorite_Emoji() { // Given var length = "💩".Select(c => UnicodeCalculator.GetWidth(c)).Sum(); // Then length.ShouldBe(2); }
public void Test_Combining_Enclosing() { // Given const string phrase = "\u0410\u0488"; var expected = new[] { 1, 0 }; // When var length = phrase.Select(c => UnicodeCalculator.GetWidth(c)); // Then length.ShouldBe(expected); }
public void Test_Combining_Cafe_Width() { // Given const string phrase = "cafe\u0301"; var expected = new[] { 1, 1, 1, 1, 0 }; // When var length = phrase.Select(c => UnicodeCalculator.GetWidth(c)); // Then length.ShouldBe(expected); }
public void Test_Control_C0_Width() { // Given const string phrase = "\x1b[0m"; var expected = new[] { -1, 1, 1, 1 }; // When var length = phrase.Select(c => UnicodeCalculator.GetWidth(c)); // Then length.ShouldBe(expected); }
public void Test_Null_Width() { // Given const string phrase = "abc\x0000def"; var expected = new[] { 1, 1, 1, 0, 1, 1, 1 }; // When var length = phrase.Select(c => UnicodeCalculator.GetWidth(c)); // Then length.ShouldBe(expected); }
public void Test_Hello_Japanese() { // Given const string phrase = "コンニチハ, セカイ!"; var expected = new[] { 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 1 }; // When var length = phrase.Select(c => UnicodeCalculator.GetWidth(c)); // Then length.ShouldBe(expected); }
public void Test_Rune_Overload() { // Given var scalar = new Rune(0x1F32D); // 🌭 var expected = 2; // When var length = UnicodeCalculator.GetWidth(scalar); // Then length.ShouldBe(expected); }
public void Test_Int32_Overload() { // Given const int codePoint = 0x1F680; // 🚀 var expected = 2; // When var length = UnicodeCalculator.GetWidth(codePoint); // Then length.ShouldBe(expected); }
public void Test_Combining_Spacing() { // Given const string phrase = "\u1B13\u1B28\u1B2E\u1B44"; var expected = new[] { 1, 1, 1, 1 }; // When var length = phrase.Select(c => UnicodeCalculator.GetWidth(c)); // Then length.ShouldBe(expected); }
public static int GetCellLength(char rune) { // TODO: We need to figure out why Segment.SplitLines fails // if we let wcwidth (which returns -1 instead of 1) // calculate the size for new line characters. // That is correct from a Unicode perspective, but the // algorithm was written before wcwidth was added and used // to work with string length and not cell length. if (rune == '\n') { return(1); } return(UnicodeCalculator.GetWidth(rune)); }
public static int GetCellLength(RenderContext context, string text) { return(text.Sum(rune => { if (context.LegacyConsole) { // Is it represented by a single byte? // In that case we don't have to calculate the // actual cell width. if (context.Encoding.GetByteCount(new[] { rune }) == 1) { return 1; } } return UnicodeCalculator.GetWidth(rune); })); }