Bläddra i källkod

Rendering text paragraphs without the Column element (not fully working)

MarcinZiabek 3 år sedan
förälder
incheckning
cbaebdd670

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

@@ -19,5 +19,6 @@ namespace QuestPDF.Elements.Text.Calculation
         public int TotalIndex { get; set; }
 
         public bool IsLast => EndIndex == TotalIndex;
+        public bool IsNewLine { get; set; }
     }
 }

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

@@ -39,18 +39,34 @@ namespace QuestPDF.Elements.Text.Items
             
             var paint = Style.ToPaint();
             var fontMetrics = Style.ToFontMetrics();
-            var spaceCodepoint = paint.ToFont().Typeface.GetGlyphs(" ")[0];
 
+            // if the element is the first one within the line,
+            // ignore leading spaces and new lines
+            var spaceCodepoint = paint.ToFont().Typeface.GetGlyph(' ');
+            var newLineCodepoint = paint.ToFont().Typeface.GetGlyph('\n');
+            var returnCodepoint = paint.ToFont().Typeface.GetGlyph('\r');
+            
             var startIndex = request.StartIndex;
             
-            // if the element is the first one within the line,
-            // ignore leading spaces
             if (!request.IsFirstElementInBlock && request.IsFirstElementInLine)
             {
-                while (startIndex < TextShapingResult.Glyphs.Length && Text[startIndex] == spaceCodepoint)
+                while (startIndex < TextShapingResult.Glyphs.Length && (Text[startIndex] == spaceCodepoint || Text[startIndex] == newLineCodepoint || Text[startIndex] == returnCodepoint))
                     startIndex++;
             }
 
+            // calculate max index (new new line)
+            var newLineIndex = startIndex;
+
+            while (newLineIndex < TextShapingResult.Glyphs.Length)
+            {
+                var glyphCodepoint = TextShapingResult.Glyphs[newLineIndex].Codepoint;
+                
+                if (glyphCodepoint == newLineCodepoint || glyphCodepoint == returnCodepoint)
+                    break;
+
+                newLineIndex++;
+            }
+            
             if (TextShapingResult.Glyphs.Length == 0 || startIndex == TextShapingResult.Glyphs.Length)
             {
                 return new TextMeasurementResult
@@ -68,6 +84,8 @@ namespace QuestPDF.Elements.Text.Items
 
             if (endIndex < startIndex)
                 return null;
+
+            endIndex = Math.Min(endIndex, newLineIndex);
   
             // break text only on spaces
             var wrappedText = WrapText(startIndex, endIndex, request.IsFirstElementInLine);
@@ -90,7 +108,9 @@ namespace QuestPDF.Elements.Text.Items
                 StartIndex = startIndex,
                 EndIndex = wrappedText.Value.endIndex,
                 NextIndex = wrappedText.Value.nextIndex,
-                TotalIndex = TextShapingResult.Glyphs.Length - 1
+                TotalIndex = TextShapingResult.Glyphs.Length - 1,
+                
+                IsNewLine = endIndex == newLineIndex
             };
         }
         

+ 8 - 1
QuestPDF/Elements/Text/TextBlock.cs

@@ -11,7 +11,8 @@ namespace QuestPDF.Elements.Text
     internal class TextBlock : Element, IStateResettable
     {
         public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
-        public List<ITextBlockItem> Items { get; set; } = new List<ITextBlockItem>();
+        public List<ITextBlockItem> Items { get; set; } = new();
+        public float ParagraphSpacing { get; set; } = 0;
 
         public string Text => string.Join(" ", Items.Where(x => x is TextBlockSpan).Cast<TextBlockSpan>().Select(x => x.Text));
 
@@ -110,6 +111,12 @@ namespace QuestPDF.Elements.Text
                 Canvas.Translate(new Position(0, line.LineHeight));
                 
                 heightOffset += line.LineHeight;
+
+                if (line.Elements.Last().Measurement.IsNewLine)
+                {
+                    heightOffset += ParagraphSpacing;
+                    Canvas.Translate(new Position(0, ParagraphSpacing));
+                }
             }
             
             Canvas.Translate(new Position(0, -heightOffset));

+ 14 - 51
QuestPDF/Fluent/TextExtensions.cs

