Browse Source

Code structure improvements. Text rendering: support for words longer than available space

Marcin Ziąbek 4 years ago
parent
commit
899c138842

+ 6 - 6
QuestPDF.Examples/TextBenchmark.cs

@@ -128,7 +128,7 @@ namespace QuestPDF.Examples
 
                                 Chapters(stack);
 
-                                stack.Item().Element(Summary);
+                                stack.Item().Element(Acknowledgements);
                             });
 
                         decoration.Footer().Element(Footer);
@@ -152,7 +152,7 @@ namespace QuestPDF.Examples
             {
                 container.Stack(stack =>
                 {
-                    SectionTitle(stack, "Table of contents");
+                    SectionTitle(stack, "Spis treści");
                     
                     foreach (var chapter in chapters)
                     {
@@ -189,19 +189,19 @@ namespace QuestPDF.Examples
                 });
             }
 
-            void Summary(IContainer container)
+            void Acknowledgements(IContainer container)
             {
                 container.Stack(stack =>
                 {
-                    SectionTitle(stack, "Acknowledgements");
+                    SectionTitle(stack, "Podziękowania");
                     
                     stack.Item().Text(text =>
                     {
                         text.DefaultTextStyle(normalStyle);
                         
-                        text.Span("This document was generated based on the book available on the ");
+                        text.Span("Ten dokument został wygenerowany na podstawie książki w formacie TXT opublikowanej w serwisie ");
                         text.ExternalLocation("wolnelektury.pl", "https://wolnelektury.pl/", normalStyle.Color(Colors.Blue.Medium).Underlined());
-                        text.Span(" website. Thank you!");
+                        text.Span(". Dziękuję za wspieranie polskiego czytelnictwa!");
                     });
                 });
             }

+ 3 - 1
QuestPDF.Examples/TextExamples.cs

@@ -31,7 +31,9 @@ namespace QuestPDF.Examples
                             text.Span("Then something bigger. ", TextStyle.Default.Size(28).Color(Colors.DeepOrange.Darken2).BackgroundColor(Colors.Yellow.Lighten3).Underlined());
                             text.Span("And tiny teeny-tiny. ", TextStyle.Default.Size(6));
                             text.Span("Stroked text also works fine. ", TextStyle.Default.Size(14).Stroked().BackgroundColor(Colors.Grey.Lighten4));
-                                
+                               
+                            text.Span("0123456789-0123456789-0123456789-0123456789-0123456789-0123456789-0123456789", TextStyle.Default.Size(18));
+                            
                             text.NewLine();
                             text.Span("Is it time for lorem  ipsum? ", TextStyle.Default.Size(12).Underlined().BackgroundColor(Colors.Grey.Lighten3));
                             text.Span(Placeholders.LoremIpsum(), TextStyle.Default.Size(12));

+ 1 - 1
QuestPDF/Elements/Text/Calculation/TextLineElement.cs

@@ -4,7 +4,7 @@ namespace QuestPDF.Elements.Text.Items
 {
     internal class TextLineElement
     {
-        public ITextBlockElement Element { get; set; }
+        public ITextBlockItem Item { get; set; }
         public TextMeasurementResult Measurement { get; set; }
     }
 }

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

@@ -9,5 +9,6 @@ namespace QuestPDF.Elements.Text.Calculation
         
         public int StartIndex { get; set; }
         public float AvailableWidth { get; set; }
+        public bool IsFirstLineElement { get; set; }
     }
 }

+ 1 - 1
QuestPDF/Elements/Text/Items/ITextBlockElement.cs → QuestPDF/Elements/Text/Items/ITextBlockItem.cs

