Browse Source

Fixed: the Column element may not render successfully when it has non-zero spacing, contains a child with zero height, and is repeated.

Marcin Ziąbek 1 year ago
parent
commit
c6fdbb7223

+ 34 - 0
Source/QuestPDF.Examples/ColumnExamples.cs

@@ -104,5 +104,39 @@ namespace QuestPDF.Examples
                         .Column(column => { });
                         .Column(column => { });
                 });
                 });
         }
         }
+        
+        [Test]
+        public void ColumnWithShowOnce()
+        {
+            RenderingTest
+                .Create()
+                .ProducePdf()
+                .MaxPages(100)
+                .ShowResults()
+                .RenderDocument(document =>
+                {
+                    document.Page(page =>
+                    {
+                        page.Size(PageSizes.A4);
+                        page.Margin(50);
+
+                        page.Content().PaddingVertical(25).Column(column =>
+                        {
+                            column.Spacing(25);
+                            
+                            foreach (var i in Enumerable.Range(0, 50))
+                                column.Item().Height(75).Width(100 + i * 5).Background(Colors.Grey.Lighten2);
+                        });
+
+                        page.Header().Background(Colors.Grey.Lighten4).Column(column =>
+                        {
+                            column.Spacing(10);
+                            column.Item().Background(Colors.Red.Lighten3).Text("First line");
+                            column.Item().Background(Colors.Green.Lighten3).ShowIf(x => x.PageNumber % 3 != 0).Text("Second line");
+                            column.Item().Background(Colors.Blue.Lighten3).ShowIf(x => x.PageNumber % 2 != 0).Text("Third line");
+                        });
+                    });
+                });
+        }
     }
     }
 }
 }

+ 44 - 0
Source/QuestPDF.LayoutTests/ColumnTests.cs

@@ -0,0 +1,44 @@
+namespace QuestPDF.LayoutTests;
+
+public class ColumnTests
+{
+    [Test]
+    public void Typical()
+    {
+        LayoutTest
+            .HavingSpaceOfSize(100, 140)
+            .WithContent(content =>
+            {
+                content.Shrink().Column(column =>
+                {
+                    column.Spacing(10);
+                    
+                    column.Item().Mock("a").Size(50, 30);
+                    column.Item().Mock("b").Size(40, 20);
+                    column.Item().Mock("c").Size(70, 40);
+                    column.Item().Mock("d").Size(60, 60);
+                });
+            })
+            .ExpectedDrawResult(document =>
+            {
+                document
+                    .Page()
+                    .RequiredAreaSize(70, 140)
+                    .Content(page =>
+                    {
+                        page.Mock("a").Position(0, 0).Size(70, 30);
+                        page.Mock("b").Position(0, 40).Size(70, 20);
+                        page.Mock("c").Position(0, 70).Size(70, 40);
+                        page.Mock("d").Position(0, 120).Size(70, 20);
+                    });
+                
+                document
+                    .Page()
+                    .RequiredAreaSize(60, 40)
+                    .Content(page =>
+                    {
+                        page.Mock("d").Position(0, 0).Size(60, 40);
+                    });
+            });
+    }
+}

+ 21 - 15
Source/QuestPDF/Elements/Column.cs

@@ -15,7 +15,6 @@ namespace QuestPDF.Elements
     {
     {
         public ColumnItem ColumnItem { get; set; }
         public ColumnItem ColumnItem { get; set; }
         public SpacePlan Measurement { get; set; }
         public SpacePlan Measurement { get; set; }
-        public Size Size { get; set; }
         public Position Offset { get; set; }
         public Position Offset { get; set; }
     }
     }
 
 
@@ -49,8 +48,8 @@ namespace QuestPDF.Elements
             if (!renderingCommands.Any())
             if (!renderingCommands.Any())
                 return SpacePlan.Wrap();
                 return SpacePlan.Wrap();
 
 
-            var width = renderingCommands.Max(x => x.Size.Width);
-            var height = renderingCommands.Last().Offset.Y + renderingCommands.Last().Size.Height;
+            var width = renderingCommands.Max(x => x.Measurement.Width);
+            var height = renderingCommands.Last().Offset.Y + renderingCommands.Last().Measurement.Height;
             var size = new Size(width, height);
             var size = new Size(width, height);
             
             
             if (width > availableSpace.Width + Size.Epsilon || height > availableSpace.Height + Size.Epsilon)
             if (width > availableSpace.Width + Size.Epsilon || height > availableSpace.Height + Size.Epsilon)
@@ -73,7 +72,7 @@ namespace QuestPDF.Elements
                 if (command.Measurement.Type == SpacePlanType.FullRender)
                 if (command.Measurement.Type == SpacePlanType.FullRender)
                     command.ColumnItem.IsRendered = true;
                     command.ColumnItem.IsRendered = true;
 
 
-                var targetSize = new Size(availableSpace.Width, command.Size.Height);
+                var targetSize = new Size(availableSpace.Width, command.Measurement.Height);
 
 
                 Canvas.Translate(command.Offset);
                 Canvas.Translate(command.Offset);
                 command.ColumnItem.Draw(targetSize);
                 command.ColumnItem.Draw(targetSize);
@@ -95,13 +94,7 @@ namespace QuestPDF.Elements
                 if (item.IsRendered)
                 if (item.IsRendered)
                     continue;
                     continue;
 
 
-                var availableHeight = availableSpace.Height - topOffset;
-                
-                if (availableHeight < -Size.Epsilon)
-                    break;
-
-                var itemSpace = new Size(availableSpace.Width, availableHeight);
-                var measurement = item.Measure(itemSpace);
+                var measurement = MeasureItem(item);
                 
                 
                 if (measurement.Type == SpacePlanType.Wrap)
                 if (measurement.Type == SpacePlanType.Wrap)
                     break;
                     break;
@@ -113,7 +106,6 @@ namespace QuestPDF.Elements
                 commands.Add(new ColumnItemRenderingCommand
                 commands.Add(new ColumnItemRenderingCommand
                 {
                 {
                     ColumnItem = item,
                     ColumnItem = item,
-                    Size = measurement,
                     Measurement = measurement,
                     Measurement = measurement,
                     Offset = new Position(0, topOffset)
                     Offset = new Position(0, topOffset)
                 });
                 });
@@ -127,10 +119,24 @@ namespace QuestPDF.Elements
                 topOffset += measurement.Height + Spacing;
                 topOffset += measurement.Height + Spacing;
             }
             }
 
 
-            foreach (var command in commands)
-                command.Size = new Size(targetWidth, command.Size.Height);
-
             return commands;
             return commands;
+
+            SpacePlan MeasureItem(ColumnItem item)
+            {
+                var availableHeight = availableSpace.Height - topOffset;
+                
+                if (availableHeight < Size.Epsilon)
+                {
+                    var measurementWithZeroSpace = item.Measure(Size.Zero);
+      
+                    return measurementWithZeroSpace.Type == SpacePlanType.FullRender
+                        ? measurementWithZeroSpace
+                        : SpacePlan.Wrap();
+                }
+                
+                var itemSpace = new Size(availableSpace.Width, availableHeight);
+                return item.Measure(itemSpace);
+            }
         }
         }
     }
     }
 }
 }