Compare commits

...

1 Commits

Author SHA1 Message Date
MarcinZiabek 704256510e Implemented experiment 2022-09-26 22:40:12 +02:00
13 changed files with 134 additions and 18 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ namespace QuestPDF.Examples
.PageSize(PageSizes.A4)
.ShowResults()
.MaxPages(10_000)
.EnableCaching(true)
//.EnableCaching(true)
.EnableDebugging(false)
.Render(container =>
{
+2 -2
View File
@@ -15,8 +15,8 @@ namespace QuestPDF.ReportSample
HeaderFields = HeaderFields(),
LogoData = Helpers.GetImage("Logo.png"),
Sections = Enumerable.Range(0, 40).Select(x => GenerateSection()).ToList(),
Photos = Enumerable.Range(0, 25).Select(x => GetReportPhotos()).ToList()
Sections = Enumerable.Range(0, 2000).Select(x => GenerateSection()).ToList(),
Photos = Enumerable.Range(0, 200).Select(x => GetReportPhotos()).ToList()
};
List<ReportHeaderField> HeaderFields()
+4 -1
View File
@@ -24,7 +24,10 @@ namespace QuestPDF.ReportSample
[Test]
public void GenerateAndShowPdf()
{
//ImagePlaceholder.Solid = true;
Settings.DocumentLayoutExceptionThreshold = 10_000;
Settings.EnableCaching = true;
Settings.EnableDebugging = false;
ImagePlaceholder.Solid = true;
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"test_result.pdf");
Report.GeneratePdf(path);
@@ -20,6 +20,7 @@ namespace QuestPDF.UnitTests.TestEngine
public void DrawRectangle(Position vector, Size size, string color) => DrawRectFunc(vector, size, color);
public void DrawText(SKTextBlob skTextBlob, Position position, TextStyle style) => throw new NotImplementedException();
public void DrawImage(SKImage image, Position position, Size size) => DrawImageFunc(image, position, size);
public void DrawPicture(SKPicture picture) => throw new NotImplementedException();
public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
@@ -18,7 +18,8 @@ namespace QuestPDF.UnitTests.TestEngine
public void DrawRectangle(Position vector, Size size, string color) => Operations.Add(new CanvasDrawRectangleOperation(vector, size, color));
public void DrawText(SKTextBlob skTextBlob, Position position, TextStyle style) => throw new NotImplementedException();
public void DrawImage(SKImage image, Position position, Size size) => Operations.Add(new CanvasDrawImageOperation(position, size));
public void DrawPicture(SKPicture picture) => throw new NotImplementedException();
public void DrawHyperlink(string url, Size size) => throw new NotImplementedException();
public void DrawSectionLink(string sectionName, Size size) => throw new NotImplementedException();
public void DrawSection(string sectionName) => throw new NotImplementedException();
+14 -2
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using QuestPDF.Drawing.Exceptions;
@@ -67,13 +68,24 @@ namespace QuestPDF.Drawing
ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
var debuggingState = Settings.EnableDebugging ? ApplyDebugging(content) : null;
debuggingState = null;
if (Settings.EnableCaching)
ApplyCaching(content);
//if (Settings.EnableCaching)
//ApplyCaching(content);
var pageContext = new PageContext();
var stopwatch = new Stopwatch();
stopwatch.Restart();
RenderPass(pageContext, new FreeCanvas(), content, debuggingState);
stopwatch.Stop();
Console.WriteLine($"Cold free: {stopwatch.Elapsed}");
stopwatch.Restart();
RenderPass(pageContext, canvas, content, debuggingState);
stopwatch.Stop();
Console.WriteLine($"Canvas: {stopwatch.Elapsed}");
}
internal static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DebuggingState? debuggingState)
+5
View File
@@ -51,6 +51,11 @@ namespace QuestPDF.Drawing
}
public void DrawPicture(SKPicture picture)
{
}
public void DrawHyperlink(string url, Size size)
{
+5
View File
@@ -38,6 +38,11 @@ namespace QuestPDF.Drawing
Canvas.DrawImage(image, new SKRect(vector.X, vector.Y, size.Width, size.Height));
}
public void DrawPicture(SKPicture picture)
{
Canvas.DrawPicture(picture);
}
public void DrawHyperlink(string url, Size size)
{
Canvas.DrawUrlAnnotation(new SKRect(0, 0, size.Width, size.Height), url);
+39
View File
@@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using SkiaSharp;
namespace QuestPDF.Drawing
{
internal class SkiaCaptureCanvas : SkiaCanvasBase
{
private SKPictureRecorder? PictureRecorder { get; set; }
private Size? CurrentPageSize { get; set; }
public SKPicture? CurrentPicture { get; set; }
public override void BeginDocument()
{
}
public override void BeginPage(Size size)
{
CurrentPageSize = size;
PictureRecorder = new SKPictureRecorder();
Canvas = PictureRecorder.BeginRecording(new SKRect(0, 0, size.Width, size.Height));
}
public override void EndPage()
{
CurrentPicture = PictureRecorder?.EndRecording();
PictureRecorder?.Dispose();
PictureRecorder = null;
}
public override void EndDocument() { }
}
}
+59
View File
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using QuestPDF.Drawing;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using SkiaSharp;
namespace QuestPDF.Elements
{
internal class DrawingCache : ContainerElement
{
private SkiaCaptureCanvas CaptureCanvas { get; } = new();
private Dictionary<int, SpacePlan> MeasureCache { get; } = new();
private Dictionary<int, SKPicture> DrawCache { get; } = new();
~DrawingCache()
{
foreach (var picture in DrawCache.Values)
picture.Dispose();
DrawCache.Clear();
}
internal override void Initialize(IPageContext pageContext, ICanvas canvas)
{
Child.VisitChildren(x => x.Canvas = CaptureCanvas);
base.Initialize(pageContext, canvas);
}
internal override SpacePlan Measure(Size availableSpace)
{
var cacheKey = PageContext.CurrentPage;
if (MeasureCache.TryGetValue(cacheKey, out var result))
return result;
var childSize = Child?.Measure(availableSpace) ?? SpacePlan.FullRender(Size.Zero);
MeasureCache.Add(cacheKey, childSize);
return childSize;
}
internal override void Draw(Size availableSpace)
{
var cacheKey = PageContext.CurrentPage;
if (DrawCache.TryGetValue(cacheKey, out var result))
{
Canvas.DrawPicture(result);
return;
}
CaptureCanvas.BeginPage(availableSpace);
Child?.Draw(availableSpace);
CaptureCanvas.EndPage();
var picture = CaptureCanvas.CurrentPicture;
DrawCache.Add(cacheKey, picture);
}
}
}
+1
View File
@@ -30,6 +30,7 @@ namespace QuestPDF.Elements
public void Compose(IContainer container)
{
container
//.Element(new DrawingCache())
.Background(BackgroundColor)
.Layers(layers =>
{
@@ -15,17 +15,6 @@ namespace QuestPDF.Fluent
return descriptor;
}
public static T Fallback<T>(this T descriptor, TextStyle? value = null) where T : TextSpanDescriptor
{
descriptor.TextStyle.Fallback = value;
return descriptor;
}
public static T Fallback<T>(this T descriptor, Func<TextStyle, TextStyle> handler) where T : TextSpanDescriptor
{
return descriptor.Fallback(handler(TextStyle.Default));
}
public static T FontColor<T>(this T descriptor, string value) where T : TextSpanDescriptor
{
descriptor.MutateTextStyle(x => x.FontColor(value));
+1
View File
@@ -10,6 +10,7 @@ namespace QuestPDF.Infrastructure
void DrawRectangle(Position vector, Size size, string color);
void DrawText(SKTextBlob skTextBlob, Position position, TextStyle style);
void DrawImage(SKImage image, Position position, Size size);
void DrawPicture(SKPicture picture);
void DrawHyperlink(string url, Size size);
void DrawSectionLink(string sectionName, Size size);