Forráskód Böngészése

Inlined: simplified implementation and improved performance

Marcin Ziąbek 1 éve
szülő
commit
56dd7d8337

+ 18 - 24
Source/QuestPDF/Elements/Inlined.cs

@@ -5,11 +5,6 @@ using QuestPDF.Infrastructure;
 
 
 namespace QuestPDF.Elements
 namespace QuestPDF.Elements
 {
 {
-    internal sealed class InlinedElement : Container
-    {
-
-    }
-
     internal enum InlinedAlignment
     internal enum InlinedAlignment
     {
     {
         Left,
         Left,
@@ -25,12 +20,12 @@ namespace QuestPDF.Elements
         public SpacePlan Size { get; set; }
         public SpacePlan Size { get; set; }
     }
     }
 
 
-    internal sealed class Inlined : Element, IStateResettable, IContentDirectionAware
+    internal sealed class Inlined : Element, IContentDirectionAware, IStateResettable
     {
     {
         public ContentDirection ContentDirection { get; set; }
         public ContentDirection ContentDirection { get; set; }
         
         
-        public List<InlinedElement> Elements { get; internal set; } = new List<InlinedElement>();
-        private Queue<InlinedElement> ChildrenQueue { get; set; }
+        public List<Element> Elements { get; internal set; } = new();
+        private int CurrentRenderingIndex { get; set; }
 
 
         internal float VerticalSpacing { get; set; }
         internal float VerticalSpacing { get; set; }
         internal float HorizontalSpacing { get; set; }
         internal float HorizontalSpacing { get; set; }
@@ -40,7 +35,7 @@ namespace QuestPDF.Elements
         
         
         public void ResetState()
         public void ResetState()
         {
         {
-            ChildrenQueue = new Queue<InlinedElement>(Elements);
+            CurrentRenderingIndex = 0;
         }
         }
         
         
         internal override IEnumerable<Element?> GetChildren()
         internal override IEnumerable<Element?> GetChildren()
@@ -52,7 +47,7 @@ namespace QuestPDF.Elements
         {
         {
             SetDefaultAlignment();   
             SetDefaultAlignment();   
             
             
-            if (!ChildrenQueue.Any())
+            if (CurrentRenderingIndex == Elements.Count)
                 return SpacePlan.FullRender(Size.Zero);
                 return SpacePlan.FullRender(Size.Zero);
             
             
             var lines = Compose(availableSpace);
             var lines = Compose(availableSpace);
@@ -74,12 +69,12 @@ namespace QuestPDF.Elements
             var height = lineSizes.Sum(x => x.Height) + (lines.Count - 1) * VerticalSpacing;
             var height = lineSizes.Sum(x => x.Height) + (lines.Count - 1) * VerticalSpacing;
             var targetSize = new Size(width, height);
             var targetSize = new Size(width, height);
 
 
-            var isPartiallyRendered = lines.Sum(x => x.Count) != ChildrenQueue.Count;
+            var totalRenderedItems = CurrentRenderingIndex + lines.Sum(x => x.Count);
+            var willBeFullyRendered = totalRenderedItems == Elements.Count;
 
 
-            if (isPartiallyRendered)
-                return SpacePlan.PartialRender(targetSize);
-            
-            return SpacePlan.FullRender(targetSize);
+            return willBeFullyRendered
+                ? SpacePlan.FullRender(targetSize)
+                : SpacePlan.PartialRender(targetSize);
         }
         }
 
 
         internal override void Draw(Size availableSpace)
         internal override void Draw(Size availableSpace)
@@ -100,10 +95,9 @@ namespace QuestPDF.Elements
             }
             }
             
             
             Canvas.Translate(new Position(0, -topOffset));
             Canvas.Translate(new Position(0, -topOffset));
-            lines.SelectMany(x => x).ToList().ForEach(x => ChildrenQueue.Dequeue());
             
             
-            if (!ChildrenQueue.Any())
-                ResetState();
+            var fullyRenderedItems = lines.Sum(x => x.Count);
+            CurrentRenderingIndex += fullyRenderedItems;
 
 
             void DrawLine(ICollection<InlinedMeasurement> lineMeasurements)
             void DrawLine(ICollection<InlinedMeasurement> lineMeasurements)
             {
             {
@@ -183,8 +177,8 @@ namespace QuestPDF.Elements
             ElementsAlignment = ContentDirection == ContentDirection.LeftToRight
             ElementsAlignment = ContentDirection == ContentDirection.LeftToRight
                 ? InlinedAlignment.Left
                 ? InlinedAlignment.Left
                 : InlinedAlignment.Right;
                 : InlinedAlignment.Right;
-        }
-
+        }
+
         static Size GetLineSize(ICollection<InlinedMeasurement> measurements)
         static Size GetLineSize(ICollection<InlinedMeasurement> measurements)
         {
         {
             var width = measurements.Sum(x => x.Size.Width);
             var width = measurements.Sum(x => x.Size.Width);
@@ -196,7 +190,7 @@ namespace QuestPDF.Elements
         // list of lines, each line is a list of elements
         // list of lines, each line is a list of elements
         private ICollection<ICollection<InlinedMeasurement>> Compose(Size availableSize)
         private ICollection<ICollection<InlinedMeasurement>> Compose(Size availableSize)
         {
         {
-            var queue = new Queue<InlinedElement>(ChildrenQueue);
+            var localRenderingIndex = CurrentRenderingIndex;
             var result = new List<ICollection<InlinedMeasurement>>();
             var result = new List<ICollection<InlinedMeasurement>>();
 
 
             var topOffset = 0f;
             var topOffset = 0f;
@@ -226,10 +220,10 @@ namespace QuestPDF.Elements
                 
                 
                 while (true)
                 while (true)
                 {
                 {
-                    if (!queue.Any())
+                    if (localRenderingIndex == Elements.Count)
                         break;
                         break;
                     
                     
-                    var element = queue.Peek();
+                    var element = Elements[localRenderingIndex];
                     var size = element.Measure(new Size(availableSize.Width, Size.Max.Height));
                     var size = element.Measure(new Size(availableSize.Width, Size.Max.Height));
                     
                     
                     if (size.Type == SpacePlanType.Wrap)
                     if (size.Type == SpacePlanType.Wrap)
@@ -238,7 +232,7 @@ namespace QuestPDF.Elements
                     if (leftOffset + size.Width > availableSize.Width + Size.Epsilon)
                     if (leftOffset + size.Width > availableSize.Width + Size.Epsilon)
                         break;
                         break;
 
 
-                    queue.Dequeue();
+                    localRenderingIndex++;
                     leftOffset += size.Width + HorizontalSpacing;
                     leftOffset += size.Width + HorizontalSpacing;
                     
                     
                     result.Add(new InlinedMeasurement
                     result.Add(new InlinedMeasurement

+ 1 - 1
Source/QuestPDF/Fluent/InlinedExtensions.cs

@@ -120,7 +120,7 @@ namespace QuestPDF.Fluent
         /// <returns>The container of the newly created item.</returns>
         /// <returns>The container of the newly created item.</returns>
         public IContainer Item()
         public IContainer Item()
         {
         {
-            var container = new InlinedElement();
+            var container = new Constrained();
             Inlined.Elements.Add(container);
             Inlined.Elements.Add(container);
             return container;
             return container;
         }
         }