Compare commits

..

17 Commits

Author SHA1 Message Date
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 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
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
130 changed files with 1715 additions and 1568 deletions
-1
View File
@@ -18,7 +18,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(400, 100)
.FileName()
.ShowResults()
.Render(container =>
{
-1
View File
@@ -15,7 +15,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 300)
.FileName()
.Render(container =>
{
container
-33
View File
@@ -1,33 +0,0 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
namespace QuestPDF.Examples
{
public class DebuggingTesting
{
[Test]
public void Stack()
{
RenderingTest
.Create()
.PageSize(500, 360)
.FileName()
.Render(container =>
{
container
.Background(Colors.White)
.Padding(15)
.Grid(grid =>
{
grid.Spacing(15);
grid.Item().Background(Colors.Grey.Medium).Text(Placeholders.LoremIpsum());
grid.Item().DebugPointer("Test").Background(Colors.Grey.Lighten1).Height(1000); // <-- problem
grid.Item().Background(Colors.Grey.Lighten2).Height(150);
});
});
}
}
}
@@ -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));
});
});
});
});
}
}
}
-170
View File
@@ -1,170 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using QuestPDF.Elements;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class OrderItem
{
public string ItemName { get; set; } = Placeholders.Label();
public int Price { get; set; } = Placeholders.Random.Next(1, 11) * 10;
public int Count { get; set; } = Placeholders.Random.Next(1, 11);
}
public class OrdersTable : IDynamicComponent
{
private ICollection<OrderItem> Items { get; }
private ICollection<OrderItem> ItemsLeft { get; set; }
public OrdersTable(ICollection<OrderItem> items)
{
Items = items;
}
public void Compose(DynamicContext context, IDynamicContainer container)
{
if (context.Operation == DynamicLayoutOperation.Reset)
{
ItemsLeft = new List<OrderItem>(Items);
return;
}
var header = ComposeHeader(context);
var sampleFooter = ComposeFooter(context, Enumerable.Empty<OrderItem>());
var decorationHeight = header.Size.Height + sampleFooter.Size.Height;
var rows = GetItemsForPage(context, decorationHeight).ToList();
var footer = ComposeFooter(context, rows.Select(x => x.Item));
if (ItemsLeft.Count > rows.Count)
container.HasMoreContent();
if (context.Operation == DynamicLayoutOperation.Draw)
ItemsLeft = ItemsLeft.Skip(rows.Count).ToList();
container.Box().Decoration(decoration =>
{
decoration.Header().Element(header);
decoration.Content().Box().Stack(stack =>
{
foreach (var row in rows)
stack.Item().Element(row.Element);
});
decoration.Footer().Element(footer);
});
}
private IDynamicElement ComposeHeader(DynamicContext context)
{
return context.CreateElement(element =>
{
element
.BorderBottom(1)
.BorderColor(Colors.Grey.Darken2)
.Padding(5)
.Row(row =>
{
var textStyle = TextStyle.Default.SemiBold();
row.ConstantColumn(30).Text("#", textStyle);
row.RelativeColumn().Text("Item name", textStyle);
row.ConstantColumn(50).AlignRight().Text("Count", textStyle);
row.ConstantColumn(50).AlignRight().Text("Price", textStyle);
row.ConstantColumn(50).AlignRight().Text("Total", textStyle);
});
});
}
private IDynamicElement ComposeFooter(DynamicContext context, IEnumerable<OrderItem> items)
{
var total = items.Sum(x => x.Count * x.Price);
return context.CreateElement(element =>
{
element
.Padding(5)
.AlignRight()
.Text($"Subtotal: {total}$", TextStyle.Default.Size(14).SemiBold());
});
}
private IEnumerable<(OrderItem Item, IDynamicElement Element)> GetItemsForPage(DynamicContext context, float decorationHeight)
{
var totalHeight = decorationHeight;
var counter = Items.Count - ItemsLeft.Count + 1;
foreach (var orderItem in ItemsLeft)
{
var element = context.CreateElement(content =>
{
content
.BorderBottom(1)
.BorderColor(Colors.Grey.Lighten2)
.Padding(5)
.Row(row =>
{
row.ConstantColumn(30).Text(counter++);
row.RelativeColumn().Text(orderItem.ItemName);
row.ConstantColumn(50).AlignRight().Text(orderItem.Count);
row.ConstantColumn(50).AlignRight().Text($"{orderItem.Price}$");
row.ConstantColumn(50).AlignRight().Text($"{orderItem.Count*orderItem.Price}$");
});
});
var elementHeight = element.Size.Height;
if (totalHeight + elementHeight > context.AvailableSize.Height)
break;
totalHeight += elementHeight;
yield return (orderItem, element);
}
}
}
public static class DynamicExamples
{
[Test]
public static void Dynamic()
{
RenderingTest
.Create()
.PageSize(PageSizes.A5)
.FileName()
.ShowResults()
.Render(container =>
{
var items = Enumerable.Range(0, 25).Select(x => new OrderItem()).ToList();
container
.Background(Colors.White)
.Padding(25)
.Decoration(decoration =>
{
decoration
.Header()
.PaddingBottom(5)
.Text(text =>
{
text.DefaultTextStyle(TextStyle.Default.SemiBold().Color(Colors.Blue.Darken2).Size(16));
text.Span("Page ");
text.CurrentPageNumber();
text.Span(" of ");
text.TotalPages();
});
decoration
.Content()
.Dynamic(new OrdersTable(items));
});
});
}
}
}
+1 -26
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)
.DebugArea("Grid example", Colors.Blue.Medium)
.Debug("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
@@ -502,7 +487,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 175)
.FileName()
.Render(container =>
{
container
@@ -554,7 +538,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(300, 200)
.FileName()
.Render(container =>
{
container
@@ -582,7 +565,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(650, 450)
.FileName()
.Render(container =>
{
container
@@ -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
@@ -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
+21 -6
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
@@ -25,12 +26,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;
@@ -67,12 +68,26 @@ namespace QuestPDF.Examples.Engine
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);
});
});
}
public void RenderDocument(Action<IDocumentContainer> content)
{
var maxPages = ResultType == RenderingTestResult.Pdf ? 1000 : 10;
var document = new SimpleDocument(container, Size, maxPages);
var document = new SimpleDocument(content, maxPages);
Render(document);
}
private void Render(IDocument document)
{
if (ResultType == RenderingTestResult.Images)
{
Func<int, string> fileNameSchema = i => $"{FileNamePrefix}-${i}.png";
+6 -11
View File
@@ -1,4 +1,5 @@
using QuestPDF.Drawing;
using System;
using QuestPDF.Drawing;
using QuestPDF.Elements;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
@@ -10,14 +11,12 @@ 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; }
public SimpleDocument(IContainer container, Size size, int maxPages)
public SimpleDocument(Action<IDocumentContainer> content, int maxPages)
{
Container = container;
Size = size;
Content = content;
MaxPages = maxPages;
}
@@ -32,11 +31,7 @@ namespace QuestPDF.Examples.Engine
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();
});
});
});
}
}
}
-1
View File
@@ -28,7 +28,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(550, 400)
.FileName()
.ShowResults()
.Render(container =>
{
+122
View File
@@ -0,0 +1,122 @@
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)
//.Box()
.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(400, 250)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Padding(20)
.Border(1)
.Background(Colors.Grey.Lighten3)
.Inlined(inlined =>
{
inlined.VerticalSpacing(50);
inlined.HorizontalSpacing(20);
inlined.AlignSpaceAround();
inlined.BaselineTop();
foreach (var _ in Enumerable.Range(0, 20))
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());
}
}
}
}
-1
View File
@@ -36,7 +36,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(350, 280)
.FileName()
.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
+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();
});
});
});
}
}
}
+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));
}
+1 -7
View File
@@ -17,7 +17,7 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(500, 300)
.FileName()
.ProduceImages()
.ShowResults()
.Render(container =>
@@ -42,7 +42,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(500, 300)
.FileName()
.ProduceImages()
.ShowResults()
.Render(container =>
@@ -71,7 +70,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(500, 200)
.FileName()
.ProduceImages()
.ShowResults()
.Render(container =>
@@ -103,7 +101,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
@@ -134,7 +131,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
@@ -164,7 +160,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
@@ -228,7 +223,6 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.FileName()
.ProducePdf()
.ShowResults()
.Render(container =>
-3
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
+1 -1
View File
@@ -6,7 +6,7 @@ namespace QuestPDF.ReportSample
{
public static class Helpers
{
public static Random Random { get; } = new Random(1);
public static Random Random { get; } = new Random();
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().Box().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().Box().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");
});
});
}
}
}
@@ -1,5 +1,6 @@
using System;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.ReportSample.Layouts
@@ -24,7 +25,7 @@ namespace QuestPDF.ReportSample.Layouts
{
container
.AspectRatio(AspectRatio)
.Background("#EEEEEE")
.Background(Colors.Grey.Lighten3)
.Image(Source(Size.Zero));
}
}
@@ -30,14 +30,14 @@ namespace QuestPDF.ReportSample.Layouts
container
.Row(row =>
{
row.RelativeColumn(2).AspectRatio(4 / 3f).Background(Colors.Grey.Lighten3);
row.RelativeColumn(2).AspectRatio(4 / 3f).Image(Placeholders.Image);
row.RelativeColumn().PaddingLeft(5).Stack(stack =>
{
stack.Spacing(7f);
stack.Item().AspectRatio(4 / 3f).Background(Colors.Grey.Lighten3);
stack.Item().AspectRatio(4 / 3f).Background(Colors.Grey.Lighten3);
stack.Item().AspectRatio(4 / 3f).Image(Placeholders.Image);
stack.Item().AspectRatio(4 / 3f).Image(Placeholders.Image);
});
});
}
@@ -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);
});
}
}
@@ -30,11 +30,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));
@@ -51,7 +51,7 @@ namespace QuestPDF.ReportSample.Layouts
{
if (model.ImageSource == null || model.Location == null)
{
container.Text("No location provided", Typography.Normal);
container.Text("No location provided");
return;
}
@@ -59,25 +59,25 @@ namespace QuestPDF.ReportSample.Layouts
{
stack.Spacing(5);
stack.Item().MaxWidth(250).AspectRatio(4 / 3f).Background(Colors.Grey.Lighten3);
stack.Item().Text(model.Location.Format(), Typography.Normal);
stack.Item().MaxWidth(250).AspectRatio(4 / 3f).Image(Placeholders.Image);
stack.Item().Text(model.Location.Format());
});
}
void PhotosElement(IContainer container, ReportSectionPhotos model)
{
if (model.Photos.Count == 0)
if (model.Photos.Count == 0)
{
container.Text("No photos", Typography.Normal);
container.Text("No photos");
return;
}
container.DebugArea("Photos").Grid(grid =>
container.Debug("Photos").Grid(grid =>
{
grid.Spacing(5);
grid.Columns(3);
model.Photos.ForEach(x => grid.Item().AspectRatio(4 / 3f).Background(Colors.Grey.Lighten3));
model.Photos.ForEach(x => grid.Item().AspectRatio(4 / 3f).Image(Placeholders.Image));
});
}
}
@@ -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").Background(Colors.Grey.Lighten3);
row.ConstantColumn(150).ExternalLink("https://www.questpdf.com").Image(Model.LogoData);
});
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));
});
}
}
-70
View File
@@ -1,70 +0,0 @@
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.Infrastructure;
using QuestPDF.ReportSample.Layouts;
namespace QuestPDF.ReportSample
{
[SimpleJob(RunStrategy.Monitoring, launchCount: 0, warmupCount: 1, targetCount: 100)]
[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()
{
var configuration = ManualConfig
.Create(DefaultConfig.Instance)
.WithOptions(ConfigOptions.DisableOptimizationsValidator);
BenchmarkRunner.Run<PerformanceTests>(configuration);
}
[IterationSetup]
public void GenerateReportData()
{
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.HandleVisitor(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,10 +8,9 @@
</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.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="SkiaSharp" Version="2.80.3" />
</ItemGroup>
+41 -24
View File
@@ -3,45 +3,62 @@ 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
{
private StandardReport Report { get; set; }
[SetUp]
public void SetUp()
{
var model = DataSource.GetReport();
Report = new StandardReport(model);
}
[Test]
public void GenerateAndShow()
{
var reportModel = DataSource.GetReport();
var report = new StandardReport(reportModel);
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"test_result.pdf");
Report.GeneratePdf(path);
report.GeneratePdf(path);
Process.Start("explorer.exe", path);
}
[Test]
public void Profile()
{
var container = new DocumentContainer();
Report.Compose(container);
var content = container.Compose();
var metadata = Report.GetMetadata();
var pageContext = new PageContext();
DocumentGenerator.RenderPass(pageContext, new FreeCanvas(), content, metadata, null);
DocumentGenerator.RenderPass(pageContext, new FreeCanvas(), content, metadata, null);
[Test]
public void PerformanceBenchmark()
{
// target document length should be around 100 pages
// 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();
sw.Start();
var totalSize = reports.Select(x => x.GeneratePdf()).Sum(x => (long)x.Length);
sw.Stop();
// 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.");
}
}
}
+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;
using QuestPDF.Drawing.SpacePlan;
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: SpacePlan.PartialRender(new Size(400, 200)))
.ExpectChildMeasure(expectedInput: new Size(1000, 500), returns: new 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: SpacePlan.FullRender(new Size(100, 50)))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new 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: SpacePlan.FullRender(new Size(100, 50)))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new 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: SpacePlan.FullRender(new Size(100, 50)))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new 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;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
}
[Test]
@@ -35,8 +35,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 201))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.PartialRender(100, 50))
.CheckMeasureResult(SpacePlan.PartialRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new PartialRender(100, 50))
.CheckMeasureResult(new PartialRender(400, 200));
}
[Test]
@@ -50,8 +50,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 201))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 200), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -65,8 +65,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 201))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
}
[Test]
@@ -80,7 +80,7 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 199))
.CheckMeasureResult(SpacePlan.Wrap());
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -94,8 +94,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(401, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
}
[Test]
@@ -109,7 +109,7 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(399, 200))
.CheckMeasureResult(SpacePlan.Wrap());
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -123,8 +123,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
}
[Test]
@@ -138,8 +138,8 @@ namespace QuestPDF.UnitTests
Ratio = 2f
})
.MeasureElement(new Size(500, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50))
.CheckMeasureResult(new FullRender(400, 200));
}
[Test]
+3 -3
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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: SpacePlan.FullRender(new Size(100, 50)))
.CheckMeasureResult( SpacePlan.FullRender(new Size(100, 50)));
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50)))
.CheckMeasureResult( new FullRender(new Size(100, 50)));
}
[Test]
+4 -4
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
using QuestPDF.UnitTests.TestEngine;
@@ -21,7 +21,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.Wrap())
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new Wrap())
.CheckDrawResult();
}
@@ -34,7 +34,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: SpacePlan.PartialRender(200, 100))
.ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new PartialRender(200, 100))
.ExpectChildDraw(new Size(200, 100))
.CheckDrawResult();
}
@@ -48,7 +48,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(500, 400))
.ExpectChildMeasure(expectedInput: new Size(500, 400), returns: SpacePlan.FullRender(300, 200))
.ExpectChildMeasure(expectedInput: new Size(500, 400), returns: new FullRender(300, 200))
.ExpectChildDraw(new Size(300, 200))
.CheckDrawResult();
}
+99 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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(SpacePlan.Wrap());
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -31,8 +33,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(400, 50))
.CheckMeasureResult(SpacePlan.FullRender(400, 100));
.ExpectChildMeasure(new Size(400, 200), new FullRender(400, 50))
.CheckMeasureResult(new FullRender(400, 100));
}
[Test]
@@ -45,8 +47,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(400, 150))
.CheckMeasureResult(SpacePlan.FullRender(400, 150));
.ExpectChildMeasure(new Size(400, 200), new FullRender(400, 150))
.CheckMeasureResult(new FullRender(400, 150));
}
[Test]
@@ -58,7 +60,7 @@ namespace QuestPDF.UnitTests
MaxHeight = 100
})
.MeasureElement(new Size(400, 150))
.CheckMeasureResult(SpacePlan.FullRender(0, 0));
.CheckMeasureResult(new FullRender(0, 0));
}
[Test]
@@ -71,8 +73,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 100), SpacePlan.PartialRender(400, 75))
.CheckMeasureResult(SpacePlan.PartialRender(400, 75));
.ExpectChildMeasure(new Size(400, 100), new PartialRender(400, 75))
.CheckMeasureResult(new PartialRender(400, 75));
}
[Test]
@@ -85,8 +87,94 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 100), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 100), new Wrap())
.CheckMeasureResult(new Wrap());
}
#endregion
#region Width
[Test]
public void Measure_MinWidth_ExpectWrap()
{
TestPlan
.For(x => new Constrained
{
MinWidth = 100
})
.MeasureElement(new Size(50, 400))
.CheckMeasureResult(new 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), new FullRender(50, 400))
.CheckMeasureResult(new 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), new FullRender(150, 400))
.CheckMeasureResult(new FullRender(150, 400));
}
[Test]
public void Measure_MaxWidth_Empty()
{
TestPlan
.For(x => new Constrained
{
MaxWidth = 100
})
.MeasureElement(new Size(150, 400))
.CheckMeasureResult(new 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), new PartialRender(75, 400))
.CheckMeasureResult(new 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), new Wrap())
.CheckMeasureResult(new Wrap());
}
#endregion
}
}
+23 -23
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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 BinaryDecoration
.For(x => new SimpleDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure("decoration", new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
public void Measure_ReturnsWrap_WhenDecorationReturnsPartialRender()
{
TestPlan
.For(x => new BinaryDecoration
.For(x => new SimpleDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure("decoration", new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new Wrap());
}
[Test]
public void Measure_ReturnsWrap_WhenContentReturnsWrap()
{
TestPlan
.For(x => new BinaryDecoration
.For(x => new SimpleDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure("decoration", new Size(400, 300), new FullRender(300, 100))
.ExpectChildMeasure("content", new Size(400, 200), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
public void Measure_ReturnsPartialRender_WhenContentReturnsPartialRender()
{
TestPlan
.For(x => new BinaryDecoration
.For(x => new SimpleDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.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));
.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));
}
[Test]
public void Measure_ReturnsFullRender_WhenContentReturnsFullRender()
{
TestPlan
.For(x => new BinaryDecoration
.For(x => new SimpleDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.MeasureElement(new Size(400, 300))
.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));
.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));
}
#endregion
@@ -97,14 +97,14 @@ namespace QuestPDF.UnitTests
public void Draw_Prepend()
{
TestPlan
.For(x => new BinaryDecoration
.For(x => new SimpleDecoration
{
Type = DecorationType.Prepend,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildMeasure("decoration", new Size(400, 300), new 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 BinaryDecoration
.For(x => new SimpleDecoration
{
Type = DecorationType.Append,
DecorationElement = x.CreateChild("decoration"),
ContentElement = x.CreateChild("content")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("decoration", new Size(400, 300), SpacePlan.FullRender(300, 100))
.ExpectChildMeasure("decoration", new Size(400, 300), new 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;
using QuestPDF.Drawing.SpacePlan;
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(SpacePlan.FullRender(300, 200));
.CheckMeasureResult(new FullRender(300, 200));
}
[Test]
@@ -51,7 +51,7 @@ namespace QuestPDF.UnitTests
[Test]
public void Draw_PassesCorrectSizeToSource()
{
Size passedSize = default;
Size passedSize = null;
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;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 100), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -33,8 +33,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 100))
.ExpectChildMeasure(new Size(400, 100), SpacePlan.PartialRender(300, 50))
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 100), new PartialRender(300, 50))
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -47,8 +47,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(300, 250))
.CheckMeasureResult(SpacePlan.PartialRender(300, 250));
.ExpectChildMeasure(new Size(400, 300), new PartialRender(300, 250))
.CheckMeasureResult(new PartialRender(300, 250));
}
[Test]
@@ -61,8 +61,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 100))
.ExpectChildMeasure(new Size(400, 100), SpacePlan.FullRender(300, 50))
.CheckMeasureResult(SpacePlan.FullRender(300, 50));
.ExpectChildMeasure(new Size(400, 100), new FullRender(300, 50))
.CheckMeasureResult(new FullRender(300, 50));
}
[Test]
@@ -75,8 +75,8 @@ namespace QuestPDF.UnitTests
MinHeight = 200
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(300, 250))
.CheckMeasureResult(SpacePlan.FullRender(300, 250));
.ExpectChildMeasure(new Size(400, 300), new FullRender(300, 250))
.CheckMeasureResult(new FullRender(300, 250));
}
[Test]
+11 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 200), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -33,8 +33,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = true
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.PartialRender(300, 100))
.CheckMeasureResult(SpacePlan.PartialRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new PartialRender(300, 100))
.CheckMeasureResult(new PartialRender(400, 200));
}
[Test]
@@ -48,8 +48,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = true
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(300, 100))
.CheckMeasureResult(SpacePlan.FullRender(400, 200));
.ExpectChildMeasure(new Size(400, 200), new FullRender(300, 100))
.CheckMeasureResult(new FullRender(400, 200));
}
[Test]
@@ -63,8 +63,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = false
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 100))
.CheckMeasureResult(SpacePlan.FullRender(400, 100));
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 100))
.CheckMeasureResult(new FullRender(400, 100));
}
[Test]
@@ -78,8 +78,8 @@ namespace QuestPDF.UnitTests
ExtendVertical = true
})
.MeasureElement(new Size(400, 200))
.ExpectChildMeasure(new Size(400, 200), SpacePlan.FullRender(100, 100))
.CheckMeasureResult(SpacePlan.FullRender(100, 200));
.ExpectChildMeasure(new Size(400, 200), new FullRender(100, 100))
.CheckMeasureResult(new FullRender(100, 200));
}
[Test]
+3 -3
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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(SpacePlan.FullRender(300, 200));
.CheckMeasureResult(new FullRender(300, 200));
}
[Test]
@@ -49,7 +49,7 @@ namespace QuestPDF.UnitTests
return container;
})
.MeasureElement(new Size(300, 200))
.CheckMeasureResult(SpacePlan.FullRender(300, 100));;
.CheckMeasureResult(new 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;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(MainLayer, new Size(800, 600), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -55,8 +55,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.PartialRender(700, 500))
.CheckMeasureResult(SpacePlan.PartialRender(700, 500));
.ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(700, 500))
.CheckMeasureResult(new 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), SpacePlan.FullRender(500, 400))
.CheckMeasureResult(SpacePlan.FullRender(500, 400));
.ExpectChildMeasure(MainLayer, new Size(800, 600), new FullRender(500, 400))
.CheckMeasureResult(new FullRender(500, 400));
}
#endregion
@@ -80,9 +80,9 @@ namespace QuestPDF.UnitTests
.For(GetLayers)
.MeasureElement(new Size(800, 600))
.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))
.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))
.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), SpacePlan.PartialRender(100, 200))
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), SpacePlan.Wrap())
.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())
.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), SpacePlan.Wrap())
.ExpectChildMeasure(MainLayer, new Size(800, 600), SpacePlan.PartialRender(200, 300))
.ExpectChildMeasure(ForegroundLayer, new Size(800, 600), SpacePlan.PartialRender(300, 400))
.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))
.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;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.FullRender(140, 60))
.CheckMeasureResult(SpacePlan.FullRender(200, 100));
.ExpectChildMeasure(new Size(340, 260), new FullRender(140, 60))
.CheckMeasureResult(new FullRender(200, 100));
}
[Test]
@@ -38,7 +38,7 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(50, 300))
.CheckMeasureResult(SpacePlan.Wrap());
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -47,7 +47,7 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(20, 300))
.CheckMeasureResult(SpacePlan.Wrap());
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -56,8 +56,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(340, 260), SpacePlan.PartialRender(40, 160))
.CheckMeasureResult(SpacePlan.PartialRender(100, 200));
.ExpectChildMeasure(new Size(340, 260), new PartialRender(40, 160))
.CheckMeasureResult(new PartialRender(100, 200));
}
[Test]
@@ -66,8 +66,8 @@ namespace QuestPDF.UnitTests
TestPlan
.For(GetPadding)
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(340, 260), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(340, 260), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
+3 -3
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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(SpacePlan.PartialRender(Size.Zero))
.CheckMeasureResult(new PartialRender(Size.Zero))
.DrawElement(new Size(400, 300))
.CheckDrawResult()
.MeasureElement(new Size(500, 400))
.CheckMeasureResult(SpacePlan.FullRender(0, 0));
.CheckMeasureResult(new FullRender(Size.Zero));
}
}
}
+1
View File
@@ -1,4 +1,5 @@
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;
using QuestPDF.Drawing.SpacePlan;
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 BinaryRow
.For(x => new SimpleRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure("left", new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
public void Measure_ReturnsWrap_WhenRightChildReturnsWrap()
{
TestPlan
.For(x => new BinaryRow
.For(x => new SimpleRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.FullRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure("left", new Size(400, 300), new FullRender(250, 150))
.ExpectChildMeasure("right", new Size(150, 300), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
public void Measure_ReturnsPartialRender_WhenLeftChildReturnsPartialRender()
{
TestPlan
.For(x => new BinaryRow
.For(x => new SimpleRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.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));
.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));
}
[Test]
public void Measure_ReturnsPartialRender_WhenRightChildReturnsPartialRender()
{
TestPlan
.For(x => new BinaryRow
.For(x => new SimpleRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.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));
.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));
}
[Test]
public void Measure_ReturnsFullRender_WhenBothChildrenReturnFullRender()
{
TestPlan
.For(x => new BinaryRow
.For(x => new SimpleRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.MeasureElement(new Size(400, 300))
.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));
.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));
}
#endregion
@@ -94,13 +94,13 @@ namespace QuestPDF.UnitTests
public void Draw()
{
TestPlan
.For(x => new BinaryRow
.For(x => new SimpleRow
{
Left = x.CreateChild("left"),
Right = x.CreateChild("right")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("left", new Size(400, 300), SpacePlan.FullRender(250, 150))
.ExpectChildMeasure("left", new Size(400, 300), new 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 BinaryRow
var expected = new SimpleRow
{
Left = new BinaryRow
Left = new SimpleRow
{
Left = new BinaryRow
Left = new SimpleRow
{
Left = new Constrained
{
@@ -202,7 +202,7 @@ namespace QuestPDF.UnitTests
MaxWidth = 25
}
},
Right = new BinaryRow
Right = new SimpleRow
{
Left = new Constrained
{
@@ -217,9 +217,9 @@ namespace QuestPDF.UnitTests
}
}
},
Right = new BinaryRow
Right = new SimpleRow
{
Left = new BinaryRow
Left = new SimpleRow
{
Left = new Constrained
{
@@ -233,7 +233,7 @@ namespace QuestPDF.UnitTests
MaxWidth = 25
}
},
Right = new BinaryRow
Right = new SimpleRow
{
Left = new Constrained
{
@@ -241,7 +241,7 @@ namespace QuestPDF.UnitTests
MaxWidth = 200,
Child = childD
},
Right = new BinaryRow
Right = new SimpleRow
{
Left = new Constrained
{
+11 -11
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(300, 400), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -37,8 +37,8 @@ namespace QuestPDF.UnitTests
ScaleY = 2
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(new Size(300, 400), SpacePlan.PartialRender(200, 350))
.CheckMeasureResult(SpacePlan.PartialRender(600, 700));
.ExpectChildMeasure(new Size(300, 400), new PartialRender(200, 350))
.CheckMeasureResult(new PartialRender(600, 700));
}
[Test]
@@ -52,8 +52,8 @@ namespace QuestPDF.UnitTests
ScaleY = 2
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(new Size(300, 400), SpacePlan.FullRender(250, 300))
.CheckMeasureResult(SpacePlan.FullRender(750, 600));
.ExpectChildMeasure(new Size(300, 400), new FullRender(250, 300))
.CheckMeasureResult(new FullRender(750, 600));
}
[Test]
@@ -67,8 +67,8 @@ namespace QuestPDF.UnitTests
ScaleY = 1
})
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(new Size(400, 600), SpacePlan.FullRender(300, 500))
.CheckMeasureResult(SpacePlan.FullRender(600, 500));
.ExpectChildMeasure(new Size(400, 600), new FullRender(300, 500))
.CheckMeasureResult(new FullRender(600, 500));
}
[Test]
@@ -82,8 +82,8 @@ namespace QuestPDF.UnitTests
ScaleY = -3
})
.MeasureElement(new Size(800, 600))
.ExpectChildMeasure(new Size(800, 200), SpacePlan.FullRender(800, 100))
.CheckMeasureResult(SpacePlan.FullRender(800, 300));
.ExpectChildMeasure(new Size(800, 200), new FullRender(800, 100))
.CheckMeasureResult(new FullRender(800, 300));
}
#endregion
+7 -7
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -31,8 +31,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -44,8 +44,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(300, 200))
.CheckMeasureResult(SpacePlan.FullRender(300, 200));
.ExpectChildMeasure(new Size(400, 300), new FullRender(300, 200))
.CheckMeasureResult(new FullRender(300, 200));
}
[Test]
+8 -8
View File
@@ -1,5 +1,5 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.PartialRender(new Size(200, 200)))
.CheckMeasureResult(SpacePlan.PartialRender(new Size(200, 200)))
.ExpectChildMeasure("child", new Size(300, 200), new PartialRender(new Size(200, 200)))
.CheckMeasureResult(new PartialRender(new Size(200, 200)))
// Draw element partially
.DrawElement(new Size(200, 200))
.ExpectChildMeasure(new Size(200, 200), SpacePlan.PartialRender(new Size(200, 200)))
.ExpectChildMeasure(new Size(200, 200), new 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), SpacePlan.FullRender(new Size(400, 200)))
.CheckMeasureResult(SpacePlan.FullRender(new Size(400, 200)))
.ExpectChildMeasure(new Size(800, 200), new FullRender(new Size(400, 200)))
.CheckMeasureResult(new 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), SpacePlan.FullRender(new Size(400, 200)))
.ExpectChildMeasure(new Size(400, 200), new 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(SpacePlan.FullRender(0, 0))
.CheckMeasureResult(new FullRender(Size.Zero))
// 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;
using QuestPDF.Drawing.SpacePlan;
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), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -35,8 +35,8 @@ namespace QuestPDF.UnitTests
TurnCount = 0
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.PartialRender(300, 200));
.ExpectChildMeasure(new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new PartialRender(300, 200));
}
[Test]
@@ -49,8 +49,8 @@ namespace QuestPDF.UnitTests
TurnCount = 1
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(300, 400), SpacePlan.FullRender(200, 300))
.CheckMeasureResult(SpacePlan.FullRender(300, 200));
.ExpectChildMeasure(new Size(300, 400), new FullRender(200, 300))
.CheckMeasureResult(new FullRender(300, 200));
}
[Test]
@@ -63,8 +63,8 @@ namespace QuestPDF.UnitTests
TurnCount = 2
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(200, 100))
.CheckMeasureResult(SpacePlan.FullRender(200, 100));
.ExpectChildMeasure(new Size(400, 300), new FullRender(200, 100))
.CheckMeasureResult(new 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), SpacePlan.FullRender(300, 350))
.CheckMeasureResult(SpacePlan.FullRender(350, 300));
.ExpectChildMeasure(new Size(400, 500), new FullRender(300, 350))
.CheckMeasureResult(new FullRender(350, 300));
}
#endregion
+47 -46
View File
@@ -1,5 +1,6 @@
using NUnit.Framework;
using QuestPDF.Drawing;
using FluentAssertions;
using NUnit.Framework;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
@@ -16,80 +17,80 @@ namespace QuestPDF.UnitTests
public void Measure_ReturnsWrap_WhenFirstChildWraps()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure("first", new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
public void Measure_ReturnsPartialRender_WhenFirstChildReturnsPartialRender()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.PartialRender(300, 200))
.CheckMeasureResult(SpacePlan.PartialRender(300, 200));
.ExpectChildMeasure("first", new Size(400, 300), new PartialRender(300, 200))
.CheckMeasureResult(new PartialRender(300, 200));
}
[Test]
public void Measure_ReturnsPartialRender_WhenSecondChildWraps()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.PartialRender(200, 100));
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildMeasure("second", new Size(400, 200), new Wrap())
.CheckMeasureResult(new PartialRender(200, 100));
}
[Test]
public void Measure_ReturnsPartialRender_WhenSecondChildReturnsPartialRender()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.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));
.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));
}
[Test]
public void Measure_ReturnsFullRender_WhenSecondChildReturnsFullRender()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.MeasureElement(new Size(400, 300))
.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));
.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));
}
[Test]
public void Measure_UsesEmpty_WhenFirstChildIsRendered()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second"),
@@ -97,8 +98,8 @@ namespace QuestPDF.UnitTests
IsFirstRendered = true
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure("second", new Size(400, 300), SpacePlan.FullRender(200, 300))
.CheckMeasureResult(SpacePlan.FullRender(200, 300));
.ExpectChildMeasure("second", new Size(400, 300), new FullRender(200, 300))
.CheckMeasureResult(new FullRender(200, 300));
}
#endregion
@@ -109,13 +110,13 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildWraps()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.Wrap())
.ExpectChildMeasure("first", new Size(400, 300), new Wrap())
.CheckDrawResult();
}
@@ -123,13 +124,13 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildPartiallyRenders()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.PartialRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), new PartialRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.CheckDrawResult();
}
@@ -138,15 +139,15 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildFullyRenders_AndSecondChildWraps()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.Wrap())
.ExpectChildMeasure("second", new Size(400, 200), new Wrap())
.CheckDrawResult();
}
@@ -154,15 +155,15 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildFullyRenders_AndSecondChildPartiallyRenders()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.PartialRender(250, 150))
.ExpectChildMeasure("second", new Size(400, 200), new PartialRender(250, 150))
.ExpectCanvasTranslate(0, 100)
.ExpectChildDraw("second", new Size(400, 150))
.ExpectCanvasTranslate(0, -100)
@@ -173,15 +174,15 @@ namespace QuestPDF.UnitTests
public void Draw_WhenFirstChildFullyRenders_AndSecondChildFullyRenders()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second")
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("first", new Size(400, 300), SpacePlan.FullRender(200, 100))
.ExpectChildMeasure("first", new Size(400, 300), new FullRender(200, 100))
.ExpectChildDraw("first", new Size(400, 100))
.ExpectChildMeasure("second", new Size(400, 200), SpacePlan.FullRender(250, 150))
.ExpectChildMeasure("second", new Size(400, 200), new FullRender(250, 150))
.ExpectCanvasTranslate(0, 100)
.ExpectChildDraw("second", new Size(400, 150))
.ExpectCanvasTranslate(0, -100)
@@ -192,7 +193,7 @@ namespace QuestPDF.UnitTests
public void Draw_UsesEmpty_WhenFirstChildIsRendered()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second"),
@@ -200,11 +201,11 @@ namespace QuestPDF.UnitTests
IsFirstRendered = true
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("second", new Size(400, 300), SpacePlan.PartialRender(200, 300))
.ExpectChildMeasure("second", new Size(400, 300), new PartialRender(200, 300))
.ExpectCanvasTranslate(0, 0)
.ExpectChildDraw("second", new Size(400, 300))
.ExpectCanvasTranslate(0, 0)
.CheckState<BinaryStack>(x => x.IsFirstRendered)
.CheckState<SimpleStack>(x => x.IsFirstRendered)
.CheckDrawResult();
}
@@ -212,7 +213,7 @@ namespace QuestPDF.UnitTests
public void Draw_TogglesFirstRenderedFlag_WhenSecondFullyRenders()
{
TestPlan
.For(x => new BinaryStack
.For(x => new SimpleStack
{
First = x.CreateChild("first"),
Second = x.CreateChild("second"),
@@ -220,12 +221,12 @@ namespace QuestPDF.UnitTests
IsFirstRendered = true
})
.DrawElement(new Size(400, 300))
.ExpectChildMeasure("second", new Size(400, 300), SpacePlan.FullRender(200, 300))
.ExpectChildMeasure("second", new Size(400, 300), new FullRender(200, 300))
.ExpectCanvasTranslate(0, 0)
.ExpectChildDraw("second", new Size(400, 300))
.ExpectCanvasTranslate(0, 0)
.CheckDrawResult()
.CheckState<BinaryStack>(x => !x.IsFirstRendered);
.CheckState<SimpleStack>(x => !x.IsFirstRendered);
}
#endregion
@@ -263,9 +264,9 @@ namespace QuestPDF.UnitTests
{
Bottom = -spacing,
Child = new BinaryStack
Child = new SimpleStack
{
First = new BinaryStack
First = new SimpleStack
{
First = new Padding
{
@@ -278,14 +279,14 @@ namespace QuestPDF.UnitTests
Child = childB
}
},
Second = new BinaryStack
Second = new SimpleStack
{
First = new Padding
{
Bottom = spacing,
Child = childC
},
Second = new BinaryStack
Second = new SimpleStack
{
First = new Padding
{
+3 -3
View File
@@ -1,5 +1,5 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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, SpacePlan> MeasureFunc { get; set; }
public Func<Size, ISpacePlan> MeasureFunc { get; set; }
public Action<Size> DrawFunc { get; set; }
internal override SpacePlan Measure(Size availableSpace) => MeasureFunc(availableSpace);
internal override ISpacePlan Measure(Size availableSpace) => MeasureFunc(availableSpace);
internal override void Draw(Size availableSpace) => DrawFunc(availableSpace);
}
}
@@ -1,4 +1,4 @@
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
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 SpacePlan Output { get; }
public ISpacePlan Output { get; }
public ChildMeasureOperation(string childId, Size input, SpacePlan output)
public ChildMeasureOperation(string childId, Size input, ISpacePlan output)
{
ChildId = childId;
Input = input;
@@ -1,4 +1,5 @@
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Infrastructure;
namespace QuestPDF.UnitTests.TestEngine
@@ -22,8 +23,8 @@ namespace QuestPDF.UnitTests.TestEngine
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(new Size(400, 300), new Wrap())
.CheckMeasureResult(new Wrap());
}
private static void Measure_PartialRender<TElement>() where TElement : Element, IContainer, new()
@@ -34,8 +35,8 @@ namespace QuestPDF.UnitTests.TestEngine
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.PartialRender(200, 100))
.CheckMeasureResult(SpacePlan.PartialRender(200, 100));
.ExpectChildMeasure(new Size(400, 300), new PartialRender(200, 100))
.CheckMeasureResult(new PartialRender(200, 100));
}
private static void Measure_FullRender<TElement>() where TElement : Element, IContainer, new()
@@ -46,8 +47,8 @@ namespace QuestPDF.UnitTests.TestEngine
Child = x.CreateChild()
})
.MeasureElement(new Size(400, 300))
.ExpectChildMeasure(new Size(400, 300), SpacePlan.FullRender(250, 150))
.CheckMeasureResult(SpacePlan.FullRender(250, 150));
.ExpectChildMeasure(new Size(400, 300), new FullRender(250, 150))
.CheckMeasureResult(new FullRender(250, 150));
}
#endregion
+17 -11
View File
@@ -4,6 +4,7 @@ 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;
@@ -156,12 +157,12 @@ namespace QuestPDF.UnitTests.TestEngine
return this;
}
public TestPlan ExpectChildMeasure(Size expectedInput, SpacePlan returns)
public TestPlan ExpectChildMeasure(Size expectedInput, ISpacePlan returns)
{
return ExpectChildMeasure(DefaultChildName, expectedInput, returns);
}
public TestPlan ExpectChildMeasure(string child, Size expectedInput, SpacePlan returns)
public TestPlan ExpectChildMeasure(string child, Size expectedInput, ISpacePlan returns)
{
return AddOperation(new ChildMeasureOperation(child, expectedInput, returns));
}
@@ -211,17 +212,22 @@ namespace QuestPDF.UnitTests.TestEngine
return AddOperation(new CanvasDrawImageOperation(position, size));
}
public TestPlan CheckMeasureResult(SpacePlan expected)
public TestPlan CheckMeasureResult(ISpacePlan expected)
{
Element.HandleVisitor(x => x?.Initialize(null, Canvas));
var actual = Element.Measure(OperationInput);
Assert.AreEqual(expected.GetType(), actual.GetType());
Assert.AreEqual(expected.Width, actual.Width, "Measure: width");
Assert.AreEqual(expected.Height, actual.Height, "Measure: height");
Assert.AreEqual(expected.Type, actual.Type, "Measure: height");
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");
}
return this;
}
@@ -272,10 +278,10 @@ namespace QuestPDF.UnitTests.TestEngine
var canvas = new FreeCanvas();
value.HandleVisitor(x => x.Initialize(null, canvas));
var valueMeasure = value.Measure(availableSpace.Value);
var valueMeasure = value.Measure(availableSpace);
expected.HandleVisitor(x => x.Initialize(null, canvas));
var expectedMeasure = expected.Measure(availableSpace.Value);
var expectedMeasure = expected.Measure(availableSpace);
valueMeasure.Should().BeEquivalentTo(expectedMeasure);
}
@@ -286,11 +292,11 @@ namespace QuestPDF.UnitTests.TestEngine
var valueCanvas = new OperationRecordingCanvas();
value.HandleVisitor(x => x.Initialize(null, valueCanvas));
value.Draw(availableSpace.Value);
value.Draw(availableSpace);
var expectedCanvas = new OperationRecordingCanvas();
expected.HandleVisitor(x => x.Initialize(null, expectedCanvas));
expected.Draw(availableSpace.Value);
expected.Draw(availableSpace);
valueCanvas.Operations.Should().BeEquivalentTo(expectedCanvas.Operations);
}
+1
View File
@@ -1,4 +1,5 @@
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;
using QuestPDF.Drawing.SpacePlan;
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, SpacePlan.Wrap())
.CheckMeasureResult(SpacePlan.Wrap());
.ExpectChildMeasure(Size.Max, new Wrap())
.CheckMeasureResult(new Wrap());
}
[Test]
@@ -33,8 +33,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, SpacePlan.PartialRender(1200, 1600))
.CheckMeasureResult(SpacePlan.PartialRender(Size.Zero));
.ExpectChildMeasure(Size.Max, new PartialRender(1200, 1600))
.CheckMeasureResult(new PartialRender(Size.Zero));
}
[Test]
@@ -46,8 +46,8 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.MeasureElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, SpacePlan.FullRender(1200, 1600))
.CheckMeasureResult(SpacePlan.FullRender(Size.Zero));
.ExpectChildMeasure(Size.Max, new FullRender(1200, 1600))
.CheckMeasureResult(new FullRender(Size.Zero));
}
#endregion
@@ -63,7 +63,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, SpacePlan.Wrap())
.ExpectChildMeasure(Size.Max, new Wrap())
.CheckDrawResult();
}
@@ -76,7 +76,7 @@ namespace QuestPDF.UnitTests
Child = x.CreateChild()
})
.DrawElement(new Size(900, 800))
.ExpectChildMeasure(Size.Max, SpacePlan.PartialRender(1200, 1600))
.ExpectChildMeasure(Size.Max, new 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, SpacePlan.FullRender(1600, 1000))
.ExpectChildMeasure(Size.Max, new FullRender(1600, 1000))
.ExpectChildDraw(new Size(1600, 1000))
.CheckDrawResult();
}
+1 -2
View File
@@ -2,5 +2,4 @@
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: InternalsVisibleTo("QuestPDF.UnitTests")]
[assembly: InternalsVisibleTo("QuestPDF.Examples")]
[assembly: InternalsVisibleTo("QuestPDF.ReportSample")]
[assembly: InternalsVisibleTo("QuestPDF.Examples")]
+34 -41
View File
@@ -1,9 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Drawing.Proxy;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Elements;
using QuestPDF.Elements.Text;
using QuestPDF.Elements.Text.Items;
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing
@@ -36,22 +39,11 @@ namespace QuestPDF.Drawing
var metadata = document.GetMetadata();
var pageContext = new PageContext();
DebuggingState debuggingState = null;
if (System.Diagnostics.Debugger.IsAttached)
{
debuggingState = ApplyDebugging(content);
}
else
{
ApplyCaching(content);
}
RenderPass(pageContext, new FreeCanvas(), content, metadata, debuggingState);
RenderPass(pageContext, canvas, content, metadata, debuggingState);
RenderPass(pageContext, new FreeCanvas(), content, metadata);
RenderPass(pageContext, canvas, content, metadata);
}
internal static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata, DebuggingState? debuggingState)
private static void RenderPass<TCanvas>(PageContext pageContext, TCanvas canvas, Container content, DocumentMetadata documentMetadata)
where TCanvas : ICanvas, IRenderingCanvas
{
content.HandleVisitor(x => x?.Initialize(pageContext, canvas));
@@ -64,11 +56,9 @@ namespace QuestPDF.Drawing
while(true)
{
pageContext.SetPageNumber(currentPage);
debuggingState?.Reset();
var spacePlan = content.Measure(Size.Max);
var spacePlan = content.Measure(Size.Max) as Size;
if (spacePlan.Type == SpacePlanType.Wrap)
if (spacePlan == null)
{
canvas.EndDocument();
ThrowLayoutException();
@@ -93,42 +83,45 @@ namespace QuestPDF.Drawing
ThrowLayoutException();
}
if (spacePlan.Type == SpacePlanType.FullRender)
if (spacePlan is FullRender)
break;
currentPage++;
}
canvas.EndDocument();
void ThrowLayoutException()
{
throw new DocumentLayoutException("Composed layout generates infinite document.")
{
ElementTrace = debuggingState?.BuildTrace() ?? "Debug trace is available only in the DEBUG mode."
};
throw new DocumentLayoutException(
$"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.");
}
}
private static void ApplyCaching(Container content)
internal static void ApplyDefaultTextStyle(this Element content, TextStyle documentDefaultTextStyle)
{
content.HandleVisitor(x =>
documentDefaultTextStyle.ApplyGlobalStyle(TextStyle.LibraryDefault);
content.HandleVisitor(element =>
{
if (x is ICacheable)
x.CreateProxy(y => new CacheProxy(y));
var text = element as TextBlock;
if (text == null)
return;
foreach (var child in text.Children)
{
if (child is TextBlockSpan textSpan)
textSpan.Style.ApplyGlobalStyle(documentDefaultTextStyle);
if (child is TextBlockElement textElement)
ApplyDefaultTextStyle(textElement.Element, documentDefaultTextStyle);
}
});
}
private static DebuggingState ApplyDebugging(Container content)
{
var debuggingState = new DebuggingState();
content.HandleVisitor(x =>
{
x.CreateProxy(y => new DebuggingProxy(debuggingState, y));
});
return debuggingState;
}
}
}
@@ -4,8 +4,6 @@ namespace QuestPDF.Drawing.Exceptions
{
public class DocumentLayoutException : Exception
{
public string ElementTrace { get; set; }
public DocumentLayoutException()
{
+6 -5
View File
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.IO;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
using SkiaSharp;
@@ -33,7 +34,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)
{
@@ -41,7 +42,7 @@ namespace QuestPDF.Drawing
{
Color = SKColor.Parse(style.Color),
Typeface = GetTypeface(style),
TextSize = style.Size,
TextSize = (style.Size ?? 12),
TextEncoding = SKTextEncoding.Utf32
};
}
@@ -51,16 +52,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 -3
View File
@@ -25,10 +25,10 @@ namespace QuestPDF.Drawing
public override void EndDocument()
{
Canvas?.Dispose();
Canvas.Dispose();
Document?.Close();
Document?.Dispose();
Document.Close();
Document.Dispose();
}
public override void BeginPage(Size size)
-45
View File
@@ -1,45 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,24 +0,0 @@
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
@@ -1,130 +0,0 @@
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.Wrap)
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 IEnumerable<IElement>))
.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
@@ -1,9 +0,0 @@
using QuestPDF.Infrastructure;
namespace QuestPDF.Drawing.Proxy
{
internal class ElementProxy : ContainerElement
{
}
}
-42
View File
@@ -1,42 +0,0 @@
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:N2} | height {Height:N2}";
}
public static implicit operator Size(SpacePlan spacePlan)
{
return new Size(spacePlan.Width, spacePlan.Height);
}
}
}
+19
View File
@@ -0,0 +1,19 @@
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
@@ -0,0 +1,7 @@
namespace QuestPDF.Drawing.SpacePlan
{
internal interface ISpacePlan
{
}
}
@@ -0,0 +1,19 @@
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()}";
}
}
@@ -1,4 +1,4 @@
namespace QuestPDF.Drawing
namespace QuestPDF.Drawing.SpacePlan
{
internal struct TextMeasurement
{
+13
View File
@@ -0,0 +1,13 @@
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
@@ -0,0 +1,7 @@
namespace QuestPDF.Drawing.SpacePlan
{
internal class Wrap : ISpacePlan
{
public override string ToString() => "Wrap";
}
}
-9
View File
@@ -1,9 +0,0 @@
namespace QuestPDF.Drawing
{
public enum SpacePlanType
{
Wrap,
PartialRender,
FullRender
}
}
+3 -4
View File
@@ -1,5 +1,4 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
@@ -14,16 +13,16 @@ namespace QuestPDF.Elements
if (Child == null)
return;
var childSize = base.Measure(availableSpace);
var childSize = Child.Measure(availableSpace) as Size;
if (childSize.Type == SpacePlanType.Wrap)
if (childSize == null)
return;
var top = GetTopOffset(availableSpace, childSize);
var left = GetLeftOffset(availableSpace, childSize);
Canvas.Translate(new Position(left, top));
base.Draw(childSize);
Child.Draw(childSize);
Canvas.Translate(new Position(-left, -top));
}
+14 -14
View File
@@ -1,37 +1,37 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class AspectRatio : ContainerElement, ICacheable
internal class AspectRatio : ContainerElement
{
public float Ratio { get; set; } = 1;
public AspectRatioOption Option { get; set; } = AspectRatioOption.FitWidth;
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
if(Child == null)
return SpacePlan.FullRender(0, 0);
return new FullRender(Size.Zero);
var targetSize = GetTargetSize(availableSpace);
if (targetSize.Height > availableSpace.Height + Size.Epsilon)
return SpacePlan.Wrap();
return new Wrap();
if (targetSize.Width > availableSpace.Width + Size.Epsilon)
return SpacePlan.Wrap();
return new Wrap();
var childSize = base.Measure(targetSize);
var childSize = Child.Measure(targetSize);
if (childSize.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (childSize is Wrap)
return new Wrap();
if (childSize.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(targetSize);
if (childSize is PartialRender)
return new PartialRender(targetSize);
if (childSize.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(targetSize);
if (childSize is FullRender)
return new FullRender(targetSize);
throw new NotSupportedException();
}
@@ -42,7 +42,7 @@ namespace QuestPDF.Elements
return;
var size = GetTargetSize(availableSpace);
base.Draw(size);
Child?.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);
base.Draw(availableSpace);
Child?.Draw(availableSpace);
}
}
}
+1 -6
View File
@@ -14,7 +14,7 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
base.Draw(availableSpace);
Child?.Draw(availableSpace);
Canvas.DrawRectangle(
new Position(-Left/2, -Top/2),
@@ -36,10 +36,5 @@ 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})";
}
}
}
+4 -5
View File
@@ -1,5 +1,4 @@
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
@@ -7,12 +6,12 @@ namespace QuestPDF.Elements
{
internal override void Draw(Size availableSpace)
{
var targetSize = base.Measure(availableSpace);
var targetSize = Child?.Measure(availableSpace) as Size;
if (targetSize.Type == SpacePlanType.Wrap)
if (targetSize == null)
return;
base.Draw(targetSize);
Child?.Draw(targetSize);
}
}
}
+4 -4
View File
@@ -1,4 +1,4 @@
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
using SkiaSharp;
@@ -6,13 +6,13 @@ namespace QuestPDF.Elements
{
public delegate void DrawOnCanvas(SKCanvas canvas, Size availableSpace);
internal class Canvas : Element, ICacheable
internal class Canvas : Element
{
public DrawOnCanvas Handler { get; set; }
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
return SpacePlan.FullRender(availableSpace);
return new FullRender(availableSpace);
}
internal override void Draw(Size availableSpace)
+28 -27
View File
@@ -1,44 +1,45 @@
using System;
using System.Linq;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Constrained : ContainerElement, ICacheable
internal class Constrained : ContainerElement
{
public float? MinWidth { get; set; }
public float? MaxWidth { get; set; }
public float? MinHeight { get; set; }
public float? MaxHeight { get; set; }
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
if (MinWidth > availableSpace.Width + Size.Epsilon)
return SpacePlan.Wrap();
return new Wrap();
if (MinHeight > availableSpace.Height + Size.Epsilon)
return SpacePlan.Wrap();
return new Wrap();
var available = new Size(
LimitMin(availableSpace.Width, MaxWidth),
LimitMin(availableSpace.Height, MaxHeight));
Min(MaxWidth, availableSpace.Width),
Min(MaxHeight, availableSpace.Height));
var measurement = base.Measure(available);
var measurement = Child?.Measure(available) ?? new FullRender(Size.Zero);
var size = measurement as Size;
if (measurement.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (measurement is Wrap)
return new Wrap();
var actualSize = new Size(
LimitMax(measurement.Width, MinWidth),
LimitMax(measurement.Height, MinHeight));
Max(MinWidth, size.Width),
Max(MinHeight, size.Height));
if (measurement.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(actualSize);
if (size is FullRender)
return new FullRender(actualSize);
if (measurement.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(actualSize);
if (size is PartialRender)
return new PartialRender(actualSize);
throw new NotSupportedException();
}
@@ -46,20 +47,20 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
var available = new Size(
LimitMin(availableSpace.Width, MaxWidth),
LimitMin(availableSpace.Height, MaxHeight));
Min(MaxWidth, availableSpace.Width),
Min(MaxHeight, availableSpace.Height));
base.Draw(available);
}
private float LimitMin(float value, float? limit)
{
return limit.HasValue ? Math.Min(value, limit.Value) : value;
Child?.Draw(available);
}
private float LimitMax(float value, float? limit)
private static float Min(float? x, float y)
{
return limit.HasValue ? Math.Max(value, limit.Value) : value;
return x.HasValue ? Math.Min(x.Value, y) : y;
}
private static float Max(float? x, float y)
{
return x.HasValue ? Math.Max(x.Value, y) : y;
}
}
}
@@ -5,7 +5,7 @@ using SkiaSharp;
namespace QuestPDF.Elements
{
internal class DebugArea : IComponent
internal class Debug : IComponent
{
public IElement? Child { get; set; }
@@ -30,7 +30,7 @@ namespace QuestPDF.Elements
.Box()
.Background(Colors.White)
.Padding(2)
.Text(Text, TextStyle.Default.Color(Color).FontType(Fonts.Consolas).Size(8));
.Text(Text, TextStyle.Default.Color(Color).FontType("Consolas").Size(8));
});
}
}
-10
View File
@@ -1,10 +0,0 @@
using System.ComponentModel;
namespace QuestPDF.Elements
{
internal class DebugPointer : Container
{
public string Target { get; set; }
public bool Highlight { get; set; }
}
}
+18 -24
View File
@@ -1,5 +1,5 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
@@ -11,7 +11,7 @@ namespace QuestPDF.Elements
Append
}
internal class BinaryDecoration : Element, ICacheable
internal class SimpleDecoration : Element
{
public Element DecorationElement { get; set; } = Empty.Instance;
public Element ContentElement { get; set; } = Empty.Instance;
@@ -25,40 +25,34 @@ namespace QuestPDF.Elements
base.HandleVisitor(visit);
}
internal override void CreateProxy(Func<Element, Element> create)
internal override ISpacePlan Measure(Size availableSpace)
{
DecorationElement = create(DecorationElement);
ContentElement = create(ContentElement);
}
internal override SpacePlan Measure(Size availableSpace)
{
var decorationMeasure = DecorationElement.Measure(availableSpace);
var decorationMeasure = DecorationElement?.Measure(availableSpace);
if (decorationMeasure.Type == SpacePlanType.Wrap || decorationMeasure.Type == SpacePlanType.PartialRender)
return SpacePlan.Wrap();
if (decorationMeasure is Wrap || decorationMeasure is PartialRender)
return new Wrap();
var decorationSize = decorationMeasure;
var contentMeasure = ContentElement.Measure(new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height));
var decorationSize = decorationMeasure as Size ?? Size.Zero;
var contentMeasure = ContentElement?.Measure(new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height)) ?? new FullRender(Size.Zero);
if (contentMeasure.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (contentMeasure is Wrap)
return new Wrap();
var contentSize = contentMeasure;
var contentSize = contentMeasure as Size ?? Size.Zero;
var resultSize = new Size(availableSpace.Width, decorationSize.Height + contentSize.Height);
if (contentSize.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(resultSize);
if (contentSize is PartialRender)
return new PartialRender(resultSize);
if (contentSize.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(resultSize);
if (contentSize is FullRender)
return new FullRender(resultSize);
throw new NotSupportedException();
}
internal override void Draw(Size availableSpace)
{
var decorationSize = DecorationElement.Measure(availableSpace);
var decorationSize = DecorationElement?.Measure(availableSpace) as Size ?? Size.Zero;
var contentSize = new Size(availableSpace.Width, availableSpace.Height - decorationSize.Height);
var translateHeight = Type == DecorationType.Prepend ? decorationSize.Height : contentSize.Height;
@@ -83,11 +77,11 @@ namespace QuestPDF.Elements
public void Compose(IContainer container)
{
container.Element(new BinaryDecoration
container.Element(new SimpleDecoration
{
Type = DecorationType.Prepend,
DecorationElement = Header,
ContentElement = new BinaryDecoration
ContentElement = new SimpleDecoration
{
Type = DecorationType.Append,
ContentElement = Content,
-120
View File
@@ -1,120 +0,0 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class DynamicHost : Element, IStateResettable
{
private IDynamicComponent Child { get; }
public DynamicHost(IDynamicComponent child)
{
Child = child;
}
public void ResetState()
{
GetContent(Size.Zero, DynamicLayoutOperation.Reset);
}
internal override SpacePlan Measure(Size availableSpace)
{
var content = GetContent(availableSpace, DynamicLayoutOperation.Measure);
var measurement = content.Measure(availableSpace);
if (measurement.Type != SpacePlanType.FullRender)
throw new DocumentLayoutException("Dynamic component generated content that does not fit on a single page.");
return content.HasMoreContent
? SpacePlan.PartialRender(measurement)
: SpacePlan.FullRender(measurement);
}
internal override void Draw(Size availableSpace)
{
GetContent(availableSpace, DynamicLayoutOperation.Draw).Draw(availableSpace);
}
DynamicContainer GetContent(Size availableSize, DynamicLayoutOperation operation)
{
var context = new DynamicContext
{
PageNumber = PageContext.GetLocationPage(Infrastructure.PageContext.CurrentPageSlot),
PageContext = PageContext,
Canvas = Canvas,
AvailableSize = availableSize,
Operation = operation
};
var container = new DynamicContainer();
Child.Compose(context, container);
container.HandleVisitor(x => x?.Initialize(PageContext, Canvas));
container.HandleVisitor(x => (x as IStateResettable)?.ResetState());
return container;
}
}
public enum DynamicLayoutOperation
{
Reset,
Measure,
Draw
}
public class DynamicContext
{
internal IPageContext PageContext { get; set; }
internal ICanvas Canvas { get; set; }
public int PageNumber { get; internal set; }
public Size AvailableSize { get; internal set; }
public DynamicLayoutOperation Operation { get; internal set; }
public IDynamicElement CreateElement(Action<IContainer> content)
{
var container = new DynamicElement();
content(container);
container.HandleVisitor(x => x?.Initialize(PageContext, Canvas));
container.HandleVisitor(x => (x as IStateResettable)?.ResetState());
container.Size = container.Measure(AvailableSize);
return container;
}
}
public interface IDynamicContainer : IContainer
{
}
internal class DynamicContainer : Container, IDynamicContainer
{
internal bool HasMoreContent { get; set; }
}
public static class DynamicContainerExtensions
{
public static IDynamicContainer HasMoreContent(this IDynamicContainer container)
{
(container as DynamicContainer).HasMoreContent = true;
return container;
}
}
public interface IDynamicElement : IElement
{
Size Size { get; }
}
internal class DynamicElement : ContainerElement, IDynamicElement
{
public Size Size { get; internal set; }
}
}
+3 -3
View File
@@ -1,5 +1,5 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
using SkiaSharp;
@@ -9,9 +9,9 @@ namespace QuestPDF.Elements
{
public Func<Size, byte[]>? Source { get; set; }
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
return SpacePlan.FullRender(availableSpace.Width, availableSpace.Height);
return new FullRender(availableSpace.Width, availableSpace.Height);
}
internal override void Draw(Size availableSpace)
+3 -3
View File
@@ -1,4 +1,4 @@
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
@@ -7,9 +7,9 @@ namespace QuestPDF.Elements
{
internal static Empty Instance { get; } = new Empty();
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
return SpacePlan.FullRender(0, 0);
return new FullRender(Size.Zero);
}
internal override void Draw(Size availableSpace)
+5 -5
View File
@@ -1,19 +1,19 @@
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class EnsureSpace : ContainerElement, ICacheable
internal class EnsureSpace : ContainerElement
{
public const float DefaultMinHeight = 150;
public float MinHeight { get; set; } = DefaultMinHeight;
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
var measurement = base.Measure(availableSpace);
if (measurement.Type == SpacePlanType.PartialRender && availableSpace.Height < MinHeight)
return SpacePlan.Wrap();
if (measurement is PartialRender && availableSpace.Height < MinHeight)
return new Wrap();
return measurement;
}
+10 -10
View File
@@ -1,28 +1,28 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Extend : ContainerElement, ICacheable
internal class Extend : ContainerElement
{
public bool ExtendVertical { get; set; }
public bool ExtendHorizontal { get; set; }
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
var childSize = base.Measure(availableSpace);
var childSize = Child?.Measure(availableSpace) ?? new FullRender(Size.Zero);
if (childSize.Type == SpacePlanType.Wrap)
if (childSize is Wrap)
return childSize;
var targetSize = GetTargetSize(availableSpace, childSize);
var targetSize = GetTargetSize(availableSpace, childSize as Size);
if (childSize.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(targetSize);
if (childSize is PartialRender)
return new PartialRender(targetSize);
if (childSize.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(targetSize);
if (childSize is FullRender)
return new FullRender(targetSize);
throw new NotSupportedException();
}
+4 -5
View File
@@ -1,5 +1,4 @@
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
@@ -9,13 +8,13 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
var targetSize = base.Measure(availableSpace);
var targetSize = Child?.Measure(availableSpace) as Size;
if (targetSize.Type == SpacePlanType.Wrap)
if (targetSize == null)
return;
Canvas.DrawExternalLink(Url, targetSize);
base.Draw(availableSpace);
Child?.Draw(availableSpace);
}
}
}
+4 -5
View File
@@ -2,7 +2,6 @@
using System.Linq;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
using static QuestPDF.Infrastructure.HorizontalAlignment;
namespace QuestPDF.Elements
{
@@ -20,7 +19,7 @@ namespace QuestPDF.Elements
public Queue<GridElement> ChildrenQueue { get; set; } = new Queue<GridElement>();
public int ColumnsCount { get; set; } = DefaultColumnsCount;
public HorizontalAlignment Alignment { get; set; } = Left;
public HorizontalAlignment Alignment { get; set; } = HorizontalAlignment.Left;
public float VerticalSpacing { get; set; } = 0;
public float HorizontalSpacing { get; set; } = 0;
@@ -62,15 +61,15 @@ namespace QuestPDF.Elements
var emptySpace = ColumnsCount - columnsWidth;
var hasEmptySpace = emptySpace >= Size.Epsilon;
if (Alignment == Center)
if (Alignment == HorizontalAlignment.Center)
emptySpace /= 2;
if (hasEmptySpace && Alignment != Left)
if (hasEmptySpace && Alignment != HorizontalAlignment.Left)
row.RelativeColumn(emptySpace);
elements.ForEach(x => row.RelativeColumn(x.Columns).Element(x.Child));
if (hasEmptySpace && Alignment != Right)
if (hasEmptySpace && Alignment != HorizontalAlignment.Right)
row.RelativeColumn(emptySpace);
}
}
+4 -4
View File
@@ -1,10 +1,10 @@
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
using SkiaSharp;
namespace QuestPDF.Elements
{
internal class Image : Element, ICacheable
internal class Image : Element
{
public SKImage? InternalImage { get; set; }
@@ -13,9 +13,9 @@ namespace QuestPDF.Elements
InternalImage?.Dispose();
}
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
return SpacePlan.FullRender(availableSpace);
return new FullRender(availableSpace);
}
internal override void Draw(Size availableSpace)
+257
View File
@@ -0,0 +1,257 @@
using System;
using System.Collections.Generic;
using System.Linq;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class InlinedElement : Container
{
public ISpacePlan? MeasureCache { get; set; }
internal override ISpacePlan Measure(Size availableSpace)
{
// TODO: once element caching proxy is introduces, this can be removed
MeasureCache ??= Child.Measure(Size.Max);
return MeasureCache;
}
}
internal enum InlinedAlignment
{
Left,
Center,
Right,
Justify,
SpaceAround
}
internal class Inlined : Element, IStateResettable
{
public List<InlinedElement> Elements { get; internal set; } = new List<InlinedElement>();
private Queue<InlinedElement> ChildrenQueue { get; set; }
internal float VerticalSpacing { get; set; }
internal float HorizontalSpacing { get; set; }
internal InlinedAlignment ElementsAlignment { get; set; }
internal VerticalAlignment BaselineAlignment { get; set; }
public void ResetState()
{
ChildrenQueue = new Queue<InlinedElement>(Elements);
}
internal override void HandleVisitor(Action<Element?> visit)
{
Elements.ForEach(x => x.HandleVisitor(visit));
base.HandleVisitor(visit);
}
internal override ISpacePlan Measure(Size availableSpace)
{
if (!ChildrenQueue.Any())
return new FullRender(Size.Zero);
var lines = Compose(availableSpace);
if (!lines.Any())
return new Wrap();
var lineSizes = lines
.Select(line =>
{
var size = GetLineSize(line);
var heightWithSpacing = size.Height + (line.Count - 1) * HorizontalSpacing;
return new Size(size.Width, heightWithSpacing);
})
.ToList();
var width = lineSizes.Max(x => x.Width);
var height = lineSizes.Sum(x => x.Height) + (lines.Count - 1) * VerticalSpacing;
var targetSize = new Size(width, height);
var isPartiallyRendered = lines.Sum(x => x.Count) != ChildrenQueue.Count;
if (isPartiallyRendered)
return new PartialRender(targetSize);
return new FullRender(targetSize);
}
internal override void Draw(Size availableSpace)
{
var lines = Compose(availableSpace);
var topOffset = 0f;
foreach (var line in lines)
{
var height = line.Select(x => x.Measure(Size.Max) as Size).Where(x => x != null).Max(x => x.Height);
DrawLine(line);
topOffset += height + VerticalSpacing;
Canvas.Translate(new Position(0, height + VerticalSpacing));
}
Canvas.Translate(new Position(0, -topOffset));
lines.SelectMany(x => x).ToList().ForEach(x => ChildrenQueue.Dequeue());
void DrawLine(ICollection<InlinedElement> elements)
{
var lineSize = GetLineSize(elements);
var elementOffset = ElementOffset();
var leftOffset = AlignOffset();
Canvas.Translate(new Position(leftOffset, 0));
foreach (var element in elements)
{
var size = element.Measure(Size.Max) as Size;
var baselineOffset = BaselineOffset(size, lineSize.Height);
Canvas.Translate(new Position(0, baselineOffset));
element.Draw(size);
Canvas.Translate(new Position(0, -baselineOffset));
leftOffset += size.Width + elementOffset;
Canvas.Translate(new Position(size.Width + elementOffset, 0));
}
Canvas.Translate(new Position(-leftOffset, 0));
float ElementOffset()
{
var difference = availableSpace.Width - lineSize.Width;
if (elements.Count == 1)
return 0;
if (ElementsAlignment == InlinedAlignment.Justify)
return difference / (elements.Count - 1);
if (ElementsAlignment == InlinedAlignment.SpaceAround)
return difference / (elements.Count + 1);
return HorizontalSpacing;
}
float AlignOffset()
{
if (ElementsAlignment == InlinedAlignment.Left)
return 0;
if (ElementsAlignment == InlinedAlignment.Justify)
return 0;
if (ElementsAlignment == InlinedAlignment.SpaceAround)
return elementOffset;
var difference = availableSpace.Width - lineSize.Width - (elements.Count - 1) * HorizontalSpacing;
if (ElementsAlignment == InlinedAlignment.Center)
return difference / 2;
if (ElementsAlignment == InlinedAlignment.Right)
return difference;
return 0;
}
float BaselineOffset(Size elementSize, float lineHeight)
{
if (BaselineAlignment == VerticalAlignment.Top)
return 0;
var difference = lineHeight - elementSize.Height;
if (BaselineAlignment == VerticalAlignment.Middle)
return difference / 2;
return difference;
}
}
}
Size GetLineSize(ICollection<InlinedElement> elements)
{
var sizes = elements
.Select(x => x.Measure(Size.Max) as Size)
.Where(x => x != null)
.ToList();
var width = sizes.Sum(x => x.Width);
var height = sizes.Max(x => x.Height);
return new Size(width, height);
}
// list of lines, each line is a list of elements
private ICollection<ICollection<InlinedElement>> Compose(Size availableSize)
{
var queue = new Queue<InlinedElement>(ChildrenQueue);
var result = new List<ICollection<InlinedElement>>();
var topOffset = 0f;
while (true)
{
var line = GetNextLine();
if (!line.Any())
break;
var height = line
.Select(x => x.Measure(availableSize) as Size)
.Where(x => x != null)
.Max(x => x.Height);
if (topOffset + height > availableSize.Height + Size.Epsilon)
break;
topOffset += height + VerticalSpacing;
result.Add(line);
}
return result;
ICollection<InlinedElement> GetNextLine()
{
var result = new List<InlinedElement>();
var leftOffset = GetInitialAlignmentOffset();
while (true)
{
if (!queue.Any())
break;
var element = queue.Peek();
var size = element.Measure(Size.Max) as Size;
if (size == null)
break;
if (leftOffset + size.Width > availableSize.Width + Size.Epsilon)
break;
queue.Dequeue();
leftOffset += size.Width + HorizontalSpacing;
result.Add(element);
}
return result;
}
float GetInitialAlignmentOffset()
{
// this method makes sure that the spacing between elements is no lesser than configured
if (ElementsAlignment == InlinedAlignment.SpaceAround)
return HorizontalSpacing * 2;
return 0;
}
}
}
}
+4 -5
View File
@@ -1,5 +1,4 @@
using QuestPDF.Drawing;
using QuestPDF.Infrastructure;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
@@ -9,13 +8,13 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
var targetSize = base.Measure(availableSpace);
var targetSize = Child?.Measure(availableSpace) as Size;
if (targetSize.Type == SpacePlanType.Wrap)
if (targetSize == null)
return;
Canvas.DrawLocationLink(LocationName, targetSize);
base.Draw(availableSpace);
Child?.Draw(availableSpace);
}
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ namespace QuestPDF.Elements
IsRendered = true;
}
base.Draw(availableSpace);
Child?.Draw(availableSpace);
}
}
}
+4 -4
View File
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
@@ -11,7 +11,7 @@ namespace QuestPDF.Elements
public bool IsPrimary { get; set; }
}
internal class Layers : Element, ICacheable
internal class Layers : Element
{
public List<Layer> Children { get; set; } = new List<Layer>();
@@ -21,7 +21,7 @@ namespace QuestPDF.Elements
base.HandleVisitor(visit);
}
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
return Children
.Single(x => x.IsPrimary)
@@ -31,7 +31,7 @@ namespace QuestPDF.Elements
internal override void Draw(Size availableSpace)
{
Children
.Where(x => x.Measure(availableSpace).Type != SpacePlanType.Wrap)
.Where(x => x.Measure(availableSpace) is Size)
.ToList()
.ForEach(x => x.Draw(availableSpace));
}
+13 -18
View File
@@ -1,40 +1,40 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Padding : ContainerElement, ICacheable
internal class Padding : ContainerElement
{
public float Top { get; set; }
public float Right { get; set; }
public float Bottom { get; set; }
public float Left { get; set; }
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
if (Child == null)
return SpacePlan.FullRender(0, 0);
return new FullRender(Size.Zero);
var internalSpace = InternalSpace(availableSpace);
if (internalSpace.Width < 0 || internalSpace.Height < 0)
return SpacePlan.Wrap();
return new Wrap();
var measure = base.Measure(internalSpace);
var measure = Child.Measure(internalSpace) as Size;
if (measure.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (measure == null)
return new Wrap();
var newSize = new Size(
measure.Width + Left + Right,
measure.Height + Top + Bottom);
if (measure.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(newSize);
if (measure is PartialRender)
return new PartialRender(newSize);
if (measure.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(newSize);
if (measure is FullRender)
return new FullRender(newSize);
throw new NotSupportedException();
}
@@ -47,7 +47,7 @@ namespace QuestPDF.Elements
var internalSpace = InternalSpace(availableSpace);
Canvas.Translate(new Position(Left, Top));
base.Draw(internalSpace);
Child?.Draw(internalSpace);
Canvas.Translate(new Position(-Left, -Top));
}
@@ -57,10 +57,5 @@ namespace QuestPDF.Elements
availableSpace.Width - Left - Right,
availableSpace.Height - Top - Bottom);
}
public override string ToString()
{
return $"Padding: Top({Top}) Right({Right}) Bottom({Bottom}) Left({Left})";
}
}
}
+11 -10
View File
@@ -1,4 +1,5 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
@@ -7,6 +8,8 @@ namespace QuestPDF.Elements
{
internal class Page : IComponent
{
public TextStyle DefaultTextStyle { get; set; } = new TextStyle();
public Size MinSize { get; set; } = PageSizes.A4;
public Size MaxSize { get; set; } = PageSizes.A4;
@@ -15,6 +18,8 @@ namespace QuestPDF.Elements
public float MarginTop { get; set; }
public float MarginBottom { get; set; }
public string BackgroundColor { get; set; } = Colors.Transparent;
public Element Header { get; set; } = Empty.Instance;
public Element Content { get; set; } = Empty.Instance;
public Element Footer { get; set; } = Empty.Instance;
@@ -22,12 +27,13 @@ namespace QuestPDF.Elements
public void Compose(IContainer container)
{
container
.MinWidth(MinSize.Width)
.MinHeight(MinSize.Height)
.MaxWidth(MaxSize.Width)
.MaxHeight(MaxSize.Height)
.Background(BackgroundColor)
.PaddingLeft(MarginLeft)
.PaddingRight(MarginRight)
@@ -36,24 +42,19 @@ namespace QuestPDF.Elements
.Decoration(decoration =>
{
decoration
.Header()
.DebugPointer("Page header")
.Element(Header);
decoration.Header().Element(Header);
decoration
.Content()
.Element(x => IsClose(MinSize.Width, MaxSize.Width) ? x.ExtendHorizontal() : x)
.Element(x => IsClose(MinSize.Height, MaxSize.Height) ? x.ExtendVertical() : x)
.DebugPointer("Page content")
.Element(Content);
decoration
.Footer()
.DebugPointer("Page footer")
.Element(Footer);
decoration.Footer().Element(Footer);
});
(container as Element).ApplyDefaultTextStyle(DefaultTextStyle);
bool IsClose(float x, float y)
{
return Math.Abs(x - y) < Size.Epsilon;
+4 -4
View File
@@ -1,4 +1,4 @@
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
@@ -12,12 +12,12 @@ namespace QuestPDF.Elements
IsRendered = false;
}
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
if (IsRendered)
return SpacePlan.FullRender(0, 0);
return new FullRender(Size.Zero);
return SpacePlan.PartialRender(Size.Zero);
return new PartialRender(Size.Zero);
}
internal override void Draw(Size availableSpace)
+15 -21
View File
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
@@ -34,7 +34,7 @@ namespace QuestPDF.Elements
}
}
internal class BinaryRow : Element, ICacheable
internal class SimpleRow : Element
{
internal Element Left { get; set; }
internal Element Right { get; set; }
@@ -47,39 +47,33 @@ namespace QuestPDF.Elements
base.HandleVisitor(visit);
}
internal override void CreateProxy(Func<Element?, Element?> create)
internal override ISpacePlan Measure(Size availableSpace)
{
Left = create(Left);
Right = create(Right);
}
internal override SpacePlan Measure(Size availableSpace)
{
var leftMeasurement = Left.Measure(new Size(availableSpace.Width, availableSpace.Height));
var leftMeasurement = Left.Measure(new Size(availableSpace.Width, availableSpace.Height)) as Size;
if (leftMeasurement.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (leftMeasurement == null)
return new Wrap();
var rightMeasurement = Right.Measure(new Size(availableSpace.Width - leftMeasurement.Width, availableSpace.Height));
var rightMeasurement = Right.Measure(new Size(availableSpace.Width - leftMeasurement.Width, availableSpace.Height)) as Size;
if (rightMeasurement.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (rightMeasurement == null)
return new Wrap();
var totalWidth = leftMeasurement.Width + rightMeasurement.Width;
var totalHeight = Math.Max(leftMeasurement.Height, rightMeasurement.Height);
var targetSize = new Size(totalWidth, totalHeight);
if (leftMeasurement.Type == SpacePlanType.PartialRender || rightMeasurement.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(targetSize);
if (leftMeasurement is PartialRender || rightMeasurement is PartialRender)
return new PartialRender(targetSize);
return SpacePlan.FullRender(targetSize);
return new FullRender(targetSize);
}
internal override void Draw(Size availableSpace)
{
var leftMeasurement = Left.Measure(new Size(availableSpace.Width, availableSpace.Height));
var leftWidth = leftMeasurement.Width;
var leftWidth = (leftMeasurement as Size)?.Width ?? 0;
Left.Draw(new Size(leftWidth, availableSpace.Height));
@@ -105,7 +99,7 @@ namespace QuestPDF.Elements
base.HandleVisitor(visit);
}
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
UpdateElementsWidth(availableSpace.Width);
return RootElement.Measure(availableSpace);
@@ -169,7 +163,7 @@ namespace QuestPDF.Elements
var half = elements.Length / 2;
return new BinaryRow
return new SimpleRow
{
Left = BuildTree(elements.Slice(0, half)),
Right = BuildTree(elements.Slice(half))
+10 -10
View File
@@ -1,34 +1,34 @@
using System;
using QuestPDF.Drawing;
using QuestPDF.Drawing.SpacePlan;
using QuestPDF.Infrastructure;
namespace QuestPDF.Elements
{
internal class Scale : ContainerElement, ICacheable
internal class Scale : ContainerElement
{
public float ScaleX { get; set; } = 1;
public float ScaleY { get; set; } = 1;
internal override SpacePlan Measure(Size availableSpace)
internal override ISpacePlan Measure(Size availableSpace)
{
var targetSpace = new Size(
Math.Abs(availableSpace.Width / ScaleX),
Math.Abs(availableSpace.Height / ScaleY));
var measure = base.Measure(targetSpace);
var measure = base.Measure(targetSpace) as Size;
if (measure.Type == SpacePlanType.Wrap)
return SpacePlan.Wrap();
if (measure == null)
return new Wrap();
var targetSize = new Size(
Math.Abs(measure.Width * ScaleX),
Math.Abs(measure.Height * ScaleY));
if (measure.Type == SpacePlanType.PartialRender)
return SpacePlan.PartialRender(targetSize);
if (measure is PartialRender)
return new PartialRender(targetSize);
if (measure.Type == SpacePlanType.FullRender)
return SpacePlan.FullRender(targetSize);
if (measure is FullRender)
return new FullRender(targetSize);
throw new ArgumentException();
}

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