Fix bug when splitting text containing CJK chars

In Segment.Split, we didn't take cell width into account
when calculating the offset, which resulted in some "fun" bugs.
I've added a new overload for Segment.Split and obsoleted the old one.

Closes #150
This commit is contained in:
Patrik Svensson
2020-12-16 23:30:03 +01:00
committed by Patrik Svensson
parent ee305702e8
commit 6932c95731
5 changed files with 125 additions and 29 deletions

View File

@ -8,32 +8,34 @@ namespace Spectre.Console.Internal
{
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 text.Sum(rune => GetCellLength(context, 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')
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;
}
}
return UnicodeCalculator.GetWidth(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);
}
}
}