Browse Source

Fixed text rendering corner case: measuring span with space at the end of the line may overflow available space

MarcinZiabek 3 years ago
parent
commit
fdf8e3eb1a

+ 25 - 0
QuestPDF.Examples/TextExamples.cs

@@ -267,5 +267,30 @@ namespace QuestPDF.Examples
                         });
                         });
                 });
                 });
         }
         }
+        
+        [Test]
+        public void MeasureIssueWhenSpaceAtLineEnd()
+        {
+            // issue 135
+            
+            RenderingTest
+                .Create()
+                .ProduceImages()
+                .ShowResults()
+                .RenderDocument(container =>
+                {
+                    container.Page(page =>
+                    {
+                        page.Margin(50);
+                        page.Background(Colors.White);
+
+                        page.Size(PageSizes.A4);
+
+                        page.Content().Text( 
+                            "This is a specially crafted sentence with a specially chosen length for demonstration of the bug that occurs ;;;;;. ",
+                            TextStyle.Default.Size(11));
+                    });
+                });
+        }
     }
     }
 }
 }

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

@@ -17,7 +17,7 @@ namespace QuestPDF.Elements.Text.Items
         public virtual TextMeasurementResult? Measure(TextMeasurementRequest request)
         public virtual TextMeasurementResult? Measure(TextMeasurementRequest request)
         {
         {
             var cacheKey = (request.StartIndex, request.AvailableWidth);
             var cacheKey = (request.StartIndex, request.AvailableWidth);
-            
+             
             if (!MeasureCache.ContainsKey(cacheKey))
             if (!MeasureCache.ContainsKey(cacheKey))
                 MeasureCache[cacheKey] = MeasureWithoutCache(request);
                 MeasureCache[cacheKey] = MeasureWithoutCache(request);
             
             
@@ -52,7 +52,7 @@ namespace QuestPDF.Elements.Text.Items
             }
             }
             
             
             // start breaking text from requested position
             // start breaking text from requested position
-            var text = Text.Substring(startIndex);
+            var text = Text.AsSpan().Slice(startIndex);
             
             
             var textLength = (int)paint.BreakText(text, request.AvailableWidth + Size.Epsilon);
             var textLength = (int)paint.BreakText(text, request.AvailableWidth + Size.Epsilon);
 
 
@@ -65,7 +65,7 @@ namespace QuestPDF.Elements.Text.Items
             // break text only on spaces
             // break text only on spaces
             if (textLength < text.Length)
             if (textLength < text.Length)
             {
             {
-                var lastSpaceIndex = text.Substring(0, textLength).LastIndexOf(space) - 1;
+                var lastSpaceIndex = text.Slice(0, textLength).LastIndexOf(space) - 1;
 
 
                 if (lastSpaceIndex <= 0)
                 if (lastSpaceIndex <= 0)
                 {
                 {
@@ -78,7 +78,7 @@ namespace QuestPDF.Elements.Text.Items
                 }
                 }
             }
             }
 
 
-            text = text.Substring(0, textLength);
+            text = text.Slice(0, textLength);
 
 
             var endIndex = startIndex + textLength;
             var endIndex = startIndex + textLength;
             var nextIndex = endIndex;
             var nextIndex = endIndex;
@@ -87,7 +87,8 @@ namespace QuestPDF.Elements.Text.Items
                 nextIndex++;
                 nextIndex++;
             
             
             // measure final text
             // measure final text
-            var width = paint.MeasureText(text);
+            var finalText = text.TrimEnd();
+            var width = paint.MeasureText(finalText);
             
             
             return new TextMeasurementResult
             return new TextMeasurementResult
             {
             {

+ 1 - 1
QuestPDF/QuestPDF.csproj

@@ -4,7 +4,7 @@
         <Authors>MarcinZiabek</Authors>
         <Authors>MarcinZiabek</Authors>
         <Company>CodeFlint</Company>
         <Company>CodeFlint</Company>
         <PackageId>QuestPDF</PackageId>
         <PackageId>QuestPDF</PackageId>
-        <Version>2022.2.5</Version>
+        <Version>2022.2.6</Version>
         <PackageDescription>QuestPDF is an open-source, modern and battle-tested library that can help you with generating PDF documents by offering friendly, discoverable and predictable C# fluent API.</PackageDescription>
         <PackageDescription>QuestPDF is an open-source, modern and battle-tested library that can help you with generating PDF documents by offering friendly, discoverable and predictable C# fluent API.</PackageDescription>
         <PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/Resources/ReleaseNotes.txt"))</PackageReleaseNotes>
         <PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/Resources/ReleaseNotes.txt"))</PackageReleaseNotes>
         <LangVersion>9</LangVersion>
         <LangVersion>9</LangVersion>