Browse Source

Text: rendering custom elements inside text

Marcin Ziąbek 4 years ago
parent
commit
755447e1fd

+ 13 - 7
QuestPDF.Examples/TextExamples.cs

@@ -17,6 +17,7 @@ namespace QuestPDF.Examples
                 .PageSize(PageSizes.A4)
                 .PageSize(PageSizes.A4)
                 .FileName()
                 .FileName()
                 .ProducePdf()
                 .ProducePdf()
+                .ShowResults()
                 .Render(container =>
                 .Render(container =>
                 {
                 {
                     container
                     container
@@ -30,17 +31,22 @@ namespace QuestPDF.Examples
                             text.Span("Then something bigger. ", TextStyle.Default.Size(28).Color(Colors.DeepOrange.Darken2).BackgroundColor(Colors.Yellow.Lighten3).Underlined());
                             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("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("Stroked text also works fine. ", TextStyle.Default.Size(14).Stroked().BackgroundColor(Colors.Grey.Lighten4));
-                            //text.NewLine();
+                                
+                            text.NewLine();
                             text.Span("Is it time for lorem  ipsum? ", TextStyle.Default.Size(12).Underlined().BackgroundColor(Colors.Grey.Lighten3));
                             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));
                             text.Span(Placeholders.LoremIpsum(), TextStyle.Default.Size(12));
                             
                             
-                            //text.NewLine();
-                            text.Span("And now some colors: ", TextStyle.Default.Size(16).Color(Colors.Green.Medium));
+                            text.Span("Before element - ");
+                            text.Element().PaddingBottom(-10).Background(Colors.Red.Lighten4).Width(50).Height(20);
+                            text.Span(" - end of element.");
                             
                             
-                            foreach (var i in Enumerable.Range(1, 100))
-                            {
-                                text.Span($"{i}: {Placeholders.Sentence()} ", TextStyle.Default.Size(12 + i / 5).LineHeight(2.75f - i / 50f).Color(Placeholders.Color()).BackgroundColor(Placeholders.BackgroundColor()));   
-                            }
+                            text.NewLine();
+                            // text.Span("And now some colors: ", TextStyle.Default.Size(16).Color(Colors.Green.Medium));
+                            //
+                            // foreach (var i in Enumerable.Range(1, 100))
+                            // {
+                            //     text.Span($"{i}: {Placeholders.Sentence()} ", TextStyle.Default.Size(12 + i / 5).LineHeight(2.75f - i / 50f).Color(Placeholders.Color()).BackgroundColor(Placeholders.BackgroundColor()));   
+                            // }
                         });
                         });
                 });
                 });
         }
         }

+ 43 - 0
QuestPDF/Elements/Text/TextItem.cs

@@ -1,6 +1,7 @@
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using QuestPDF.Drawing;
 using QuestPDF.Drawing;
+using QuestPDF.Drawing.SpacePlan;
 using QuestPDF.Infrastructure;
 using QuestPDF.Infrastructure;
 using Size = QuestPDF.Infrastructure.Size;
 using Size = QuestPDF.Infrastructure.Size;
 
 
@@ -225,4 +226,46 @@ namespace QuestPDF.Elements.Text
             };
             };
         }
         }
     }
     }