@@ -2,7 +2,7 @@
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal interface ITextBlockElement
+    internal interface ITextBlockItem
     {
         TextMeasurementResult? Measure(TextMeasurementRequest request);
         void Draw(TextDrawingRequest request);

+ 1 - 1
QuestPDF/Elements/Text/Items/TextBlockElement.cs

@@ -4,7 +4,7 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal class TextBlockElement : ITextBlockElement
+    internal class TextBlockElement : ITextBlockItem
     {
         public Element Element { get; set; } = Empty.Instance;
         

+ 3 - 3
QuestPDF/Elements/Text/Items/TextBlockExternalLink.cs

@@ -3,7 +3,7 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal class TextBlockExternalLink : ITextBlockElement
+    internal class TextBlockExternalLink : ITextBlockItem
     {
         public TextStyle Style { get; set; } = new TextStyle();
         public string Text { get; set; }
@@ -23,9 +23,9 @@ namespace QuestPDF.Elements.Text.Items
             GetItem().Draw(request);
         }
 
-        private TextItem GetItem()
+        private TextBlockSpan GetItem()
         {
-            return new TextItem
+            return new TextBlockSpan
             {
                 Style = Style,
                 Text = Text

+ 3 - 3
QuestPDF/Elements/Text/Items/TextBlockInternalLink.cs

@@ -3,7 +3,7 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal class TextBlockInternalLink : ITextBlockElement
+    internal class TextBlockInternalLink : ITextBlockItem
     {
         public TextStyle Style { get; set; } = new TextStyle();
         public string Text { get; set; }
@@ -23,9 +23,9 @@ namespace QuestPDF.Elements.Text.Items
             GetItem().Draw(request);
         }
 
-        private TextItem GetItem()
+        private TextBlockSpan GetItem()
         {
-            return new TextItem
+            return new TextBlockSpan
             {
                 Style = Style,
                 Text = Text

+ 3 - 3
QuestPDF/Elements/Text/Items/TextBlockPageNumber.cs

@@ -3,7 +3,7 @@ using QuestPDF.Infrastructure;
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal class TextBlockPageNumber : ITextBlockElement
+    internal class TextBlockPageNumber : ITextBlockItem
     {
         public TextStyle Style { get; set; } = new TextStyle();
         public string SlotName { get; set; }
@@ -18,7 +18,7 @@ namespace QuestPDF.Elements.Text.Items
             GetItem(request.PageContext).Draw(request);
         }
 
-        private TextItem GetItem(IPageContext context)
+        private TextBlockSpan GetItem(IPageContext context)
         {
             var pageNumberPlaceholder = 123;
             
@@ -26,7 +26,7 @@ namespace QuestPDF.Elements.Text.Items
                 ? context.GetLocationPage(SlotName)
                 : pageNumberPlaceholder;
             
-            return new TextItem
+            return new TextBlockSpan
             {
                 Style = Style,
                 Text = pageNumber.ToString()

+ 11 - 6
QuestPDF/Elements/Text/Items/TextItem.cs → QuestPDF/Elements/Text/Items/TextBlockSpan.cs

@@ -6,7 +6,7 @@ using Size = QuestPDF.Infrastructure.Size;
 
 namespace QuestPDF.Elements.Text.Items
 {
-    internal class TextItem : ITextBlockElement
+    internal class TextBlockSpan : ITextBlockItem
     {
         public string Text { get; set; }
         public TextStyle Style { get; set; } = new TextStyle();
@@ -39,12 +39,17 @@ namespace QuestPDF.Elements.Text.Items
             // break text only on spaces
             if (breakingIndex < text.Length)
             {
-                breakingIndex = text.Substring(0, breakingIndex).LastIndexOf(" ");
+                var lastSpaceIndex = text.Substring(0, breakingIndex).LastIndexOf(" ");
 
-                if (breakingIndex <= 0)
-                    return null;
-
-                breakingIndex += 1;
+                if (lastSpaceIndex <= 0)
+                {
+                    if (!request.IsFirstLineElement)
+                        return null;
+                }
+                else
+                {
+                    breakingIndex = lastSpaceIndex + 1;
+                }
             }
 
             text = text.Substring(0, breakingIndex);

+ 10 - 9
QuestPDF/Elements/Text/TextBlock.cs

@@ -10,14 +10,14 @@ namespace QuestPDF.Elements.Text
     internal class TextBlock : Element, IStateResettable
     {
         public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
-        public List<ITextBlockElement> Children { get; set; } = new List<ITextBlockElement>();
+        public List<ITextBlockItem> Children { get; set; } = new List<ITextBlockItem>();
 
-        public Queue<ITextBlockElement> RenderingQueue { get; set; }
+        public Queue<ITextBlockItem> RenderingQueue { get; set; }
         public int CurrentElementIndex { get; set; }
 
         public void ResetState()
         {
-            RenderingQueue = new Queue<ITextBlockElement>(Children);
+            RenderingQueue = new Queue<ITextBlockItem>(Children);
             CurrentElementIndex = 0;
         }
 
@@ -39,7 +39,7 @@ namespace QuestPDF.Elements.Text
 
             var fullyRenderedItemsCount = lines
                 .SelectMany(x => x.Elements)
-                .GroupBy(x => x.Element)
+                .GroupBy(x => x.Item)
                 .Count(x => x.Any(y => y.Measurement.IsLast));
             
             if (fullyRenderedItemsCount == RenderingQueue.Count)
@@ -86,7 +86,7 @@ namespace QuestPDF.Elements.Text
                         TotalAscent = line.Ascent
                     };
                 
-                    item.Element.Draw(textDrawingRequest);
+                    item.Item.Draw(textDrawingRequest);
                 
                     Canvas.Translate(new Position(item.Measurement.Width, 0));
                     widthOffset += item.Measurement.Width;
@@ -105,7 +105,7 @@ namespace QuestPDF.Elements.Text
             
             lines
                 .SelectMany(x => x.Elements)
-                .GroupBy(x => x.Element)
+                .GroupBy(x => x.Item)
                 .Where(x => x.Any(y => y.Measurement.IsLast))
                 .Select(x => x.Key)
                 .ToList()
@@ -120,7 +120,7 @@ namespace QuestPDF.Elements.Text
 
         public IEnumerable<TextLine> DivideTextItemsIntoLines(float availableWidth, float availableHeight)
         {
-            var queue = new Queue<ITextBlockElement>(RenderingQueue);
+            var queue = new Queue<ITextBlockItem>(RenderingQueue);
             var currentItemIndex = CurrentElementIndex;
             var currentHeight = 0f;
 
@@ -157,7 +157,8 @@ namespace QuestPDF.Elements.Text
                         PageContext = PageContext,
                         
                         StartIndex = currentItemIndex,
-                        AvailableWidth = availableWidth - currentWidth
+                        AvailableWidth = availableWidth - currentWidth,
+                        IsFirstLineElement = !currentLineElements.Any()
                     };
                 
                     var measurementResponse = currentElement.Measure(measurementRequest);
@@ -167,7 +168,7 @@ namespace QuestPDF.Elements.Text
                     
                     currentLineElements.Add(new TextLineElement
                     {
-                        Element = currentElement,
+                        Item = currentElement,
                         Measurement = measurementResponse
                     });
 

+ 4 - 4
QuestPDF/Fluent/TextExtensions.cs

@@ -40,12 +40,12 @@ namespace QuestPDF.Fluent
             Spacing = value;
         }
 
-        private void AddItemToLastTextBlock(ITextBlockElement element)
+        private void AddItemToLastTextBlock(ITextBlockItem item)
         {
             if (!TextBlocks.Any())
                 TextBlocks.Add(new TextBlock());
             
-            TextBlocks.Last().Children.Add(element);
+            TextBlocks.Last().Children.Add(item);
         }
         
         public void Span(string text, TextStyle? style = null)
@@ -57,7 +57,7 @@ namespace QuestPDF.Fluent
             
             var items = text
                 .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
-                .Select(x => new TextItem
+                .Select(x => new TextBlockSpan
                 {
                     Text = x,
                     Style = style
@@ -70,7 +70,7 @@ namespace QuestPDF.Fluent
                 .Skip(1)
                 .Select(x => new TextBlock
                 {   
-                    Children = new List<ITextBlockElement> { x }
+                    Children = new List<ITextBlockItem> { x }
                 })
                 .ToList()
                 .ForEach(TextBlocks.Add);