diff --git a/QuestPDF.Examples/ElementExamples.cs b/QuestPDF.Examples/ElementExamples.cs
index 5494050..01f7ff2 100644
--- a/QuestPDF.Examples/ElementExamples.cs
+++ b/QuestPDF.Examples/ElementExamples.cs
@@ -558,7 +558,7 @@ namespace QuestPDF.Examples
{
RenderingTest
.Create()
- .PageSize(350, 350)
+ .PageSize(650, 450)
.FileName()
.Render(container =>
{
@@ -572,8 +572,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 fb5be83..eb19990 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 3c49859..6678048 100644
--- a/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj
+++ b/QuestPDF.ReportSample/QuestPDF.ReportSample.csproj
@@ -9,8 +9,8 @@
-
-
+
+
diff --git a/QuestPDF.UnitTests/BoxTests.cs b/QuestPDF.UnitTests/BoxTests.cs
new file mode 100644
index 0000000..8f7c782
--- /dev/null
+++ b/QuestPDF.UnitTests/BoxTests.cs
@@ -0,0 +1,53 @@
+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 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/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/QuestPDF.UnitTests.csproj b/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj
index 213f6f3..5497f7f 100644
--- a/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj
+++ b/QuestPDF.UnitTests/QuestPDF.UnitTests.csproj
@@ -6,10 +6,10 @@
-
+
-
-
+
+
diff --git a/QuestPDF.UnitTests/RotateTests.cs b/QuestPDF.UnitTests/RotateTests.cs
new file mode 100644
index 0000000..ee30546
--- /dev/null
+++ b/QuestPDF.UnitTests/RotateTests.cs
@@ -0,0 +1,28 @@
+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 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/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/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/TestEngine/CanvasMock.cs b/QuestPDF.UnitTests/TestEngine/CanvasMock.cs
index e1b73f6..e399678 100644
--- a/QuestPDF.UnitTests/TestEngine/CanvasMock.cs
+++ b/QuestPDF.UnitTests/TestEngine/CanvasMock.cs
@@ -7,11 +7,16 @@ namespace QuestPDF.UnitTests.TestEngine
internal class CanvasMock : 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);
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/TestPlan.cs b/QuestPDF.UnitTests/TestEngine/TestPlan.cs
index 6c3ffff..cfe176d 100644
--- a/QuestPDF.UnitTests/TestEngine/TestPlan.cs
+++ b/QuestPDF.UnitTests/TestEngine/TestPlan.cs
@@ -55,6 +55,23 @@ namespace QuestPDF.UnitTests.TestEngine
//position.Should().BeEquivalentTo(expected.Position);
},
+ RotateFunc = angle =>
+ {
+ var expected = GetExpected();
+
+ Assert.AreEqual(expected.Angle, angle, "Rotate angle");
+
+ //position.Should().BeEquivalentTo(expected.Position);
+ },
+ ScaleFunc = (scaleX, scaleY) =>
+ {
+ var expected = GetExpected();
+
+ Assert.AreEqual(expected.ScaleX, scaleX, "Scale X");
+ Assert.AreEqual(expected.ScaleY, scaleY, "Scale Y");
+
+ //position.Should().BeEquivalentTo(expected.Position);
+ },
DrawRectFunc = (position, size, color) =>
{
var expected = GetExpected();
@@ -188,6 +205,16 @@ namespace QuestPDF.UnitTests.TestEngine
return AddOperation(new CanvasTranslateOperationBase(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));
diff --git a/QuestPDF.UnitTests/TranslateTests.cs b/QuestPDF.UnitTests/TranslateTests.cs
new file mode 100644
index 0000000..9d4bb70
--- /dev/null
+++ b/QuestPDF.UnitTests/TranslateTests.cs
@@ -0,0 +1,29 @@
+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 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 f6de0ae..824656a 100644
--- a/QuestPDF/Drawing/SkiaCanvasBase.cs
+++ b/QuestPDF/Drawing/SkiaCanvasBase.cs
@@ -54,5 +54,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/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 9926138..148b1a2 100644
--- a/QuestPDF/Elements/SimpleRotate.cs
+++ b/QuestPDF/Elements/SimpleRotate.cs
@@ -34,26 +34,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/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 9001161..38a37d9 100644
--- a/QuestPDF/Infrastructure/ICanvas.cs
+++ b/QuestPDF/Infrastructure/ICanvas.cs
@@ -14,5 +14,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