+    
+    internal class ElementTextItem : ITextElement
+    {
+        public Element Element { get; set; } = Empty.Instance;
+        
+        public TextMeasurementResult? Measure(TextMeasurementRequest request)
+        {
+            Element.HandleVisitor(x => (x as IStateResettable)?.ResetState());
+            Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas));
+
+            var measurement = Element.Measure(new Size(request.AvailableWidth, Size.Max.Height));
+
+            if (measurement is Wrap || measurement is PartialRender)
+                return null;
+
+            var elementSize = measurement as Size;
+            
+            return new TextMeasurementResult
+            {
+                Width = elementSize.Width,
+                
+                Ascent = -elementSize.Height,
+                Descent = 0,
+                
+                LineHeight = 1,
+                
+                StartIndex = 0,
+                EndIndex = 0,
+                TotalIndex = 0
+            };
+        }
+
+        public void Draw(TextDrawingRequest request)
+        {
+            Element.HandleVisitor(x => (x as IStateResettable)?.ResetState());
+            Element.HandleVisitor(x => x.Initialize(request.PageContext, request.Canvas));
+            
+            request.Canvas.Translate(new Position(0, request.TotalAscent));
+            Element.Draw(new Size(request.TextSize.Width, -request.TotalAscent));
+            request.Canvas.Translate(new Position(0, -request.TotalAscent));
+        }
+    }
 }
 }

+ 24 - 16
QuestPDF/Fluent/TextExtensions.cs

@@ -38,6 +38,14 @@ namespace QuestPDF.Fluent
         {
         {
             Spacing = value;
             Spacing = value;
         }
         }
+
+        private void AddItemToLastTextBlock(ITextElement element)
+        {
+            if (!TextBlocks.Any())
+                TextBlocks.Add(new TextBlock());
+            
+            TextBlocks.Last().Children.Add(element);
+        }
         
         
         public void Span(string text, TextStyle? style = null)
         public void Span(string text, TextStyle? style = null)
         {
         {
@@ -55,10 +63,7 @@ namespace QuestPDF.Fluent
                 })
                 })
                 .ToList();
                 .ToList();
 
 
-            if (!TextBlocks.Any())
-                TextBlocks.Add(new TextBlock());
-            
-            TextBlocks.First().Children.Add(items.First());
+            AddItemToLastTextBlock(items.First());
 
 
             items
             items
                 .Skip(1)
                 .Skip(1)
@@ -79,10 +84,7 @@ namespace QuestPDF.Fluent
         {
         {
             style ??= DefaultStyle;
             style ??= DefaultStyle;
             
             
-            if (!TextBlocks.Any())
-                TextBlocks.Add(new TextBlock());
-            
-            TextBlocks.First().Children.Add(new PageNumberTextItem()
+            AddItemToLastTextBlock(new PageNumberTextItem()
             {
             {
                 Style = style,
                 Style = style,
                 SlotName = slotName
                 SlotName = slotName
@@ -108,10 +110,7 @@ namespace QuestPDF.Fluent
         {
         {
             style ??= DefaultStyle;
             style ??= DefaultStyle;
             
             
-            if (!TextBlocks.Any())
-                TextBlocks.Add(new TextBlock());
-            
-            TextBlocks.First().Children.Add(new InternalLinkTextItem
+            AddItemToLastTextBlock(new InternalLinkTextItem
             {
             {
                 Style = style,
                 Style = style,
                 Text = text,
                 Text = text,
@@ -123,10 +122,7 @@ namespace QuestPDF.Fluent
         {
         {
             style ??= DefaultStyle;
             style ??= DefaultStyle;
             
             
-            if (!TextBlocks.Any())
-                TextBlocks.Add(new TextBlock());
-            
-            TextBlocks.First().Children.Add(new ExternalLinkTextItem
+            AddItemToLastTextBlock(new ExternalLinkTextItem
             {
             {
                 Style = style,
                 Style = style,
                 Text = text,
                 Text = text,
@@ -134,6 +130,18 @@ namespace QuestPDF.Fluent
             });
             });
         }
         }
         
         
+        public IContainer Element()
+        {
+            var container = new Container();
+                
+            AddItemToLastTextBlock(new ElementTextItem
+            {
+                Element = container
+            });
+            
+            return container.Box();
+        }
+        
         internal void Compose(IContainer container)
         internal void Compose(IContainer container)
         {
         {
             TextBlocks.ToList().ForEach(x => x.Alignment = Alignment);
             TextBlocks.ToList().ForEach(x => x.Alignment = Alignment);