Browse Source

Rendering algorithm partially working

MarcinZiabek 4 years ago
parent
commit
3e5e3843d2

+ 15 - 1
QuestPDF.Examples/Engine/RenderingTest.cs

@@ -20,6 +20,8 @@ namespace QuestPDF.Examples.Engine
         private Size Size { get; set; }
         private int? MaxPagesThreshold { get; set; }
         private bool ShowResult { get; set; }
+        private bool ApplyCaching { get; set; }
+        private bool ApplyDebugging { get; set; }
         private RenderingTestResult ResultType { get; set; } = RenderingTestResult.Images;
         
         private RenderingTest()
@@ -73,6 +75,18 @@ namespace QuestPDF.Examples.Engine
             return this;
         }
         
+        public RenderingTest EnableCaching(bool value = true)
+        {
+            ApplyCaching = value;
+            return this;
+        }
+        
+        public RenderingTest EnableDebugging(bool value = true)
+        {
+            ApplyDebugging = value;
+            return this;
+        }
+        
         public void Render(Action<IContainer> content)
         {
             RenderDocument(container =>
@@ -88,7 +102,7 @@ namespace QuestPDF.Examples.Engine
         public void RenderDocument(Action<IDocumentContainer> content)
         {
             MaxPagesThreshold ??= ResultType == RenderingTestResult.Pdf ? 1000 : 10;
-            var document = new SimpleDocument(content, MaxPagesThreshold.Value);
+            var document = new SimpleDocument(content, MaxPagesThreshold.Value, ApplyCaching, ApplyDebugging);
 
             Render(document);
         }

+ 8 - 2
QuestPDF.Examples/Engine/SimpleDocument.cs

@@ -13,11 +13,15 @@ namespace QuestPDF.Examples.Engine
         
         private Action<IDocumentContainer> Content { get; }
         private int MaxPages { get; }
+        private bool ApplyCaching { get; }
+        private bool ApplyDebugging { get; }
 
-        public SimpleDocument(Action<IDocumentContainer> content, int maxPages)
+        public SimpleDocument(Action<IDocumentContainer> content, int maxPages, bool applyCaching, bool applyDebugging)
         {
             Content = content;
             MaxPages = maxPages;
+            ApplyCaching = applyCaching;
+            ApplyDebugging = applyDebugging;
         }
         
         public DocumentMetadata GetMetadata()
@@ -25,7 +29,9 @@ namespace QuestPDF.Examples.Engine
             return new DocumentMetadata()
             {
                 RasterDpi = PageSizes.PointsPerInch * ImageScalingFactor,
-                DocumentLayoutExceptionThreshold = MaxPages
+                DocumentLayoutExceptionThreshold = MaxPages,
+                ApplyCaching = ApplyCaching,
+                ApplyDebugging = ApplyDebugging
             };
         }
         

+ 11 - 5
QuestPDF.Examples/TableExamples.cs

@@ -77,12 +77,15 @@ namespace QuestPDF.Examples
             RenderingTest
                 .Create()
                 .ProducePdf()
-                .PageSize(1000, 2000)
+                .PageSize(1002, 2002)
                 .MaxPages(1000)
+                .EnableCaching()
+                .EnableDebugging(false)
                 .ShowResults()
                 .Render(container =>
                 {
                     container
+                        .Padding(1)
                         .Table(table =>
                         {
                             table.ColumnsDefinition(columns =>
@@ -91,7 +94,7 @@ namespace QuestPDF.Examples
                                     columns.ConstantColumn(100);
                             });
 
-                            foreach (var i in Enumerable.Range(1, 10000))
+                            foreach (var i in Enumerable.Range(1, 10_000))
                             {
                                 table
                                     .Cell()
@@ -110,14 +113,17 @@ namespace QuestPDF.Examples
                 var height = Random.Next(2, 7) * 25;
                     
                 container
-                    .Border(1)
+                    .Border(2)
                     .Background(Placeholders.BackgroundColor())
                     .Layers(layers =>
                     {
                         layers
                             .PrimaryLayer()
-                            .ExtendHorizontal()
-                            .Height(height);
+                            .AlignCenter()
+                            .AlignMiddle()
+                            .Height(height)
+                            .Width(80)
+                            .Border(1);
                             
                         layers
                             .Layer()

+ 27 - 23
QuestPDF/Elements/Table/Table.cs

@@ -8,8 +8,8 @@ namespace QuestPDF.Elements.Table
 {
     internal class Table : Element, IStateResettable
     {
-        public ICollection<TableColumnDefinition> Columns { get; } = new List<TableColumnDefinition>();
-        public ICollection<TableCell> Children { get; } = new List<TableCell>();
+        public List<TableColumnDefinition> Columns { get; } = new List<TableColumnDefinition>();
+        public List<TableCell> Children { get; } = new List<TableCell>();
         public float Spacing { get; set; }
         
         public int CurrentRow { get; set; }
@@ -67,13 +67,29 @@ namespace QuestPDF.Elements.Table
         {
             var cellRenderingCommands = new List<TableCellRenderingCommand>();
             
+            var cellOffsets = new float[Columns.Count + 1];
+            cellOffsets[0] = 0;
+            
+            Enumerable
+                .Range(1, cellOffsets.Length - 1)
+                .ToList()
+                .ForEach(x => cellOffsets[x] = Columns[x - 1].Width + cellOffsets[x - 1]);
+            
             // update row heights
             var rowsCount = GetRowsCount();
             var rowBottomOffsets = new float[rowsCount];
             var childrenToTry = Children.Where(x => x.Row >= CurrentRow).OrderBy(x => x.Row);
+
+            var currentRow = CurrentRow;
             
             foreach (var child in childrenToTry)
             {
+                if (currentRow < child.Row)
+                {
+                    rowBottomOffsets[currentRow] = Math.Max(rowBottomOffsets[currentRow], rowBottomOffsets[currentRow-1]);
+                    currentRow = child.Row;
+                }
+                
                 var rowIndex = child.Row - 1;
                 
                 var topOffset = 0f;
@@ -86,13 +102,11 @@ namespace QuestPDF.Elements.Table
                 
                 var targetRowId = child.Row + child.RowSpan - 2; // -1 because indexing starts at 0, -1 because rowSpan starts at 1
                 rowBottomOffsets[targetRowId] = Math.Max(rowBottomOffsets[targetRowId], cellBottomOffset);
+                
+                //if (targetRowId > 1 && rowBottomOffsets[targetRowId - 1] > availableSpace.Height)
+                //    break;
             }
             
-            Enumerable
-                .Range(1, rowsCount - 1)
-                .ToList()
-                .ForEach(x => rowBottomOffsets[x] = Math.Max(rowBottomOffsets[x], rowBottomOffsets[x-1]));
-            
             var rowHeights = new float[rowsCount];
             rowHeights[0] = rowBottomOffsets[0];
             
@@ -107,17 +121,17 @@ namespace QuestPDF.Elements.Table
             
             var totalHeight = rowHeights.Sum();
             var totalWidth = Columns.Sum(x => x.Width);
-
+            
             foreach (var cell in Children)
             {
-                if (!IsCellVisible(cell, rowsToDisplay))
+                if (cell.Row >= CurrentRow && cell.Row > rowsToDisplay)
                     continue;
 
-                var leftOffset = GetCellWidthOffset(cell);
-                var topOffset = rowHeights.Take(cell.Row - 1).Sum();
+                var leftOffset = cellOffsets[cell.Column - 1];
+                var topOffset = cell.Row == 1 ? 0 : rowBottomOffsets[cell.Row - 2];
 
                 var width = GetCellWidth(cell);
-                var height = rowHeights.Skip(cell.Row - 1).Take(cell.RowSpan).Sum();
+                var height = Enumerable.Range(cell.Row - 1, cell.RowSpan).TakeWhile(x => x < rowHeights.Length).Select(x => rowHeights[x]).Sum();
 
                 cellRenderingCommands.Add(new TableCellRenderingCommand()
                 {
@@ -134,14 +148,9 @@ namespace QuestPDF.Elements.Table
                 MaxRowRendered = rowsToDisplay
             };
             
-            float GetCellWidthOffset(TableCell cell)
-            {
-                return Columns.Take(cell.Column - 1).Select(x => x.Width).DefaultIfEmpty(0).Sum();
-            }
-
             float GetCellWidth(TableCell cell)
             {
-                return Columns.Skip(cell.Column - 1).Take(cell.ColumnSpan).Sum(x => x.Width);   
+                return cellOffsets[cell.Column + cell.ColumnSpan - 1] - cellOffsets[cell.Column - 1];
             }
             
             Size GetCellSize(TableCell cell)
@@ -156,11 +165,6 @@ namespace QuestPDF.Elements.Table
 
                 return measurement;
             }
-
-            bool IsCellVisible(TableCell cell, int maxRow)
-            {
-                return cell.Row <= maxRow;
-            }
         }
         
         int GetRowsCount()

+ 3 - 0
QuestPDF/Elements/Table/TableLayoutPlanner.cs

@@ -35,6 +35,9 @@ namespace QuestPDF.Elements.Table
 
                 foreach (var location in GenerateCoordinates(columnsCount, currentLocation))
                 {
+                    if (location.x + cell.ColumnSpan - 1 > columnsCount)
+                        continue;
+                    
                     cell.Column = location.x;
                     cell.Row = location.y;