Browse Source

Fixed rendering images

Marcin Ziąbek 4 years ago
parent
commit
c79a4a0c08

+ 67 - 67
QuestPDF.Examples/ElementExamples.cs

@@ -56,41 +56,41 @@ namespace QuestPDF.Examples
                 });
                 });
         }
         }
         
         
-        [Test]
-        public void Page()
-        {
-            RenderingTest
-                .Create()
-                .PageSize(298, 421)
-                .Render(container =>
-                {
-                    container
-                        .Background("#FFF")
-                        .Padding(15)
-                        .Page(page =>
-                        {
-                            page.Header()
-                                .Height(60)
-                                .Background(Colors.Grey.Lighten1)
-                                .AlignCenter()
-                                .AlignMiddle()
-                                .Text("Header");
-                    
-                            page.Content()
-                                .Background(Colors.Grey.Lighten2)
-                                .AlignCenter()
-                                .AlignMiddle()
-                                .Text("Content");
-                        
-                            page.Footer()
-                                .Height(30)
-                                .Background(Colors.Grey.Lighten1)
-                                .AlignCenter()
-                                .AlignMiddle()
-                                .Text("Footer");
-                        });
-                });
-        }
+        // [Test]
+        // public void Page()
+        // {
+        //     RenderingTest
+        //         .Create()
+        //         .PageSize(298, 421)
+        //         .Render(container =>
+        //         {
+        //             container
+        //                 .Background("#FFF")
+        //                 .Padding(15)
+        //                 .Page(page =>
+        //                 {
+        //                     page.Header()
+        //                         .Height(60)
+        //                         .Background(Colors.Grey.Lighten1)
+        //                         .AlignCenter()
+        //                         .AlignMiddle()
+        //                         .Text("Header");
+        //             
+        //                     page.Content()
+        //                         .Background(Colors.Grey.Lighten2)
+        //                         .AlignCenter()
+        //                         .AlignMiddle()
+        //                         .Text("Content");
+        //                 
+        //                     page.Footer()
+        //                         .Height(30)
+        //                         .Background(Colors.Grey.Lighten1)
+        //                         .AlignCenter()
+        //                         .AlignMiddle()
+        //                         .Text("Footer");
+        //                 });
+        //         });
+        // }
         
         
         [Test]
         [Test]
         public void Row()
         public void Row()
@@ -234,8 +234,8 @@ namespace QuestPDF.Examples
                         .AlignRight()
                         .AlignRight()
                         .Grid(grid =>
                         .Grid(grid =>
                         {
                         {
-                            grid.VerticalSpacing(15);
-                            grid.HorizontalSpacing(15);
+                            grid.VerticalSpacing(10);
+                            grid.HorizontalSpacing(10);
                             grid.AlignCenter();
                             grid.AlignCenter();
                             grid.Columns(10); // 12 by default
                             grid.Columns(10); // 12 by default
 
 
@@ -322,40 +322,40 @@ namespace QuestPDF.Examples
                             layers
                             layers
                                 .Layer()
                                 .Layer()
                                 .AlignBottom()
                                 .AlignBottom()
-                                .PageNumber("Page {number}", TextStyle.Default.Size(16).Color(Colors.Green.Medium));
+                                .PageNumber("Page {pdf:currentPage}", TextStyle.Default.Size(16).Color(Colors.Green.Medium));
                         });
                         });
                 });
                 });
         }
         }
 
 
-        [Test]
-        public void EnsureSpace()
-        {
-            RenderingTest
-                .Create()
-                .PageSize(300, 400)
-                .Render(container =>
-                {
-                    container
-                        .Padding(50)
-                        .Page(page =>
-                        {
-                            page.Header().PageNumber("Page {number}");
-                    
-                            page.Content().Height(300).Stack(content =>
-                            {
-                                content.Item().Height(200).Background(Colors.Grey.Lighten2);
-                        
-                                content.Item().EnsureSpace(100).Stack(stack =>
-                                {
-                                    stack.Spacing(10);
-                            
-                                    foreach (var _ in Enumerable.Range(0, 4))
-                                        stack.Item().Height(50).Background(Colors.Green.Lighten1);
-                                }); 
-                            });
-                        });
-                });
-        }
+        // [Test]
+        // public void EnsureSpace()
+        // {
+        //     RenderingTest
+        //         .Create()
+        //         .PageSize(300, 400)
+        //         .Render(container =>
+        //         {
+        //             container
+        //                 .Padding(50)
+        //                 .Page(page =>
+        //                 {
+        //                     page.Header().PageNumber("Page {pdf:currentPage}");
+        //             
+        //                     page.Content().Height(300).Stack(content =>
+        //                     {
+        //                         content.Item().Height(200).Background(Colors.Grey.Lighten2);
+        //                 
+        //                         content.Item().EnsureSpace(100).Stack(stack =>
+        //                         {
+        //                             stack.Spacing(10);
+        //                     
+        //                             foreach (var _ in Enumerable.Range(0, 4))
+        //                                 stack.Item().Height(50).Background(Colors.Green.Lighten1);
+        //                         }); 
+        //                     });
+        //                 });
+        //         });
+        // }
 
 
         [Test]
         [Test]
         public void RandomColorMatrix()
         public void RandomColorMatrix()

