diff --git a/QuestPDF.Examples/QuestPDF.Examples.csproj b/QuestPDF.Examples/QuestPDF.Examples.csproj index e7fea32..2e9494a 100644 --- a/QuestPDF.Examples/QuestPDF.Examples.csproj +++ b/QuestPDF.Examples/QuestPDF.Examples.csproj @@ -13,7 +13,6 @@ - diff --git a/QuestPDF.UnitTests/AlignmentTests.cs b/QuestPDF.UnitTests/AlignmentTests.cs index 004a32e..1e623f1 100644 --- a/QuestPDF.UnitTests/AlignmentTests.cs +++ b/QuestPDF.UnitTests/AlignmentTests.cs @@ -21,10 +21,10 @@ namespace QuestPDF.UnitTests TestPlan .For(x => new Alignment { - Child = x.CreateChild("child") + Child = x.CreateChild() }) .MeasureElement(new Size(1000, 500)) - .ExpectChildMeasure("child", expectedInput: new Size(1000, 500), returns: new Wrap()) + .ExpectChildMeasure(expectedInput: new Size(1000, 500), returns: new Wrap()) .CheckMeasureResult(new Wrap()); } @@ -37,12 +37,12 @@ namespace QuestPDF.UnitTests Horizontal = HorizontalAlignment.Center, Vertical = VerticalAlignment.Middle, - Child = x.CreateChild("child") + Child = x.CreateChild() }) .DrawElement(new Size(1000, 500)) - .ExpectChildMeasure("child", expectedInput: new Size(1000, 500), returns: new PartialRender(new Size(400, 200))) + .ExpectChildMeasure(expectedInput: new Size(1000, 500), returns: new PartialRender(new Size(400, 200))) .ExpectCanvasTranslate(new Position(300, 150)) - .ExpectChildDraw("child", new Size(400, 200)) + .ExpectChildDraw(new Size(400, 200)) .ExpectCanvasTranslate(new Position(-300, -150)) .CheckDrawResult(); } @@ -56,12 +56,12 @@ namespace QuestPDF.UnitTests Horizontal = HorizontalAlignment.Left, Vertical = VerticalAlignment.Middle, - Child = x.CreateChild("child") + Child = x.CreateChild() }) .DrawElement(new Size(400, 300)) - .ExpectChildMeasure("child", expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50))) + .ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50))) .ExpectCanvasTranslate(new Position(0, 125)) - .ExpectChildDraw("child", new Size(100, 50)) + .ExpectChildDraw(new Size(100, 50)) .ExpectCanvasTranslate(new Position(0, -125)) .CheckDrawResult(); } @@ -75,12 +75,12 @@ namespace QuestPDF.UnitTests Horizontal = HorizontalAlignment.Center, Vertical = VerticalAlignment.Bottom, - Child = x.CreateChild("child") + Child = x.CreateChild() }) .DrawElement(new Size(400, 300)) - .ExpectChildMeasure("child", expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50))) + .ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50))) .ExpectCanvasTranslate(new Position(150, 250)) - .ExpectChildDraw("child", new Size(100, 50)) + .ExpectChildDraw(new Size(100, 50)) .ExpectCanvasTranslate(new Position(-150, -250)) .CheckDrawResult(); } @@ -94,12 +94,12 @@ namespace QuestPDF.UnitTests Horizontal = HorizontalAlignment.Right, Vertical = VerticalAlignment.Top, - Child = x.CreateChild("child") + Child = x.CreateChild() }) .DrawElement(new Size(400, 300)) - .ExpectChildMeasure("child", expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50))) + .ExpectChildMeasure(expectedInput: new Size(400, 300), returns: new FullRender(new Size(100, 50))) .ExpectCanvasTranslate(new Position(300, 0)) - .ExpectChildDraw("child", new Size(100, 50)) + .ExpectChildDraw(new Size(100, 50)) .ExpectCanvasTranslate(new Position(-300, 0)) .CheckDrawResult(); } diff --git a/QuestPDF.UnitTests/AspectRatioTests.cs b/QuestPDF.UnitTests/AspectRatioTests.cs index 7feb54e..33e83a3 100644 --- a/QuestPDF.UnitTests/AspectRatioTests.cs +++ b/QuestPDF.UnitTests/AspectRatioTests.cs @@ -15,5 +15,168 @@ namespace QuestPDF.UnitTests [Test] public void Draw_ShouldHandleNullChild() => new AspectRatio().DrawWithoutChild(); + + [Test] + public void Measure_FitWidth_EnoughSpace_FullRender() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitArea, + Ratio = 2f + }) + .MeasureElement(new Size(400, 201)) + .ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50)) + .CheckMeasureResult(new FullRender(400, 200)); + } + + [Test] + public void Measure_FitWidth_EnoughSpace_PartialRender() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitArea, + Ratio = 2f + }) + .MeasureElement(new Size(400, 201)) + .ExpectChildMeasure(new Size(400, 200), new PartialRender(100, 50)) + .CheckMeasureResult(new PartialRender(400, 200)); + } + + [Test] + public void Measure_FitWidth_EnoughSpace_Wrap() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitArea, + Ratio = 2f + }) + .MeasureElement(new Size(400, 201)) + .ExpectChildMeasure(new Size(400, 200), new Wrap()) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Measure_FitWidth_EnoughSpace() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitWidth, + Ratio = 2f + }) + .MeasureElement(new Size(400, 201)) + .ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50)) + .CheckMeasureResult(new FullRender(400, 200)); + } + + [Test] + public void Measure_FitWidth_NotEnoughSpace() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitWidth, + Ratio = 2f + }) + .MeasureElement(new Size(400, 199)) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Measure_FitHeight_EnoughSpace() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitHeight, + Ratio = 2f + }) + .MeasureElement(new Size(401, 200)) + .ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50)) + .CheckMeasureResult(new FullRender(400, 200)); + } + + [Test] + public void Measure_FitHeight_NotEnoughSpace() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitHeight, + Ratio = 2f + }) + .MeasureElement(new Size(399, 200)) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Measure_FitArea_ToWidth() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitArea, + Ratio = 2f + }) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50)) + .CheckMeasureResult(new FullRender(400, 200)); + } + + [Test] + public void Measure_FitArea_ToHeight() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitArea, + Ratio = 2f + }) + .MeasureElement(new Size(500, 200)) + .ExpectChildMeasure(new Size(400, 200), new FullRender(100, 50)) + .CheckMeasureResult(new FullRender(400, 200)); + } + + [Test] + public void DrawChild_PerWidth() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitArea, + Ratio = 2f + }) + .DrawElement(new Size(500, 200)) + .ExpectChildDraw(new Size(400, 200)) + .CheckDrawResult(); + } + + [Test] + public void DrawChild_PerHeight() + { + TestPlan + .For(x => new AspectRatio + { + Child = x.CreateChild(), + Option = AspectRatioOption.FitArea, + Ratio = 2f + }) + .DrawElement(new Size(400, 300)) + .ExpectChildDraw(new Size(400, 200)) + .CheckDrawResult(); + } } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/BackgroundTests.cs b/QuestPDF.UnitTests/BackgroundTests.cs index 496d7d4..14ad989 100644 --- a/QuestPDF.UnitTests/BackgroundTests.cs +++ b/QuestPDF.UnitTests/BackgroundTests.cs @@ -31,11 +31,11 @@ namespace QuestPDF.UnitTests .For(x => new Background { Color = "#F00", - Child = x.CreateChild("a") + Child = x.CreateChild() }) .DrawElement(new Size(400, 300)) .ExpectCanvasDrawRectangle(new Position(0, 0), new Size(400, 300), "#F00") - .ExpectChildDraw("a", new Size(400, 300)) + .ExpectChildDraw(new Size(400, 300)) .CheckDrawResult(); } } diff --git a/QuestPDF.UnitTests/BorderTests.cs b/QuestPDF.UnitTests/BorderTests.cs index 2a98a1a..26c481b 100644 --- a/QuestPDF.UnitTests/BorderTests.cs +++ b/QuestPDF.UnitTests/BorderTests.cs @@ -23,10 +23,10 @@ namespace QuestPDF.UnitTests Bottom = 30, Left = 40, - Child = x.CreateChild("child") + Child = x.CreateChild() }) .MeasureElement(new Size(400, 300)) - .ExpectChildMeasure("child", expectedInput: new Size(400, 300), returns: new 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))); } @@ -43,15 +43,15 @@ namespace QuestPDF.UnitTests Color = "#FF0000", - Child = x.CreateChild("child") + Child = x.CreateChild() }) .DrawElement(new Size(400, 300)) - .ExpectChildDraw("child", new Size(400, 300)) + .ExpectChildDraw(new Size(400, 300)) .ExpectCanvasDrawRectangle(new Position(-20, -5), new Size(430, 10), "#FF0000") // top .ExpectCanvasDrawRectangle(new Position(-20, -5), new Size(40, 320), "#FF0000") // left .ExpectCanvasDrawRectangle(new Position(-20, 285), new Size(430, 30), "#FF0000") // bottom .ExpectCanvasDrawRectangle(new Position(390, -5), new Size(20, 320), "#FF0000") // right - .ExpectChildDraw("child", new Size(400, 300)) + .ExpectChildDraw(new Size(400, 300)) .CheckDrawResult(); } } diff --git a/QuestPDF.UnitTests/ConstrainedTests.cs b/QuestPDF.UnitTests/ConstrainedTests.cs index 81c4432..80d19bb 100644 --- a/QuestPDF.UnitTests/ConstrainedTests.cs +++ b/QuestPDF.UnitTests/ConstrainedTests.cs @@ -34,10 +34,10 @@ namespace QuestPDF.UnitTests .For(x => new Constrained { MinHeight = 100, - Child = x.CreateChild("a") + Child = x.CreateChild() }) .MeasureElement(new Size(400, 200)) - .ExpectChildMeasure("a", new Size(400, 200), new FullRender(400, 50)) + .ExpectChildMeasure(new Size(400, 200), new FullRender(400, 50)) .CheckMeasureResult(new FullRender(400, 100)); } @@ -48,10 +48,10 @@ namespace QuestPDF.UnitTests .For(x => new Constrained { MinHeight = 100, - Child = x.CreateChild("a") + Child = x.CreateChild() }) .MeasureElement(new Size(400, 200)) - .ExpectChildMeasure("a", new Size(400, 200), new FullRender(400, 150)) + .ExpectChildMeasure(new Size(400, 200), new FullRender(400, 150)) .CheckMeasureResult(new FullRender(400, 150)); } @@ -74,10 +74,10 @@ namespace QuestPDF.UnitTests .For(x => new Constrained { MaxHeight = 100, - Child = x.CreateChild("a") + Child = x.CreateChild() }) .MeasureElement(new Size(400, 200)) - .ExpectChildMeasure("a", new Size(400, 100), new PartialRender(400, 75)) + .ExpectChildMeasure(new Size(400, 100), new PartialRender(400, 75)) .CheckMeasureResult(new PartialRender(400, 75)); } @@ -88,10 +88,10 @@ namespace QuestPDF.UnitTests .For(x => new Constrained { MaxHeight = 100, - Child = x.CreateChild("a") + Child = x.CreateChild() }) .MeasureElement(new Size(400, 200)) - .ExpectChildMeasure("a", new Size(400, 100), new Wrap()) + .ExpectChildMeasure(new Size(400, 100), new Wrap()) .CheckMeasureResult(new Wrap()); } } diff --git a/QuestPDF.UnitTests/DynamicImageTests.cs b/QuestPDF.UnitTests/DynamicImageTests.cs index 1c06ae5..461f22f 100644 --- a/QuestPDF.UnitTests/DynamicImageTests.cs +++ b/QuestPDF.UnitTests/DynamicImageTests.cs @@ -1,10 +1,86 @@ -using NUnit.Framework; +using System; +using FluentAssertions; +using NUnit.Framework; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; +using SkiaSharp; namespace QuestPDF.UnitTests { [TestFixture] public class DynamicImageTests { + [Test] + public void Measure_TakesAvailableSpaceRegardlessOfSize() + { + TestPlan + .For(x => new DynamicImage + { + Source = GenerateImage + }) + .MeasureElement(new Size(300, 200)) + .CheckMeasureResult(new FullRender(300, 200)); + } + [Test] + public void Draw_HandlesNull() + { + TestPlan + .For(x => new DynamicImage + { + Source = size => null + }) + .DrawElement(new Size(300, 200)) + .CheckDrawResult(); + } + + [Test] + public void Draw_PreservesSize() + { + TestPlan + .For(x => new DynamicImage + { + Source = GenerateImage + }) + .DrawElement(new Size(300, 200)) + .ExpectCanvasDrawImage(Position.Zero, new Size(300, 200)) + .CheckDrawResult(); + } + + [Test] + public void Draw_PassesCorrectSizeToSource() + { + Size passedSize = null; + + TestPlan + .For(x => new DynamicImage + { + Source = size => + { + passedSize = size; + return GenerateImage(size); + } + }) + .DrawElement(new Size(400, 300)) + .ExpectCanvasDrawImage(Position.Zero, new Size(400, 300)) + .CheckDrawResult(); + + passedSize.Should().Be(new Size(400, 300)); + } + + byte[] GenerateImage(Size size) + { + var image = GenerateImage((int) size.Width, (int) size.Height); + return image.Encode(SKEncodedImageFormat.Png, 100).ToArray(); + } + + SKImage GenerateImage(int width, int height) + { + var imageInfo = new SKImageInfo(width, height); + using var surface = SKSurface.Create(imageInfo); + return surface.Snapshot(); + } } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/EmptyTests.cs b/QuestPDF.UnitTests/EmptyTests.cs deleted file mode 100644 index 4826216..0000000 --- a/QuestPDF.UnitTests/EmptyTests.cs +++ /dev/null @@ -1,10 +0,0 @@ -using NUnit.Framework; - -namespace QuestPDF.UnitTests -{ - [TestFixture] - public class EmptyTests - { - - } -} \ No newline at end of file diff --git a/QuestPDF.UnitTests/ImageTests.cs b/QuestPDF.UnitTests/ImageTests.cs index e0c8406..15331c7 100644 --- a/QuestPDF.UnitTests/ImageTests.cs +++ b/QuestPDF.UnitTests/ImageTests.cs @@ -1,7 +1,12 @@ using Moq; using NUnit.Framework; +using QuestPDF.Drawing; +using QuestPDF.Drawing.SpacePlan; using QuestPDF.Elements; +using QuestPDF.Fluent; using QuestPDF.Infrastructure; +using QuestPDF.UnitTests.TestEngine; +using SkiaSharp; namespace QuestPDF.UnitTests { @@ -9,17 +14,57 @@ namespace QuestPDF.UnitTests public class ImageTests { [Test] - public void Draw_ShouldHandleNullChild() + public void Measure_ShouldHandleNullChild() => new AspectRatio().MeasureWithoutChild(); + + [Test] + public void Draw_ShouldHandleNullChild() => new AspectRatio().DrawWithoutChild(); + + [Test] + public void Measure_TakesAvailableSpaceRegardlessOfSize() { - Assert.DoesNotThrow(() => - { - var image = new Image() + TestPlan + .For(x => new Image { - InternalImage = null - }; - - image.Draw(It.IsAny(), Size.Zero); - }); + InternalImage = GenerateImage(400, 300) + }) + .MeasureElement(new Size(300, 200)) + .CheckMeasureResult(new FullRender(300, 200)); + } + + [Test] + public void Draw_TakesAvailableSpaceRegardlessOfSize() + { + TestPlan + .For(x => new Image + { + InternalImage = GenerateImage(400, 300) + }) + .DrawElement(new Size(300, 200)) + .ExpectCanvasDrawImage(new Position(0, 0), new Size(300, 200)) + .CheckDrawResult(); + } + + [Test] + public void Fluent_RecognizesImageProportions() + { + var image = GenerateImage(600, 200).Encode(SKEncodedImageFormat.Png, 100).ToArray(); + + TestPlan + .For(x => + { + var container = new Container(); + container.Image(image); + return container; + }) + .MeasureElement(new Size(300, 200)) + .CheckMeasureResult(new FullRender(300, 100));; + } + + SKImage GenerateImage(int width, int height) + { + var imageInfo = new SKImageInfo(width, height); + using var surface = SKSurface.Create(imageInfo); + return surface.Snapshot(); } } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/PaddingTests.cs b/QuestPDF.UnitTests/PaddingTests.cs index 1a79734..09c90f5 100644 --- a/QuestPDF.UnitTests/PaddingTests.cs +++ b/QuestPDF.UnitTests/PaddingTests.cs @@ -17,62 +17,77 @@ namespace QuestPDF.UnitTests [Test] public void Draw_ShouldHandleNullChild() => new Padding().DrawWithoutChild(); - private Padding GetPadding(Element child) + private Padding GetPadding(TestPlan plan) { return new Padding() { - Top = 5, - Right = 10, - Bottom = 15, - Left = 20, + Top = 10, + Right = 20, + Bottom = 30, + Left = 40, - Child = child + Child = plan.CreateChild() }; } [Test] - public void Measure_WhenChildReturnsWrap_ReturnsWrap() + public void Measure_General_EnoughSpace() { - var child = new Mock(); - - child - .Setup(x => x.Measure(It.IsAny())) - .Returns(() => new Wrap()); - - GetPadding(child.Object) - .Measure(Size.Zero) - .Should() - .BeOfType(); + TestPlan + .For(GetPadding) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(340, 260), new FullRender(140, 60)) + .CheckMeasureResult(new FullRender(200, 100)); + } + + [Test] + public void Measure_NotEnoughWidth() + { + TestPlan + .For(GetPadding) + .MeasureElement(new Size(50, 300)) + .CheckMeasureResult(new Wrap()); } [Test] - public void Measure_WhenChildReturnsFullRender_ReturnsFullRender() + public void Measure_NotEnoughHeight() { - var child = new Mock(); - - child - .Setup(x => x.Measure(It.IsAny())) - .Returns(() => new FullRender(Size.Zero)); - - GetPadding(child.Object) - .Measure(Size.Zero) - .Should() - .BeOfType(); + TestPlan + .For(GetPadding) + .MeasureElement(new Size(20, 300)) + .CheckMeasureResult(new Wrap()); } [Test] - public void Measure_WhenChildReturnsPartialRender_ReturnsPartialRender() + public void Measure_AcceptsPartialRender() { - var child = new Mock(); - - child - .Setup(x => x.Measure(It.IsAny())) - .Returns(() => new PartialRender(Size.Zero)); - - GetPadding(child.Object) - .Measure(Size.Zero) - .Should() - .BeOfType(); + TestPlan + .For(GetPadding) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(340, 260), new PartialRender(40, 160)) + .CheckMeasureResult(new PartialRender(100, 200)); + } + + [Test] + public void Measure_AcceptsWrap() + { + TestPlan + .For(GetPadding) + .MeasureElement(new Size(400, 300)) + .ExpectChildMeasure(new Size(340, 260), new Wrap()) + .CheckMeasureResult(new Wrap()); + } + + [Test] + public void Draw_General() + { + TestPlan + .For(GetPadding) + .DrawElement(new Size(400, 300)) + .ExpectCanvasTranslate(new Position(40, 10)) + .ExpectChildDraw(new Size(340, 260)) + .ExpectCanvasTranslate(new Position(-40, -10)) + .CheckDrawResult(); } } } \ No newline at end of file diff --git a/QuestPDF.UnitTests/PlaceholderTests.cs b/QuestPDF.UnitTests/PlaceholderTests.cs deleted file mode 100644 index c9be9d6..0000000 --- a/QuestPDF.UnitTests/PlaceholderTests.cs +++ /dev/null @@ -1,10 +0,0 @@ -using NUnit.Framework; - -namespace QuestPDF.UnitTests -{ - [TestFixture] - public class PlaceholderTests - { - - } -} \ No newline at end of file diff --git a/QuestPDF.UnitTests/ShowOnceTest.cs b/QuestPDF.UnitTests/ShowOnceTest.cs index f7edb86..29d0258 100644 --- a/QuestPDF.UnitTests/ShowOnceTest.cs +++ b/QuestPDF.UnitTests/ShowOnceTest.cs @@ -42,7 +42,7 @@ namespace QuestPDF.UnitTests TestPlan .For(x => new ShowOnce() { - Child = x.CreateChild("child") + Child = x.CreateChild() }) // Measure the element and return result @@ -52,21 +52,21 @@ namespace QuestPDF.UnitTests // Draw element partially .DrawElement(new Size(200, 200)) - .ExpectChildMeasure("child", new Size(200, 200), new PartialRender(new Size(200, 200))) - .ExpectChildDraw("child", 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("child", new Size(800, 200), new 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("child", new Size(400, 200), new FullRender(new Size(400, 200))) - .ExpectChildDraw("child", 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. diff --git a/QuestPDF.UnitTests/TestEngine/TestPlan.cs b/QuestPDF.UnitTests/TestEngine/TestPlan.cs index 9cf72c2..fba14ef 100644 --- a/QuestPDF.UnitTests/TestEngine/TestPlan.cs +++ b/QuestPDF.UnitTests/TestEngine/TestPlan.cs @@ -10,6 +10,8 @@ namespace QuestPDF.UnitTests.TestEngine { internal class TestPlan { + private const string DefaultChildName = "child"; + private Element Element { get; set; } private ICanvas Canvas { get; } @@ -100,6 +102,8 @@ namespace QuestPDF.UnitTests.TestEngine } }; } + + public Element CreateChild() => CreateChild(DefaultChildName); public Element CreateChild(string id) { @@ -153,11 +157,21 @@ namespace QuestPDF.UnitTests.TestEngine return this; } + public TestPlan ExpectChildMeasure(Size expectedInput, ISpacePlan returns) + { + return ExpectChildMeasure(DefaultChildName, expectedInput, returns); + } + public TestPlan ExpectChildMeasure(string child, Size expectedInput, ISpacePlan returns) { return AddOperation(new ChildMeasureOperationBase(child, expectedInput, returns)); } + public TestPlan ExpectChildDraw(Size expectedInput) + { + return ExpectChildDraw(DefaultChildName, expectedInput); + } + public TestPlan ExpectChildDraw(string child, Size expectedInput) { return AddOperation(new ChildDrawOperationBase(child, expectedInput)); diff --git a/QuestPDF/Elements/AspectRatio.cs b/QuestPDF/Elements/AspectRatio.cs index b512c75..2b3bf18 100644 --- a/QuestPDF/Elements/AspectRatio.cs +++ b/QuestPDF/Elements/AspectRatio.cs @@ -14,15 +14,26 @@ namespace QuestPDF.Elements if(Child == null) return new FullRender(Size.Zero); - var size = GetTargetSize(availableSpace); + var targetSize = GetTargetSize(availableSpace); - if (size.Height > availableSpace.Height + Size.Epsilon) + if (targetSize.Height > availableSpace.Height + Size.Epsilon) return new Wrap(); - if (size.Width > availableSpace.Width + Size.Epsilon) + if (targetSize.Width > availableSpace.Width + Size.Epsilon) return new Wrap(); + + var childSize = Child.Measure(targetSize); + + if (childSize is Wrap) + return new Wrap(); + + if (childSize is PartialRender) + return new PartialRender(targetSize); + + if (childSize is FullRender) + return new FullRender(targetSize); - return new FullRender(size); + throw new NotSupportedException(); } internal override void Draw(ICanvas canvas, Size availableSpace) diff --git a/QuestPDF/Elements/DynamicImage.cs b/QuestPDF/Elements/DynamicImage.cs index a567e32..6434729 100644 --- a/QuestPDF/Elements/DynamicImage.cs +++ b/QuestPDF/Elements/DynamicImage.cs @@ -11,9 +11,6 @@ namespace QuestPDF.Elements internal override ISpacePlan Measure(Size availableSpace) { - if (availableSpace.Width < 0 || availableSpace.Height < 0) - return new Wrap(); - return new FullRender(availableSpace.Width, availableSpace.Height); } diff --git a/QuestPDF/Elements/Padding.cs b/QuestPDF/Elements/Padding.cs index 0694fd1..db9b6eb 100644 --- a/QuestPDF/Elements/Padding.cs +++ b/QuestPDF/Elements/Padding.cs @@ -17,6 +17,10 @@ namespace QuestPDF.Elements return new FullRender(Size.Zero); var internalSpace = InternalSpace(availableSpace); + + if (internalSpace.Width <= 0 || internalSpace.Height <= 0) + return new Wrap(); + var measure = Child.Measure(internalSpace) as Size; if (measure == null) diff --git a/QuestPDF/Elements/Placeholder.cs b/QuestPDF/Elements/Placeholder.cs index 64476a8..1e2e3c1 100644 --- a/QuestPDF/Elements/Placeholder.cs +++ b/QuestPDF/Elements/Placeholder.cs @@ -14,8 +14,6 @@ namespace QuestPDF.Elements public void Compose(IContainer container) { - // TODO: consider moving this element into fluent API - container .Background("CCC") .AlignMiddle() diff --git a/QuestPDF/Fluent/ElementExtensions.cs b/QuestPDF/Fluent/ElementExtensions.cs index a2153ef..96d5151 100644 --- a/QuestPDF/Fluent/ElementExtensions.cs +++ b/QuestPDF/Fluent/ElementExtensions.cs @@ -48,45 +48,7 @@ namespace QuestPDF.Fluent { return parent.Element(new Debug()); } - - public static void Image(this IContainer parent, byte[] data, ImageScaling scaling = ImageScaling.FitWidth) - { - if (data == null) - return; - - var image = SKImage.FromEncodedData(data); - var aspectRatio = image.Width / (float)image.Height; - - var imageElement = new Image - { - InternalImage = image - }; - if (scaling != ImageScaling.Resize) - parent = parent.AspectRatio(aspectRatio, Map(scaling)); - - parent.Element(imageElement); - - static AspectRatioOption Map(ImageScaling scaling) - { - return scaling switch - { - ImageScaling.FitWidth => AspectRatioOption.FitWidth, - ImageScaling.FitHeight => AspectRatioOption.FitHeight, - ImageScaling.FitArea => AspectRatioOption.FitArea, - _ => throw new ArgumentOutOfRangeException() - }; - } - } - - public static void DynamicImage(this IContainer element, Func imageSource) - { - element.Element(new DynamicImage - { - Source = imageSource - }); - } - public static void PageNumber(this IContainer element, string textFormat = "{number}", TextStyle? style = null) { element.Element(new PageNumber diff --git a/QuestPDF/Fluent/ImageExtensions.cs b/QuestPDF/Fluent/ImageExtensions.cs new file mode 100644 index 0000000..d327bfe --- /dev/null +++ b/QuestPDF/Fluent/ImageExtensions.cs @@ -0,0 +1,48 @@ +using System; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; +using SkiaSharp; + +namespace QuestPDF.Fluent +{ + public static class ImageExtensions + { + public static void Image(this IContainer parent, byte[] data, ImageScaling scaling = ImageScaling.FitWidth) + { + if (data == null) + return; + + var image = SKImage.FromEncodedData(data); + var aspectRatio = image.Width / (float)image.Height; + + var imageElement = new Image + { + InternalImage = image + }; + + if (scaling != ImageScaling.Resize) + parent = parent.AspectRatio(aspectRatio, Map(scaling)); + + parent.Element(imageElement); + + static AspectRatioOption Map(ImageScaling scaling) + { + return scaling switch + { + ImageScaling.FitWidth => AspectRatioOption.FitWidth, + ImageScaling.FitHeight => AspectRatioOption.FitHeight, + ImageScaling.FitArea => AspectRatioOption.FitArea, + _ => throw new ArgumentOutOfRangeException() + }; + } + } + + public static void DynamicImage(this IContainer element, Func imageSource) + { + element.Element(new DynamicImage + { + Source = imageSource + }); + } + } +} \ No newline at end of file