Improved text rendering (space corner cases)

This commit is contained in:
Marcin Ziąbek 2021-09-07 13:16:34 +02:00
Родитель 8ada092531
Коммит 99f004dd85
5 изменённых файлов: 29 добавлений и 10 удалений

Просмотреть файл

@ -18,7 +18,7 @@
<ItemGroup>
<None Update="quo-vadis.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

Просмотреть файл

@ -93,7 +93,7 @@ namespace QuestPDF.Examples
var lineFrom = chapterPointers[index];
var lineTo = chapterPointers[index + 1] - 1;
var lines = book.Skip(lineFrom + 1).Take(lineTo - lineFrom);
var lines = book.Skip(lineFrom + 1).Take(lineTo - lineFrom).Where(x => !string.IsNullOrWhiteSpace(x));
var content = string.Join(Environment.NewLine, lines);
yield return new BookChapter
@ -158,7 +158,7 @@ namespace QuestPDF.Examples
{
stack.Item().InternalLink(chapter.Title).Row(row =>
{
row.RelativeColumn().Text(chapter.Title);
row.RelativeColumn().Text(chapter.Title, normalStyle);
row.ConstantColumn(100).AlignRight().Text(text => text.PageNumberOfLocation(chapter.Title, normalStyle));
});
}

Просмотреть файл

@ -14,6 +14,7 @@ namespace QuestPDF.Elements.Text.Calculation
public int StartIndex { get; set; }
public int EndIndex { get; set; }
public int NextIndex { get; set; }
public int TotalIndex { get; set; }
public bool IsLast => EndIndex == TotalIndex;

Просмотреть файл

@ -26,19 +26,30 @@ namespace QuestPDF.Elements.Text.Items
internal TextMeasurementResult? MeasureWithoutCache(TextMeasurementRequest request)
{
const char space = ' ';
var paint = Style.ToPaint();
var fontMetrics = Style.ToFontMetrics();
var startIndex = request.StartIndex;
while (startIndex + 1 < Text.Length && Text[startIndex] == space)
startIndex++;
if (Text.Length == 0)
{
return new TextMeasurementResult
{
Width = request.AvailableWidth
Width = 0,
LineHeight = Style.LineHeight,
Ascent = fontMetrics.Ascent,
Descent = fontMetrics.Descent
};
}
// start breaking text from requested position
var text = Text.Substring(request.StartIndex);
var text = Text.Substring(startIndex);
var breakingIndex = (int)paint.BreakText(text, request.AvailableWidth);
@ -48,7 +59,7 @@ namespace QuestPDF.Elements.Text.Items
// break text only on spaces
if (breakingIndex < text.Length)
{
var lastSpaceIndex = text.Substring(0, breakingIndex).LastIndexOf(" ");
var lastSpaceIndex = text.Substring(0, breakingIndex).LastIndexOf(space) - 1;
if (lastSpaceIndex <= 0)
{
@ -62,6 +73,12 @@ namespace QuestPDF.Elements.Text.Items
}
text = text.Substring(0, breakingIndex);
var endIndex = startIndex + breakingIndex;
var nextIndex = endIndex;
while (nextIndex + 1 < Text.Length && Text[nextIndex] == space)
nextIndex++;
// measure final text
var width = paint.MeasureText(text);
@ -75,8 +92,9 @@ namespace QuestPDF.Elements.Text.Items
LineHeight = Style.LineHeight,
StartIndex = request.StartIndex,
EndIndex = request.StartIndex + breakingIndex,
StartIndex = startIndex,
EndIndex = endIndex,
NextIndex = nextIndex,
TotalIndex = Text.Length
};
}

Просмотреть файл

@ -112,7 +112,7 @@ namespace QuestPDF.Elements.Text
.ForEach(x => RenderingQueue.Dequeue());
var lastElementMeasurement = lines.Last().Elements.Last().Measurement;
CurrentElementIndex = lastElementMeasurement.IsLast ? 0 : (lastElementMeasurement.EndIndex + 1);
CurrentElementIndex = lastElementMeasurement.IsLast ? 0 : lastElementMeasurement.NextIndex;
if (!RenderingQueue.Any())
ResetState();
@ -173,7 +173,7 @@ namespace QuestPDF.Elements.Text
});
currentWidth += measurementResponse.Width;
currentItemIndex = measurementResponse.EndIndex;
currentItemIndex = measurementResponse.NextIndex;
if (!measurementResponse.IsLast)
break;