+ 3 - 3
QuestPDF.UnitTests/ShowOnceTest.cs

@@ -30,10 +30,10 @@ namespace QuestPDF.UnitTests
                 Child = child.Object
                 Child = child.Object
             };
             };
 
 
-            element.Draw(null, Size.Zero);
-            element.Draw(null, Size.Zero);
+            element.Draw(Size.Zero);
+            element.Draw(Size.Zero);
             
             
-            child.Verify(x => x.Draw(It.IsAny<ICanvas>(), It.IsAny<Size>()), Times.Once);
+            child.Verify(x => x.Draw(It.IsAny<Size>()), Times.Once);
         }
         }
         
         
         [Test]
         [Test]

+ 1 - 1
QuestPDF.UnitTests/TestEngine/ElementMock.cs

@@ -11,6 +11,6 @@ namespace QuestPDF.UnitTests.TestEngine
         public Action<Size> DrawFunc { get; set; }
         public Action<Size> DrawFunc { get; set; }
 
 
         internal override ISpacePlan Measure(Size availableSpace) => MeasureFunc(availableSpace);
         internal override ISpacePlan Measure(Size availableSpace) => MeasureFunc(availableSpace);
-        internal override void Draw(ICanvas canvas, Size availableSpace) => DrawFunc(availableSpace);
+        internal override void Draw(Size availableSpace) => DrawFunc(availableSpace);
     }
     }
 }
 }

+ 1 - 1
QuestPDF.UnitTests/TestEngine/TestPlan.cs

@@ -223,7 +223,7 @@ namespace QuestPDF.UnitTests.TestEngine
         
         
         public TestPlan CheckDrawResult()
         public TestPlan CheckDrawResult()
         {
         {
-            Element.Draw(Canvas, OperationInput);
+            Element.Draw(OperationInput);
             return this;
             return this;
         }
         }
 
 

+ 21 - 73
QuestPDF/Drawing/DocumentGenerator.cs

@@ -15,6 +15,23 @@ namespace QuestPDF.Drawing
     static class DocumentGenerator
     static class DocumentGenerator
     {
     {
         internal static void GeneratePdf(Stream stream, IDocument document)
         internal static void GeneratePdf(Stream stream, IDocument document)
+        {
+            var metadata = document.GetMetadata();
+            var canvas = new PdfCanvas(stream, metadata);
+            RenderDocument(canvas, document);
+        }
+        
+        internal static ICollection<byte[]> GenerateImages(IDocument document)
+        {
+            var metadata = document.GetMetadata();
+            var canvas = new ImageCanvas(metadata);
+            RenderDocument(canvas, document);
+
+            return canvas.Images;
+        }
+
+        private static void RenderDocument<TCanvas>(TCanvas canvas, IDocument document)
+            where TCanvas : ICanvas, IRenderingCanvas
         {
         {
             var container = new DocumentContainer();
             var container = new DocumentContainer();
             document.Compose(container);
             document.Compose(container);
@@ -23,21 +40,11 @@ namespace QuestPDF.Drawing
             var metadata = document.GetMetadata();
             var metadata = document.GetMetadata();
             var pageContext = new PageContext();
             var pageContext = new PageContext();
 
 
-            var timer = new Stopwatch();
-            
-            timer.Start();
-            RenderDocument(pageContext, new FreeCanvas(), content, metadata);
-            
-            Console.WriteLine($"First rendering pass: {timer.Elapsed:g}");
-            timer.Restart();
-            
-            var canvas = new PdfCanvas(stream, metadata);
-            RenderDocument(pageContext, canvas, content, metadata);
-            
-            Console.WriteLine($"Second rendering pass: {timer.Elapsed:g}");
+            RenderPass(pageContext, new FreeCanvas(), content, metadata);
+            RenderPass(pageContext, canvas, content, metadata);
         }
         }
-
-        private static void RenderDocument<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata)
+        
+        private static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata)
             where TCanvas : ICanvas, IRenderingCanvas
             where TCanvas : ICanvas, IRenderingCanvas
         {
         {
             content.HandleVisitor(x => x.Initialize(pageContext, canvas));
             content.HandleVisitor(x => x.Initialize(pageContext, canvas));
@@ -82,64 +89,5 @@ namespace QuestPDF.Drawing
             
             
             canvas.EndDocument();
             canvas.EndDocument();
         }
         }
