Compare commits

...

76 Commits

Author SHA1 Message Date
Marcin Ziąbek 51508bbe0b Table: added support for headers and footers 2022-01-06 21:10:54 +01:00
Marcin Ziąbek 62b5054a2f Updated release notes 2022-01-06 00:40:32 +01:00
Marcin Ziąbek 51dac22422 2022.1.0-beta3 Renaming Box() to MinimalBox() 2022-01-06 00:22:07 +01:00
Marcin Ziąbek 01980e5635 Table: row height fixes for overlapping cells. Added code examples 2022-01-06 00:06:24 +01:00
Marcin Ziąbek 6e59fa6e3d Table: improved repeating+paging support, added example 2022-01-05 20:30:23 +01:00
Marcin Ziąbek 4003337d01 Fixed: traversing elements graph 2022-01-05 01:35:29 +01:00
Marcin Ziąbek 5931b12b90 VisitChildren -> GetChildren traversal refactorization 2022-01-05 01:10:05 +01:00
Marcin Ziąbek 935c575221 Table: added default style, fixed bugs, added examples 2022-01-05 00:52:28 +01:00
Marcin Ziąbek 18a710e2a3 Table: fixed cross-cell size adjusting 2022-01-03 17:13:57 +01:00
Marcin Ziąbek d39e93b924 Update Table.cs 2022-01-02 22:27:48 +01:00
MarcinZiabek c8cc968705 Typo fixes 2021-12-30 21:53:42 +01:00
MarcinZiabek ffccbe37a4 2022.1.0-beta0 2021-12-30 21:43:07 +01:00
MarcinZiabek a6439c1883 2022.1.0-alpha0 2021-12-30 21:28:09 +01:00
MarcinZiabek c0e4ec6df1 Border radius: added example 2021-12-30 21:07:34 +01:00
MarcinZiabek a80258aa58 Improved readibility of the table layout algorithm 2021-12-30 20:29:32 +01:00
MarcinZiabek 48c5771abb Table layout: refactorization 2021-12-30 19:56:51 +01:00
MarcinZiabek b79122aca5 Table: layouting improvements for paging 2021-12-30 19:42:40 +01:00
MarcinZiabek 2fcf543817 Fixed: corner cases of paging support 2021-12-30 18:40:54 +01:00
MarcinZiabek 7f72e50eb8 Improved wrapping support 2021-12-29 22:51:01 +01:00
MarcinZiabek f718cb3324 Table: optimized rendering performance 2021-12-27 18:24:37 +01:00
MarcinZiabek efdc8903a5 Table: minor optimizations + performance test 2021-12-26 17:04:59 +01:00
MarcinZiabek 647b1fd0f4 Rendering algorithm partially working 2021-12-25 11:53:39 +01:00
MarcinZiabek 8a62591940 Table: refactorization, cell placement algorithm 2021-12-24 14:40:54 +01:00
Marcin Ziąbek 6da3075e7a Improved table paging support 2021-12-19 05:11:23 +01:00
Marcin Ziąbek 0a27b80b73 Row: added support for mixed columns (constant + relational), good when performing visual column merging 2021-12-18 16:54:35 +01:00
Marcin Ziąbek 656d1a6ecf Improved Row element stability 2021-12-16 01:39:26 +01:00
Marcin Ziąbek 5f636beb9d Added missing assertions to test that are supposed to throw an exception 2021-12-09 17:10:45 +01:00
Marcin Ziąbek 10683776bb 2021.12.0 2021-12-06 09:28:02 +01:00
Marcin Ziąbek f2c47c4fd3 2021.12.0-alpha1 2021-11-30 00:34:04 +01:00
Marcin Ziąbek 77b8f04659 Synced to 2021.12-alpha0 2021-11-19 00:50:38 +01:00
Marcin Ziąbek 5235ada66f Merge branch 'main' into element-proxy
# Conflicts:
#	QuestPDF/Drawing/PdfCanvas.cs
#	QuestPDF/QuestPDF.csproj
2021-11-19 00:46:46 +01:00
Marcin Ziąbek 4ce66878f2 2021.12.0-alpha0 2021-11-19 00:24:32 +01:00
Marcin Ziąbek 79cc5f1507 Added support for XPS rendering 2021-11-19 00:22:45 +01:00
Marcin Ziąbek 7c7d461c4b Merge pull request #53 from donmurta/main
Add simple chart example
2021-11-14 23:09:27 +01:00
Marcin Ziąbek 63af713935 2021.11.4 - Fixed measuring the Inlined element 2021-11-14 23:03:22 +01:00
Don Murta 2419a25cbd Add simple chart example 2021-11-09 10:26:46 -07:00
Marcin Ziąbek 014ec15908 2021.11.3 2021-11-07 16:46:34 +01:00
Marcin Ziąbek 82e29d5fdd ImagePlaceholder.Solid = true; 2021-11-07 16:19:54 +01:00
Marcin Ziąbek c64754241d Updated base to 2021.11 2021-11-04 01:02:44 +01:00
Marcin Ziąbek 9de87061e4 Merge branch 'main' into element-proxy
# Conflicts:
#	QuestPDF.ReportSample/Layouts/PhotoTemplate.cs
#	QuestPDF.ReportSample/Layouts/SectionTemplate.cs
#	QuestPDF.ReportSample/Tests.cs
#	QuestPDF/Drawing/DocumentGenerator.cs
#	QuestPDF/Elements/Constrained.cs
#	QuestPDF/Infrastructure/Position.cs
#	QuestPDF/Infrastructure/Size.cs
2021-11-04 00:22:22 +01:00
Marcin Ziąbek 86cfd22316 2021.11.0-beta3 2021-11-03 21:39:20 +01:00
Marcin Ziąbek 520bfc840c Improved code benchmarking (removed an unnecessary cost of image placeholder generation) 2021-11-03 21:22:08 +01:00
Marcin Ziąbek 22cdad69b7 Text element improvement: null string behaves like an empty text, not throws an exception 2021-11-03 21:21:23 +01:00
Marcin Ziąbek d260fa7587 Added generating symbols 2021-10-29 01:30:28 +02:00
Marcin Ziąbek 011668fb4c Image: added support for common overloads 2021-10-29 01:24:56 +02:00
Marcin Ziąbek 5a886452cf Merge pull request #40 from QuestPDF/2021.11
2021.11
2021-10-23 03:07:56 +02:00
Marcin Ziąbek b044208195 Updated nuget details 2021-10-23 03:02:18 +02:00
Marcin Ziąbek dadb8a5087 Improved test engine. Added more examples 2021-10-23 02:59:47 +02:00
Marcin Ziąbek 11f0809efc Improved default text style 2021-10-23 02:59:29 +02:00
Marcin Ziąbek 0a6673dd4f Update QuestPDF.csproj 2021-10-21 15:46:31 +02:00
Marcin Ziąbek 525bf534e5 Update DocumentGenerator.cs 2021-10-19 00:37:07 +02:00
Marcin Ziąbek 68f050a154 Adjusted tests for better benchmarking 2021-10-16 22:34:54 +02:00
Marcin Ziąbek fd696c5b66 Added missing tests to the constrained element 2021-10-12 23:58:28 +02:00
Marcin Ziąbek 0ccc8cc236 Improved the DocumentLayoutException message 2021-10-11 23:01:26 +02:00
Marcin Ziąbek 9ef444462a Implemented the Inlined document 2021-10-11 22:48:44 +02:00
Marcin Ziąbek 479915b68f Implemented the Inlined element 2021-10-11 01:48:12 +02:00
Marcin Ziąbek 5deea91fe4 Code refactorization 2021-10-10 23:21:11 +02:00
Marcin Ziąbek 7174a2afa1 Code style improvements 2021-10-10 19:17:31 +02:00
Marcin Ziąbek 1371fe1df9 Merge pull request #32 from QuestPDF/global-text-style
Global text style
2021-10-10 18:40:19 +02:00
Marcin Ziąbek bb00dfd4d4 Merge pull request #28 from jcl86/main
SkipOnce element for different headers and footers
2021-10-10 18:39:15 +02:00
Marcin Ziąbek 70e5783f0e Updated report sample to follow new text style approach 2021-10-07 23:23:07 +02:00
Marcin Ziąbek e8b7f38187 Fixed setting text style in the text-block-elements 2021-10-07 23:10:12 +02:00
Marcin Ziąbek c2ba2addfc Fixed handling global text style when setting block-wide style 2021-10-07 22:56:51 +02:00
Marcin Ziąbek e379502a64 Implemented prototype of global, document-wide text style 2021-10-07 22:38:41 +02:00
Marcin Ziąbek 88e58500a8 Improved caching 2021-10-07 21:26:14 +02:00
jcl-aadlab caa779e1e0 Added skip element for headers and footers 2021-10-05 10:50:55 +02:00
Marcin Ziąbek 4938e97e6d Update readme.md 2021-10-01 14:09:25 +02:00
Marcin Ziąbek 7980befb77 Synced with 2021.10 2021-10-01 02:32:35 +02:00
Marcin Ziąbek f3b75b43ac Merge branch 'main' of https://github.com/QuestPDF/library into element-proxy
 Conflicts:
	QuestPDF.ReportSample/QuestPDF.ReportSample.csproj
	QuestPDF.ReportSample/Tests.cs
	QuestPDF.UnitTests/ShowOnceTest.cs
	QuestPDF.UnitTests/StackTests.cs
	QuestPDF.UnitTests/TestEngine/Operations/ChildMeasureOperation.cs
	QuestPDF.UnitTests/TestEngine/SingleChildTests.cs
	QuestPDF.UnitTests/TestEngine/TestPlan.cs
	QuestPDF/Drawing/DocumentGenerator.cs
	QuestPDF/Drawing/TextRender.cs
	QuestPDF/Elements/PageBreak.cs
	QuestPDF/Elements/PageNumber.cs
	QuestPDF/Elements/Rotate.cs
	QuestPDF/Elements/Row.cs
	QuestPDF/Elements/Scale.cs
	QuestPDF/Elements/SimpleRotate.cs
	QuestPDF/Elements/Text.cs
	QuestPDF/Elements/Unconstrained.cs
	QuestPDF/Infrastructure/Element.cs
