Browse Source

Improved text rendering (space corner cases)

Marcin Ziąbek 4 years ago
parent
commit
99f004dd85

+ 1 - 1
QuestPDF.Examples/QuestPDF.Examples.csproj

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

+ 2 - 2
QuestPDF.Examples/TextBenchmark.cs

@@ -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));
                         });
                     }

+ 1 - 0
QuestPDF/Elements/Text/Calculation/TextMeasurementResult.cs

@@ -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;

+ 23 - 5
QuestPDF/Elements/Text/Items/TextBlockSpan.cs

@@ -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
             };
         }

+ 2 - 2
QuestPDF/Elements/Text/TextBlock.cs

@@ -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;