@@ -40,10 +40,9 @@ namespace QuestPDF.Fluent
     
     public class TextDescriptor
     {
-        private ICollection<TextBlock> TextBlocks { get; } = new List<TextBlock>();
+        internal TextBlock TextBlock = new();
         private TextStyle DefaultStyle { get; set; } = TextStyle.Default;
         internal HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
-        private float Spacing { get; set; } = 0f;
 
         public void DefaultTextStyle(TextStyle style)
         {
@@ -72,17 +71,9 @@ namespace QuestPDF.Fluent
 
         public void ParagraphSpacing(float value, Unit unit = Unit.Point)
         {
-            Spacing = value.ToPoints(unit);
+            TextBlock.ParagraphSpacing = value.ToPoints(unit);
         }
 
-        private void AddItemToLastTextBlock(ITextBlockItem item)
-        {
-            if (!TextBlocks.Any())
-                TextBlocks.Add(new TextBlock());
-            
-            TextBlocks.Last().Items.Add(item);
-        }
-        
         [Obsolete("This element has been renamed since version 2022.3. Please use the overload that returns a TextSpanDescriptor object which allows to specify text style.")]
         public void Span(string? text, TextStyle style)
         {
@@ -96,28 +87,13 @@ namespace QuestPDF.Fluent
 
             if (text == null)
                 return descriptor;
- 
-            var items = text
-                .Replace("\r", string.Empty)
-                .Split(new[] { '\n' }, StringSplitOptions.None)
-                .Select(x => new TextBlockSpan
-                {
-                    Text = x,
-                    Style = style
-                })
-                .ToList();
-
-            AddItemToLastTextBlock(items.First());
-
-            items
-                .Skip(1)
-                .Select(x => new TextBlock
-                {   
-                    Items = new List<ITextBlockItem> { x }
-                })
-                .ToList()
-                .ForEach(TextBlocks.Add);
-
+            
+            TextBlock.Items.Add(new TextBlockSpan
+            {
+                Text = text,
+                Style = style
+            });
+            
             return descriptor;
         }
 
@@ -137,7 +113,7 @@ namespace QuestPDF.Fluent
             var style = DefaultStyle.Clone();
             var descriptor = new TextPageNumberDescriptor(style);
             
-            AddItemToLastTextBlock(new TextBlockPageNumber
+            TextBlock.Items.Add(new TextBlockPageNumber
             {
                 Source = context => descriptor.FormatFunction(pageNumber(context)),
                 Style = style
@@ -193,7 +169,7 @@ namespace QuestPDF.Fluent
             if (IsNullOrEmpty(text))
                 return descriptor;
             
-            AddItemToLastTextBlock(new TextBlockSectionLink
+            TextBlock.Items.Add(new TextBlockSectionLink
             {
                 Style = style,
                 Text = text,
@@ -220,7 +196,7 @@ namespace QuestPDF.Fluent
             if (IsNullOrEmpty(text))
                 return descriptor;
             
-            AddItemToLastTextBlock(new TextBlockHyperlink
+            TextBlock.Items.Add(new TextBlockHyperlink
             {
                 Style = style,
                 Text = text,
@@ -240,26 +216,13 @@ namespace QuestPDF.Fluent
         {
             var container = new Container();
                 
-            AddItemToLastTextBlock(new TextBlockElement
+            TextBlock.Items.Add(new TextBlockElement
             {
                 Element = container
             });
             
             return container.AlignBottom().MinimalBox();
         }
-        
-        internal void Compose(IContainer container)
-        {
-            TextBlocks.ToList().ForEach(x => x.Alignment = Alignment);
-
-            container.DefaultTextStyle(DefaultStyle).Column(column =>
-            {
-                column.Spacing(Spacing);
-
-                foreach (var textBlock in TextBlocks)
-                    column.Item().Element(textBlock);
-            });
-        }
     }
     
     public static class TextExtensions
@@ -272,7 +235,7 @@ namespace QuestPDF.Fluent
                 descriptor.Alignment = alignment.Horizontal;
             
             content?.Invoke(descriptor);
-            descriptor.Compose(element);
+            element.Element(descriptor.TextBlock);
         }
         
         [Obsolete("This element has been renamed since version 2022.3. Please use the overload that returns a TextSpanDescriptor object which allows to specify text style.")]