diff --git a/QuestPDF.Examples/ElementExamples.cs b/QuestPDF.Examples/ElementExamples.cs index faca1fe..da81826 100644 --- a/QuestPDF.Examples/ElementExamples.cs +++ b/QuestPDF.Examples/ElementExamples.cs @@ -581,7 +581,7 @@ namespace QuestPDF.Examples { RenderingTest .Create() - .PageSize(350, 350) + .PageSize(650, 450) .FileName() .Render(container => { @@ -595,8 +595,8 @@ namespace QuestPDF.Examples foreach (var turns in Enumerable.Range(0, 4)) { grid.Item() - .Width(150) - .Height(150) + .Width(300) + .Height(200) .Background(Colors.Grey.Lighten2) .Padding(10) .Element(element => diff --git a/QuestPDF.Examples/QuestPDF.Examples.csproj b/QuestPDF.Examples/QuestPDF.Examples.csproj index cfc382a..5dc14b7 100644 --- a/QuestPDF.Examples/QuestPDF.Examples.csproj +++ b/QuestPDF.Examples/QuestPDF.Examples.csproj @@ -6,8 +6,8 @@ - - + + diff --git a/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj b/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj index d0cbe3e..fddd3d8 100644 --- a/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj +++ b/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj @@ -8,9 +8,8 @@ - - - + + diff --git a/QuestPDF.UnitTests/AlignmentTests.cs b/QuestPDF.UnitTests/AlignmentTests.cs index 93cb535..5b19f53 100644 --- a/QuestPDF.UnitTests/AlignmentTests.cs +++ b/QuestPDF.UnitTests/AlignmentTests.cs @@ -10,11 +10,7 @@ namespace QuestPDF.UnitTests public class AlignmentTests { [Test] - public void Measure_ShouldHandleNullChild() => new Alignment().MeasureWithoutChild(); - - [Test] - public void Draw_ShouldHandleNullChild() => new Alignment().DrawWithoutChild(); - + public void Measure() => SimpleContainerTests.Measure(); [Test] public void Draw_HorizontalCenter_VerticalCenter() { diff --git a/QuestPDF.UnitTests/AspectRatioTests.cs b/QuestPDF.UnitTests/AspectRatioTests.cs index 3a201d3..a8e02c5 100644 --- a/QuestPDF.UnitTests/AspectRatioTests.cs +++ b/QuestPDF.UnitTests/AspectRatioTests.cs @@ -9,12 +9,6 @@ namespace QuestPDF.UnitTests [TestFixture] public class AspectRatioTests { - [Test] - public void Measure_ShouldHandleNullChild() => new AspectRatio().MeasureWithoutChild(); - - [Test] - public void Draw_ShouldHandleNullChild() => new AspectRatio().DrawWithoutChild(); - [Test] public void Measure_FitWidth_EnoughSpace_FullRender() { diff --git a/QuestPDF.UnitTests/BackgroundTests.cs b/QuestPDF.UnitTests/BackgroundTests.cs index a99575b..f68282c 100644 --- a/QuestPDF.UnitTests/BackgroundTests.cs +++ b/QuestPDF.UnitTests/BackgroundTests.cs @@ -10,8 +10,8 @@ namespace QuestPDF.UnitTests public class BackgroundTests { [Test] - public void Measure_ShouldHandleNullChild() => new Background().MeasureWithoutChild(); - + public void Measure() => SimpleContainerTests.Measure(); + [Test] public void Draw_ShouldHandleNullChild() { diff --git a/QuestPDF.UnitTests/BorderTests.cs b/QuestPDF.UnitTests/BorderTests.cs index 611ad11..a2d943f 100644 --- a/QuestPDF.UnitTests/BorderTests.cs +++ b/QuestPDF.UnitTests/BorderTests.cs @@ -11,8 +11,8 @@ namespace QuestPDF.UnitTests public class BorderTests { [Test] - public void Measure_ShouldHandleNullChild() => new Border().MeasureWithoutChild(); - + public void Measure() => SimpleContainerTests.Measure(); + [Test] public void ComponentShouldNotAffectLayout() { diff --git a/QuestPDF.UnitTests/BoxTests.cs b/QuestPDF.UnitTests/BoxTests.cs new file mode 100644 index 0000000..c7153d1 --- /dev/null +++ b/QuestPDF.UnitTests/BoxTests.cs @@ -0,0 +1,56 @@ +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class BoxTests + { + [Test] + public void Measure() => SimpleContainerTests.Measure(); + + [Test] + public void Draw_Wrap() + { + TestPlan + .For(x => new Box + { + Child = x.CreateChild() + }) + .DrawElement(new Size(400, 300)) + .ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new Wrap()) + .CheckDrawResult(); + } + + [Test] + public void Measure_PartialRender() + { + TestPlan + .For(x => new Box + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new PartialRender(200, 100)) + .ExpectChildDraw(new Size(200, 100)) + .CheckDrawResult(); + } + + [Test] + public void Measure_FullRender() + { + TestPlan + .For(x => new Box + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(500, 400)) + .ExpectChildMeasure(expectedInput: new Size(500, 400), returns: new FullRender(300, 200)) + .ExpectChildDraw(new Size(300, 200)) + .CheckDrawResult(); + } + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/ConstrainedTests.cs b/QuestPDF.UnitTests/ConstrainedTests.cs index 80d19bb..8ffb806 100644 --- a/QuestPDF.UnitTests/ConstrainedTests.cs +++ b/QuestPDF.UnitTests/ConstrainedTests.cs @@ -9,12 +9,6 @@ namespace QuestPDF.UnitTests [TestFixture] public class ConstrainedTests { - [Test] - public void Measure_ShouldHandleNullChild() => new Constrained().MeasureWithoutChild(); - - [Test] - public void Draw_ShouldHandleNullChild() => new Constrained().DrawWithoutChild(); - [Test] public void Measure_MinHeight_ExpectWrap() { diff --git a/QuestPDF.UnitTests/DebugTests.cs b/QuestPDF.UnitTests/DebugTests.cs deleted file mode 100644 index 51a08a5..0000000 --- a/QuestPDF.UnitTests/DebugTests.cs +++ /dev/null @@ -1,10 +0,0 @@ -using NUnit.Framework; - -namespace QuestPDF.UnitTests -{ - [TestFixture] - public class DebugTests - { - - } -} \ No newline at end of file diff --git a/QuestPDF.UnitTests/EnsureSpaceTests.cs b/QuestPDF.UnitTests/EnsureSpaceTests.cs index 67ac3cb..ab7e979 100644 --- a/QuestPDF.UnitTests/EnsureSpaceTests.cs +++ b/QuestPDF.UnitTests/EnsureSpaceTests.cs @@ -78,5 +78,8 @@ namespace QuestPDF.UnitTests .ExpectChildMeasure(new Size(400, 300), new FullRender(300, 250)) .CheckMeasureResult(new FullRender(300, 250)); } + + [Test] + public void Draw() => SimpleContainerTests.Draw(); } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/ExtendTests.cs b/QuestPDF.UnitTests/ExtendTests.cs index a2f5408..db83e23 100644 --- a/QuestPDF.UnitTests/ExtendTests.cs +++ b/QuestPDF.UnitTests/ExtendTests.cs @@ -9,12 +9,6 @@ namespace QuestPDF.UnitTests [TestFixture] public class ExtendTests { - [Test] - public void Measure_ShouldHandleNullChild() => new Extend().MeasureWithoutChild(); - - [Test] - public void Draw_ShouldHandleNullChild() => new Extend().DrawWithoutChild(); - [Test] public void Measure_ReturnsWrap_WhenChildReturnsWrap() { @@ -87,5 +81,8 @@ namespace QuestPDF.UnitTests .ExpectChildMeasure(new Size(400, 200), new FullRender(100, 100)) .CheckMeasureResult(new FullRender(100, 200)); } + + [Test] + public void Draw() => SimpleContainerTests.Draw(); } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/ExternalLinkTests.cs b/QuestPDF.UnitTests/ExternalLinkTests.cs new file mode 100644 index 0000000..cd6853d --- /dev/null +++ b/QuestPDF.UnitTests/ExternalLinkTests.cs @@ -0,0 +1,15 @@ +using NUnit.Framework; +using QuestPDF.Elements; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class ExternalLinkTests + { + [Test] + public void Measure() => SimpleContainerTests.Measure(); + + // TODO: consider tests for the Draw method + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/GridTests.cs b/QuestPDF.UnitTests/GridTests.cs index d14bfe8..e55d08e 100644 --- a/QuestPDF.UnitTests/GridTests.cs +++ b/QuestPDF.UnitTests/GridTests.cs @@ -39,30 +39,30 @@ namespace QuestPDF.UnitTests // assert var expected = new Container(); - expected.Container().Stack(stack => + expected.Stack(stack => { stack.Item().Row(row => { - row.RelativeColumn(6).Container().Element(childA); - row.RelativeColumn(4).Container().Element(childB); + row.RelativeColumn(6).Element(childA); + row.RelativeColumn(4).Element(childB); row.RelativeColumn(2); }); stack.Item().Row(row => { - row.RelativeColumn(4).Container().Element(childC); - row.RelativeColumn(2).Container().Element(childD); + row.RelativeColumn(4).Element(childC); + row.RelativeColumn(2).Element(childD); row.RelativeColumn(6); }); stack.Item().Row(row => { - row.RelativeColumn(8).Container().Element(childE); + row.RelativeColumn(8).Element(childE); row.RelativeColumn(4); }); }); - structure.Should().BeEquivalentTo(expected, o => o.WithTracing().WithAutoConversion().WithStrictOrdering().IncludingAllRuntimeProperties()); + TestPlan.CompareOperations(structure, expected); } [Test] @@ -93,33 +93,33 @@ namespace QuestPDF.UnitTests // assert var expected = new Container(); - expected.Container().Stack(stack => + expected.Stack(stack => { stack.Item().Row(row => { row.RelativeColumn(1); - row.RelativeColumn(6).Container().Element(childA); - row.RelativeColumn(4).Container().Element(childB); + row.RelativeColumn(6).Element(childA); + row.RelativeColumn(4).Element(childB); row.RelativeColumn(1); }); stack.Item().Row(row => { row.RelativeColumn(3); - row.RelativeColumn(4).Container().Element(childC); - row.RelativeColumn(2).Container().Element(childD); + row.RelativeColumn(4).Element(childC); + row.RelativeColumn(2).Element(childD); row.RelativeColumn(3); }); stack.Item().Row(row => { row.RelativeColumn(2); - row.RelativeColumn(8).Container().Element(childE); + row.RelativeColumn(8).Element(childE); row.RelativeColumn(2); }); }); - structure.Should().BeEquivalentTo(expected, o => o.WithTracing().WithAutoConversion().WithStrictOrdering().IncludingAllRuntimeProperties()); + TestPlan.CompareOperations(structure, expected); } [Test] @@ -150,30 +150,30 @@ namespace QuestPDF.UnitTests // assert var expected = new Container(); - expected.Container().Stack(stack => + expected.Stack(stack => { stack.Item().Row(row => { row.RelativeColumn(2); - row.RelativeColumn(6).Container().Element(childA); - row.RelativeColumn(4).Container().Element(childB); + row.RelativeColumn(6).Element(childA); + row.RelativeColumn(4).Element(childB); }); stack.Item().Row(row => { row.RelativeColumn(6); - row.RelativeColumn(4).Container().Element(childC); - row.RelativeColumn(2).Container().Element(childD); + row.RelativeColumn(4).Element(childC); + row.RelativeColumn(2).Element(childD); }); stack.Item().Row(row => { row.RelativeColumn(4); - row.RelativeColumn(8).Container().Element(childE); + row.RelativeColumn(8).Element(childE); }); }); - structure.Should().BeEquivalentTo(expected, o => o.WithTracing().WithAutoConversion().WithStrictOrdering().IncludingAllRuntimeProperties()); + TestPlan.CompareOperations(structure, expected); } #endregion @@ -210,7 +210,7 @@ namespace QuestPDF.UnitTests // assert var expected = new Container(); - expected.Container().Stack(stack => + expected.Stack(stack => { stack.Spacing(20); @@ -219,8 +219,8 @@ namespace QuestPDF.UnitTests row.Spacing(30); row.RelativeColumn(3); - row.RelativeColumn(5).Container().Element(childA); - row.RelativeColumn(5).Container().Element(childB); + row.RelativeColumn(5).Element(childA); + row.RelativeColumn(5).Element(childB); row.RelativeColumn(3); }); @@ -229,7 +229,7 @@ namespace QuestPDF.UnitTests row.Spacing(30); row.RelativeColumn(3); - row.RelativeColumn(10).Container().Element(childC); + row.RelativeColumn(10).Element(childC); row.RelativeColumn(3); }); @@ -238,12 +238,12 @@ namespace QuestPDF.UnitTests row.Spacing(30); row.RelativeColumn(2); - row.RelativeColumn(12).Container().Element(childD); + row.RelativeColumn(12).Element(childD); row.RelativeColumn(2); }); }); - structure.Should().BeEquivalentTo(expected, o => o.WithTracing().WithAutoConversion().WithStrictOrdering().IncludingAllRuntimeProperties().AllowingInfiniteRecursion()); + TestPlan.CompareOperations(structure, expected); } #endregion diff --git a/QuestPDF.UnitTests/Helpers.cs b/QuestPDF.UnitTests/Helpers.cs deleted file mode 100644 index 13e5efa..0000000 --- a/QuestPDF.UnitTests/Helpers.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using FluentAssertions; -using QuestPDF.Infrastructure; -using QuestPDF.UnitTests.TestEngine; - -namespace QuestPDF.UnitTests -{ - public static class Helpers - { - public static Random Random = new Random(); - - public static Size RandomSize => new Size(Random.Next(200, 400), Random.Next(100, 200)); - - public static void ShouldEqual(this IEnumerable commands, IEnumerable expected) - { - commands.Should().HaveSameCount(expected); - - commands - .Zip(expected) - .ToList() - .ForEach(x => - { - x.First.Should().BeOfType(x.Second.GetType()); - x.First.Should().BeEquivalentTo(x.Second, y => y.RespectingRuntimeTypes()); - }); - } - } -} \ No newline at end of file diff --git a/QuestPDF.UnitTests/ImageTests.cs b/QuestPDF.UnitTests/ImageTests.cs index 5007feb..b2bc693 100644 --- a/QuestPDF.UnitTests/ImageTests.cs +++ b/QuestPDF.UnitTests/ImageTests.cs @@ -11,12 +11,6 @@ namespace QuestPDF.UnitTests [TestFixture] public class ImageTests { - [Test] - public void Measure_ShouldHandleNullChild() => new AspectRatio().MeasureWithoutChild(); - - [Test] - public void Draw_ShouldHandleNullChild() => new AspectRatio().DrawWithoutChild(); - [Test] public void Measure_TakesAvailableSpaceRegardlessOfSize() { diff --git a/QuestPDF.UnitTests/InternalLinkTests.cs b/QuestPDF.UnitTests/InternalLinkTests.cs new file mode 100644 index 0000000..bd52d1c --- /dev/null +++ b/QuestPDF.UnitTests/InternalLinkTests.cs @@ -0,0 +1,15 @@ +using NUnit.Framework; +using QuestPDF.Elements; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class InternalLinkTests + { + [Test] + public void Measure() => SimpleContainerTests.Measure(); + + // TODO: consider tests for the Draw method + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/InternalLocationTests.cs b/QuestPDF.UnitTests/InternalLocationTests.cs new file mode 100644 index 0000000..8a21fcb --- /dev/null +++ b/QuestPDF.UnitTests/InternalLocationTests.cs @@ -0,0 +1,15 @@ +using NUnit.Framework; +using QuestPDF.Elements; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class InternalLocationTests + { + [Test] + public void Measure() => SimpleContainerTests.Measure(); + + // TODO: consider tests for the Draw method + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/LayersTests.cs b/QuestPDF.UnitTests/LayersTests.cs new file mode 100644 index 0000000..57a35ec --- /dev/null +++ b/QuestPDF.UnitTests/LayersTests.cs @@ -0,0 +1,131 @@ +using System.Collections.Generic; +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class LayersTests + { + private const string BackgroundLayer = "background"; + private const string MainLayer = "main"; + private const string ForegroundLayer = "foreground"; + + private static Layers GetLayers(TestPlan x) + { + return new Layers + { + Children = new List + { + new Layer + { + Child = x.CreateChild(BackgroundLayer) + }, + new Layer + { + Child = x.CreateChild(MainLayer), + IsPrimary = true + }, + new Layer + { + Child = x.CreateChild(ForegroundLayer) + } + } + }; + } + + #region measure + + [Test] + public void Measure_Wrap() + { + TestPlan + .For(GetLayers) + .MeasureElement(new Size(800, 600)) + .ExpectChildMeasure(MainLayer, new Size(800, 600), new Wrap()) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Measure_PartialRender() + { + TestPlan + .For(GetLayers) + .MeasureElement(new Size(800, 600)) + .ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(700, 500)) + .CheckMeasureResult(new PartialRender(700, 500)); + } + + [Test] + public void Measure_FullRender() + { + TestPlan + .For(GetLayers) + .MeasureElement(new Size(800, 600)) + .ExpectChildMeasure(MainLayer, new Size(800, 600), new FullRender(500, 400)) + .CheckMeasureResult(new FullRender(500, 400)); + } + + #endregion + + #region draw + + [Test] + public void Draw_Simple() + { + TestPlan + .For(GetLayers) + .MeasureElement(new Size(800, 600)) + + .ExpectChildMeasure(BackgroundLayer, new Size(800, 600), new FullRender(100, 200)) + .ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(200, 300)) + .ExpectChildMeasure(ForegroundLayer, new Size(800, 600), new FullRender(300, 400)) + + + .ExpectChildDraw(BackgroundLayer, new Size(800, 600)) + .ExpectChildDraw(MainLayer, new Size(800, 600)) + .ExpectChildDraw(ForegroundLayer, new Size(800, 600)) + + .CheckDrawResult(); + } + + [Test] + public void Draw_WhenSecondaryLayerReturnsWrap_SkipThatLayer_1() + { + TestPlan + .For(GetLayers) + .MeasureElement(new Size(800, 600)) + + .ExpectChildMeasure(BackgroundLayer, new Size(800, 600), new PartialRender(100, 200)) + .ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(200, 300)) + .ExpectChildMeasure(ForegroundLayer, new Size(800, 600), new Wrap()) + + .ExpectChildDraw(BackgroundLayer, new Size(800, 600)) + .ExpectChildDraw(MainLayer, new Size(800, 600)) + + .CheckDrawResult(); + } + + [Test] + public void Draw_WhenSecondaryLayerReturnsWrap_SkipThatLayer_2() + { + TestPlan + .For(GetLayers) + .MeasureElement(new Size(800, 600)) + + .ExpectChildMeasure(BackgroundLayer, new Size(800, 600), new Wrap()) + .ExpectChildMeasure(MainLayer, new Size(800, 600), new PartialRender(200, 300)) + .ExpectChildMeasure(ForegroundLayer, new Size(800, 600), new PartialRender(300, 400)) + + .ExpectChildDraw(MainLayer, new Size(800, 600)) + .ExpectChildDraw(ForegroundLayer, new Size(800, 600)) + + .CheckDrawResult(); + } + + #endregion + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/PaddingTests.cs b/QuestPDF.UnitTests/PaddingTests.cs index 7f04740..7650920 100644 --- a/QuestPDF.UnitTests/PaddingTests.cs +++ b/QuestPDF.UnitTests/PaddingTests.cs @@ -9,12 +9,6 @@ namespace QuestPDF.UnitTests [TestFixture] public class PaddingTests { - [Test] - public void Measure_ShouldHandleNullChild() => new Padding().MeasureWithoutChild(); - - [Test] - public void Draw_ShouldHandleNullChild() => new Padding().DrawWithoutChild(); - private Padding GetPadding(TestPlan plan) { return new Padding() diff --git a/QuestPDF.UnitTests/PageNumberTests.cs b/QuestPDF.UnitTests/PageNumberTests.cs deleted file mode 100644 index 4efd17b..0000000 --- a/QuestPDF.UnitTests/PageNumberTests.cs +++ /dev/null @@ -1,10 +0,0 @@ -using NUnit.Framework; - -namespace QuestPDF.UnitTests -{ - [TestFixture] - public class PageNumberTests - { - - } -} \ No newline at end of file diff --git a/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj b/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj index d9dc74a..a2f71d7 100644 --- a/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj +++ b/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj @@ -6,10 +6,9 @@ - - - - + + + diff --git a/QuestPDF.UnitTests/RotateTests.cs b/QuestPDF.UnitTests/RotateTests.cs new file mode 100644 index 0000000..9ed94cc --- /dev/null +++ b/QuestPDF.UnitTests/RotateTests.cs @@ -0,0 +1,31 @@ +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class RotateTests + { + [Test] + public void Measure() => SimpleContainerTests.Measure(); + + [Test] + public void Draw() + { + TestPlan + .For(x => new Rotate + { + Child = x.CreateChild(), + Angle = 123 + }) + .DrawElement(new Size(400, 300)) + .ExpectCanvasRotate(123) + .ExpectChildDraw(new Size(400, 300)) + .ExpectCanvasRotate(-123) + .CheckDrawResult(); + } + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/RowTests.cs b/QuestPDF.UnitTests/RowTests.cs index c49c84d..9b8a970 100644 --- a/QuestPDF.UnitTests/RowTests.cs +++ b/QuestPDF.UnitTests/RowTests.cs @@ -1,6 +1,7 @@ using NUnit.Framework; using QuestPDF.Drawing.SpacePlan; using QuestPDF.Elements; +using QuestPDF.Fluent; using QuestPDF.Infrastructure; using QuestPDF.UnitTests.TestEngine; @@ -109,8 +110,158 @@ namespace QuestPDF.UnitTests #endregion - // TODO: add tests for the spacing property - // TODO: add tests for the tree builder method - // TODO: add tests for relative column + #region Structure + + [Test] + public void Structure_RelativeColumnsHandling() + { + // arrange + var childA = TestPlan.CreateUniqueElement(); + var childB = TestPlan.CreateUniqueElement(); + var childC = TestPlan.CreateUniqueElement(); + var childD = TestPlan.CreateUniqueElement(); + var childE = TestPlan.CreateUniqueElement(); + + const int spacing = 25; + var availableSpace = new Size(1100, 400); + + // act + var value = new Container(); + + value.Row(row => + { + row.Spacing(spacing); + + row.ConstantColumn(150).Element(childA); + row.ConstantColumn(250).Element(childB); + row.RelativeColumn(1).Element(childC); + row.RelativeColumn(2).Element(childD); + row.RelativeColumn(3).Element(childE); + }); + + // assert + var expected = new Container(); + + expected.Row(row => + { + row.Spacing(spacing); + + row.ConstantColumn(150).Element(childA); + row.ConstantColumn(250).Element(childB); + row.ConstantColumn(100).Element(childC); + row.ConstantColumn(200).Element(childD); + row.ConstantColumn(300).Element(childE); + }); + + TestPlan.CompareOperations(value, expected, availableSpace); + } + + [Test] + public void Structure_Tree() + { + // arrange + var childA = TestPlan.CreateUniqueElement(); + var childB = TestPlan.CreateUniqueElement(); + var childC = TestPlan.CreateUniqueElement(); + var childD = TestPlan.CreateUniqueElement(); + var childE = TestPlan.CreateUniqueElement(); + + const int spacing = 25; + var availableSpace = new Size(1200, 400); + + // act + var value = new Container(); + + value.Row(row => + { + row.Spacing(spacing); + + row.ConstantColumn(150).Element(childA); + row.ConstantColumn(200).Element(childB); + row.ConstantColumn(250).Element(childC); + row.RelativeColumn(2).Element(childD); + row.RelativeColumn(3).Element(childE); + }); + + // assert + var expected = new SimpleRow + { + Left = new SimpleRow + { + Left = new SimpleRow + { + Left = new Constrained + { + MinWidth = 150, + MaxWidth = 150, + Child = childA + }, + Right = new Constrained + { + MinWidth = 25, + MaxWidth = 25 + } + }, + Right = new SimpleRow + { + Left = new Constrained + { + MinWidth = 200, + MaxWidth = 200, + Child = childB + }, + Right = new Constrained + { + MinWidth = 25, + MaxWidth = 25 + } + } + }, + Right = new SimpleRow + { + Left = new SimpleRow + { + Left = new Constrained + { + MinWidth = 250, + MaxWidth = 250, + Child = childC + }, + Right = new Constrained + { + MinWidth = 25, + MaxWidth = 25 + } + }, + Right = new SimpleRow + { + Left = new Constrained + { + MinWidth = 200, + MaxWidth = 200, + Child = childD + }, + Right = new SimpleRow + { + Left = new Constrained + { + MinWidth = 25, + MaxWidth = 25 + }, + Right = new Constrained + { + MinWidth = 300, + MaxWidth = 300, + Child = childE + } + } + } + } + }; + + TestPlan.CompareOperations(value, expected, availableSpace); + } + + #endregion } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/ScaleTests.cs b/QuestPDF.UnitTests/ScaleTests.cs new file mode 100644 index 0000000..0084fde --- /dev/null +++ b/QuestPDF.UnitTests/ScaleTests.cs @@ -0,0 +1,152 @@ +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class ScaleTests + { + #region measure + + [Test] + public void Measure_Wrap() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = 3, + ScaleY = 2 + }) + .MeasureElement(new Size(900, 800)) + .ExpectChildMeasure(new Size(300, 400), new Wrap()) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Measure_PartialRender() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = 3, + ScaleY = 2 + }) + .MeasureElement(new Size(900, 800)) + .ExpectChildMeasure(new Size(300, 400), new PartialRender(200, 350)) + .CheckMeasureResult(new PartialRender(600, 700)); + } + + [Test] + public void Measure_FullRender() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = 3, + ScaleY = 2 + }) + .MeasureElement(new Size(900, 800)) + .ExpectChildMeasure(new Size(300, 400), new FullRender(250, 300)) + .CheckMeasureResult(new FullRender(750, 600)); + } + + [Test] + public void Measure_NegativeScaleX() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = -2, + ScaleY = 1 + }) + .MeasureElement(new Size(800, 600)) + .ExpectChildMeasure(new Size(400, 600), new FullRender(300, 500)) + .CheckMeasureResult(new FullRender(600, 500)); + } + + [Test] + public void Measure_NegativeScaleY() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = 1, + ScaleY = -3 + }) + .MeasureElement(new Size(800, 600)) + .ExpectChildMeasure(new Size(800, 200), new FullRender(800, 100)) + .CheckMeasureResult(new FullRender(800, 300)); + } + + #endregion + + #region draw + + [Test] + public void Draw_Simple() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = 3, + ScaleY = 2 + }) + .DrawElement(new Size(900, 800)) + .ExpectCanvasTranslate(0, 0) + .ExpectCanvasScale(3, 2) + .ExpectChildDraw(new Size(300, 400)) + .ExpectCanvasScale(1/3f, 1/2f) + .ExpectCanvasTranslate(0, 0) + .CheckDrawResult(); + } + + [Test] + public void Draw_NegativeScaleX() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = -3, + ScaleY = 2 + }) + .DrawElement(new Size(900, 800)) + .ExpectCanvasTranslate(900, 0) + .ExpectCanvasScale(-3, 2) + .ExpectChildDraw(new Size(300, 400)) + .ExpectCanvasScale(-1/3f, 1/2f) + .ExpectCanvasTranslate(-900, 0) + .CheckDrawResult(); + } + + [Test] + public void Draw_NegativeScaleY() + { + TestPlan + .For(x => new Scale + { + Child = x.CreateChild(), + ScaleX = 3, + ScaleY = -2 + }) + .DrawElement(new Size(900, 800)) + .ExpectCanvasTranslate(0, 800) + .ExpectCanvasScale(3, -2) + .ExpectChildDraw(new Size(300, 400)) + .ExpectCanvasScale(1/3f, -1/2f) + .ExpectCanvasTranslate(0, -800) + .CheckDrawResult(); + } + + #endregion + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/ShowEntireTests.cs b/QuestPDF.UnitTests/ShowEntireTests.cs index e31e6af..3553880 100644 --- a/QuestPDF.UnitTests/ShowEntireTests.cs +++ b/QuestPDF.UnitTests/ShowEntireTests.cs @@ -47,5 +47,8 @@ namespace QuestPDF.UnitTests .ExpectChildMeasure(new Size(400, 300), new FullRender(300, 200)) .CheckMeasureResult(new FullRender(300, 200)); } + + [Test] + public void Draw() => SimpleContainerTests.Draw(); } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/ShowOnceTest.cs b/QuestPDF.UnitTests/ShowOnceTest.cs index 0e8bef4..24323f8 100644 --- a/QuestPDF.UnitTests/ShowOnceTest.cs +++ b/QuestPDF.UnitTests/ShowOnceTest.cs @@ -1,5 +1,4 @@ -using Moq; -using NUnit.Framework; +using NUnit.Framework; using QuestPDF.Drawing.SpacePlan; using QuestPDF.Elements; using QuestPDF.Infrastructure; @@ -11,33 +10,7 @@ namespace QuestPDF.UnitTests public class ShowOnceTest { [Test] - public void Measure_ShouldHandleNullChild() => new ShowOnce().MeasureWithoutChild(); - - [Test] - public void Draw_ShouldHandleNullChild() => new ShowOnce().DrawWithoutChild(); - - [Test] - public void ShouldRenderOnce_WhenRenderingCalledMultipleTimes() - { - var child = new Mock(); - - child - .Setup(x => x.Measure(It.IsAny())) - .Returns(() => new FullRender(Size.Zero)); - - var element = new ShowOnce() - { - Child = child.Object - }; - - element.Draw(Size.Zero); - element.Draw(Size.Zero); - - child.Verify(x => x.Draw(It.IsAny()), Times.Once); - } - - [Test] - public void Draw_HorizontalRight_VerticalTop() + public void Draw() { TestPlan .For(x => new ShowOnce() diff --git a/QuestPDF.UnitTests/SimpleRotateTests.cs b/QuestPDF.UnitTests/SimpleRotateTests.cs new file mode 100644 index 0000000..fe8455c --- /dev/null +++ b/QuestPDF.UnitTests/SimpleRotateTests.cs @@ -0,0 +1,162 @@ +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class SimpleRotateTests + { + #region measure + + [Test] + public void Measure_Wrap() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 0 + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(400, 300), new Wrap()) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Measure_PartialRender() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 0 + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(400, 300), new PartialRender(300, 200)) + .CheckMeasureResult(new PartialRender(300, 200)); + } + + [Test] + public void Measure_RotateRight() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 1 + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(300, 400), new FullRender(200, 300)) + .CheckMeasureResult(new FullRender(300, 200)); + } + + [Test] + public void Measure_RotateFlip() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 2 + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(400, 300), new FullRender(200, 100)) + .CheckMeasureResult(new FullRender(200, 100)); + } + + [Test] + public void Measure_RotateLeft() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 3 // or -1 + }) + .MeasureElement(new Size(500, 400)) + .ExpectChildMeasure(new Size(400, 500), new FullRender(300, 350)) + .CheckMeasureResult(new FullRender(350, 300)); + } + + #endregion + + #region draw + + [Test] + public void Draw_Simple() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 0 + }) + .DrawElement(new Size(640, 480)) + .ExpectCanvasTranslate(0, 0) + .ExpectCanvasRotate(0) + .ExpectChildDraw(new Size(640, 480)) + .ExpectCanvasRotate(0) + .ExpectCanvasTranslate(0, 0) + .CheckDrawResult(); + } + + [Test] + public void Draw_RotateRight() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 1 + }) + .DrawElement(new Size(640, 480)) + .ExpectCanvasTranslate(640, 0) + .ExpectCanvasRotate(90) + .ExpectChildDraw(new Size(480, 640)) + .ExpectCanvasRotate(-90) + .ExpectCanvasTranslate(-640, 0) + .CheckDrawResult(); + } + + [Test] + public void Draw_RotateFlip() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 2 + }) + .DrawElement(new Size(640, 480)) + .ExpectCanvasTranslate(640, 480) + .ExpectCanvasRotate(180) + .ExpectChildDraw(new Size(640, 480)) + .ExpectCanvasRotate(-180) + .ExpectCanvasTranslate(-640, -480) + .CheckDrawResult(); + } + + [Test] + public void Draw_RotateLeft() + { + TestPlan + .For(x => new SimpleRotate + { + Child = x.CreateChild(), + TurnCount = 3 // or -1 + }) + .DrawElement(new Size(640, 480)) + .ExpectCanvasTranslate(0, 480) + .ExpectCanvasRotate(270) + .ExpectChildDraw(new Size(480, 640)) + .ExpectCanvasRotate(-270) + .ExpectCanvasTranslate(0, -480) + .CheckDrawResult(); + } + + #endregion + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/StackTests.cs b/QuestPDF.UnitTests/StackTests.cs index 134810b..6e261f5 100644 --- a/QuestPDF.UnitTests/StackTests.cs +++ b/QuestPDF.UnitTests/StackTests.cs @@ -1,6 +1,8 @@ -using NUnit.Framework; +using FluentAssertions; +using NUnit.Framework; using QuestPDF.Drawing.SpacePlan; using QuestPDF.Elements; +using QuestPDF.Fluent; using QuestPDF.Infrastructure; using QuestPDF.UnitTests.TestEngine; @@ -229,7 +231,81 @@ namespace QuestPDF.UnitTests #endregion - // TODO: add tests for the spacing property - // TODO: add tests for the tree builder method + #region Structure + + [Test] + public void Structure_Simple() + { + // arrange + var childA = TestPlan.CreateUniqueElement(); + var childB = TestPlan.CreateUniqueElement(); + var childC = TestPlan.CreateUniqueElement(); + var childD = TestPlan.CreateUniqueElement(); + var childE = TestPlan.CreateUniqueElement(); + + const int spacing = 20; + + // act + var structure = new Container(); + + structure.Stack(stack => + { + stack.Spacing(spacing); + + stack.Item().Element(childA); + stack.Item().Element(childB); + stack.Item().Element(childC); + stack.Item().Element(childD); + stack.Item().Element(childE); + }); + + // assert + var expected = new Padding + { + Bottom = -spacing, + + Child = new SimpleStack + { + First = new SimpleStack + { + First = new Padding + { + Bottom = spacing, + Child = childA + }, + Second = new Padding + { + Bottom = spacing, + Child = childB + } + }, + Second = new SimpleStack + { + First = new Padding + { + Bottom = spacing, + Child = childC + }, + Second = new SimpleStack + { + First = new Padding + { + Bottom = spacing, + Child = childD + }, + Second = new Padding + { + Bottom = spacing, + Child = childE + } + } + } + } + }; + + TestPlan.CompareOperations(structure, expected); + } + + #endregion } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestEngine/CanvasMock.cs b/QuestPDF.UnitTests/TestEngine/MockCanvas.cs similarity index 58% rename from QuestPDF.UnitTests/TestEngine/CanvasMock.cs rename to QuestPDF.UnitTests/TestEngine/MockCanvas.cs index e1b73f6..fbed591 100644 --- a/QuestPDF.UnitTests/TestEngine/CanvasMock.cs +++ b/QuestPDF.UnitTests/TestEngine/MockCanvas.cs @@ -4,41 +4,25 @@ using SkiaSharp; namespace QuestPDF.UnitTests.TestEngine { - internal class CanvasMock : ICanvas + internal class MockCanvas : ICanvas { public Action TranslateFunc { get; set; } + public Action RotateFunc { get; set; } + public Action ScaleFunc { get; set; } public Action DrawImageFunc { get; set; } public Action DrawTextFunc { get; set; } public Action DrawRectFunc { get; set; } public void Translate(Position vector) => TranslateFunc(vector); + public void Rotate(float angle) => RotateFunc(angle); + public void Scale(float scaleX, float scaleY) => ScaleFunc(scaleX, scaleY); + public void DrawRectangle(Position vector, Size size, string color) => DrawRectFunc(vector, size, color); public void DrawText(string text, Position position, TextStyle style) => DrawTextFunc(text, position, style); public void DrawImage(SKImage image, Position position, Size size) => DrawImageFunc(image, position, size); - public void DrawExternalLink(string url, Size size) - { - throw new NotImplementedException(); - } - - public void DrawLocationLink(string locationName, Size size) - { - throw new NotImplementedException(); - } - - public void DrawLocation(string locationName) - { - throw new NotImplementedException(); - } - - public void DrawLink(string url, Size size) - { - throw new NotImplementedException(); - } - - public Size MeasureText(string text, TextStyle style) - { - return new Size(text.Length * style.Size, style.Size); - } + public void DrawExternalLink(string url, Size size) => throw new NotImplementedException(); + public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException(); + public void DrawLocation(string locationName) => throw new NotImplementedException(); } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs b/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs new file mode 100644 index 0000000..3617052 --- /dev/null +++ b/QuestPDF.UnitTests/TestEngine/OperationRecordingCanvas.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine.Operations; +using SkiaSharp; + +namespace QuestPDF.UnitTests.TestEngine +{ + internal class OperationRecordingCanvas : ICanvas + { + public ICollection Operations { get; } = new List(); + + public void Translate(Position vector) => Operations.Add(new CanvasTranslateOperation(vector)); + public void Rotate(float angle) => Operations.Add(new CanvasRotateOperation(angle)); + public void Scale(float scaleX, float scaleY) => Operations.Add(new CanvasScaleOperation(scaleX, scaleY)); + + public void DrawRectangle(Position vector, Size size, string color) => Operations.Add(new CanvasDrawRectangleOperation(vector, size, color)); + public void DrawText(string text, Position position, TextStyle style) => Operations.Add(new CanvasDrawTextOperation(text, position, style)); + public void DrawImage(SKImage image, Position position, Size size) => Operations.Add(new CanvasDrawImageOperation(position, size)); + + public void DrawExternalLink(string url, Size size) => throw new NotImplementedException(); + public void DrawLocationLink(string locationName, Size size) => throw new NotImplementedException(); + public void DrawLocation(string locationName) => throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawImageOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawImageOperation.cs index 7f0bdde..682a668 100644 --- a/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawImageOperation.cs +++ b/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawImageOperation.cs @@ -2,12 +2,12 @@ namespace QuestPDF.UnitTests.TestEngine.Operations { - internal class CanvasDrawImageOperationBase : OperationBase + internal class CanvasDrawImageOperation : OperationBase { public Position Position { get; } public Size Size { get; } - public CanvasDrawImageOperationBase(Position position, Size size) + public CanvasDrawImageOperation(Position position, Size size) { Position = position; Size = size; diff --git a/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawRectangleOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawRectangleOperation.cs index a648b2c..0b1cd98 100644 --- a/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawRectangleOperation.cs +++ b/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawRectangleOperation.cs @@ -2,13 +2,13 @@ namespace QuestPDF.UnitTests.TestEngine.Operations { - internal class CanvasDrawRectangleOperationBase : OperationBase + internal class CanvasDrawRectangleOperation : OperationBase { public Position Position { get; } public Size Size { get; } public string Color { get; } - public CanvasDrawRectangleOperationBase(Position position, Size size, string color) + public CanvasDrawRectangleOperation(Position position, Size size, string color) { Position = position; Size = size; diff --git a/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawTextOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawTextOperation.cs index 74b2b60..dd9b2ef 100644 --- a/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawTextOperation.cs +++ b/QuestPDF.UnitTests/TestEngine/Operations/CanvasDrawTextOperation.cs @@ -2,13 +2,13 @@ namespace QuestPDF.UnitTests.TestEngine.Operations { - internal class CanvasDrawTextOperationBase : OperationBase + internal class CanvasDrawTextOperation : OperationBase { public string Text { get; } public Position Position { get; } public TextStyle Style { get; } - public CanvasDrawTextOperationBase(string text, Position position, TextStyle style) + public CanvasDrawTextOperation(string text, Position position, TextStyle style) { Text = text; Position = position; diff --git a/QuestPDF.UnitTests/TestEngine/Operations/CanvasRotateOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/CanvasRotateOperation.cs new file mode 100644 index 0000000..dbc9ed2 --- /dev/null +++ b/QuestPDF.UnitTests/TestEngine/Operations/CanvasRotateOperation.cs @@ -0,0 +1,12 @@ +namespace QuestPDF.UnitTests.TestEngine.Operations +{ + public class CanvasRotateOperation : OperationBase + { + public float Angle { get; } + + public CanvasRotateOperation(float angle) + { + Angle = angle; + } + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestEngine/Operations/CanvasScaleOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/CanvasScaleOperation.cs new file mode 100644 index 0000000..f503f0c --- /dev/null +++ b/QuestPDF.UnitTests/TestEngine/Operations/CanvasScaleOperation.cs @@ -0,0 +1,14 @@ +namespace QuestPDF.UnitTests.TestEngine.Operations +{ + public class CanvasScaleOperation : OperationBase + { + public float ScaleX { get; } + public float ScaleY { get; } + + public CanvasScaleOperation(float scaleX, float scaleY) + { + ScaleX = scaleX; + ScaleY = scaleY; + } + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestEngine/Operations/CanvasTranslateOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/CanvasTranslateOperation.cs index 0e387a7..0599c1f 100644 --- a/QuestPDF.UnitTests/TestEngine/Operations/CanvasTranslateOperation.cs +++ b/QuestPDF.UnitTests/TestEngine/Operations/CanvasTranslateOperation.cs @@ -2,11 +2,11 @@ namespace QuestPDF.UnitTests.TestEngine.Operations { - internal class CanvasTranslateOperationBase : OperationBase + internal class CanvasTranslateOperation : OperationBase { public Position Position { get; } - public CanvasTranslateOperationBase(Position position) + public CanvasTranslateOperation(Position position) { Position = position; } diff --git a/QuestPDF.UnitTests/TestEngine/Operations/ChildDrawOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/ChildDrawOperation.cs index d1928e0..792aca8 100644 --- a/QuestPDF.UnitTests/TestEngine/Operations/ChildDrawOperation.cs +++ b/QuestPDF.UnitTests/TestEngine/Operations/ChildDrawOperation.cs @@ -2,12 +2,12 @@ namespace QuestPDF.UnitTests.TestEngine.Operations { - public class ChildDrawOperationBase : OperationBase + public class ChildDrawOperation : OperationBase { public string ChildId { get; } public Size Input { get; } - public ChildDrawOperationBase(string childId, Size input) + public ChildDrawOperation(string childId, Size input) { ChildId = childId; Input = input; diff --git a/QuestPDF.UnitTests/TestEngine/Operations/ChildMeasureOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/ChildMeasureOperation.cs index 323c2dd..bc7b141 100644 --- a/QuestPDF.UnitTests/TestEngine/Operations/ChildMeasureOperation.cs +++ b/QuestPDF.UnitTests/TestEngine/Operations/ChildMeasureOperation.cs @@ -3,13 +3,13 @@ using QuestPDF.Infrastructure; namespace QuestPDF.UnitTests.TestEngine.Operations { - internal class ChildMeasureOperationBase : OperationBase + internal class ChildMeasureOperation : OperationBase { public string ChildId { get; } public Size Input { get; } public ISpacePlan Output { get; } - public ChildMeasureOperationBase(string childId, Size input, ISpacePlan output) + public ChildMeasureOperation(string childId, Size input, ISpacePlan output) { ChildId = childId; Input = input; diff --git a/QuestPDF.UnitTests/TestEngine/Operations/ElementMeasureOperation.cs b/QuestPDF.UnitTests/TestEngine/Operations/ElementMeasureOperation.cs index 8e4df23..cb8f0a8 100644 --- a/QuestPDF.UnitTests/TestEngine/Operations/ElementMeasureOperation.cs +++ b/QuestPDF.UnitTests/TestEngine/Operations/ElementMeasureOperation.cs @@ -2,9 +2,9 @@ namespace QuestPDF.UnitTests.TestEngine.Operations { - public class ElementMeasureOperationBase : OperationBase + public class ElementMeasureOperation : OperationBase { - public ElementMeasureOperationBase(Size input) + public ElementMeasureOperation(Size input) { } diff --git a/QuestPDF.UnitTests/TestEngine/SimpleContainerTests.cs b/QuestPDF.UnitTests/TestEngine/SimpleContainerTests.cs new file mode 100644 index 0000000..542be2f --- /dev/null +++ b/QuestPDF.UnitTests/TestEngine/SimpleContainerTests.cs @@ -0,0 +1,68 @@ +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; + +namespace QuestPDF.UnitTests.TestEngine +{ + internal static class SimpleContainerTests + { + #region measure + + public static void Measure() where TElement : Element, IContainer, new() + { + Measure_Wrap(); + Measure_PartialRender(); + Measure_FullRender(); + } + + private static void Measure_Wrap() where TElement : Element, IContainer, new() + { + TestPlan + .For(x => new TElement + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(400, 300), new Wrap()) + .CheckMeasureResult(new Wrap()); + } + + private static void Measure_PartialRender() where TElement : Element, IContainer, new() + { + TestPlan + .For(x => new TElement + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(400, 300), new PartialRender(200, 100)) + .CheckMeasureResult(new PartialRender(200, 100)); + } + + private static void Measure_FullRender() where TElement : Element, IContainer, new() + { + TestPlan + .For(x => new TElement + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(400, 300), new FullRender(250, 150)) + .CheckMeasureResult(new FullRender(250, 150)); + } + + #endregion + + public static void Draw() where TElement : Element, IContainer, new() + { + TestPlan + .For(x => new TElement + { + Child = x.CreateChild() + }) + .DrawElement(new Size(1200, 900)) + .ExpectChildDraw(new Size(1200, 900)) + .CheckDrawResult(); + } + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestEngine/SingleChildTests.cs b/QuestPDF.UnitTests/TestEngine/SingleChildTests.cs deleted file mode 100644 index 507dcca..0000000 --- a/QuestPDF.UnitTests/TestEngine/SingleChildTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -using FluentAssertions; -using NUnit.Framework; -using QuestPDF.Drawing.SpacePlan; -using QuestPDF.Infrastructure; - -namespace QuestPDF.UnitTests.TestEngine -{ - public static class SingleChildTests - { - internal static void MeasureWithoutChild(this T element) where T : ContainerElement - { - element.Child = null; - element.Measure(Size.Zero).Should().BeEquivalentTo(new FullRender(Size.Zero)); - } - - internal static void DrawWithoutChild(this T element) where T : ContainerElement - { - // component does not throw an exception when called with null child - Assert.DoesNotThrow(() => - { - element.Child = null; - - // component does not perform any canvas operation when called with null child - TestPlan - .For(x => element) - .DrawElement(new Size(200, 100)) - .CheckDrawResult(); - }); - } - } -} \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestEngine/TestPlan.cs b/QuestPDF.UnitTests/TestEngine/TestPlan.cs index 426aebd..ae35300 100644 --- a/QuestPDF.UnitTests/TestEngine/TestPlan.cs +++ b/QuestPDF.UnitTests/TestEngine/TestPlan.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Text.Json; +using FluentAssertions; using NUnit.Framework; +using QuestPDF.Drawing; using QuestPDF.Drawing.SpacePlan; using QuestPDF.Elements; using QuestPDF.Helpers; @@ -13,6 +15,8 @@ namespace QuestPDF.UnitTests.TestEngine internal class TestPlan { private const string DefaultChildName = "child"; + + private static Random Random { get; } = new Random(); private Element Element { get; set; } private ICanvas Canvas { get; } @@ -45,20 +49,31 @@ namespace QuestPDF.UnitTests.TestEngine private ICanvas CreateCanvas() { - return new CanvasMock + return new MockCanvas { TranslateFunc = position => { - var expected = GetExpected(); + var expected = GetExpected(); Assert.AreEqual(expected.Position.X, position.X, "Translate X"); Assert.AreEqual(expected.Position.Y, position.Y, "Translate Y"); - - //position.Should().BeEquivalentTo(expected.Position); + }, + RotateFunc = angle => + { + var expected = GetExpected(); + + Assert.AreEqual(expected.Angle, angle, "Rotate angle"); + }, + ScaleFunc = (scaleX, scaleY) => + { + var expected = GetExpected(); + + Assert.AreEqual(expected.ScaleX, scaleX, "Scale X"); + Assert.AreEqual(expected.ScaleY, scaleY, "Scale Y"); }, DrawRectFunc = (position, size, color) => { - var expected = GetExpected(); + var expected = GetExpected(); Assert.AreEqual(expected.Position.X, position.X, "Draw rectangle: X"); Assert.AreEqual(expected.Position.Y, position.Y, "Draw rectangle: Y"); @@ -67,14 +82,10 @@ namespace QuestPDF.UnitTests.TestEngine Assert.AreEqual(expected.Size.Height, size.Height, "Draw rectangle: height"); Assert.AreEqual(expected.Color, color, "Draw rectangle: color"); - - /*position.Should().BeEquivalentTo(expected.Position); - size.Should().BeEquivalentTo(expected.Size); - color.Should().Be(expected.Color);*/ }, DrawTextFunc = (text, position, style) => { - var expected = GetExpected(); + var expected = GetExpected(); Assert.AreEqual(expected.Text, text); @@ -84,23 +95,16 @@ namespace QuestPDF.UnitTests.TestEngine Assert.AreEqual(expected.Style.Color, style.Color, "Draw text: color"); Assert.AreEqual(expected.Style.FontType, style.FontType, "Draw text: font"); Assert.AreEqual(expected.Style.Size, style.Size, "Draw text: size"); - - /*text.Should().Be(expected.Text); - position.Should().BeEquivalentTo(expected.Position); - style.Should().BeEquivalentTo(expected.Style);*/ }, DrawImageFunc = (image, position, size) => { - var expected = GetExpected(); + var expected = GetExpected(); Assert.AreEqual(expected.Position.X, position.X, "Draw image: X"); Assert.AreEqual(expected.Position.Y, position.Y, "Draw image: Y"); Assert.AreEqual(expected.Size.Width, size.Width, "Draw image: width"); Assert.AreEqual(expected.Size.Height, size.Height, "Draw image: height"); - - /*position.Should().BeEquivalentTo(expected.Position); - size.Should().BeEquivalentTo(expected.Size);*/ } }; } @@ -114,29 +118,23 @@ namespace QuestPDF.UnitTests.TestEngine Id = id, MeasureFunc = availableSpace => { - var expected = GetExpected(); + var expected = GetExpected(); Assert.AreEqual(expected.ChildId, id); Assert.AreEqual(expected.Input.Width, availableSpace.Width, $"Measure: width of child '{expected.ChildId}'"); Assert.AreEqual(expected.Input.Height, availableSpace.Height, $"Measure: height of child '{expected.ChildId}'"); - // id.Should().Be(expected.ChildId); - // availableSpace.Should().Be(expected.Input); - return expected.Output; }, DrawFunc = availableSpace => { - var expected = GetExpected(); + var expected = GetExpected(); Assert.AreEqual(expected.ChildId, id); Assert.AreEqual(expected.Input.Width, availableSpace.Width, $"Draw: width of child '{expected.ChildId}'"); Assert.AreEqual(expected.Input.Height, availableSpace.Height, $"Draw: width of child '{expected.ChildId}'"); - - /*id.Should().Be(expected.ChildId); - availableSpace.Should().Be(expected.Input);*/ } }; } @@ -166,7 +164,7 @@ namespace QuestPDF.UnitTests.TestEngine public TestPlan ExpectChildMeasure(string child, Size expectedInput, ISpacePlan returns) { - return AddOperation(new ChildMeasureOperationBase(child, expectedInput, returns)); + return AddOperation(new ChildMeasureOperation(child, expectedInput, returns)); } public TestPlan ExpectChildDraw(Size expectedInput) @@ -176,32 +174,42 @@ namespace QuestPDF.UnitTests.TestEngine public TestPlan ExpectChildDraw(string child, Size expectedInput) { - return AddOperation(new ChildDrawOperationBase(child, expectedInput)); + return AddOperation(new ChildDrawOperation(child, expectedInput)); } public TestPlan ExpectCanvasTranslate(Position position) { - return AddOperation(new CanvasTranslateOperationBase(position)); + return AddOperation(new CanvasTranslateOperation(position)); } public TestPlan ExpectCanvasTranslate(float left, float top) { - return AddOperation(new CanvasTranslateOperationBase(new Position(left, top))); + return AddOperation(new CanvasTranslateOperation(new Position(left, top))); } + public TestPlan ExpectCanvasScale(float scaleX, float scaleY) + { + return AddOperation(new CanvasScaleOperation(scaleX, scaleY)); + } + + public TestPlan ExpectCanvasRotate(float angle) + { + return AddOperation(new CanvasRotateOperation(angle)); + } + public TestPlan ExpectCanvasDrawRectangle(Position position, Size size, string color) { - return AddOperation(new CanvasDrawRectangleOperationBase(position, size, color)); + return AddOperation(new CanvasDrawRectangleOperation(position, size, color)); } public TestPlan ExpectCanvasDrawText(string text, Position position, TextStyle style) { - return AddOperation(new CanvasDrawTextOperationBase(text, position, style)); + return AddOperation(new CanvasDrawTextOperation(text, position, style)); } public TestPlan ExpectCanvasDrawImage(Position position, Size size) { - return AddOperation(new CanvasDrawImageOperationBase(position, size)); + return AddOperation(new CanvasDrawImageOperation(position, size)); } public TestPlan CheckMeasureResult(ISpacePlan expected) @@ -251,5 +259,40 @@ namespace QuestPDF.UnitTests.TestEngine Source = Placeholders.Image }; } + + public static void CompareOperations(Element value, Element expected, Size? availableSpace = null) + { + CompareMeasureOperations(value, expected, availableSpace); + CompareDrawOperations(value, expected, availableSpace); + } + + private static void CompareMeasureOperations(Element value, Element expected, Size? availableSpace = null) + { + availableSpace ??= new Size(400, 300); + + var canvas = new FreeCanvas(); + value.HandleVisitor(x => x.Initialize(null, canvas)); + var valueMeasure = value.Measure(availableSpace); + + expected.HandleVisitor(x => x.Initialize(null, canvas)); + var expectedMeasure = expected.Measure(availableSpace); + + valueMeasure.Should().BeEquivalentTo(expectedMeasure); + } + + private static void CompareDrawOperations(Element value, Element expected, Size? availableSpace = null) + { + availableSpace ??= new Size(400, 300); + + var valueCanvas = new OperationRecordingCanvas(); + value.HandleVisitor(x => x.Initialize(null, valueCanvas)); + value.Draw(availableSpace); + + var expectedCanvas = new OperationRecordingCanvas(); + expected.HandleVisitor(x => x.Initialize(null, expectedCanvas)); + expected.Draw(availableSpace); + + valueCanvas.Operations.Should().BeEquivalentTo(expectedCanvas.Operations); + } } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/TestsBase.cs b/QuestPDF.UnitTests/TestsBase.cs new file mode 100644 index 0000000..0a477d4 --- /dev/null +++ b/QuestPDF.UnitTests/TestsBase.cs @@ -0,0 +1,22 @@ +using FluentAssertions; +using NUnit.Framework; + +namespace QuestPDF.UnitTests +{ + [SetUpFixture] + public class TestsBase + { + [OneTimeSetUp] + public void RunBeforeAnyTests() + { + AssertionOptions.AssertEquivalencyUsing(options => options + .IncludingNestedObjects() + .IncludingInternalProperties() + .IncludingInternalFields() + .AllowingInfiniteRecursion() + .RespectingRuntimeTypes() + .WithTracing() + .WithStrictOrdering()); + } + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/TextTests.cs b/QuestPDF.UnitTests/TextTests.cs deleted file mode 100644 index 95dc0bb..0000000 --- a/QuestPDF.UnitTests/TextTests.cs +++ /dev/null @@ -1,10 +0,0 @@ -using NUnit.Framework; - -namespace QuestPDF.UnitTests -{ - [TestFixture] - public class TextTests - { - - } -} \ No newline at end of file diff --git a/QuestPDF.UnitTests/TranslateTests.cs b/QuestPDF.UnitTests/TranslateTests.cs new file mode 100644 index 0000000..f035346 --- /dev/null +++ b/QuestPDF.UnitTests/TranslateTests.cs @@ -0,0 +1,32 @@ +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class TranslateTests + { + [Test] + public void Measure() => SimpleContainerTests.Measure(); + + [Test] + public void Draw() + { + TestPlan + .For(x => new Translate + { + Child = x.CreateChild(), + TranslateX = 50, + TranslateY = 75 + }) + .DrawElement(new Size(400, 300)) + .ExpectCanvasTranslate(50, 75) + .ExpectChildDraw(new Size(400, 300)) + .ExpectCanvasTranslate(-50, -75) + .CheckDrawResult(); + } + } +} \ No newline at end of file diff --git a/QuestPDF.UnitTests/UnconstrainedTests.cs b/QuestPDF.UnitTests/UnconstrainedTests.cs new file mode 100644 index 0000000..317eea0 --- /dev/null +++ b/QuestPDF.UnitTests/UnconstrainedTests.cs @@ -0,0 +1,100 @@ +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; + +namespace QuestPDF.UnitTests +{ + [TestFixture] + public class UnconstrainedTests + { + #region measure + + [Test] + public void Measure_Wrap() + { + TestPlan + .For(x => new Unconstrained + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(900, 800)) + .ExpectChildMeasure(Size.Max, new Wrap()) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Measure_PartialRender() + { + TestPlan + .For(x => new Unconstrained + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(900, 800)) + .ExpectChildMeasure(Size.Max, new PartialRender(1200, 1600)) + .CheckMeasureResult(new PartialRender(Size.Zero)); + } + + [Test] + public void Measure_FullRender() + { + TestPlan + .For(x => new Unconstrained + { + Child = x.CreateChild() + }) + .MeasureElement(new Size(900, 800)) + .ExpectChildMeasure(Size.Max, new FullRender(1200, 1600)) + .CheckMeasureResult(new FullRender(Size.Zero)); + } + + #endregion + + #region draw + + [Test] + public void Draw_SkipWhenChildWraps() + { + TestPlan + .For(x => new Unconstrained + { + Child = x.CreateChild() + }) + .DrawElement(new Size(900, 800)) + .ExpectChildMeasure(Size.Max, new Wrap()) + .CheckDrawResult(); + } + + [Test] + public void Draw_WhenChildPartiallyRenders() + { + TestPlan + .For(x => new Unconstrained + { + Child = x.CreateChild() + }) + .DrawElement(new Size(900, 800)) + .ExpectChildMeasure(Size.Max, new PartialRender(1200, 1600)) + .ExpectChildDraw(new Size(1200, 1600)) + .CheckDrawResult(); + } + + [Test] + public void Draw_WhenChildFullyRenders() + { + TestPlan + .For(x => new Unconstrained + { + Child = x.CreateChild() + }) + .DrawElement(new Size(900, 800)) + .ExpectChildMeasure(Size.Max, new FullRender(1600, 1000)) + .ExpectChildDraw(new Size(1600, 1000)) + .CheckDrawResult(); + } + + #endregion + } +} \ No newline at end of file diff --git a/QuestPDF/Drawing/FreeCanvas.cs b/QuestPDF/Drawing/FreeCanvas.cs index cc03c1f..6716e9e 100644 --- a/QuestPDF/Drawing/FreeCanvas.cs +++ b/QuestPDF/Drawing/FreeCanvas.cs @@ -66,6 +66,16 @@ namespace QuestPDF.Drawing } + public void Rotate(float angle) + { + + } + + public void Scale(float scaleX, float scaleY) + { + + } + #endregion } } \ No newline at end of file diff --git a/QuestPDF/Drawing/SkiaCanvasBase.cs b/QuestPDF/Drawing/SkiaCanvasBase.cs index 9d4b57f..9ec37a8 100644 --- a/QuestPDF/Drawing/SkiaCanvasBase.cs +++ b/QuestPDF/Drawing/SkiaCanvasBase.cs @@ -51,5 +51,15 @@ namespace QuestPDF.Drawing { Canvas.DrawNamedDestinationAnnotation(new SKPoint(0, 0), locationName); } + + public void Rotate(float angle) + { + Canvas.RotateDegrees(angle); + } + + public void Scale(float scaleX, float scaleY) + { + Canvas.Scale(scaleX, scaleY); + } } } \ No newline at end of file diff --git a/QuestPDF/Elements/Grid.cs b/QuestPDF/Elements/Grid.cs index 5f08722..4649ac4 100644 --- a/QuestPDF/Elements/Grid.cs +++ b/QuestPDF/Elements/Grid.cs @@ -16,7 +16,7 @@ namespace QuestPDF.Elements { public const int DefaultColumnsCount = 12; - public List Children { get; set; } = new List(); + public List Children { get; } = new List(); public Queue ChildrenQueue { get; set; } = new Queue(); public int ColumnsCount { get; set; } = DefaultColumnsCount; diff --git a/QuestPDF/Elements/Rotate.cs b/QuestPDF/Elements/Rotate.cs index 8ad368c..1fd3db6 100644 --- a/QuestPDF/Elements/Rotate.cs +++ b/QuestPDF/Elements/Rotate.cs @@ -8,16 +8,9 @@ namespace QuestPDF.Elements internal override void Draw(Size availableSpace) { - var skiaCanvas = (Canvas as Drawing.SkiaCanvasBase)?.Canvas; - - if (skiaCanvas == null) - return; - - var currentMatrix = skiaCanvas.TotalMatrix; - - skiaCanvas.RotateDegrees(Angle); + Canvas.Rotate(Angle); Child?.Draw(availableSpace); - skiaCanvas.SetMatrix(currentMatrix); + Canvas.Rotate(-Angle); } } } \ No newline at end of file diff --git a/QuestPDF/Elements/Scale.cs b/QuestPDF/Elements/Scale.cs index 0f27aa9..69f66c8 100644 --- a/QuestPDF/Elements/Scale.cs +++ b/QuestPDF/Elements/Scale.cs @@ -35,26 +35,21 @@ namespace QuestPDF.Elements internal override void Draw(Size availableSpace) { - var skiaCanvas = (Canvas as Drawing.SkiaCanvasBase)?.Canvas; - - if (skiaCanvas == null) - return; - var targetSpace = new Size( Math.Abs(availableSpace.Width / ScaleX), Math.Abs(availableSpace.Height / ScaleY)); - var currentMatrix = skiaCanvas.TotalMatrix; + var translate = new Position( + ScaleX < 0 ? availableSpace.Width : 0, + ScaleY < 0 ? availableSpace.Height : 0); - if (ScaleX < 0) - skiaCanvas.Translate(availableSpace.Width, 0); + Canvas.Translate(translate); + Canvas.Scale(ScaleX, ScaleY); - if (ScaleY < 0) - skiaCanvas.Translate(0, availableSpace.Height); - - skiaCanvas.Scale(ScaleX, ScaleY); Child?.Draw(targetSpace); - skiaCanvas.SetMatrix(currentMatrix); + + Canvas.Scale(1/ScaleX, 1/ScaleY); + Canvas.Translate(translate.Reverse()); } } } \ No newline at end of file diff --git a/QuestPDF/Elements/SimpleRotate.cs b/QuestPDF/Elements/SimpleRotate.cs index 0d818b9..5e0af1a 100644 --- a/QuestPDF/Elements/SimpleRotate.cs +++ b/QuestPDF/Elements/SimpleRotate.cs @@ -33,26 +33,22 @@ namespace QuestPDF.Elements internal override void Draw(Size availableSpace) { - var skiaCanvas = (Canvas as Drawing.SkiaCanvasBase)?.Canvas; + var translate = new Position( + (NormalizedTurnCount == 1 || NormalizedTurnCount == 2) ? availableSpace.Width : 0, + (NormalizedTurnCount == 2 || NormalizedTurnCount == 3) ? availableSpace.Height : 0); + + var rotate = NormalizedTurnCount * 90; - if (skiaCanvas == null) - return; - - var currentMatrix = skiaCanvas.TotalMatrix; - - if (NormalizedTurnCount == 1 || NormalizedTurnCount == 2) - skiaCanvas.Translate(availableSpace.Width, 0); - - if (NormalizedTurnCount == 2 || NormalizedTurnCount == 3) - skiaCanvas.Translate(0, availableSpace.Height); - - skiaCanvas.RotateDegrees(NormalizedTurnCount * 90); + Canvas.Translate(translate); + Canvas.Rotate(rotate); if (NormalizedTurnCount == 1 || NormalizedTurnCount == 3) availableSpace = new Size(availableSpace.Height, availableSpace.Width); Child?.Draw(availableSpace); - skiaCanvas.SetMatrix(currentMatrix); + + Canvas.Rotate(-rotate); + Canvas.Translate(translate.Reverse()); } } } \ No newline at end of file diff --git a/QuestPDF/Elements/Stack.cs b/QuestPDF/Elements/Stack.cs index 46d1968..c01dadf 100644 --- a/QuestPDF/Elements/Stack.cs +++ b/QuestPDF/Elements/Stack.cs @@ -91,7 +91,7 @@ namespace QuestPDF.Elements internal class Stack : IComponent { - public ICollection Children { get; internal set; } = new List(); + public ICollection Children { get; } = new List(); public float Spacing { get; set; } = 0; public void Compose(IContainer container) diff --git a/QuestPDF/Elements/Translate.cs b/QuestPDF/Elements/Translate.cs index d027eed..c418cc9 100644 --- a/QuestPDF/Elements/Translate.cs +++ b/QuestPDF/Elements/Translate.cs @@ -10,14 +10,11 @@ namespace QuestPDF.Elements internal override void Draw(Size availableSpace) { - var skiaCanvas = (Canvas as Drawing.SkiaCanvasBase)?.Canvas; + var translate = new Position(TranslateX, TranslateY); - if (skiaCanvas == null) - return; - - skiaCanvas.Translate(TranslateX, TranslateY); + Canvas.Translate(translate); base.Draw(availableSpace); - skiaCanvas.Translate(-TranslateX, -TranslateY); + Canvas.Translate(translate.Reverse()); } } } \ No newline at end of file diff --git a/QuestPDF/Infrastructure/ICanvas.cs b/QuestPDF/Infrastructure/ICanvas.cs index f5a5ec9..e2bb3fb 100644 --- a/QuestPDF/Infrastructure/ICanvas.cs +++ b/QuestPDF/Infrastructure/ICanvas.cs @@ -13,5 +13,8 @@ namespace QuestPDF.Infrastructure void DrawExternalLink(string url, Size size); void DrawLocationLink(string locationName, Size size); void DrawLocation(string locationName); + + void Rotate(float angle); + void Scale(float scaleX, float scaleY); } } \ No newline at end of file