mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-06-19 13:28:16 +08:00
Fix rendering bug when splitting lines
The bug might occur if there are wide characters such as emojis at the end of a line. The SplitLines method mixed cell width and text length, which might give incorrect results. This commit makes sure that comparison and calculation is done using cell width where it's appropriate.
This commit is contained in:
@ -66,7 +66,7 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
var child = _child.Render(context, maxWidth - paddingWidth);
|
||||
foreach (var (_, _, _, line) in Segment.SplitLines(child).Enumerate())
|
||||
foreach (var (_, _, _, line) in Segment.SplitLines(context, child).Enumerate())
|
||||
{
|
||||
// Left padding
|
||||
if (Padding.Left != 0)
|
||||
@ -83,7 +83,7 @@ namespace Spectre.Console
|
||||
}
|
||||
|
||||
// Missing space on right side?
|
||||
var lineWidth = line.CellWidth(context);
|
||||
var lineWidth = line.CellCount(context);
|
||||
var diff = width - lineWidth - Padding.Left - Padding.Right;
|
||||
if (diff > 0)
|
||||
{
|
||||
|
@ -94,7 +94,7 @@ namespace Spectre.Console
|
||||
|
||||
// Split the child segments into lines.
|
||||
var childSegments = ((IRenderable)child).Render(context, childWidth);
|
||||
foreach (var line in Segment.SplitLines(childSegments, childWidth))
|
||||
foreach (var line in Segment.SplitLines(context, childSegments, childWidth))
|
||||
{
|
||||
if (line.Count == 1 && line[0].IsWhiteSpace)
|
||||
{
|
||||
@ -109,7 +109,7 @@ namespace Spectre.Console
|
||||
content.AddRange(line);
|
||||
|
||||
// Do we need to pad the panel?
|
||||
var length = line.Sum(segment => segment.CellLength(context));
|
||||
var length = line.Sum(segment => segment.CellCount(context));
|
||||
if (length < childWidth)
|
||||
{
|
||||
var diff = childWidth - length;
|
||||
@ -148,7 +148,7 @@ namespace Spectre.Console
|
||||
var headerWidth = panelWidth - (EdgeWidth * 2);
|
||||
var header = Segment.TruncateWithEllipsis(Header.Text, Header.Style ?? borderStyle, context, headerWidth);
|
||||
|
||||
var excessWidth = headerWidth - header.CellLength(context);
|
||||
var excessWidth = headerWidth - header.CellCount(context);
|
||||
if (excessWidth > 0)
|
||||
{
|
||||
switch (Header.Alignment ?? Justify.Left)
|
||||
|
@ -119,8 +119,8 @@ namespace Spectre.Console
|
||||
return new Measurement(0, 0);
|
||||
}
|
||||
|
||||
var min = _lines.Max(line => line.Max(segment => segment.CellLength(context)));
|
||||
var max = _lines.Max(x => x.CellWidth(context));
|
||||
var min = _lines.Max(line => line.Max(segment => segment.CellCount(context)));
|
||||
var max = _lines.Max(x => x.CellCount(context));
|
||||
|
||||
return new Measurement(min, Math.Min(max, maxWidth));
|
||||
}
|
||||
@ -187,7 +187,7 @@ namespace Spectre.Console
|
||||
return new List<SegmentLine>();
|
||||
}
|
||||
|
||||
if (_lines.Max(x => x.CellWidth(context)) <= maxWidth)
|
||||
if (_lines.Max(x => x.CellCount(context)) <= maxWidth)
|
||||
{
|
||||
return Clone();
|
||||
}
|
||||
@ -231,7 +231,7 @@ namespace Spectre.Console
|
||||
continue;
|
||||
}
|
||||
|
||||
var length = current.CellLength(context);
|
||||
var length = current.CellCount(context);
|
||||
if (length > maxWidth)
|
||||
{
|
||||
// The current segment is longer than the width of the console,
|
||||
@ -239,7 +239,7 @@ namespace Spectre.Console
|
||||
var segments = Segment.SplitOverflow(current, Overflow, context, maxWidth);
|
||||
if (segments.Count > 0)
|
||||
{
|
||||
if (line.CellWidth(context) + segments[0].CellLength(context) > maxWidth)
|
||||
if (line.CellCount(context) + segments[0].CellCount(context) > maxWidth)
|
||||
{
|
||||
lines.Add(line);
|
||||
line = new SegmentLine();
|
||||
@ -259,7 +259,7 @@ namespace Spectre.Console
|
||||
}
|
||||
else
|
||||
{
|
||||
if (line.CellWidth(context) + length > maxWidth)
|
||||
if (line.CellCount(context) + length > maxWidth)
|
||||
{
|
||||
line.Add(Segment.Empty);
|
||||
lines.Add(line);
|
||||
|
@ -52,7 +52,7 @@ namespace Spectre.Console
|
||||
|
||||
// Get the title and make sure it fits.
|
||||
var title = GetTitleSegments(context, Title, maxWidth - 6);
|
||||
if (Segment.CellLength(context, title) > maxWidth - 6)
|
||||
if (Segment.CellCount(context, title) > maxWidth - 6)
|
||||
{
|
||||
// Truncate the title
|
||||
title = Segment.TruncateWithEllipsis(title, context, maxWidth - 6);
|
||||
@ -88,13 +88,13 @@ namespace Spectre.Console
|
||||
{
|
||||
var alignment = Alignment ?? Justify.Center;
|
||||
|
||||
var titleLength = Segment.CellLength(context, title);
|
||||
var titleLength = Segment.CellCount(context, title);
|
||||
|
||||
if (alignment == Justify.Left)
|
||||
{
|
||||
var left = new Segment(new string('─', 2) + " ", Style ?? Style.Plain);
|
||||
|
||||
var rightLength = maxWidth - titleLength - left.CellLength(context) - 1;
|
||||
var rightLength = maxWidth - titleLength - left.CellCount(context) - 1;
|
||||
var right = new Segment(" " + new string('─', rightLength), Style ?? Style.Plain);
|
||||
|
||||
return (left, right);
|
||||
@ -104,7 +104,7 @@ namespace Spectre.Console
|
||||
var leftLength = ((maxWidth - titleLength) / 2) - 1;
|
||||
var left = new Segment(new string('─', leftLength) + " ", Style ?? Style.Plain);
|
||||
|
||||
var rightLength = maxWidth - titleLength - left.CellLength(context) - 1;
|
||||
var rightLength = maxWidth - titleLength - left.CellCount(context) - 1;
|
||||
var right = new Segment(" " + new string('─', rightLength), Style ?? Style.Plain);
|
||||
|
||||
return (left, right);
|
||||
@ -113,7 +113,7 @@ namespace Spectre.Console
|
||||
{
|
||||
var right = new Segment(" " + new string('─', 2), Style ?? Style.Plain);
|
||||
|
||||
var leftLength = maxWidth - titleLength - right.CellLength(context) - 1;
|
||||
var leftLength = maxWidth - titleLength - right.CellCount(context) - 1;
|
||||
var left = new Segment(new string('─', leftLength) + " ", Style ?? Style.Plain);
|
||||
|
||||
return (left, right);
|
||||
|
@ -217,7 +217,7 @@ namespace Spectre.Console
|
||||
var justification = _columns[columnIndex].Alignment;
|
||||
var childContext = context.WithJustification(justification);
|
||||
|
||||
var lines = Segment.SplitLines(cell.Render(childContext, rowWidth));
|
||||
var lines = Segment.SplitLines(context, cell.Render(childContext, rowWidth));
|
||||
cellHeight = Math.Max(cellHeight, lines.Count);
|
||||
cells.Add(lines);
|
||||
}
|
||||
@ -261,7 +261,7 @@ namespace Spectre.Console
|
||||
rowResult.AddRange(cell[cellRowIndex]);
|
||||
|
||||
// Pad cell content right
|
||||
var length = cell[cellRowIndex].Sum(segment => segment.CellLength(context));
|
||||
var length = cell[cellRowIndex].Sum(segment => segment.CellCount(context));
|
||||
if (length < columnWidths[cellIndex])
|
||||
{
|
||||
rowResult.Add(new Segment(new string(' ', columnWidths[cellIndex] - length)));
|
||||
@ -295,7 +295,7 @@ namespace Spectre.Console
|
||||
Aligner.Align(context, rowResult, Alignment, actualMaxWidth);
|
||||
|
||||
// Is the row larger than the allowed max width?
|
||||
if (Segment.CellLength(context, rowResult) > actualMaxWidth)
|
||||
if (Segment.CellCount(context, rowResult) > actualMaxWidth)
|
||||
{
|
||||
result.AddRange(Segment.Truncate(context, rowResult, actualMaxWidth));
|
||||
}
|
||||
|
Reference in New Issue
Block a user