-        
-        internal static IEnumerable<byte[]> GenerateImages(IDocument document)
-        {
-            return null;
-            
-            // var container = new DocumentContainer();
-            // document.Compose(container);
-            // var content = container.Compose();
-            //
-            // var metadata = document.GetMetadata();
-            //
-            // var currentPage = 1;
-            //
-            // while (true)
-            // {
-            //     var spacePlan = content.Measure(null, Size.Max) as Size;
-            //     byte[] result;
-            //
-            //     if (spacePlan == null)
-            //         break;
-            //     
-            //     try
-            //     {
-            //         result = RenderPage(spacePlan, content);
-            //     }
-            //     catch (Exception exception)
-            //     {
-            //         throw new DocumentDrawingException("An exception occured during document drawing.", exception);
-            //     }
-            //
-            //     yield return result;
-            //
-            //     if (currentPage >= metadata.DocumentLayoutExceptionThreshold)
-            //     {
-            //         throw new DocumentLayoutException("Composed layout generates infinite document.");
-            //     }
-            //
-            //     if (spacePlan is FullRender)
-            //         break;
-            //
-            //     currentPage++;
-            // }
-
-            // byte[] RenderPage(Size size, Element element)
-            // {
-            //     // scale the result so it is more readable
-            //     var scalingFactor = metadata.RasterDpi / (float) PageSizes.PointsPerInch;
-            //     
-            //     var imageInfo = new SKImageInfo((int) (size.Width * scalingFactor), (int) (size.Height * scalingFactor));
-            //     using var surface = SKSurface.Create(imageInfo);
-            //     surface.Canvas.Scale(scalingFactor);
-            //
-            //     var canvas = new SkiaCanvasBase(surface.Canvas, new Dictionary<string, int>());
-            //     element?.Draw(canvas, size);
-            //
-            //     surface.Canvas.Save();
-            //     return surface.Snapshot().Encode(SKEncodedImageFormat.Png, 100).ToArray();
-            // }
-        }
     }
     }
 }
 }

+ 53 - 0
QuestPDF/Drawing/ImageCanvas.cs

@@ -0,0 +1,53 @@
+using System.Collections.Generic;
+using QuestPDF.Helpers;
+using QuestPDF.Infrastructure;
+using SkiaSharp;
+
+namespace QuestPDF.Drawing
+{
+    internal class ImageCanvas : SkiaCanvasBase
+    {
+        private DocumentMetadata Metadata { get; }
+        private SKSurface Surface { get; set; }
+
+        internal ICollection<byte[]> Images { get; } = new List<byte[]>();
+        
+        public ImageCanvas(DocumentMetadata metadata)
+        {
+            Metadata = metadata;
+        }
+        
+        public override void BeginDocument()
+        {
+            
+        }
+
+        public override void EndDocument()
+        {
+            Canvas?.Dispose();
+            Surface?.Dispose();
+        }
+
+        public override void BeginPage(Size size)
+        {
+            var scalingFactor = Metadata.RasterDpi / (float) PageSizes.PointsPerInch;
+            
+            var imageInfo = new SKImageInfo((int) (size.Width * scalingFactor), (int) (size.Height * scalingFactor));
+            
+            Surface = SKSurface.Create(imageInfo);
+            Canvas = Surface.Canvas;
+            
+            Canvas.Scale(scalingFactor);
+        }
+
+        public override void EndPage()
+        {
+            Canvas.Save();
+            var image = Surface.Snapshot().Encode(SKEncodedImageFormat.Png, 100).ToArray();
+            Images.Add(image);
+            
+            Canvas.Dispose();
+            Surface.Dispose();
+        }
+    }
+}

+ 5 - 1
QuestPDF/Elements/PageNumber.cs

@@ -25,7 +25,7 @@ namespace QuestPDF.Elements
 
 
         internal override ISpacePlan Measure(Size availableSpace)
         internal override ISpacePlan Measure(Size availableSpace)
         {
         {
-            TextElement.Value = Regex.Replace(TextFormat, @"{pdf:[ \w]+}", "123");
+            TextElement.Value = GetText();
             return TextElement.Measure(availableSpace);
             return TextElement.Measure(availableSpace);
         }
         }
 
 
@@ -39,9 +39,13 @@ namespace QuestPDF.Elements
         {
         {
             var result = TextFormat;
             var result = TextFormat;
             
             
+            // replace known locations
             foreach (var location in PageContext.GetRegisteredLocations())
             foreach (var location in PageContext.GetRegisteredLocations())
                 result = result.Replace($"{{pdf:{location}}}", PageContext.GetLocationPage(location).ToString());
                 result = result.Replace($"{{pdf:{location}}}", PageContext.GetLocationPage(location).ToString());
 
 
+            // placeholder unknown locations
+            result = Regex.Replace(result, @"{pdf:[ \w]+}", "123");
+            
             return result;
             return result;
         }
         }
     }
     }