2021-10-01 02:20:21 +02:00
Marcin Ziąbek 17e2727833 Added missing option to style a line 2021-10-01 01:44:53 +02:00
Marcin Ziąbek eca93b7e66 Added debug pointers to page 2021-09-07 11:17:49 +02:00
Marcin Ziąbek 6a3bfd855e Improved infinite layout debugging experience 2021-09-07 00:32:51 +02:00
Marcin Ziąbek 5e7f2a3adf Simple layout debugging when overflow 2021-09-06 21:43:31 +02:00
Marcin Ziąbek 2f1dd4b383 Improved tests with Benchmark.net 2021-09-06 21:43:12 +02:00
Marcin Ziąbek adec37007b Refactorization: space planning algorithm 2021-09-02 21:48:20 +02:00
Marcin Ziąbek 814d325376 Implemented measurement cache proxy 2021-09-02 13:30:39 +02:00
160 changed files with 4490 additions and 1148 deletions
-33
View File
@@ -1,33 +0,0 @@
using System.IO;
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class BarCode
{
[Test]
public void Example()
{
FontManager.RegisterFontType("LibreBarcode39", File.OpenRead("LibreBarcode39-Regular.ttf"));
RenderingTest
.Create()
.PageSize(400, 100)
.FileName()
.ShowResults()
.Render(container =>
{
container
.Background(Colors.White)
.AlignCenter()
.AlignMiddle()
.Text("*QuestPDF*", TextStyle.Default.FontType("LibreBarcode39").Size(64));
});
}
}
}
+13 -13
View File
@@ -1,4 +1,6 @@
using NUnit.Framework;
using System.IO;
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
@@ -6,27 +8,25 @@ using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
[TestFixture]
public class BarcodeExamples
{
[Test]
public void Barcode()
public void Example()
{
FontManager.RegisterFontType("LibreBarcode39", File.OpenRead("LibreBarcode39-Regular.ttf"));
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.PageSize(400, 100)
.ShowResults()
.Render(container =>
{
container
.Background("#FFF")
.Padding(25)
.Stack(stack =>
{
stack.Item().Border(1).Background(Colors.Grey.Lighten3).Padding(5).Text("Barcode Example");
stack.Item().Border(1).Padding(5).AlignCenter().Text("*123456789*", TextStyle.Default.FontType("CarolinaBar-Demo-25E2").Size(20));
});
.Background(Colors.White)
.AlignCenter()
.AlignMiddle()
.Text("*QuestPDF*", TextStyle.Default.FontType("LibreBarcode39").Size(64));
});
}
}
}
}
+57
View File
@@ -0,0 +1,57 @@
using Microcharts;
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using SkiaSharp;
namespace QuestPDF.Examples
{
public class CanvasExamples
{
[Test]
public void BorderRadius()
{
RenderingTest
.Create()
.PageSize(175, 100)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Background(Colors.Grey.Lighten2)
.Padding(25)
.MinimalBox()
.Layers(layers =>
{
layers.Layer().Canvas((canvas, size) =>
{
DrawRoundedRectangle(Colors.White, false);
DrawRoundedRectangle(Colors.Blue.Darken2, true);
void DrawRoundedRectangle(string color, bool isStroke)
{
using var paint = new SKPaint
{
Color = SKColor.Parse(color),
IsStroke = isStroke,
StrokeWidth = 2,
IsAntialias = true
};
canvas.DrawRoundRect(0, 0, size.Width, size.Height, 20, 20, paint);
}
});
layers
.PrimaryLayer()
.PaddingVertical(10)
.PaddingHorizontal(20)
.Text("Sample text", TextStyle.Default.Size(16).Color(Colors.Blue.Darken2).SemiBold());
});
});
}
}
}
+85
View File
@@ -0,0 +1,85 @@
using System.Linq;
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using Microcharts;
using SkiaSharp;
namespace QuestPDF.Examples
{
public class ChartExample
{
[Test]
public void MicrochartChart()
{
var entries = new[]
{
new ChartEntry(212)
{
Label = "UWP",
ValueLabel = "112",
Color = SKColor.Parse("#2c3e50")
},
new ChartEntry(248)
{
Label = "Android",
ValueLabel = "648",
Color = SKColor.Parse("#77d065")
},
new ChartEntry(128)
{
Label = "iOS",
ValueLabel = "428",
Color = SKColor.Parse("#b455b6")
},
new ChartEntry(514)
{
Label = "Forms",
ValueLabel = "214",
Color = SKColor.Parse("#3498db")
}
};
RenderingTest
.Create()
.PageSize(400, 600)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Background(Colors.White)
.Padding(25)
.Stack(stack =>
{
stack
.Item()
.PaddingBottom(10)
.Text("Chart example", TextStyle.Default.Size(20).SemiBold().Color(Colors.Blue.Medium));
stack
.Item()
.Border(1)
.ExtendHorizontal()
.Height(300)
.Canvas((canvas, size) =>
{
var chart = new BarChart
{
Entries = entries,
LabelOrientation = Orientation.Horizontal,
ValueLabelOrientation = Orientation.Horizontal,
IsAnimated = false,
};
chart.DrawContent(canvas, (int)size.Width, (int)size.Height);
});
});
});
}
}
}
@@ -0,0 +1,56 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class ComplexLayoutBenchmark
{
[Test]
public void ComplexLayout()
{
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.ProducePdf()
.ShowResults()
.Render(x => GenerateStructure(x, 16));
}
private void GenerateStructure(IContainer container, int level)
{
if (level <= 0)
{
container.Background(Placeholders.BackgroundColor()).Height(10);
return;
}
level--;
if (level % 3 == 0)
{
container
.Border(level / 4f)
.BorderColor(Colors.Black)
.Row(row =>
{
row.RelativeColumn().Element(x => GenerateStructure(x, level));
row.RelativeColumn().Element(x => GenerateStructure(x, level));
});
}
else
{
container
.Border(level / 4f)
.BorderColor(Colors.Black)
.Stack(stack =>
{
stack.Item().Element(x => GenerateStructure(x, level));
stack.Item().Element(x => GenerateStructure(x, level));
});
}
}
}
}
+76
View File
@@ -0,0 +1,76 @@
using NUnit.Framework;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
namespace QuestPDF.Examples
{
public class DebuggingTesting
{
[Test]
public void Stack()
{
Assert.Throws<DocumentLayoutException>(() =>
{
RenderingTest
.Create()
.PageSize(500, 360)
.Render(container =>
{
container
.Padding(10)
.Width(100)
.Background(Colors.Grey.Lighten3)
.DebugPointer("Example debug pointer")
.Stack(x =>
{
x.Item().Text("Test");
x.Item().Width(150);
});
});
});
}
[Test]
public void Simple()
{
Assert.Throws<DocumentLayoutException>(() =>
{
RenderingTest
.Create()
.PageSize(500, 360)
.Render(container =>
{
container
.Padding(10)
.Width(100)
.Background(Colors.Grey.Lighten3)
.Width(150)
.Text("Test");
});
});
}
[Test]
public void DebugPointer()
{
Assert.Throws<DocumentLayoutException>(() =>
{
RenderingTest
.Create()
.PageSize(500, 360)
.Render(container =>
{
container
.Background(Colors.Grey.Lighten3)
.Padding(10)
.Width(100)
.DebugPointer("Example debug pointer")
.Width(150)
.Text("Example");
});
});
}
}
}
@@ -0,0 +1,48 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class DefaultTextStyleExample
{
[Test]
public void DefaultTextStyle()
{
RenderingTest
.Create()
.ProduceImages()
.ShowResults()
.RenderDocument(container =>
{
container.Page(page =>
{
// all text in this set of pages has size 20
page.DefaultTextStyle(TextStyle.Default.Size(20));
page.Margin(20);
page.Size(PageSizes.A4);
page.Background(Colors.White);
page.Content().Stack(stack =>
{
stack.Item().Text(Placeholders.Sentence());
stack.Item().Text(text =>
{
// text in this block is additionally semibold
text.DefaultTextStyle(TextStyle.Default.SemiBold());
text.Line(Placeholders.Sentence());
// this text has size 20 but also semibold and red
text.Span(Placeholders.Sentence(), TextStyle.Default.Color(Colors.Red.Medium));
});
});
});
});
}
}
}
@@ -0,0 +1,53 @@
using System.Drawing;
using System.Linq;
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class DefaultTextStyleExamples
{
[Test]
public void Placeholder()
{
RenderingTest
.Create()
.PageSize(220, 270)
.ProduceImages()
.ShowResults()
.EnableDebugging()
.Render(container =>
{
container
.Padding(10)
.DefaultTextStyle(TextStyle.Default.Bold().Underline())
.Stack(stack =>
{
stack.Item().Text("Default style applies to all children", TextStyle.Default);
stack.Item().Text("You can override certain styles", TextStyle.Default.Underline(false).Color(Colors.Green.Darken2));
stack.Item().PaddingTop(10).Border(1).Grid(grid =>
{
grid.Columns(4);
foreach (var i in Enumerable.Range(1, 16))
{
grid.Item()
.Border(1)
.BorderColor(Colors.Grey.Lighten1)
.Background(Colors.Grey.Lighten3)
.Width(50)
.Height(50)
.AlignCenter()
.AlignMiddle()
.Text(i, TextStyle.Default.Size(16 + i / 4));
}
});
});
});
}
}
}
@@ -0,0 +1,55 @@
using System.Linq;
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class DifferentHeaderOnFirstPageExample
{
[Test]
public void Placeholder()
{
RenderingTest
.Create()
.PageSize(PageSizes.A6)
.ProduceImages()
.ShowResults()
.EnableDebugging()
.RenderDocument(container =>
{
container.Page(page =>
{
page.Size(PageSizes.A6);
page.Margin(30);
page.Background(Colors.White);
page.Header().Stack(stack =>
{
stack.Item().ShowOnce().Background(Colors.Blue.Lighten2).Height(60);
stack.Item().SkipOnce().Background(Colors.Green.Lighten2).Height(40);
});
page.Content().PaddingVertical(10).Stack(stack =>
{
stack.Spacing(10);
foreach (var _ in Enumerable.Range(0, 13))
stack.Item().Background(Colors.Grey.Lighten2).Height(40);
});
page.Footer().AlignCenter().Text(text =>
{
text.DefaultTextStyle(TextStyle.Default.Size(16));
text.CurrentPageNumber();
text.Span(" / ");
text.TotalPages();
});
});
});
}
}
}
+5 -30
View File
@@ -17,7 +17,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(200, 150)
.FileName()
.Render(container =>
{
container
@@ -33,7 +32,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.Render(container =>
{
container
@@ -63,7 +61,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(740, 200)
.FileName()
.Render(container =>
{
container
@@ -104,7 +101,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(740, 200)
.FileName()
.Render(container =>
{
container
@@ -126,7 +122,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(500, 360)
.FileName()
.Render(container =>
{
container
@@ -149,12 +144,11 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(210, 210)
.FileName()
.Render(container =>
{
container
.Padding(25)
.Debug("Grid example", Colors.Blue.Medium)
.DebugArea("Grid example", Colors.Blue.Medium)
.Grid(grid =>
{
grid.Columns(3);
@@ -172,7 +166,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 200)
.FileName()
.Render(container =>
{
var text = "";
@@ -195,7 +188,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(400, 230)
.FileName()
.Render(container =>
{
var textStyle = TextStyle.Default.Size(14);
@@ -230,7 +222,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 200)
.FileName()
.Render(container =>
{
container
@@ -260,7 +251,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(400, 250)
.FileName()
.Render(container =>
{
container
@@ -336,7 +326,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.Render(container =>
{
container
@@ -381,7 +370,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(450, 150)
.FileName()
.Render(container =>
{
container
@@ -414,7 +402,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(500, 175)
.FileName()
.Render(container =>
{
container
@@ -441,7 +428,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.Render(container =>
{
container
@@ -481,7 +467,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 150)
.FileName()
.Render(container =>
{
container
@@ -489,7 +474,7 @@ namespace QuestPDF.Examples
.Padding(15)
.Border(4)
.BorderColor(Colors.Blue.Medium)
//.Box()
//.MinimalBox()
.Background(Colors.Grey.Lighten2)
.Padding(15)
.Text("Test of the \n box element", TextStyle.Default.Size(20));
@@ -502,7 +487,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 175)
.FileName()
.Render(container =>
{
container
@@ -554,12 +538,11 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 200)
.FileName()
.Render(container =>
{
container
.Background("#FFF")
.Box()
.MinimalBox()
.Padding(25)
@@ -582,7 +565,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(650, 450)
.FileName()
.Render(container =>
{
container
@@ -606,7 +588,7 @@ namespace QuestPDF.Examples
return element;
})
.Box()
.MinimalBox()
.Background(Colors.White)
.Padding(10)
.Text($"Rotated {turns * 90}°", TextStyle.Default.Size(16));
@@ -621,7 +603,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.Render(container =>
{
container
@@ -648,7 +629,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.Render(container =>
{
container
@@ -680,7 +660,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(350, 350)
.FileName()
.Render(container =>
{
container
@@ -707,7 +686,7 @@ namespace QuestPDF.Examples
return element;
})
.Box()
.MinimalBox()
.Background(Colors.White)
.Padding(10)
.Text($"Flipped {turns}", TextStyle.Default.Size(16));
@@ -722,7 +701,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(200, 200)
.FileName()
.Render(container =>
{
container
@@ -748,7 +726,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(400, 350)
.FileName()
.Render(container =>
{
container
@@ -785,7 +762,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(500, 225)
.FileName()
.Render(container =>
{
container
@@ -839,7 +815,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(600, 310)
.FileName()
.Render(container =>
{
container
+43 -7
View File
@@ -3,6 +3,7 @@ using System.Diagnostics;
using System.Runtime.CompilerServices;
using QuestPDF.Elements;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples.Engine
@@ -17,7 +18,10 @@ namespace QuestPDF.Examples.Engine
{
private string FileNamePrefix = "test";
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()
@@ -25,12 +29,12 @@ namespace QuestPDF.Examples.Engine
}
public static RenderingTest Create()
public static RenderingTest Create([CallerMemberName] string fileName = "test")
{
return new RenderingTest();
return new RenderingTest().FileName(fileName);
}
public RenderingTest FileName([CallerMemberName] string fileName = "test")
public RenderingTest FileName(string fileName)
{
FileNamePrefix = fileName;
return this;
@@ -65,14 +69,46 @@ namespace QuestPDF.Examples.Engine
return this;
}
public RenderingTest MaxPages(int value)
{
MaxPagesThreshold = value;
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)
{
var container = new Container();
content(container);
RenderDocument(container =>
{
container.Page(page =>
{
page.Size(new PageSize(Size.Width, Size.Height));
page.Content().Container().Background(Colors.White).Element(content);
});
});
}
var maxPages = ResultType == RenderingTestResult.Pdf ? 1000 : 10;
var document = new SimpleDocument(container, Size, maxPages);
public void RenderDocument(Action<IDocumentContainer> content)
{
MaxPagesThreshold ??= ResultType == RenderingTestResult.Pdf ? 1000 : 10;
var document = new SimpleDocument(content, MaxPagesThreshold.Value, ApplyCaching, ApplyDebugging);
Render(document);
}
private void Render(IDocument document)
{
if (ResultType == RenderingTestResult.Images)
{
Func<int, string> fileNameSchema = i => $"{FileNamePrefix}-${i}.png";
+13 -12
View File
@@ -1,4 +1,5 @@
using QuestPDF.Drawing;
using System;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
@@ -10,15 +11,17 @@ namespace QuestPDF.Examples.Engine
{
public const int ImageScalingFactor = 2;
private IContainer Container { get; }
private Size Size { get; }
private Action<IDocumentContainer> Content { get; }
private int MaxPages { get; }
private bool ApplyCaching { get; }
private bool ApplyDebugging { get; }
public SimpleDocument(IContainer container, Size size, int maxPages)
public SimpleDocument(Action<IDocumentContainer> content, int maxPages, bool applyCaching, bool applyDebugging)
{
Container = container;
Size = size;
Content = content;
MaxPages = maxPages;
ApplyCaching = applyCaching;
ApplyDebugging = applyDebugging;
}
public DocumentMetadata GetMetadata()
@@ -26,17 +29,15 @@ namespace QuestPDF.Examples.Engine
return new DocumentMetadata()
{
RasterDpi = PageSizes.PointsPerInch * ImageScalingFactor,
DocumentLayoutExceptionThreshold = MaxPages
DocumentLayoutExceptionThreshold = MaxPages,
ApplyCaching = ApplyCaching,
ApplyDebugging = ApplyDebugging
};
}
public void Compose(IDocumentContainer container)
{
container.Page(page =>
{
page.Size(new PageSize(Size.Width, Size.Height));
page.Content().Container().Background(Colors.White).Element(Container as Container);
});
Content(container);
}
}
}
+53
View File
@@ -0,0 +1,53 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class EnsureSpaceExample
{
[Test]
public void EnsureSpaceWith()
{
RenderingTest
.Create()
.ProduceImages()
.ShowResults()
.RenderDocument(container =>
{
container.Page(page =>
{
page.Margin(20);
page.Size(PageSizes.A7.Landscape());
page.Background(Colors.White);
page.Header().Text("With ensure space", TextStyle.Default.SemiBold());
page.Content().Stack(stack =>
{
stack
.Item()
.ExtendHorizontal()
.Height(75)
.Background(Colors.Grey.Lighten2);
stack
.Item()
.EnsureSpace(100)
.Text(Placeholders.LoremIpsum());
});
page.Footer().Text(text =>
{
text.Span("Page ");
text.CurrentPageNumber();
text.Span(" out of ");
text.TotalPages();
});
});
});
}
}
}
+6 -5
View File
@@ -12,12 +12,14 @@ namespace QuestPDF.Examples
{
return container
.Border(1)
.Background(dark ? Colors.Grey.Lighten2 : Colors.White)
.Padding(10);
.BorderColor(Colors.Grey.Medium)
.Background(dark ? Colors.Grey.Lighten3 : Colors.White)
.Padding(5);
}
public static void LabelCell(this IContainer container, string text) => container.Cell(true).Text(text, TextStyle.Default.Medium());
public static void LabelCell(this IContainer container, string text) => container.Cell(true).Text(text, TextStyle.Default.SemiBold());
public static IContainer ValueCell(this IContainer container) => container.Cell(false);
public static void ValueCell(this IContainer container, string text) => container.ValueCell().Text(text, TextStyle.Default);
}
public class FrameExample
@@ -28,7 +30,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(550, 400)
.FileName()
.ShowResults()
.Render(container =>
{
@@ -37,7 +38,7 @@ namespace QuestPDF.Examples
.Padding(25)
.Stack(stack =>
{
for(var i=1; i<=4; i++)
for(var i = 1; i <= 4; i++)
{
stack.Item().Row(row =>
{
+51
View File
@@ -0,0 +1,51 @@
using System.IO;
using NUnit.Framework;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
namespace QuestPDF.Examples
{
public class ImageExamples
{
[Test]
public void LoadingImage()
{
RenderingTest
.Create()
.PageSize(PageSizes.A5)
.ProducePdf()
.ShowResults()
.Render(page =>
{
page.Padding(25).Stack(stack =>
{
stack.Spacing(25);
stack.Item().Image("logo.png");
var binaryData = File.ReadAllBytes("logo.png");
stack.Item().Image(binaryData);
using var stream = new FileStream("logo.png", FileMode.Open);
stack.Item().Image(stream);
});
});
}
[Test]
public void Exception()
{
Assert.Throws<DocumentComposeException>(() =>
{
RenderingTest
.Create()
.PageSize(PageSizes.A2)
.ProducePdf()
.ShowResults()
.Render(page => page.Image("non_existent.png"));
});
}
}
}
+123
View File
@@ -0,0 +1,123 @@
using System;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class InlinedExamples
{
[Test]
public void Inlined()
{
RenderingTest
.Create()
.PageSize(800, 650)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Padding(25)
.Decoration(decoration =>
{
decoration.Header().Text(text =>
{
text.DefaultTextStyle(TextStyle.Default.Size(20));
text.CurrentPageNumber();
text.Span(" / ");
text.TotalPages();
});
decoration
.Content()
.PaddingTop(25)
//.MinimalBox()
.Border(1)
.Background(Colors.Grey.Lighten2)
.Inlined(inlined =>
{
inlined.Spacing(25);
inlined.AlignSpaceAround();
inlined.BaselineMiddle();
var random = new Random(123);
foreach (var _ in Enumerable.Range(0, 50))
{
var width = random.Next(2, 7);
var height = random.Next(2, 7);
var sizeText = $"{width}×{height}";
inlined
.Item()
.Border(1)
.Width(width * 25)
.Height(height * 25)
.Background(Placeholders.BackgroundColor())
.Layers(layers =>
{
layers.Layer().Grid(grid =>
{
grid.Columns(width);
Enumerable.Range(0, width * height).ToList().ForEach(x => grid.Item().Border(1).BorderColor(Colors.White).Width(25).Height(25));
});
layers
.PrimaryLayer()
.AlignCenter()
.AlignMiddle()
.Text(sizeText, TextStyle.Default.Size(15));
});
}
});
});
});
}
[Test]
public void Inline_AlignLeft_BaselineBottom()
{
RenderingTest
.Create()
.PageSize(800, 600)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Padding(20)
.MinimalBox()
.Border(1)
.Background(Colors.Grey.Lighten4)
.Inlined(inlined =>
{
inlined.VerticalSpacing(50);
inlined.HorizontalSpacing(25);
inlined.AlignRight();
inlined.BaselineMiddle();
foreach (var _ in Enumerable.Range(0, 100))
inlined.Item().Element(RandomBlock);
});
});
void RandomBlock(IContainer container)
{
container
.Width(Placeholders.Random.Next(1, 5) * 20)
.Height(Placeholders.Random.Next(1, 5) * 20)
.Border(1)
.BorderColor(Colors.Grey.Darken2)
.Background(Placeholders.BackgroundColor());
}
}
}
}
+2 -1
View File
@@ -36,7 +36,8 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(350, 280)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
{
container
-4
View File
@@ -13,7 +13,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.ShowResults()
.Render(container =>
{
@@ -37,7 +36,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(200, 150)
.FileName()
.Render(container =>
{
container
@@ -62,7 +60,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(200, 150)
.FileName()
.Render(container =>
{
container
@@ -113,7 +110,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(200, 150)
.FileName()
.Render(container =>
{
container
@@ -6,6 +6,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="microcharts" Version="0.9.5.9" />
<PackageReference Include="nunit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
@@ -23,6 +25,9 @@
<None Update="LibreBarcode39-Regular.ttf">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="logo.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+94
View File
@@ -0,0 +1,94 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class RowExamples
{
[Test]
public void ColumnTypes()
{
RenderingTest
.Create()
.ProducePdf()
.PageSize(650, 300)
.ShowResults()
.Render(container =>
{
container
.Padding(25)
.MinimalBox()
.Border(1)
.Stack(stack =>
{
stack.Item().LabelCell("Total width: 600px");
stack.Item().Row(row =>
{
row.ConstantColumn(150).ValueCell("150px");
row.ConstantColumn(100).ValueCell("100px");
row.RelativeColumn(4).ValueCell("200px");
row.RelativeColumn(3).ValueCell("150px");
});
stack.Item().Row(row =>
{
row.ConstantColumn(100).ValueCell("100px");
row.ConstantColumn(50).ValueCell("50px");
row.Column(constantWidth: 100, relativeWidth: 4).ValueCell("350px");
row.RelativeColumn(2).ValueCell("100px");
row.RelativeColumn(1).ValueCell("50px");
});
});
});
}
[Test]
public void Stability()
{
// up to version 2021.12, this code would always result with the infinite layout exception
RenderingTest
.Create()
.ProducePdf()
.MaxPages(100)
.PageSize(250, 150)
.ShowResults()
.Render(container =>
{
container
.Padding(25)
.Row(row =>
{
row.RelativeColumn().Stack(stack =>
{
stack.Item().ShowOnce().Element(CreateBox).Text("X");
stack.Item().Element(CreateBox).Text("1");
stack.Item().Element(CreateBox).Text("2");
});
row.RelativeColumn().Stack(stack =>
{
stack.Item().Element(CreateBox).Text("1");
stack.Item().Element(CreateBox).Text("2");
});
});
});
static IContainer CreateBox(IContainer container)
{
return container
.ExtendHorizontal()
.ExtendVertical()
.Background(Colors.Grey.Lighten4)
.Border(1)
.AlignCenter()
.AlignMiddle()
.ShowOnce();
}
}
}
}
+54
View File
@@ -0,0 +1,54 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class ShowOnceExample
{
[Test]
public void ShowOnce()
{
RenderingTest
.Create()
.ProduceImages()
.ShowResults()
.RenderDocument(container =>
{
container.Page(page =>
{
page.Margin(20);
page.Size(PageSizes.A7.Landscape());
page.Background(Colors.White);
page.Header().Text("With show once", TextStyle.Default.SemiBold());
page.Content().PaddingVertical(5).Row(row =>
{
row.RelativeColumn()
.Background(Colors.Grey.Lighten2)
.Border(1)
.Padding(5)
.ShowOnce()
.Text(Placeholders.Label());
row.RelativeColumn(2)
.Border(1)
.Padding(5)
.Text(Placeholders.Paragraph());
});
page.Footer().Text(text =>
{
text.Span("Page ");
text.CurrentPageNumber();
text.Span(" out of ");
text.TotalPages();
});
});
});
}
}
}
+47
View File
@@ -0,0 +1,47 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class SkipOnceExample
{
[Test]
public void SkipOnce()
{
RenderingTest
.Create()
.ProduceImages()
.ShowResults()
.RenderDocument(container =>
{
container.Page(page =>
{
page.Margin(20);
page.Size(PageSizes.A7.Landscape());
page.Background(Colors.White);
page.Header().Stack(stack =>
{
stack.Item().ShowOnce().Text("This header is visible on the first page.");
stack.Item().SkipOnce().Text("This header is visible on the second page and all following.");
});
page.Content()
.PaddingVertical(10)
.Text(Placeholders.Paragraphs(), TextStyle.Default.Color(Colors.Grey.Medium));
page.Footer().Text(text =>
{
text.Span("Page ");
text.CurrentPageNumber();
text.Span(" out of ");
text.TotalPages();
});
});
});
}
}
}
+465
View File
@@ -0,0 +1,465 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using IContainer = QuestPDF.Infrastructure.IContainer;
namespace QuestPDF.Examples
{
public class TableExamples
{
[Test]
public void BasicPlacement()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(220, 220)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.MinimalBox()
.Border(1)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
// by using custom 'Element' method, we can reuse visual configuration
table.Cell().Row(1).Column(4).Element(Block).Text("A");
table.Cell().Row(2).Column(2).Element(Block).Text("B");
table.Cell().Row(3).Column(3).Element(Block).Text("C");
table.Cell().Row(4).Column(1).Element(Block).Text("D");
});
});
}
[Test]
public void DefaultCellStyle()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(220, 120)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.MinimalBox()
.Border(1)
.DefaultTextStyle(TextStyle.Default.Size(16))
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
table.Cell().Row(1).Column(1).Element(Block).Text("A");
table.Cell().Row(2).Column(2).Element(Block).Text("B");
table.Cell().Row(1).Column(3).Element(Block).Text("C");
table.Cell().Row(2).Column(4).Element(Block).Text("D");
});
});
}
[Test]
public void ColumnsDefinition()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(320, 80)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.ConstantColumn(50);
columns.ConstantColumn(100);
columns.RelativeColumn(2);
columns.RelativeColumn(3);
});
table.Cell().ColumnSpan(4).LabelCell("Total width: 300px");
table.Cell().ValueCell("50px");
table.Cell().ValueCell("100px");
table.Cell().ValueCell("100px");
table.Cell().ValueCell("150px");
});
});
}
[Test]
public void PartialAutoPlacement()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(220, 220)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.MinimalBox()
.Border(1)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
table.Cell().Element(Block).Text("A");
table.Cell().Row(2).Column(2).Element(Block).Text("B");
table.Cell().Element(Block).Text("C");
table.Cell().Row(3).Column(3).Element(Block).Text("D");
table.Cell().ColumnSpan(2).Element(Block).Text("E");
});
});
}
[Test]
public void ExtendLastCellsToTableBottom()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(220, 170)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.MinimalBox()
.Border(1)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
table.ExtendLastCellsToTableBottom();
table.Cell().Row(1).Column(1).Element(Block).Text("A");
table.Cell().Row(3).Column(1).Element(Block).Text("B");
table.Cell().Row(2).Column(2).Element(Block).Text("C");
table.Cell().Row(3).Column(3).Element(Block).Text("D");
table.Cell().Row(2).RowSpan(2).Column(4).Element(Block).Text("E");
});
});
}
[Test]
public void Overlapping()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(170, 170)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.MinimalBox()
.Border(1)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
table.Cell().Row(1).RowSpan(3).Column(1).ColumnSpan(3).Background(Colors.Grey.Lighten3).MinHeight(150);
table.Cell().Row(1).RowSpan(2).Column(1).ColumnSpan(2).Background(Colors.Grey.Lighten1).MinHeight(100);
table.Cell().Row(3).Column(3).Background(Colors.Grey.Darken1).MinHeight(50);
});
});
}
[Test]
public void Spans()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(220, 220)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
table.Cell().RowSpan(2).ColumnSpan(2).Element(Block).Text("1");
table.Cell().ColumnSpan(2).Element(Block).Text("2");
table.Cell().Element(Block).Text("3");
table.Cell().Element(Block).Text("4");
table.Cell().RowSpan(2).Element(Block).Text("5");
table.Cell().ColumnSpan(2).Element(Block).Text("6");
table.Cell().RowSpan(2).Element(Block).Text("7");
table.Cell().Element(Block).Text("8");
table.Cell().Element(Block).Text("9");
});
});
}
[Test]
public void Stability()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(300, 300)
.ShowResults()
.Render(container =>
{
container
.Padding(10)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
table.Cell().RowSpan(4).Element(Block).Text("1");
table.Cell().RowSpan(2).Element(Block).Text("2");
table.Cell().RowSpan(1).Element(Block).Text("3");
table.Cell().RowSpan(1).Element(Block).Text("4");
table.Cell().RowSpan(2).Element(Block).Text("5");
table.Cell().RowSpan(1).Element(Block).Text("6");
table.Cell().RowSpan(1).Element(Block).Text("7");
});
});
}
[Test]
public void TableHeader()
{
RenderingTest
.Create()
.ProduceImages()
.PageSize(500, 200)
.ShowResults()
.EnableDebugging()
.Render(container =>
{
var pageSizes = new List<(string name, double width, double height)>()
{
("Letter (ANSI A)", 8.5f, 11),
("Legal", 8.5f, 14),
("Ledger (ANSI B)", 11, 17),
("Tabloid (ANSI B)", 17, 11),
("ANSI C", 22, 17),
("ANSI D", 34, 22),
("ANSI E", 44, 34)
};
const int inchesToPoints = 72;
container
.Padding(10)
.MinimalBox()
.Border(1)
.Table(table =>
{
IContainer DefaultCellStyle(IContainer container, string backgroundColor)
{
return container
.Border(1)
.BorderColor(Colors.Grey.Lighten1)
.Background(backgroundColor)
.PaddingVertical(5)
.PaddingHorizontal(10)
.AlignCenter()
.AlignMiddle();
}
table.ColumnsDefinition(columns =>
{
columns.RelativeColumn();
columns.ConstantColumn(75);
columns.ConstantColumn(75);
columns.ConstantColumn(75);
columns.ConstantColumn(75);
});
table.Header(header =>
{
header.Cell().RowSpan(2).Element(CellStyle).ExtendHorizontal().AlignLeft().Text("Document type");
header.Cell().ColumnSpan(2).Element(CellStyle).Text("Inches");
header.Cell().ColumnSpan(2).Element(CellStyle).Text("Points");
header.Cell().Element(CellStyle).Text("Width");
header.Cell().Element(CellStyle).Text("Height");
header.Cell().Element(CellStyle).Text("Width");
header.Cell().Element(CellStyle).Text("Height");
// you can extend already existing styles by creating additional methods
IContainer CellStyle(IContainer container) => DefaultCellStyle(container, Colors.Grey.Lighten3);
});
foreach (var page in pageSizes)
{
table.Cell().Element(CellStyle).ExtendHorizontal().AlignLeft().Text(page.name);
// inches
table.Cell().Element(CellStyle).Text(page.width);
table.Cell().Element(CellStyle).Text(page.height);
// points
table.Cell().Element(CellStyle).Text(page.width * inchesToPoints);
table.Cell().Element(CellStyle).Text(page.height * inchesToPoints);
IContainer CellStyle(IContainer container) => DefaultCellStyle(container, Colors.White);
}
});
});
}
[Test]
public void PerformanceText_TemperatureReport()
{
RenderingTest
.Create()
.ProducePdf()
.PageSize(PageSizes.A4)
.MaxPages(10_000)
.EnableCaching()
.EnableDebugging(false)
.ShowResults()
.Render(container => GeneratePerformanceStructure(container, 1000));
}
public static void GeneratePerformanceStructure(IContainer container, int repeats)
{
container
.Padding(25)
//.Background(Colors.Blue.Lighten2)
.MinimalBox()
.Border(1)
//.Background(Colors.Red.Lighten2)
.Table(table =>
{
table.ColumnsDefinition(columns =>
{
columns.ConstantColumn(100);
columns.RelativeColumn();
columns.ConstantColumn(100);
columns.RelativeColumn();
});
table.ExtendLastCellsToTableBottom();
foreach (var i in Enumerable.Range(0, repeats))
{
table.Cell().RowSpan(3).LabelCell("Project");
table.Cell().RowSpan(3).ShowEntire().ValueCell(Placeholders.Sentence());
table.Cell().LabelCell("Report number");
table.Cell().ValueCell(i.ToString());
table.Cell().LabelCell("Date");
table.Cell().ValueCell(Placeholders.ShortDate());
table.Cell().LabelCell("Inspector");
table.Cell().ValueCell("Marcin Ziąbek");
table.Cell().ColumnSpan(2).LabelCell("Morning weather");
table.Cell().ColumnSpan(2).LabelCell("Evening weather");
table.Cell().ValueCell("Time");
table.Cell().ValueCell("7:13");
table.Cell().ValueCell("Time");
table.Cell().ValueCell("18:25");
table.Cell().ValueCell("Description");
table.Cell().ValueCell("Sunny");
table.Cell().ValueCell("Description");
table.Cell().ValueCell("Windy");
table.Cell().ValueCell("Wind");
table.Cell().ValueCell("Mild");
table.Cell().ValueCell("Wind");
table.Cell().ValueCell("Strong");
table.Cell().ValueCell("Temperature");
table.Cell().ValueCell("17°C");
table.Cell().ValueCell("Temperature");
table.Cell().ValueCell("32°C");
table.Cell().LabelCell("Remarks");
table.Cell().ColumnSpan(3).ValueCell(Placeholders.Paragraph());
}
});
}
// this method uses a higher order function to define a custom and dynamic style
static IContainer Block(IContainer container)
{
return container
.Border(1)
.Background(Colors.Grey.Lighten3)
.MinWidth(50)
.MinHeight(50)
.AlignCenter()
.AlignMiddle();
}
}
}
+1 -3
View File
@@ -21,7 +21,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(x => ComposeBook(x, chapters));
@@ -43,8 +42,7 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ProducePdf()
.Render(x => ComposeBook(x, chapters));
}
+88 -8
View File
@@ -11,13 +11,96 @@ namespace QuestPDF.Examples
{
public class TextExamples
{
[Test]
public void SimpleTextBlock()
{
RenderingTest
.Create()
.PageSize(500, 300)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Padding(5)
.MinimalBox()
.Border(1)
.Padding(10)
.Text(text =>
{
text.DefaultTextStyle(TextStyle.Default.Size(20));
text.Span("This is a normal text, followed by an ");
text.Span("underlined red text.", TextStyle.Default.Size(20).Color(Colors.Red.Medium).Underline());
});
});
}
[Test]
public void ParagraphSpacing()
{
RenderingTest
.Create()
.PageSize(500, 300)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Padding(5)
.MinimalBox()
.Border(1)
.Padding(10)
.Text(text =>
{
text.ParagraphSpacing(10);
foreach (var i in Enumerable.Range(1, 3))
{
text.Span($"Paragraph {i}: ", TextStyle.Default.SemiBold());
text.Line(Placeholders.Paragraph());
}
});
});
}
[Test]
public void CustomElement()
{
RenderingTest
.Create()
.PageSize(500, 200)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Padding(5)
.MinimalBox()
.Border(1)
.Padding(10)
.Text(text =>
{
text.DefaultTextStyle(TextStyle.Default.Size(20));
text.Span("This is a random image aligned to the baseline: ");
text.Element()
.PaddingBottom(-6)
.Height(24)
.Width(48)
.Image(Placeholders.Image);
text.Span(".");
});
});
}
[Test]
public void TextElements()
{
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
@@ -25,7 +108,7 @@ namespace QuestPDF.Examples
container
.Padding(20)
.Padding(10)
.Box()
.MinimalBox()
.Border(1)
.Padding(5)
.Padding(10)
@@ -48,7 +131,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
@@ -56,7 +138,7 @@ namespace QuestPDF.Examples
container
.Padding(20)
.Padding(10)
.Box()
.MinimalBox()
.Border(1)
.Padding(5)
.Padding(10)
@@ -78,7 +160,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
@@ -86,7 +167,7 @@ namespace QuestPDF.Examples
container
.Padding(20)
.Padding(10)
.Box()
.MinimalBox()
.Border(1)
.Padding(5)
.Padding(10)
@@ -142,7 +223,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
@@ -150,7 +230,7 @@ namespace QuestPDF.Examples
container
.Padding(20)
.Padding(10)
.Box()
.MinimalBox()
.Border(1)
.Padding(5)
.Padding(10)
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+2 -14
View File
@@ -7,9 +7,6 @@ namespace QuestPDF.ReportSample
{
public static class DataSource
{
public static int SectionCounter { get; set; }
public static int FieldCounter { get; set; }
public static ReportModel GetReport()
{
return new ReportModel
@@ -89,7 +86,6 @@ namespace QuestPDF.ReportSample
return new ReportSectionMap
{
Label = "Location",
ImageSource = Placeholders.Image,
Location = Helpers.RandomLocation()
};
}
@@ -99,10 +95,7 @@ namespace QuestPDF.ReportSample
return new ReportSectionPhotos
{
Label = "Photos",
Photos = Enumerable
.Range(0, Helpers.Random.Next(1, 15))
.Select(x => Placeholders.Image(400, 300))
.ToList()
PhotoCount = Helpers.Random.Next(1, 15)
};
}
@@ -110,14 +103,9 @@ namespace QuestPDF.ReportSample
{
return new ReportPhoto()
{
PhotoData = Placeholders.Image(800, 600),
Comments = Placeholders.Sentence(),
Date = DateTime.Now - TimeSpan.FromDays(Helpers.Random.NextDouble() * 100),
Location = Helpers.RandomLocation(),
MapContextSource = x => Placeholders.Image(400, 300),
MapDetailsSource = x => Placeholders.Image(400, 300)
Location = Helpers.RandomLocation()
};
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ namespace QuestPDF.ReportSample
{
public static class Helpers
{
public static Random Random { get; } = new Random();
public static Random Random { get; } = new Random(1);
public static string GetTestItem(string path) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", path);
@@ -0,0 +1,85 @@
using QuestPDF.Drawing;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.ReportSample.Layouts
{
public class DifferentHeadersTemplate : IDocument
{
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.Margin(40);
page.Size(PageSizes.A4);
page.Header().Element(ComposeHeader);
page.Content().Element(ComposeContent);
page.Footer().Element(ComposeFooter);
});
}
private void ComposeHeader(IContainer container)
{
container.Background(Colors.Grey.Lighten3).Border(1).Stack(stack =>
{
stack.Item().ShowOnce().Padding(5).AlignMiddle().Row(row =>
{
row.RelativeColumn(2).AlignMiddle().Text("PRIMARY HEADER", TextStyle.Default.Color(Colors.Grey.Darken3).Size(30).Bold());
row.RelativeColumn(1).AlignRight().MinimalBox().AlignMiddle().Background(Colors.Blue.Darken2).Padding(30);
});
stack.Item().SkipOnce().Padding(5).Row(row =>
{
row.RelativeColumn(2).Text("SECONDARY HEADER", TextStyle.Default.Color(Colors.Grey.Darken3).Size(30).Bold());
row.RelativeColumn(1).AlignRight().MinimalBox().Background(Colors.Blue.Lighten4).Padding(15);
});
});
}
private void ComposeContent(IContainer container)
{
container.Stack(stack =>
{
stack.Item().PaddingVertical(80).Text("First");
stack.Item().PageBreak();
stack.Item().PaddingVertical(80).Text("Second");
stack.Item().PageBreak();
stack.Item().PaddingVertical(80).Text("Third");
stack.Item().PageBreak();
});
}
private void ComposeFooter(IContainer container)
{
container.Background(Colors.Grey.Lighten3).Stack(stack =>
{
stack.Item().ShowOnce().Background(Colors.Grey.Lighten3).Row(row =>
{
row.RelativeColumn().Text(x =>
{
x.CurrentPageNumber();
x.Span(" / ");
x.TotalPages();
});
row.RelativeColumn().AlignRight().Text("Footer for header");
});
stack.Item().SkipOnce().Background(Colors.Grey.Lighten3).Row(row =>
{
row.RelativeColumn().Text(x =>
{
x.CurrentPageNumber();
x.Span(" / ");
x.TotalPages();
});
row.RelativeColumn().AlignRight().Text("Footer for every page except header");
});
});
}
}
}
@@ -0,0 +1,20 @@
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.ReportSample.Layouts
{
public class ImagePlaceholder : IComponent
{
public static bool Solid { get; set; } = false;
public void Compose(IContainer container)
{
if (Solid)
container.Background(Placeholders.Color());
else
container.Image(Placeholders.Image);
}
}
}
@@ -1,31 +0,0 @@
using System;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
namespace QuestPDF.ReportSample.Layouts
{
public class ImageTemplate : IComponent
{
private Func<Size, byte[]> Source { get; }
private float AspectRatio { get; }
public ImageTemplate(byte[] source, float aspectRatio = 1.333333f) : this(_ => source, aspectRatio)
{
}
public ImageTemplate(Func<Size, byte[]> source, float aspectRatio = 1.333333f)
{
Source = source;
AspectRatio = aspectRatio;
}
public void Compose(IContainer container)
{
container
.AspectRatio(AspectRatio)
.Background("#EEEEEE")
.Image(Source(Size.Zero));
}
}
}
@@ -30,14 +30,14 @@ namespace QuestPDF.ReportSample.Layouts
container
.Row(row =>
{
row.RelativeColumn(2).AspectRatio(4 / 3f).Image(Placeholders.Image);
row.RelativeColumn(2).AspectRatio(4 / 3f).Component<ImagePlaceholder>();
row.RelativeColumn().PaddingLeft(5).Stack(stack =>
{
stack.Spacing(7f);
stack.Item().AspectRatio(4 / 3f).Image(Placeholders.Image);
stack.Item().AspectRatio(4 / 3f).Image(Placeholders.Image);
stack.Item().AspectRatio(4 / 3f).Component<ImagePlaceholder>();
stack.Item().AspectRatio(4 / 3f).Component<ImagePlaceholder>();
});
});
}
@@ -48,13 +48,13 @@ namespace QuestPDF.ReportSample.Layouts
{
grid.Columns(6);
grid.Item().LabelCell().Text("Date", Typography.Normal);
grid.Item(2).ValueCell().Text(Model.Date?.ToString("g") ?? string.Empty, Typography.Normal);
grid.Item().LabelCell().Text("Location", Typography.Normal);
grid.Item(2).ValueCell().Text(Model.Location.Format(), Typography.Normal);
grid.Item().LabelCell().Text("Date");
grid.Item(2).ValueCell().Text(Model.Date?.ToString("g") ?? string.Empty);
grid.Item().LabelCell().Text("Location");
grid.Item(2).ValueCell().Text(Model.Location.Format());
grid.Item().LabelCell().Text("Comments", Typography.Normal);
grid.Item(5).ValueCell().Text(Model.Comments, Typography.Normal);
grid.Item().LabelCell().Text("Comments");
grid.Item(5).ValueCell().Text(Model.Comments);
});
}
}
@@ -1,3 +1,4 @@
using System.Linq;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
@@ -30,11 +31,11 @@ namespace QuestPDF.ReportSample.Layouts
{
stack.Item().EnsureSpace(25).Row(row =>
{
row.ConstantColumn(150).LabelCell().Text(part.Label, Typography.Normal);
row.ConstantColumn(150).LabelCell().Text(part.Label);
var frame = row.RelativeColumn().ValueCell();
if (part is ReportSectionText text)
frame.ShowEntire().Text(text.Text, Typography.Normal);
frame.ShowEntire().Text(text.Text);
if (part is ReportSectionMap map)
frame.Element(x => MapElement(x, map));
@@ -49,9 +50,9 @@ namespace QuestPDF.ReportSample.Layouts
void MapElement(IContainer container, ReportSectionMap model)
{
if (model.ImageSource == null || model.Location == null)
if (model.Location == null)
{
container.Text("No location provided", Typography.Normal);
container.Text("No location provided");
return;
}
@@ -59,25 +60,28 @@ namespace QuestPDF.ReportSample.Layouts
{
stack.Spacing(5);
stack.Item().MaxWidth(250).AspectRatio(4 / 3f).Image(Placeholders.Image);
stack.Item().Text(model.Location.Format(), Typography.Normal);
stack.Item().MaxWidth(250).AspectRatio(4 / 3f).Component<ImagePlaceholder>();
stack.Item().Text(model.Location.Format());
});
}
void PhotosElement(IContainer container, ReportSectionPhotos model)
{
if (model.Photos.Count == 0)
if (model.PhotoCount == 0)
{
container.Text("No photos", Typography.Normal);
return;
}
container.Debug("Photos").Grid(grid =>
container.DebugArea("Photos").Grid(grid =>
{
grid.Spacing(5);
grid.Columns(3);
model.Photos.ForEach(x => grid.Item().AspectRatio(4 / 3f).Image(Placeholders.Image));
Enumerable
.Range(0, model.PhotoCount)
.ToList()
.ForEach(x => grid.Item().AspectRatio(4 / 3f).Component<ImagePlaceholder>());
});
}
}
@@ -27,6 +27,8 @@ namespace QuestPDF.ReportSample.Layouts
container
.Page(page =>
{
page.DefaultTextStyle(Typography.Normal);
page.MarginVertical(40);
page.MarginHorizontal(50);
@@ -37,8 +39,6 @@ namespace QuestPDF.ReportSample.Layouts
page.Footer().AlignCenter().Text(text =>
{
text.DefaultTextStyle(Typography.Normal);
text.CurrentPageNumber();
text.Span(" / ");
text.TotalPages();
@@ -55,7 +55,7 @@ namespace QuestPDF.ReportSample.Layouts
row.Spacing(50);
row.RelativeColumn().PaddingTop(-10).Text(Model.Title, Typography.Title);
row.ConstantColumn(150).ExternalLink("https://www.questpdf.com").Image(Model.LogoData);
row.ConstantColumn(90).ExternalLink("https://www.questpdf.com").MaxHeight(30).Component<ImagePlaceholder>();
});
stack.Item().ShowOnce().PaddingVertical(15).Border(1f).BorderColor(Colors.Grey.Lighten1).ExtendHorizontal();
@@ -69,8 +69,8 @@ namespace QuestPDF.ReportSample.Layouts
{
grid.Item().Text(text =>
{
text.Span($"{field.Label}: ", Typography.Normal.SemiBold());
text.Span(field.Value, Typography.Normal);
text.Span($"{field.Label}: ", TextStyle.Default.SemiBold());
text.Span(field.Value);
});
}
});
@@ -41,9 +41,9 @@ namespace QuestPDF.ReportSample.Layouts
.InternalLink(locationName)
.Row(row =>
{
row.ConstantColumn(25).Text($"{number}.", Typography.Normal);
row.RelativeColumn().Text(locationName, Typography.Normal);
row.ConstantColumn(150).AlignRight().Text(text => text.PageNumberOfLocation(locationName, Typography.Normal));
row.ConstantColumn(25).Text($"{number}.");
row.RelativeColumn().Text(locationName);
row.ConstantColumn(150).AlignRight().Text(text => text.PageNumberOfLocation(locationName));
});
}
}
+2 -8
View File
@@ -44,22 +44,16 @@ namespace QuestPDF.ReportSample
public class ReportSectionMap : ReportSectionElement
{
public Func<Size, byte[]> ImageSource { get; set; }
public Location Location { get; set; }
}
public class ReportSectionPhotos : ReportSectionElement
{
public List<byte[]> Photos { get; set; }
public int PhotoCount { get; set; }
}
public class ReportPhoto
{
public byte[] PhotoData { get; set; }
public Func<Size, byte[]> MapDetailsSource { get; set; }
public Func<Size, byte[]> MapContextSource { get; set; }
{
public Location Location { get; set; }
public DateTime? Date { get; set; }
+75
View File
@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Engines;
using BenchmarkDotNet.Running;
using Microsoft.VisualStudio.TestPlatform.TestHost;
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.Proxy;
using QuestPDF.Elements;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
using QuestPDF.ReportSample.Layouts;
namespace QuestPDF.ReportSample
{
[SimpleJob(RunStrategy.Monitoring, launchCount: 0, warmupCount: 1, targetCount: 256)]
[MinColumn, MaxColumn, MeanColumn, MedianColumn]
public class PerformanceTests
{
private PageContext PageContext { get; set; }
private DocumentMetadata Metadata { get; set; }
private Container Content { get; set; }
[Test]
public void Run()
{
ImagePlaceholder.Solid = true;
var configuration = ManualConfig
.Create(DefaultConfig.Instance)
.WithOptions(ConfigOptions.DisableOptimizationsValidator);
BenchmarkRunner.Run<PerformanceTests>(configuration);
}
[IterationSetup]
public void GenerateReportData()
{
ImagePlaceholder.Solid = true;
var model = DataSource.GetReport();
var report = new StandardReport(model);
Metadata = report.GetMetadata();
var documentContainer = new DocumentContainer();
report.Compose(documentContainer);
Content = documentContainer.Compose();
PageContext = new PageContext();
DocumentGenerator.RenderPass(PageContext, new FreeCanvas(), Content, Metadata, null);
var sw = new Stopwatch();
sw.Start();
Content.VisitChildren(x =>
{
if (x is ICacheable)
x.CreateProxy(y => new CacheProxy(y));
});
sw.Stop();
Console.WriteLine($"Creating cache took: {sw.ElapsedMilliseconds}");
}
[Benchmark]
public void GenerationTest()
{
DocumentGenerator.RenderPass(PageContext, new FreeCanvas(), Content, Metadata, null);
}
}
}
@@ -8,9 +8,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="nunit" Version="3.13.2" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="SkiaSharp" Version="2.80.3" />
</ItemGroup>
+34 -40
View File
@@ -3,62 +3,56 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
using QuestPDF.ReportSample.Layouts;
namespace QuestPDF.ReportSample
{
public class ReportGeneration
{
[Test]
public void GenerateAndShow()
private StandardReport Report { get; set; }
[SetUp]
public void SetUp()
{
var reportModel = DataSource.GetReport();
var report = new StandardReport(reportModel);
var model = DataSource.GetReport();
Report = new StandardReport(model);
}
[Test]
public void GenerateAndShowPdf()
{
ImagePlaceholder.Solid = true;
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"test_result.pdf");
report.GeneratePdf(path);
Report.GeneratePdf(path);
Process.Start("explorer.exe", path);
}
[Test]
public void PerformanceBenchmark()
public void GenerateAndShowXps()
{
// target document length should be around 100 pages
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"test_result.xps");
Report.GenerateXps(path);
Process.Start("explorer.exe", path);
}
[Test]
public void Profile()
{
ImagePlaceholder.Solid = true;
// test size
const int testSize = 10;
const decimal performanceTarget = 1; // documents per second
// create report models
var reports = Enumerable
.Range(0, testSize)
.Select(x =>
{
var reportModel = DataSource.GetReport();
return new StandardReport(reportModel);
})
.ToList();
// generate documents
var sw = new Stopwatch();
var container = new DocumentContainer();
Report.Compose(container);
var content = container.Compose();
sw.Start();
var totalSize = reports.Select(x => x.GeneratePdf()).Sum(x => (long)x.Length);
sw.Stop();
var metadata = Report.GetMetadata();
var pageContext = new PageContext();
// show summary
Console.WriteLine($"Total size: {totalSize:N0} bytes");
var performance = sw.ElapsedMilliseconds / (decimal)testSize;
var speed = 1000M / performance;
Console.WriteLine($"Test time: {sw.ElapsedMilliseconds} ms");
Console.WriteLine($"Time per document: {performance:N} ms");
Console.WriteLine($"Documents per second: {speed:N} d/s");
//if (speed < performanceTarget)
// throw new Exception("Rendering algorithm is too slow.");
DocumentGenerator.RenderPass(pageContext, new FreeCanvas(), content, metadata, null);
DocumentGenerator.RenderPass(pageContext, new FreeCanvas(), content, metadata, null);
}
}
}
+1 -1
View File
@@ -8,6 +8,6 @@ namespace QuestPDF.ReportSample
{
public static TextStyle Title => TextStyle.Default.FontType(Fonts.Calibri).Color(Colors.Blue.Darken3).Size(26).Black();
public static TextStyle Headline => TextStyle.Default.FontType(Fonts.Calibri).Color(Colors.Blue.Medium).Size(16).SemiBold();
public static TextStyle Normal => TextStyle.Default.FontType(Fonts.Calibri).Color(Colors.Black).Size(11).LineHeight(1.1f);
public static TextStyle Normal => TextStyle.Default.FontType(Fonts.Verdana).Color(Colors.Black).Size(10).LineHeight(1.2f);
}
}
+5 -5
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -23,7 +23,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(1000, 500))
.ExpectChildMeasure(expectedInput: new Size(1000, 500), returns: new PartialRender(new Size(400, 200)))
.ExpectChildMeasure(expectedInput: new Size(1000, 500), returns: SpacePlan.PartialRender(new Size(400, 200)))
.ExpectCanvasTranslate(new Position(300, 150))
.ExpectChildDraw(new Size(400, 200))
.ExpectCanvasTranslate(new Position(-300, -150))
@@ -42,7 +42,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50)))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.FullRender(new Size(100, 50)))
.ExpectCanvasTranslate(new Position(0, 125))
.ExpectChildDraw(new Size(100, 50))
.ExpectCanvasTranslate(new Position(0, -125))
@@ -61,7 +61,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50)))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.FullRender(new Size(100, 50)))
.ExpectCanvasTranslate(new Position(150, 250))
.ExpectChildDraw(new Size(100, 50))
.ExpectCanvasTranslate(new Position(-150, -250))
@@ -80,7 +80,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50)))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.FullRender(new Size(100, 50)))
.ExpectCanvasTranslate(new Position(300, 0))
.ExpectChildDraw(new Size(100, 50))
.ExpectCanvasTranslate(new Position(-300, 0))
+17 -17
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -20,8 +20,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 201))
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
}
[Test]
@@ -35,8 +35,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 201))
.ExpectChildMeasure(new Size(400, 200), new PartialRender(100, 50))
.CheckMeasureResult(new PartialRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.PartialRender(100, 50))
.CheckMeasureResult(SpacePlan.PartialRender(400, 200));
}
[Test]
@@ -50,8 +50,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 201))
.ExpectChildMeasure(new Size(400, 200), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 200), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -65,8 +65,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 201))
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
}
[Test]
@@ -80,7 +80,7 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 199))
.CheckMeasureResult(new Wrap());
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -94,8 +94,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(401, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
}
[Test]
@@ -109,7 +109,7 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(399, 200))
.CheckMeasureResult(new Wrap());
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -123,8 +123,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
}
[Test]
@@ -138,8 +138,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(500, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
}
[Test]
+3 -3
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
@@ -27,8 +27,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50)))
.CheckMeasureResult( new FullRender(new Size(100, 50)));
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.FullRender(new Size(100, 50)))
.CheckMeasureResult( SpacePlan.FullRender(new Size(100, 50)));
}
[Test]
+8 -8
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -10,18 +10,18 @@ namespace QuestPDF.UnitTests
public class BoxTests
{
[Test]
public void Measure() => SimpleContainerTests.Measure<Box>();
public void Measure() => SimpleContainerTests.Measure<MinimalBox>();
[Test]
public void Draw_Wrap()
{
TestPlan
.For(x => new Box
.For(x => new MinimalBox
{
Child = x.CreateChild()
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new Wrap())
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.Wrap())
.CheckDrawResult();
}
@@ -29,12 +29,12 @@ namespace QuestPDF.UnitTests
public void Measure_PartialRender()
{
TestPlan
.For(x => new Box
.For(x => new MinimalBox
{
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new PartialRender(200, 100))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.PartialRender(200, 100))
.ExpectChildDraw(new Size(200, 100))
.CheckDrawResult();
}
@@ -43,12 +43,12 @@ namespace QuestPDF.UnitTests
public void Measure_FullRender()
{
TestPlan
.For(x => new Box
.For(x => new MinimalBox
{
Child = x.CreateChild()
})
.MeasureElement(new Size(500, 400))
.ExpectChildMeasure(expectedInput: new Size(500, 400), returns: new FullRender(300, 200))
.ExpectChildMeasure(expectedInput: new Size(500, 400), returns: SpacePlan.FullRender(300, 200))
.ExpectChildDraw(new Size(300, 200))
.CheckDrawResult();
}
+99 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -9,6 +9,8 @@ namespace QuestPDF.UnitTests
[TestFixture]
public class ConstrainedTests
{
#region Height
[Test]
public void Measure_MinHeight_ExpectWrap()
{
@@ -18,7 +20,7 @@ namespace QuestPDF.UnitTests
MinHeight = 100
})
.MeasureElement(new Size(400, 50))
.CheckMeasureResult(new Wrap());
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -31,8 +33,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(400, 50))
.CheckMeasureResult(new FullRender(400, 100));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(400, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 100));
}
[Test]
@@ -45,8 +47,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(400, 150))
.CheckMeasureResult(new FullRender(400, 150));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(400, 150))
.CheckMeasureResult(SpacePlan.FullRender(400, 150));
}
[Test]
@@ -58,7 +60,7 @@ namespace QuestPDF.UnitTests
MaxHeight = 100
})
.MeasureElement(new Size(400, 150))
.CheckMeasureResult(new FullRender(0, 0));
.CheckMeasureResult(SpacePlan.FullRender(0, 0));
}
[Test]
@@ -71,8 +73,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 100), new PartialRender(400, 75))
.CheckMeasureResult(new PartialRender(400, 75));
.ExpectChildMeasure(new Size(400, 100), SpacePlan.PartialRender(400, 75))
.CheckMeasureResult(SpacePlan.PartialRender(400, 75));
}
[Test]
@@ -85,8 +87,94 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 100), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 100), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
#endregion
#region Width
[Test]
public void Measure_MinWidth_ExpectWrap()
{
TestPlan
.For(x => new Constrained
{
MinWidth = 100
})
.MeasureElement(new Size(50, 400))
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
public void Measure_MinWidth_ExtendHeight()
{
TestPlan
.For(x => new Constrained
{
MinWidth = 100,
Child = x.CreateChild()
})
.MeasureElement(new Size(200, 400))
.ExpectChildMeasure(new Size(200, 400), SpacePlan.FullRender(50, 400))
.CheckMeasureResult(SpacePlan.FullRender(100, 400));
}
[Test]
public void Measure_MinWidth_PassHeight()
{
TestPlan
.For(x => new Constrained
{
MinWidth = 100,
Child = x.CreateChild()
})
.MeasureElement(new Size(200, 400))
.ExpectChildMeasure(new Size(200, 400), SpacePlan.FullRender(150, 400))
.CheckMeasureResult(SpacePlan.FullRender(150, 400));
}
[Test]
public void Measure_MaxWidth_Empty()
{
TestPlan
.For(x => new Constrained
{
MaxWidth = 100
})
.MeasureElement(new Size(150, 400))
.CheckMeasureResult(SpacePlan.FullRender(0, 0));
}
[Test]
public void Measure_MaxWidth_PartialRender()
{
TestPlan
.For(x => new Constrained
{
MaxWidth = 100,
Child = x.CreateChild()
})
.MeasureElement(new Size(200, 400))
.ExpectChildMeasure(new Size(100, 400), SpacePlan.PartialRender(75, 400))
.CheckMeasureResult(SpacePlan.PartialRender(75, 400));
}
[Test]
public void Measure_MaxWidth_ExpectWrap()
{
TestPlan
.For(x => new Constrained
{
MaxWidth = 100,
Child = x.CreateChild()
})
.MeasureElement(new Size(200, 400))
.ExpectChildMeasure(new Size(100, 400), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
#endregion
}
}
+23 -23
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -15,78 +15,78 @@ namespace QuestPDF.UnitTests
public void Measure_ReturnsWrap_WhenDecorationReturnsWrap()
{
TestPlan
.For(x => new SimpleDecoration
.For(x => new BinaryDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
public void Measure_ReturnsWrap_WhenDecorationReturnsPartialRender()
{
TestPlan
.For(x => new SimpleDecoration
.For(x => new BinaryDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
public void Measure_ReturnsWrap_WhenContentReturnsWrap()
{
TestPlan
.For(x => new SimpleDecoration
.For(x => new BinaryDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), new FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
public void Measure_ReturnsPartialRender_WhenContentReturnsPartialRender()
{
TestPlan
.For(x => new SimpleDecoration
.For(x => new BinaryDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), new FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), new PartialRender(200, 150))
.CheckMeasureResult(new PartialRender(400, 250));
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), SpacePlan.PartialRender(200, 150))
.CheckMeasureResult(SpacePlan.PartialRender(400, 250));
}
[Test]
public void Measure_ReturnsFullRender_WhenContentReturnsFullRender()
{
TestPlan
.For(x => new SimpleDecoration
.For(x => new BinaryDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), new FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), new FullRender(200, 150))
.CheckMeasureResult(new FullRender(400, 250));
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), SpacePlan.FullRender(200, 150))
.CheckMeasureResult(SpacePlan.FullRender(400, 250));
}
#endregion
@@ -97,14 +97,14 @@ namespace QuestPDF.UnitTests
public void Draw_Prepend()
{
TestPlan
.For(x => new SimpleDecoration
.For(x => new BinaryDecoration
{
Type = DecorationType.Prepend,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), new FullRender(300, 100))
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildDraw("decoration", new Size(400, 100))
.ExpectCanvasTranslate(0, 100)
.ExpectChildDraw("content", new Size(400, 200))
@@ -116,14 +116,14 @@ namespace QuestPDF.UnitTests
public void Draw_Append()
{
TestPlan
.For(x => new SimpleDecoration
.For(x => new BinaryDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), new FullRender(300, 100))
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildDraw("content", new Size(400, 200))
.ExpectCanvasTranslate(0, 200)
.ExpectChildDraw("decoration", new Size(400, 100))
+4 -4
View File
@@ -1,6 +1,6 @@
using FluentAssertions;
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -20,7 +20,7 @@ namespace QuestPDF.UnitTests
Source = GenerateImage
})
.MeasureElement(new Size(300, 200))
.CheckMeasureResult(new FullRender(300, 200));
.CheckMeasureResult(SpacePlan.FullRender(300, 200));
}
[Test]
@@ -51,7 +51,7 @@ namespace QuestPDF.UnitTests
[Test]
public void Draw_PassesCorrectSizeToSource()
{
Size passedSize = null;
Size passedSize = default;
TestPlan
.For(x => new DynamicImage
@@ -66,7 +66,7 @@ namespace QuestPDF.UnitTests
.ExpectCanvasDrawImage(Position.Zero, new Size(400, 300))
.CheckDrawResult();
passedSize.Should().Be(new Size(400, 300));
passedSize.Should().BeEquivalentTo(new Size(400, 300));
}
byte[] GenerateImage(Size size)
+11 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -19,8 +19,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 100))
.ExpectChildMeasure(new Size(400, 100), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 100), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -33,8 +33,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 100))
.ExpectChildMeasure(new Size(400, 100), new PartialRender(300, 50))
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 100), SpacePlan.PartialRender(300, 50))
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -47,8 +47,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new PartialRender(300, 250))
.CheckMeasureResult(new PartialRender(300, 250));
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(300, 250))
.CheckMeasureResult(SpacePlan.PartialRender(300, 250));
}
[Test]
@@ -61,8 +61,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 100))
.ExpectChildMeasure(new Size(400, 100), new FullRender(300, 50))
.CheckMeasureResult(new FullRender(300, 50));
.ExpectChildMeasure(new Size(400, 100), SpacePlan.FullRender(300, 50))
.CheckMeasureResult(SpacePlan.FullRender(300, 50));
}
[Test]
@@ -75,8 +75,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new FullRender(300, 250))
.CheckMeasureResult(new FullRender(300, 250));
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(300, 250))
.CheckMeasureResult(SpacePlan.FullRender(300, 250));
}
[Test]
+11 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -18,8 +18,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 200), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -33,8 +33,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = true
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new PartialRender(300, 100))
.CheckMeasureResult(new PartialRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.PartialRender(300, 100))
.CheckMeasureResult(SpacePlan.PartialRender(400, 200));
}
[Test]
@@ -48,8 +48,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = true
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(300, 100))
.CheckMeasureResult(new FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(300, 100))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
}
[Test]
@@ -63,8 +63,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = false
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 100))
.CheckMeasureResult(new FullRender(400, 100));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 100))
.CheckMeasureResult(SpacePlan.FullRender(400, 100));
}
[Test]
@@ -78,8 +78,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = true
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 100))
.CheckMeasureResult(new FullRender(100, 200));
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 100))
.CheckMeasureResult(SpacePlan.FullRender(100, 200));
}
[Test]
+3 -3
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
@@ -20,7 +20,7 @@ namespace QuestPDF.UnitTests
InternalImage = GenerateImage(400, 300)
})
.MeasureElement(new Size(300, 200))
.CheckMeasureResult(new FullRender(300, 200));
.CheckMeasureResult(SpacePlan.FullRender(300, 200));
}
[Test]
@@ -49,7 +49,7 @@ namespace QuestPDF.UnitTests
return container;
})
.MeasureElement(new Size(300, 200))
.CheckMeasureResult(new FullRender(300, 100));;
.CheckMeasureResult(SpacePlan.FullRender(300, 100));;
}
SKImage GenerateImage(int width, int height)
+16 -16
View File
@@ -1,6 +1,6 @@
using System.Collections.Generic;
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -45,8 +45,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(MainLayer, new Size(800, 600), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -55,8 +55,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(700, 500))
.CheckMeasureResult(new PartialRender(700, 500));
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.PartialRender(700, 500))
.CheckMeasureResult(SpacePlan.PartialRender(700, 500));
}
[Test]
@@ -65,8 +65,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(MainLayer, new Size(800, 600), new FullRender(500, 400))
.CheckMeasureResult(new FullRender(500, 400));
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.FullRender(500, 400))
.CheckMeasureResult(SpacePlan.FullRender(500, 400));
}
#endregion
@@ -80,9 +80,9 @@ namespace QuestPDF.UnitTests
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(BackgroundLayer, new Size(800, 600), new FullRender(100, 200))
.ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), new FullRender(300, 400))
.ExpectChildMeasure(BackgroundLayer, new Size(800, 600), SpacePlan.FullRender(100, 200))
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), SpacePlan.FullRender(300, 400))
.ExpectChildDraw(BackgroundLayer, new Size(800, 600))
@@ -99,9 +99,9 @@ namespace QuestPDF.UnitTests
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(BackgroundLayer, new Size(800, 600), new PartialRender(100, 200))
.ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), new Wrap())
.ExpectChildMeasure(BackgroundLayer, new Size(800, 600), SpacePlan.PartialRender(100, 200))
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), SpacePlan.Wrap())
.ExpectChildDraw(BackgroundLayer, new Size(800, 600))
.ExpectChildDraw(MainLayer, new Size(800, 600))
@@ -116,9 +116,9 @@ namespace QuestPDF.UnitTests
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(BackgroundLayer, new Size(800, 600), new Wrap())
.ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), new PartialRender(300, 400))
.ExpectChildMeasure(BackgroundLayer, new Size(800, 600), SpacePlan.Wrap())
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), SpacePlan.PartialRender(300, 400))
.ExpectChildDraw(MainLayer, new Size(800, 600))
.ExpectChildDraw(ForegroundLayer, new Size(800, 600))
+9 -9
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -28,8 +28,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(340, 260), new FullRender(140, 60))
.CheckMeasureResult(new FullRender(200, 100));
.ExpectChildMeasure(new Size(340, 260), SpacePlan.FullRender(140, 60))
.CheckMeasureResult(SpacePlan.FullRender(200, 100));
}
[Test]
@@ -38,7 +38,7 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(50, 300))
.CheckMeasureResult(new Wrap());
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -47,7 +47,7 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(20, 300))
.CheckMeasureResult(new Wrap());
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -56,8 +56,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(340, 260), new PartialRender(40, 160))
.CheckMeasureResult(new PartialRender(100, 200));
.ExpectChildMeasure(new Size(340, 260), SpacePlan.PartialRender(40, 160))
.CheckMeasureResult(SpacePlan.PartialRender(100, 200));
}
[Test]
@@ -66,8 +66,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(340, 260), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(340, 260), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
+3 -3
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -16,13 +16,13 @@ namespace QuestPDF.UnitTests
.For(x => new PageBreak())
.MeasureElement(new Size(400, 300))
.CheckMeasureResult(new PartialRender(Size.Zero))
.CheckMeasureResult(SpacePlan.PartialRender(Size.Zero))
.DrawElement(new Size(400, 300))
.CheckDrawResult()
.MeasureElement(new Size(500, 400))
.CheckMeasureResult(new FullRender(Size.Zero));
.CheckMeasureResult(SpacePlan.FullRender(0, 0));
}
}
}
-1
View File
@@ -1,5 +1,4 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
+30 -30
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
@@ -16,74 +16,74 @@ namespace QuestPDF.UnitTests
public void Measure_ReturnsWrap_WhenLeftChildReturnsWrap()
{
TestPlan
.For(x => new SimpleRow
.For(x => new BinaryRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
public void Measure_ReturnsWrap_WhenRightChildReturnsWrap()
{
TestPlan
.For(x => new SimpleRow
.For(x => new BinaryRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), new FullRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.FullRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
public void Measure_ReturnsPartialRender_WhenLeftChildReturnsPartialRender()
{
TestPlan
.For(x => new SimpleRow
.For(x => new BinaryRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), new PartialRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), new FullRender(100, 100))
.CheckMeasureResult(new PartialRender(350, 150));
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.PartialRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), SpacePlan.FullRender(100, 100))
.CheckMeasureResult(SpacePlan.PartialRender(350, 150));
}
[Test]
public void Measure_ReturnsPartialRender_WhenRightChildReturnsPartialRender()
{
TestPlan
.For(x => new SimpleRow
.For(x => new BinaryRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), new FullRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), new PartialRender(100, 100))
.CheckMeasureResult(new PartialRender(350, 150));
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.FullRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), SpacePlan.PartialRender(100, 100))
.CheckMeasureResult(SpacePlan.PartialRender(350, 150));
}
[Test]
public void Measure_ReturnsFullRender_WhenBothChildrenReturnFullRender()
{
TestPlan
.For(x => new SimpleRow
.For(x => new BinaryRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), new FullRender(200, 150))
.ExpectChildMeasure("right", new Size(200, 300), new FullRender(100, 100))
.CheckMeasureResult(new FullRender(300, 150));
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.FullRender(200, 150))
.ExpectChildMeasure("right", new Size(200, 300), SpacePlan.FullRender(100, 100))
.CheckMeasureResult(SpacePlan.FullRender(300, 150));
}
#endregion
@@ -94,13 +94,13 @@ namespace QuestPDF.UnitTests
public void Draw()
{
TestPlan
.For(x => new SimpleRow
.For(x => new BinaryRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), new FullRender(250, 150))
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.FullRender(250, 150))
.ExpectChildDraw("left", new Size(250, 300))
.ExpectCanvasTranslate(250, 0)
.ExpectChildDraw("right", new Size(150, 300))
@@ -184,11 +184,11 @@ namespace QuestPDF.UnitTests
});
// assert
var expected = new SimpleRow
var expected = new BinaryRow
{
Left = new SimpleRow
Left = new BinaryRow
{
Left = new SimpleRow
Left = new BinaryRow
{
Left = new Constrained
{
@@ -202,7 +202,7 @@ namespace QuestPDF.UnitTests
MaxWidth = 25
}
},
Right = new SimpleRow
Right = new BinaryRow
{
Left = new Constrained
{
@@ -217,9 +217,9 @@ namespace QuestPDF.UnitTests
}
}
},
Right = new SimpleRow
Right = new BinaryRow
{
Left = new SimpleRow
Left = new BinaryRow
{
Left = new Constrained
{
@@ -233,7 +233,7 @@ namespace QuestPDF.UnitTests
MaxWidth = 25
}
},
Right = new SimpleRow
Right = new BinaryRow
{
Left = new Constrained
{
@@ -241,7 +241,7 @@ namespace QuestPDF.UnitTests
MaxWidth = 200,
Child = childD
},
Right = new SimpleRow
Right = new BinaryRow
{
Left = new Constrained
{
+11 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -22,8 +22,8 @@ namespace QuestPDF.UnitTests
ScaleY = 2
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(new Size(300, 400), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(300, 400), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -37,8 +37,8 @@ namespace QuestPDF.UnitTests
ScaleY = 2
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(new Size(300, 400), new PartialRender(200, 350))
.CheckMeasureResult(new PartialRender(600, 700));
.ExpectChildMeasure(new Size(300, 400), SpacePlan.PartialRender(200, 350))
.CheckMeasureResult(SpacePlan.PartialRender(600, 700));
}
[Test]
@@ -52,8 +52,8 @@ namespace QuestPDF.UnitTests
ScaleY = 2
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(new Size(300, 400), new FullRender(250, 300))
.CheckMeasureResult(new FullRender(750, 600));
.ExpectChildMeasure(new Size(300, 400), SpacePlan.FullRender(250, 300))
.CheckMeasureResult(SpacePlan.FullRender(750, 600));
}
[Test]
@@ -67,8 +67,8 @@ namespace QuestPDF.UnitTests
ScaleY = 1
})
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(new Size(400, 600), new FullRender(300, 500))
.CheckMeasureResult(new FullRender(600, 500));
.ExpectChildMeasure(new Size(400, 600), SpacePlan.FullRender(300, 500))
.CheckMeasureResult(SpacePlan.FullRender(600, 500));
}
[Test]
@@ -82,8 +82,8 @@ namespace QuestPDF.UnitTests
ScaleY = -3
})
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(new Size(800, 200), new FullRender(800, 100))
.CheckMeasureResult(new FullRender(800, 300));
.ExpectChildMeasure(new Size(800, 200), SpacePlan.FullRender(800, 100))
.CheckMeasureResult(SpacePlan.FullRender(800, 300));
}
#endregion
+7 -7
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -18,8 +18,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -31,8 +31,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -44,8 +44,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new FullRender(300, 200))
.CheckMeasureResult(new FullRender(300, 200));
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(300, 200))
.CheckMeasureResult(SpacePlan.FullRender(300, 200));
}
[Test]
+8 -8
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -20,31 +20,31 @@ namespace QuestPDF.UnitTests
// Measure the element and return result
.MeasureElement(new Size(300, 200))
.ExpectChildMeasure("child", new Size(300, 200), new PartialRender(new Size(200, 200)))
.CheckMeasureResult(new PartialRender(new Size(200, 200)))
.ExpectChildMeasure("child", new Size(300, 200), SpacePlan.PartialRender(new Size(200, 200)))
.CheckMeasureResult(SpacePlan.PartialRender(new Size(200, 200)))
// Draw element partially
.DrawElement(new Size(200, 200))
.ExpectChildMeasure(new Size(200, 200), new PartialRender(new Size(200, 200)))
.ExpectChildMeasure(new Size(200, 200), SpacePlan.PartialRender(new Size(200, 200)))
.ExpectChildDraw(new Size(200, 200))
.CheckDrawResult()
// Element was not fully drawn
// It should be measured again for rendering on next page
.MeasureElement(new Size(800, 200))
.ExpectChildMeasure(new Size(800, 200), new FullRender(new Size(400, 200)))
.CheckMeasureResult(new FullRender(new Size(400, 200)))
.ExpectChildMeasure(new Size(800, 200), SpacePlan.FullRender(new Size(400, 200)))
.CheckMeasureResult(SpacePlan.FullRender(new Size(400, 200)))
// Draw element on next page
// Element was fully drawn at this point
.DrawElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), new FullRender(new Size(400, 200)))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(new Size(400, 200)))
.ExpectChildDraw(new Size(400, 200))
.CheckDrawResult()
// In the next attempt of measuring element, it should behave like empty parent.
.MeasureElement(new Size(600, 200))
.CheckMeasureResult(new FullRender(Size.Zero))
.CheckMeasureResult(SpacePlan.FullRender(0, 0))
// In the next attempt of measuring element, it should not draw its child
.DrawElement(new Size(600, 200))
+11 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -21,8 +21,8 @@ namespace QuestPDF.UnitTests
TurnCount = 0
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -35,8 +35,8 @@ namespace QuestPDF.UnitTests
TurnCount = 0
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new PartialRender(300, 200));
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.PartialRender(300, 200));
}
[Test]
@@ -49,8 +49,8 @@ namespace QuestPDF.UnitTests
TurnCount = 1
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(300, 400), new FullRender(200, 300))
.CheckMeasureResult(new FullRender(300, 200));
.ExpectChildMeasure(new Size(300, 400), SpacePlan.FullRender(200, 300))
.CheckMeasureResult(SpacePlan.FullRender(300, 200));
}
[Test]
@@ -63,8 +63,8 @@ namespace QuestPDF.UnitTests
TurnCount = 2
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new FullRender(200, 100))
.CheckMeasureResult(new FullRender(200, 100));
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(200, 100))
.CheckMeasureResult(SpacePlan.FullRender(200, 100));
}
[Test]
@@ -77,8 +77,8 @@ namespace QuestPDF.UnitTests
TurnCount = 3 // or -1
})
.MeasureElement(new Size(500, 400))
.ExpectChildMeasure(new Size(400, 500), new FullRender(300, 350))
.CheckMeasureResult(new FullRender(350, 300));
.ExpectChildMeasure(new Size(400, 500), SpacePlan.FullRender(300, 350))
.CheckMeasureResult(SpacePlan.FullRender(350, 300));
}
#endregion
+46 -47
View File
@@ -1,6 +1,5 @@
using FluentAssertions;
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
@@ -17,80 +16,80 @@ namespace QuestPDF.UnitTests
public void Measure_ReturnsWrap_WhenFirstChildWraps()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
public void Measure_ReturnsPartialRender_WhenFirstChildReturnsPartialRender()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new PartialRender(300, 200));
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.PartialRender(300, 200));
}
[Test]
public void Measure_ReturnsPartialRender_WhenSecondChildWraps()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), new Wrap())
.CheckMeasureResult(new PartialRender(200, 100));
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.PartialRender(200, 100));
}
[Test]
public void Measure_ReturnsPartialRender_WhenSecondChildReturnsPartialRender()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), new PartialRender(300, 150))
.CheckMeasureResult(new PartialRender(300, 250));
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.PartialRender(300, 150))
.CheckMeasureResult(SpacePlan.PartialRender(300, 250));
}
[Test]
public void Measure_ReturnsFullRender_WhenSecondChildReturnsFullRender()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(200, 150));
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(200, 150));
}
[Test]
public void Measure_UsesEmpty_WhenFirstChildIsRendered()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second"),
@@ -98,8 +97,8 @@ namespace QuestPDF.UnitTests
IsFirstRendered = true
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("second", new Size(400, 300), new FullRender(200, 300))
.CheckMeasureResult(new FullRender(200, 300));
.ExpectChildMeasure("second", new Size(400, 300), SpacePlan.FullRender(200, 300))
.CheckMeasureResult(SpacePlan.FullRender(200, 300));
}
#endregion
@@ -110,13 +109,13 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildWraps()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new Wrap())
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.Wrap())
.CheckDrawResult();
}
@@ -124,13 +123,13 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildPartiallyRenders()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new PartialRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.PartialRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.CheckDrawResult();
}
@@ -139,15 +138,15 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildFullyRenders_AndSecondChildWraps()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.ExpectChildMeasure("second", new Size(400, 200), new Wrap())
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.Wrap())
.CheckDrawResult();
}
@@ -155,15 +154,15 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildFullyRenders_AndSecondChildPartiallyRenders()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.ExpectChildMeasure("second", new Size(400, 200), new PartialRender(250, 150))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.PartialRender(250, 150))
.ExpectCanvasTranslate(0, 100)
.ExpectChildDraw("second", new Size(400, 150))
.ExpectCanvasTranslate(0, -100)
@@ -174,15 +173,15 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildFullyRenders_AndSecondChildFullyRenders()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.ExpectChildMeasure("second", new Size(400, 200), new FullRender(250, 150))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.FullRender(250, 150))
.ExpectCanvasTranslate(0, 100)
.ExpectChildDraw("second", new Size(400, 150))
.ExpectCanvasTranslate(0, -100)
@@ -193,7 +192,7 @@ namespace QuestPDF.UnitTests
public void Draw_UsesEmpty_WhenFirstChildIsRendered()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second"),
@@ -201,11 +200,11 @@ namespace QuestPDF.UnitTests
IsFirstRendered = true
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("second", new Size(400, 300), new PartialRender(200, 300))
.ExpectChildMeasure("second", new Size(400, 300), SpacePlan.PartialRender(200, 300))
.ExpectCanvasTranslate(0, 0)
.ExpectChildDraw("second", new Size(400, 300))
.ExpectCanvasTranslate(0, 0)
.CheckState<SimpleStack>(x => x.IsFirstRendered)
.CheckState<BinaryStack>(x => x.IsFirstRendered)
.CheckDrawResult();
}
@@ -213,7 +212,7 @@ namespace QuestPDF.UnitTests
public void Draw_TogglesFirstRenderedFlag_WhenSecondFullyRenders()
{
TestPlan
.For(x => new SimpleStack
.For(x => new BinaryStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second"),
@@ -221,12 +220,12 @@ namespace QuestPDF.UnitTests
IsFirstRendered = true
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("second", new Size(400, 300), new FullRender(200, 300))
.ExpectChildMeasure("second", new Size(400, 300), SpacePlan.FullRender(200, 300))
.ExpectCanvasTranslate(0, 0)
.ExpectChildDraw("second", new Size(400, 300))
.ExpectCanvasTranslate(0, 0)
.CheckDrawResult()
.CheckState<SimpleStack>(x => !x.IsFirstRendered);
.CheckState<BinaryStack>(x => !x.IsFirstRendered);
}
#endregion
@@ -264,9 +263,9 @@ namespace QuestPDF.UnitTests
{
Bottom = -spacing,
Child = new SimpleStack
Child = new BinaryStack
{
First = new SimpleStack
First = new BinaryStack
{
First = new Padding
{
@@ -279,14 +278,14 @@ namespace QuestPDF.UnitTests
Child = childB
}
},
Second = new SimpleStack
Second = new BinaryStack
{
First = new Padding
{
Bottom = spacing,
Child = childC
},
Second = new SimpleStack
Second = new BinaryStack
{
First = new Padding
{
+3 -3
View File
@@ -1,5 +1,5 @@
using System;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.UnitTests.TestEngine
@@ -7,10 +7,10 @@ namespace QuestPDF.UnitTests.TestEngine
internal class ElementMock : Element
{
public string Id { get; set; }
public Func<Size, ISpacePlan> MeasureFunc { get; set; }
public Func<Size, SpacePlan> MeasureFunc { get; set; }
public Action<Size> DrawFunc { get; set; }
internal override ISpacePlan Measure(Size availableSpace) => MeasureFunc(availableSpace);
internal override SpacePlan Measure(Size availableSpace) => MeasureFunc(availableSpace);
internal override void Draw(Size availableSpace) => DrawFunc(availableSpace);
}
}
@@ -1,4 +1,4 @@
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.UnitTests.TestEngine.Operations
@@ -7,9 +7,9 @@ namespace QuestPDF.UnitTests.TestEngine.Operations
{
public string ChildId { get; }
public Size Input { get; }
public ISpacePlan Output { get; }
public SpacePlan Output { get; }
public ChildMeasureOperation(string childId, Size input, ISpacePlan output)
public ChildMeasureOperation(string childId, Size input, SpacePlan output)
{
ChildId = childId;
Input = input;
@@ -1,5 +1,4 @@
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.UnitTests.TestEngine
@@ -23,8 +22,8 @@ namespace QuestPDF.UnitTests.TestEngine
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
private static void Measure_PartialRender<TElement>() where TElement : Element, IContainer, new()
@@ -35,8 +34,8 @@ namespace QuestPDF.UnitTests.TestEngine
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new PartialRender(200, 100))
.CheckMeasureResult(new PartialRender(200, 100));
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(200, 100))
.CheckMeasureResult(SpacePlan.PartialRender(200, 100));
}
private static void Measure_FullRender<TElement>() where TElement : Element, IContainer, new()
@@ -47,8 +46,8 @@ namespace QuestPDF.UnitTests.TestEngine
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), new FullRender(250, 150))
.CheckMeasureResult(new FullRender(250, 150));
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(250, 150))
.CheckMeasureResult(SpacePlan.FullRender(250, 150));
}
#endregion
+17 -23
View File
@@ -4,7 +4,6 @@ using System.Text.Json;
using FluentAssertions;
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
@@ -157,12 +156,12 @@ namespace QuestPDF.UnitTests.TestEngine
return this;
}
public TestPlan ExpectChildMeasure(Size expectedInput, ISpacePlan returns)
public TestPlan ExpectChildMeasure(Size expectedInput, SpacePlan returns)
{
return ExpectChildMeasure(DefaultChildName, expectedInput, returns);
}
public TestPlan ExpectChildMeasure(string child, Size expectedInput, ISpacePlan returns)
public TestPlan ExpectChildMeasure(string child, Size expectedInput, SpacePlan returns)
{
return AddOperation(new ChildMeasureOperation(child, expectedInput, returns));
}
@@ -212,29 +211,24 @@ namespace QuestPDF.UnitTests.TestEngine
return AddOperation(new CanvasDrawImageOperation(position, size));
}
public TestPlan CheckMeasureResult(ISpacePlan expected)
public TestPlan CheckMeasureResult(SpacePlan expected)
{
Element.HandleVisitor(x => x?.Initialize(null, Canvas));
Element.VisitChildren(x => x?.Initialize(null, Canvas));
var actual = Element.Measure(OperationInput);
Assert.AreEqual(expected.GetType(), actual.GetType());
var expectedSize = expected as Size;
var actualSize = actual as Size;
if (expectedSize != null)
{
Assert.AreEqual(expectedSize.Width, actualSize.Width, "Measure: width");
Assert.AreEqual(expectedSize.Height, actualSize.Height, "Measure: height");
}
Assert.AreEqual(expected.Width, actual.Width, "Measure: width");
Assert.AreEqual(expected.Height, actual.Height, "Measure: height");
Assert.AreEqual(expected.Type, actual.Type, "Measure: height");
return this;
}
public TestPlan CheckDrawResult()
{
Element.HandleVisitor(x => x?.Initialize(null, Canvas));
Element.VisitChildren(x => x?.Initialize(null, Canvas));
Element.Draw(OperationInput);
return this;
}
@@ -277,11 +271,11 @@ namespace QuestPDF.UnitTests.TestEngine
availableSpace ??= new Size(400, 300);
var canvas = new FreeCanvas();
value.HandleVisitor(x => x.Initialize(null, canvas));
var valueMeasure = value.Measure(availableSpace);
value.VisitChildren(x => x.Initialize(null, canvas));
var valueMeasure = value.Measure(availableSpace.Value);
expected.HandleVisitor(x => x.Initialize(null, canvas));
var expectedMeasure = expected.Measure(availableSpace);
expected.VisitChildren(x => x.Initialize(null, canvas));
var expectedMeasure = expected.Measure(availableSpace.Value);
valueMeasure.Should().BeEquivalentTo(expectedMeasure);
}
@@ -291,12 +285,12 @@ namespace QuestPDF.UnitTests.TestEngine
availableSpace ??= new Size(400, 300);
var valueCanvas = new OperationRecordingCanvas();
value.HandleVisitor(x => x.Initialize(null, valueCanvas));
value.Draw(availableSpace);
value.VisitChildren(x => x.Initialize(null, valueCanvas));
value.Draw(availableSpace.Value);
var expectedCanvas = new OperationRecordingCanvas();
expected.HandleVisitor(x => x.Initialize(null, expectedCanvas));
expected.Draw(availableSpace);
expected.VisitChildren(x => x.Initialize(null, expectedCanvas));
expected.Draw(availableSpace.Value);
valueCanvas.Operations.Should().BeEquivalentTo(expectedCanvas.Operations);
}
-1
View File
@@ -1,5 +1,4 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
+10 -10
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -20,8 +20,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, new Wrap())
.CheckMeasureResult(new Wrap());
.ExpectChildMeasure(Size.Max, SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
}
[Test]
@@ -33,8 +33,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, new PartialRender(1200, 1600))
.CheckMeasureResult(new PartialRender(Size.Zero));
.ExpectChildMeasure(Size.Max, SpacePlan.PartialRender(1200, 1600))
.CheckMeasureResult(SpacePlan.PartialRender(Size.Zero));
}
[Test]
@@ -46,8 +46,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, new FullRender(1200, 1600))
.CheckMeasureResult(new FullRender(Size.Zero));
.ExpectChildMeasure(Size.Max, SpacePlan.FullRender(1200, 1600))
.CheckMeasureResult(SpacePlan.FullRender(Size.Zero));
}
#endregion
@@ -63,7 +63,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, new Wrap())
.ExpectChildMeasure(Size.Max, SpacePlan.Wrap())
.CheckDrawResult();
}
@@ -76,7 +76,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, new PartialRender(1200, 1600))
.ExpectChildMeasure(Size.Max, SpacePlan.PartialRender(1200, 1600))
.ExpectChildDraw(new Size(1200, 1600))
.CheckDrawResult();
}
@@ -90,7 +90,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, new FullRender(1600, 1000))
.ExpectChildMeasure(Size.Max, SpacePlan.FullRender(1600, 1000))
.ExpectChildDraw(new Size(1600, 1000))
.CheckDrawResult();
}
+2 -1
View File
@@ -2,4 +2,5 @@
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: InternalsVisibleTo("QuestPDF.UnitTests")]
[assembly: InternalsVisibleTo("QuestPDF.Examples")]
[assembly: InternalsVisibleTo("QuestPDF.Examples")]
[assembly: InternalsVisibleTo("QuestPDF.ReportSample")]
+96 -12
View File
@@ -1,9 +1,14 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing.Proxy;
using QuestPDF.Elements;
using QuestPDF.Elements.Text;
using QuestPDF.Elements.Text.Items;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing
@@ -17,6 +22,13 @@ namespace QuestPDF.Drawing
RenderDocument(canvas, document);
}
internal static void GenerateXps(Stream stream, IDocument document)
{
var metadata = document.GetMetadata();
var canvas = new XpsCanvas(stream, metadata);
RenderDocument(canvas, document);
}
internal static ICollection<byte[]> GenerateImages(IDocument document)
{
var metadata = document.GetMetadata();
@@ -32,19 +44,25 @@ namespace QuestPDF.Drawing
var container = new DocumentContainer();
document.Compose(container);
var content = container.Compose();
ApplyDefaultTextStyle(content, TextStyle.LibraryDefault);
var metadata = document.GetMetadata();
var pageContext = new PageContext();
RenderPass(pageContext, new FreeCanvas(), content, metadata);
RenderPass(pageContext, canvas, content, metadata);
var debuggingState = metadata.ApplyDebugging ? ApplyDebugging(content) : null;
if (metadata.ApplyCaching)
ApplyCaching(content);
RenderPass(pageContext, new FreeCanvas(), content, metadata, debuggingState);
RenderPass(pageContext, canvas, content, metadata, debuggingState);
}
private static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata)
internal static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata, DebuggingState? debuggingState)
where TCanvas : ICanvas, IRenderingCanvas
{
content.HandleVisitor(x => x?.Initialize(pageContext, canvas));
content.HandleVisitor(x => (x as IStateResettable)?.ResetState());
content.VisitChildren(x => x?.Initialize(pageContext, canvas));
content.VisitChildren(x => (x as IStateResettable)?.ResetState());
canvas.BeginDocument();
@@ -53,9 +71,11 @@ namespace QuestPDF.Drawing
while(true)
{
pageContext.SetPageNumber(currentPage);
var spacePlan = content.Measure(Size.Max) as Size;
debuggingState?.Reset();
var spacePlan = content.Measure(Size.Max);
if (spacePlan == null)
if (spacePlan.Type == SpacePlanType.Wrap)
{
canvas.EndDocument();
ThrowLayoutException();
@@ -77,21 +97,85 @@ namespace QuestPDF.Drawing
if (currentPage >= documentMetadata.DocumentLayoutExceptionThreshold)
{
canvas.EndDocument();
throw new DocumentLayoutException("Composed layout generates infinite document.");
ThrowLayoutException();
}
if (spacePlan is FullRender)
if (spacePlan.Type == SpacePlanType.FullRender)
break;
currentPage++;
}
canvas.EndDocument();
void ThrowLayoutException()
{
throw new DocumentLayoutException("Composed layout generates infinite document.");
var message = $"Composed layout generates infinite document. This may happen in two cases. " +
$"1) Your document and its layout configuration is correct but the content takes more than {documentMetadata.DocumentLayoutExceptionThreshold} pages. " +
$"In this case, please increase the value {nameof(DocumentMetadata)}.{nameof(DocumentMetadata.DocumentLayoutExceptionThreshold)} property configured in the {nameof(IDocument.GetMetadata)} method. " +
$"2) The layout configuration of your document is invalid. Some of the elements require more space than is provided." +
$"Please analyze your documents structure to detect this element and fix its size constraints.";
throw new DocumentLayoutException(message)
{
ElementTrace = debuggingState?.BuildTrace() ?? "Debug trace is available only in the DEBUG mode."
};
}
}
private static void ApplyCaching(Container content)
{
content.VisitChildren(x =>
{
if (x is ICacheable)
x.CreateProxy(y => new CacheProxy(y));
});
}
private static DebuggingState ApplyDebugging(Container content)
{
var debuggingState = new DebuggingState();
content.VisitChildren(x =>
{
x.CreateProxy(y => new DebuggingProxy(debuggingState, y));
});
return debuggingState;
}
private static void ApplyDefaultTextStyle(this Element? content, TextStyle documentDefaultTextStyle)
{
if (content == null)
return;
if (content is TextBlock textBlock)
{
foreach (var textBlockItem in textBlock.Items)
{
if (textBlockItem is TextBlockSpan textSpan)
{
textSpan.Style.ApplyGlobalStyle(documentDefaultTextStyle);
}
else if (textBlockItem is TextBlockElement textElement)
{
ApplyDefaultTextStyle(textElement.Element, documentDefaultTextStyle);
}
}
return;
}
var targetTextStyle = documentDefaultTextStyle;
if (content is DefaultTextStyle defaultTextStyleElement)
{
defaultTextStyleElement.TextStyle.ApplyParentStyle(documentDefaultTextStyle);
targetTextStyle = defaultTextStyleElement.TextStyle;
}
foreach (var child in content.GetChildren())
ApplyDefaultTextStyle(child, targetTextStyle);
}
}
}
+4 -1
View File
@@ -23,7 +23,10 @@ namespace QuestPDF.Drawing
/// (likely due to infinite layout), the exception is thrown.
/// </summary>
public int DocumentLayoutExceptionThreshold { get; set; } = 250;
public bool ApplyCaching { get; set; } = !System.Diagnostics.Debugger.IsAttached;
public bool ApplyDebugging { get; set; } = System.Diagnostics.Debugger.IsAttached;
public static DocumentMetadata Default => new DocumentMetadata();
}
}
@@ -4,6 +4,8 @@ namespace QuestPDF.Drawing.Exceptions
{
public class DocumentLayoutException : Exception
{
public string ElementTrace { get; set; }
public DocumentLayoutException()
{
+5 -6
View File
@@ -1,7 +1,6 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
using SkiaSharp;
@@ -34,7 +33,7 @@ namespace QuestPDF.Drawing
internal static SKPaint ToPaint(this TextStyle style)
{
return Paints.GetOrAdd(style.ToString(), key => Convert(style));
return Paints.GetOrAdd(style.Key, key => Convert(style));
static SKPaint Convert(TextStyle style)
{
@@ -42,7 +41,7 @@ namespace QuestPDF.Drawing
{
Color = SKColor.Parse(style.Color),
Typeface = GetTypeface(style),
TextSize = style.Size,
TextSize = (style.Size ?? 12),
TextEncoding = SKTextEncoding.Utf32
};
}
@@ -52,16 +51,16 @@ namespace QuestPDF.Drawing
if (Typefaces.TryGetValue(style.FontType, out var result))
return result;
var slant = style.IsItalic ? SKFontStyleSlant.Italic : SKFontStyleSlant.Upright;
var slant = (style.IsItalic ?? false) ? SKFontStyleSlant.Italic : SKFontStyleSlant.Upright;
return SKTypeface.FromFamilyName(style.FontType, (int)style.FontWeight, (int)SKFontStyleWidth.Normal, slant)
return SKTypeface.FromFamilyName(style.FontType, (int)(style.FontWeight ?? FontWeight.Normal), (int)SKFontStyleWidth.Normal, slant)
?? throw new ArgumentException($"The typeface {style.FontType} could not be found.");
}
}
internal static SKFontMetrics ToFontMetrics(this TextStyle style)
{
return FontMetrics.GetOrAdd(style.ToString(), key => style.ToPaint().FontMetrics);
return FontMetrics.GetOrAdd(style.Key, key => style.ToPaint().FontMetrics);
}
}
}
+3 -33
View File
@@ -4,43 +4,13 @@ using SkiaSharp;
namespace QuestPDF.Drawing
{
internal class PdfCanvas : SkiaCanvasBase
internal class PdfCanvas : SkiaDocumentCanvasBase
{
private SKDocument Document { get; }
public PdfCanvas(Stream stream, DocumentMetadata documentMetadata)
{
Document = SKDocument.CreatePdf(stream, MapMetadata(documentMetadata));
}
~PdfCanvas()
{
Document.Dispose();
}
public override void BeginDocument()
public PdfCanvas(Stream stream, DocumentMetadata documentMetadata)
: base(SKDocument.CreatePdf(stream, MapMetadata(documentMetadata)))
{
}
public override void EndDocument()
{
Canvas.Dispose();
Document.Close();
Document.Dispose();
}
public override void BeginPage(Size size)
{
Canvas = Document.BeginPage(size.Width, size.Height);
}
public override void EndPage()
{
Document.EndPage();
Canvas.Dispose();
}
private static SKDocumentPdfMetadata MapMetadata(DocumentMetadata metadata)
{
+45
View File
@@ -0,0 +1,45 @@
using System;
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.Proxy
{
internal class CacheProxy : ElementProxy
{
public Size? AvailableSpace { get; set; }
public SpacePlan? MeasurementResult { get; set; }
public CacheProxy(Element child)
{
Child = child;
}
internal override SpacePlan Measure(Size availableSpace)
{
if (MeasurementResult != null &&
AvailableSpace != null &&
IsClose(AvailableSpace.Value.Width, availableSpace.Width) &&
IsClose(AvailableSpace.Value.Height, availableSpace.Height))
{
return MeasurementResult.Value;
}
AvailableSpace = availableSpace;
MeasurementResult = base.Measure(availableSpace);
return MeasurementResult.Value;
}
internal override void Draw(Size availableSpace)
{
AvailableSpace = null;
MeasurementResult = null;
base.Draw(availableSpace);
}
private bool IsClose(float x, float y)
{
return Math.Abs(x - y) < Size.Epsilon;
}
}
}
+14
View File
@@ -0,0 +1,14 @@
using System.Collections.Generic;
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.Proxy
{
public class DebugStackItem
{
public IElement Element { get; internal set; }
public Size AvailableSpace { get; internal set; }
public SpacePlan SpacePlan { get; internal set; }
public ICollection<DebugStackItem> Stack { get; internal set; } = new List<DebugStackItem>();
}
}
+24
View File
@@ -0,0 +1,24 @@
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.Proxy
{
internal class DebuggingProxy : ElementProxy
{
private DebuggingState DebuggingState { get; }
public DebuggingProxy(DebuggingState debuggingState, Element child)
{
DebuggingState = debuggingState;
Child = child;
}
internal override SpacePlan Measure(Size availableSpace)
{
DebuggingState.RegisterMeasure(Child, availableSpace);
var spacePlan = base.Measure(availableSpace);
DebuggingState.RegisterMeasureResult(Child, spacePlan);
return spacePlan;
}
}
}
+130
View File
@@ -0,0 +1,130 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QuestPDF.Elements;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.Proxy
{
internal class DebuggingState
{
private DebugStackItem Root { get; set; }
private Stack<DebugStackItem> Stack { get; set; }
public DebuggingState()
{
Reset();
}
public void Reset()
{
Root = null;
Stack = new Stack<DebugStackItem>();
}
public void RegisterMeasure(IElement element, Size availableSpace)
{
if (element.GetType() == typeof(Container))
return;
var item = new DebugStackItem
{
Element = element,
AvailableSpace = availableSpace
};
Root ??= item;
if (Stack.Any())
Stack.Peek().Stack.Add(item);
Stack.Push(item);
}
public void RegisterMeasureResult(IElement element, SpacePlan spacePlan)
{
if (element.GetType() == typeof(Container))
return;
var item = Stack.Pop();
if (item.Element != element)
throw new Exception();
item.SpacePlan = spacePlan;
}
public string BuildTrace()
{
var builder = new StringBuilder();
var nestingLevel = 0;
Traverse(Root);
return builder.ToString();
void Traverse(DebugStackItem item)
{
var indent = new string(' ', nestingLevel * 4);
var title = item.Element.GetType().Name;
if (item.Element is DebugPointer debugPointer)
{
title = debugPointer.Target;
title += debugPointer.Highlight ? " 🌟" : string.Empty;
}
if (item.SpacePlan.Type != SpacePlanType.FullRender)
title = "🔥 " + title;
builder.AppendLine(indent + title);
builder.AppendLine(indent + new string('-', title.Length));
builder.AppendLine(indent + "Available space: " + item.AvailableSpace);
builder.AppendLine(indent + "Requested space: " + item.SpacePlan);
foreach (var configuration in GetElementConfiguration(item.Element))
builder.AppendLine(indent + configuration);
builder.AppendLine();
nestingLevel++;
item.Stack.ToList().ForEach(Traverse);
nestingLevel--;
}
static IEnumerable<string> GetElementConfiguration(IElement element)
{
if (element is DebugPointer)
return Enumerable.Empty<string>();
return element
.GetType()
.GetProperties()
.Select(x => new
{
Property = x.Name.PrettifyName(),
Value = x.GetValue(element)
})
.Where(x => !(x.Value is IElement))
.Where(x => x.Value is string || !(x.Value is IEnumerable))
.Where(x => !(x.Value is TextStyle))
.Select(x => $"{x.Property}: {FormatValue(x.Value)}");
string FormatValue(object value)
{
const int maxLength = 100;
var text = value?.ToString() ?? "-";
if (text.Length < maxLength)
return text;
return text.AsSpan(0, maxLength).ToString() + "...";
}
}
}
}
}
+9
View File
@@ -0,0 +1,9 @@
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.Proxy
{
internal class ElementProxy : ContainerElement
{
}
}
@@ -0,0 +1,45 @@
using System.IO;
using QuestPDF.Infrastructure;
using SkiaSharp;
namespace QuestPDF.Drawing
{
internal class SkiaDocumentCanvasBase : SkiaCanvasBase
{
private SKDocument Document { get; }
public SkiaDocumentCanvasBase(SKDocument document)
{
Document = document;
}
~SkiaDocumentCanvasBase()
{
Document.Dispose();
}
public override void BeginDocument()
{
}
public override void EndDocument()
{
Canvas.Dispose();
Document.Close();
Document.Dispose();
}
public override void BeginPage(Size size)
{
Canvas = Document.BeginPage(size.Width, size.Height);
}
public override void EndPage()
{
Document.EndPage();
Canvas.Dispose();
}
}
}
+42
View File
@@ -0,0 +1,42 @@
using System.Collections.Generic;
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing
{
public readonly struct SpacePlan
{
public readonly SpacePlanType Type;
public readonly float Width;
public readonly float Height;
internal SpacePlan(SpacePlanType type, float width, float height)
{
Type = type;
Width = width;
Height = height;
}
internal static SpacePlan Wrap() => new SpacePlan(SpacePlanType.Wrap, 0, 0);
internal static SpacePlan PartialRender(float width, float height) => new SpacePlan(SpacePlanType.PartialRender, width, height);
internal static SpacePlan PartialRender(Size size) => PartialRender(size.Width, size.Height);
internal static SpacePlan FullRender(float width, float height) => new SpacePlan(SpacePlanType.FullRender, width, height);
internal static SpacePlan FullRender(Size size) => FullRender(size.Width, size.Height);
public override string ToString()
{
if (Type == SpacePlanType.Wrap)
return Type.ToString();
return $"{Type} (Width: {Width:N3}, Height: {Height:N3})";
}
public static implicit operator Size(SpacePlan spacePlan)
{
return new Size(spacePlan.Width, spacePlan.Height);
}
}
}
-19
View File
@@ -1,19 +0,0 @@
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.SpacePlan
{
internal class FullRender : Size, ISpacePlan
{
public FullRender(Size size) : this(size.Width, size.Height)
{
}
public FullRender(float width, float height) : base(width, height)
{
}
public override string ToString() => $"FullRender {base.ToString()}";
}
}
-7
View File
@@ -1,7 +0,0 @@
namespace QuestPDF.Drawing.SpacePlan
{
internal interface ISpacePlan
{
}
}
@@ -1,19 +0,0 @@
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.SpacePlan
{
internal class PartialRender : Size, ISpacePlan
{
public PartialRender(Size size) : this(size.Width, size.Height)
{
}
public PartialRender(float width, float height) : base(width, height)
{
}
public override string ToString() => $"PartialRender {base.ToString()}";
}
}
-13
View File
@@ -1,13 +0,0 @@
namespace QuestPDF.Drawing.SpacePlan
{
internal class TextRender : FullRender
{
public float Ascent { get; set; }
public float Descent { get; set; }
public TextRender(float width, float height) : base(width, height)
{
}
}
}
-7
View File
@@ -1,7 +0,0 @@
namespace QuestPDF.Drawing.SpacePlan
{
internal class Wrap : ISpacePlan
{
public override string ToString() => "Wrap";
}
}
+9
View File
@@ -0,0 +1,9 @@
namespace QuestPDF.Drawing
{
public enum SpacePlanType
{
Wrap,
PartialRender,
FullRender
}
}
@@ -1,4 +1,4 @@
namespace QuestPDF.Drawing.SpacePlan
namespace QuestPDF.Drawing
{
internal struct TextMeasurement
{
+15
View File
@@ -0,0 +1,15 @@
using System.IO;
using QuestPDF.Infrastructure;
using SkiaSharp;
namespace QuestPDF.Drawing
{
internal class XpsCanvas : SkiaDocumentCanvasBase
{
public XpsCanvas(Stream stream, DocumentMetadata documentMetadata)
: base(SKDocument.CreateXps(stream, documentMetadata.RasterDpi))
{
}
}
}
+4 -3
View File
@@ -1,4 +1,5 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
@@ -13,16 +14,16 @@ namespace QuestPDF.Elements
if (Child == null)
return;
var childSize = Child.Measure(availableSpace) as Size;
var childSize = base.Measure(availableSpace);
if (childSize == null)
if (childSize.Type == SpacePlanType.Wrap)
return;
var top = GetTopOffset(availableSpace, childSize);
var left = GetLeftOffset(availableSpace, childSize);
Canvas.Translate(new Position(left, top));
Child.Draw(childSize);
base.Draw(childSize);
Canvas.Translate(new Position(-left, -top));
}
+14 -14
View File
@@ -1,37 +1,37 @@
using System;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class AspectRatio : ContainerElement
internal class AspectRatio : ContainerElement, ICacheable
{
public float Ratio { get; set; } = 1;
public AspectRatioOption Option { get; set; } = AspectRatioOption.FitWidth;
internal override ISpacePlan Measure(Size availableSpace)
internal override SpacePlan Measure(Size availableSpace)
{
if(Child == null)
return new FullRender(Size.Zero);
return SpacePlan.FullRender(0, 0);
var targetSize = GetTargetSize(availableSpace);
if (targetSize.Height > availableSpace.Height + Size.Epsilon)
return new Wrap();
return SpacePlan.Wrap();
if (targetSize.Width > availableSpace.Width + Size.Epsilon)
return new Wrap();
return SpacePlan.Wrap();
var childSize = Child.Measure(targetSize);
var childSize = base.Measure(targetSize);
if (childSize is Wrap)
return new Wrap();
if (childSize.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (childSize is PartialRender)
return new PartialRender(targetSize);
if (childSize.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(targetSize);
if (childSize is FullRender)
return new FullRender(targetSize);
if (childSize.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(targetSize);
throw new NotSupportedException();
}
@@ -42,7 +42,7 @@ namespace QuestPDF.Elements
return;
var size = GetTargetSize(availableSpace);
Child?.Draw(size);
base.Draw(size);
}
private Size GetTargetSize(Size availableSpace)
+1 -1
View File
@@ -10,7 +10,7 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
Canvas.DrawRectangle(Position.Zero, availableSpace, Color);
Child?.Draw(availableSpace);
base.Draw(availableSpace);
}
}
}
+6 -1
View File
@@ -14,7 +14,7 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
Child?.Draw(availableSpace);
base.Draw(availableSpace);
Canvas.DrawRectangle(
new Position(-Left/2, -Top/2),
@@ -36,5 +36,10 @@ namespace QuestPDF.Elements
new Size(Right, availableSpace.Height + Top/2 + Bottom/2),
Color);
}
public override string ToString()
{
return $"Border: Top({Top}) Right({Right}) Bottom({Bottom}) Left({Left}) Color({Color})";
}
}
}
-17
View File
@@ -1,17 +0,0 @@
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Box : ContainerElement
{
internal override void Draw(Size availableSpace)
{
var targetSize = Child?.Measure(availableSpace) as Size;
if (targetSize == null)
return;
Child?.Draw(targetSize);
}
}
}
+6 -6
View File
@@ -1,4 +1,4 @@
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
using SkiaSharp;
@@ -6,13 +6,13 @@ namespace QuestPDF.Elements
{
public delegate void DrawOnCanvas(SKCanvas canvas, Size availableSpace);
internal class Canvas : Element
internal class Canvas : Element, ICacheable
{
public DrawOnCanvas Handler { get; set; }
internal override ISpacePlan Measure(Size availableSpace)
internal override SpacePlan Measure(Size availableSpace)
{
return new FullRender(availableSpace);
return SpacePlan.FullRender(availableSpace);
}
internal override void Draw(Size availableSpace)
@@ -22,9 +22,9 @@ namespace QuestPDF.Elements
if (Handler == null || skiaCanvas == null)
return;
var currentMatrix = skiaCanvas.TotalMatrix;
var originalMatrix = skiaCanvas.TotalMatrix;
Handler.Invoke(skiaCanvas, availableSpace);
skiaCanvas.SetMatrix(currentMatrix);
skiaCanvas.SetMatrix(originalMatrix);
}
}
}
+24 -28
View File
@@ -1,45 +1,44 @@
using System;
using System.Linq;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Constrained : ContainerElement
internal class Constrained : ContainerElement, ICacheable
{
public float? MinWidth { get; set; }
public float? MaxWidth { get; set; }
public float? MinHeight { get; set; }
public float? MaxHeight { get; set; }
internal override ISpacePlan Measure(Size availableSpace)
internal override SpacePlan Measure(Size availableSpace)
{
if (MinWidth > availableSpace.Width + Size.Epsilon)
return new Wrap();
return SpacePlan.Wrap();
if (MinHeight > availableSpace.Height + Size.Epsilon)
return new Wrap();
return SpacePlan.Wrap();
var available = new Size(
MathHelpers.Min(MaxWidth, availableSpace.Width),
MathHelpers.Min(MaxHeight, availableSpace.Height));
Min(MaxWidth, availableSpace.Width),
Min(MaxHeight, availableSpace.Height));
var measurement = Child?.Measure(available) ?? new FullRender(Size.Zero);
var size = measurement as Size;
var measurement = base.Measure(available);
if (measurement is Wrap)
return new Wrap();
if (measurement.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
var actualSize = new Size(
MathHelpers.Max(MinWidth, size.Width),
MathHelpers.Max(MinHeight, size.Height));
Max(MinWidth, measurement.Width),
Max(MinHeight, measurement.Height));
if (size is FullRender)
return new FullRender(actualSize);
if (measurement.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(actualSize);
if (size is PartialRender)
return new PartialRender(actualSize);
if (measurement.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(actualSize);
throw new NotSupportedException();
}
@@ -47,23 +46,20 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
var available = new Size(
MathHelpers.Min(MaxWidth, availableSpace.Width),
MathHelpers.Min(MaxHeight, availableSpace.Height));
Min(MaxWidth, availableSpace.Width),
Min(MaxHeight, availableSpace.Height));
Child?.Draw(available);
}
}
static class MathHelpers
{
public static float Min(params float?[] values)
private static float Min(float? x, float y)
{
return values.Where(x => x.HasValue).Min().Value;
return x.HasValue ? Math.Min(x.Value, y) : y;
}
public static float Max(params float?[] values)
private static float Max(float? x, float y)
{
return values.Where(x => x.HasValue).Max().Value;
return x.HasValue ? Math.Max(x.Value, y) : y;
}
}
}
@@ -5,7 +5,7 @@ using SkiaSharp;
namespace QuestPDF.Elements
{
internal class Debug : IComponent
internal class DebugArea : IComponent
{
public IElement? Child { get; set; }
@@ -27,10 +27,10 @@ namespace QuestPDF.Elements
.Layer()
.ShowIf(!string.IsNullOrWhiteSpace(Text))
.AlignCenter()
.Box()
.MinimalBox()
.Background(Colors.White)
.Padding(2)
.Text(Text, TextStyle.Default.Color(Color).FontType("Consolas").Size(8));
.Text(Text, TextStyle.Default.Color(Color).FontType(Fonts.Consolas).Size(8));
});
}
}
+10
View File
@@ -0,0 +1,10 @@
using System.ComponentModel;
namespace QuestPDF.Elements
{
internal class DebugPointer : Container
{
public string Target { get; set; }
public bool Highlight { get; set; }
}
}
+29 -24
View File
@@ -1,5 +1,6 @@
using System;
using QuestPDF.Drawing.SpacePlan;
using System.Collections.Generic;
using QuestPDF.Drawing;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
@@ -11,48 +12,52 @@ namespace QuestPDF.Elements
Append
}
internal class SimpleDecoration : Element
internal class BinaryDecoration : Element, ICacheable
{
public Element DecorationElement { get; set; } = Empty.Instance;
public Element ContentElement { get; set; } = Empty.Instance;
public DecorationType Type { get; set; }
internal override void HandleVisitor(Action<Element?> visit)
internal override IEnumerable<Element?> GetChildren()
{
DecorationElement?.HandleVisitor(visit);
ContentElement?.HandleVisitor(visit);
base.HandleVisitor(visit);
yield return DecorationElement;
yield return ContentElement;
}
internal override ISpacePlan Measure(Size availableSpace)
internal override void CreateProxy(Func<Element, Element> create)
{
var decorationMeasure = DecorationElement?.Measure(availableSpace);
if (decorationMeasure is Wrap || decorationMeasure is PartialRender)
return new Wrap();
DecorationElement = create(DecorationElement);
ContentElement = create(ContentElement);
}
var decorationSize = decorationMeasure as Size ?? Size.Zero;
var contentMeasure = ContentElement?.Measure(new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height)) ?? new FullRender(Size.Zero);
internal override SpacePlan Measure(Size availableSpace)
{
var decorationMeasure = DecorationElement.Measure(availableSpace);
if (contentMeasure is Wrap)
return new Wrap();
if (decorationMeasure.Type == SpacePlanType.Wrap || decorationMeasure.Type == SpacePlanType.PartialRender)
return SpacePlan.Wrap();
var contentSize = contentMeasure as Size ?? Size.Zero;
var decorationSize = decorationMeasure;
var contentMeasure = ContentElement.Measure(new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height));
if (contentMeasure.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
var contentSize = contentMeasure;
var resultSize = new Size(availableSpace.Width, decorationSize.Height + contentSize.Height);
if (contentSize is PartialRender)
return new PartialRender(resultSize);
if (contentSize.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(resultSize);
if (contentSize is FullRender)
return new FullRender(resultSize);
if (contentSize.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(resultSize);
throw new NotSupportedException();
}
internal override void Draw(Size availableSpace)
{
var decorationSize = DecorationElement?.Measure(availableSpace) as Size ?? Size.Zero;
var decorationSize = DecorationElement.Measure(availableSpace);
var contentSize = new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height);
var translateHeight = Type == DecorationType.Prepend ? decorationSize.Height : contentSize.Height;
@@ -77,11 +82,11 @@ namespace QuestPDF.Elements
public void Compose(IContainer container)
{
container.Element(new SimpleDecoration
container.Element(new BinaryDecoration
{
Type = DecorationType.Prepend,
DecorationElement = Header,
ContentElement = new SimpleDecoration
ContentElement = new BinaryDecoration
{
Type = DecorationType.Append,
ContentElement = Content,
+10
View File
@@ -0,0 +1,10 @@
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class DefaultTextStyle : ContainerElement
{
public TextStyle TextStyle { get; set; } = TextStyle.Default;
}
}
+3 -3
View File
@@ -1,5 +1,5 @@
using System;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
using SkiaSharp;
@@ -9,9 +9,9 @@ namespace QuestPDF.Elements
{
public Func<Size, byte[]>? Source { get; set; }
internal override ISpacePlan Measure(Size availableSpace)
internal override SpacePlan Measure(Size availableSpace)
{
return new FullRender(availableSpace.Width, availableSpace.Height);
return SpacePlan.FullRender(availableSpace.Width, availableSpace.Height);
}
internal override void Draw(Size availableSpace)
+3 -3
View File
@@ -1,4 +1,4 @@
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
@@ -7,9 +7,9 @@ namespace QuestPDF.Elements
{
internal static Empty Instance { get; } = new Empty();
internal override ISpacePlan Measure(Size availableSpace)
internal override SpacePlan Measure(Size availableSpace)
{
return new FullRender(Size.Zero);
return SpacePlan.FullRender(0, 0);
}
internal override void Draw(Size availableSpace)

Some files were not shown because too many files have changed in this diff Show More