From 6d3c8d070871df2919a90cfc53720ae8d0e1ee85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zi=C4=85bek?= Date: Sun, 1 Aug 2021 21:09:16 +0200 Subject: [PATCH] Added elements: Rotate, Unconstrained --- QuestPDF.Examples/ElementExamples.cs | 30 +++++++++++ QuestPDF.Examples/Engine/SimpleDocument.cs | 2 +- QuestPDF/Drawing/ImageCanvas.cs | 1 - QuestPDF/Elements/Rotate.cs | 44 ++-------------- QuestPDF/Elements/SimpleRotate.cs | 59 ++++++++++++++++++++++ QuestPDF/Elements/Unconstrained.cs | 27 ++++++++++ QuestPDF/Fluent/ElementExtensions.cs | 5 ++ QuestPDF/Fluent/RotateExtensions.cs | 17 +++++-- QuestPDF/Fluent/TranslateExtensions.cs | 7 +-- 9 files changed, 140 insertions(+), 52 deletions(-) create mode 100644 QuestPDF/Elements/SimpleRotate.cs create mode 100644 QuestPDF/Elements/Unconstrained.cs diff --git a/QuestPDF.Examples/ElementExamples.cs b/QuestPDF.Examples/ElementExamples.cs index 9466ad0..5900f2a 100644 --- a/QuestPDF.Examples/ElementExamples.cs +++ b/QuestPDF.Examples/ElementExamples.cs @@ -649,6 +649,7 @@ namespace QuestPDF.Examples .Render(container => { container + .Padding(10) .Border(2) .Row(row => { @@ -663,5 +664,34 @@ namespace QuestPDF.Examples }); }); } + + [Test] + public void Floating() + { + RenderingTest + .Create() + .PageSize(400, 300) + .Render(container => + { + container + .Padding(50) + .Layers(layers => + { + layers + .PrimaryLayer() + .Background(Colors.Green.Lighten4) + .Extend(); + + layers + .Layer() + .Rotate(17) + .TranslateX(-100) + .TranslateY(-50) + .Width(200) + .Height(100) + .Background(Colors.Green.Medium); + }); + }); + } } } diff --git a/QuestPDF.Examples/Engine/SimpleDocument.cs b/QuestPDF.Examples/Engine/SimpleDocument.cs index 5b182cf..2cf1153 100644 --- a/QuestPDF.Examples/Engine/SimpleDocument.cs +++ b/QuestPDF.Examples/Engine/SimpleDocument.cs @@ -33,7 +33,7 @@ namespace QuestPDF.Examples.Engine container.Page(page => { page.Size(new PageSize(Size.Width, Size.Height)); - page.Content().Container().Element(Container as Container); + page.Content().Container().Background(Colors.White).Element(Container as Container); }); } } diff --git a/QuestPDF/Drawing/ImageCanvas.cs b/QuestPDF/Drawing/ImageCanvas.cs index 0ae683f..64037bf 100644 --- a/QuestPDF/Drawing/ImageCanvas.cs +++ b/QuestPDF/Drawing/ImageCanvas.cs @@ -31,7 +31,6 @@ namespace QuestPDF.Drawing public override void BeginPage(Size size) { var scalingFactor = Metadata.RasterDpi / (float) PageSizes.PointsPerInch; - var imageInfo = new SKImageInfo((int) (size.Width * scalingFactor), (int) (size.Height * scalingFactor)); Surface = SKSurface.Create(imageInfo); diff --git a/QuestPDF/Elements/Rotate.cs b/QuestPDF/Elements/Rotate.cs index dadf526..eeae4a9 100644 --- a/QuestPDF/Elements/Rotate.cs +++ b/QuestPDF/Elements/Rotate.cs @@ -1,36 +1,10 @@ -using System; -using System.Linq; -using QuestPDF.Drawing.SpacePlan; -using QuestPDF.Infrastructure; +using QuestPDF.Infrastructure; namespace QuestPDF.Elements { internal class Rotate : ContainerElement { - public int TurnCount { get; set; } - public int NormalizedTurnCount => (TurnCount % 4 + 4) % 4; - - internal override ISpacePlan Measure(Size availableSpace) - { - if (NormalizedTurnCount == 0 || NormalizedTurnCount == 2) - return base.Measure(availableSpace); - - availableSpace = new Size(availableSpace.Height, availableSpace.Width); - var childSpace = base.Measure(availableSpace) as Size; - - if (childSpace == null) - return new Wrap(); - - var targetSpace = new Size(childSpace.Height, childSpace.Width); - - if (childSpace is FullRender) - return new FullRender(targetSpace); - - if (childSpace is PartialRender) - return new PartialRender(targetSpace); - - throw new ArgumentException(); - } + public float Angle { get; set; } = 0; internal override void Draw(Size availableSpace) { @@ -38,20 +12,10 @@ namespace QuestPDF.Elements 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.RotateRadians(NormalizedTurnCount * (float) Math.PI / 2f); - - if (NormalizedTurnCount == 1 || NormalizedTurnCount == 3) - availableSpace = new Size(availableSpace.Height, availableSpace.Width); + skiaCanvas.RotateDegrees(Angle); Child?.Draw(availableSpace); skiaCanvas.SetMatrix(currentMatrix); } diff --git a/QuestPDF/Elements/SimpleRotate.cs b/QuestPDF/Elements/SimpleRotate.cs new file mode 100644 index 0000000..9926138 --- /dev/null +++ b/QuestPDF/Elements/SimpleRotate.cs @@ -0,0 +1,59 @@ +using System; +using System.Linq; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements +{ + internal class SimpleRotate : ContainerElement + { + public int TurnCount { get; set; } + public int NormalizedTurnCount => (TurnCount % 4 + 4) % 4; + + internal override ISpacePlan Measure(Size availableSpace) + { + if (NormalizedTurnCount == 0 || NormalizedTurnCount == 2) + return base.Measure(availableSpace); + + availableSpace = new Size(availableSpace.Height, availableSpace.Width); + var childSpace = base.Measure(availableSpace) as Size; + + if (childSpace == null) + return new Wrap(); + + var targetSpace = new Size(childSpace.Height, childSpace.Width); + + if (childSpace is FullRender) + return new FullRender(targetSpace); + + if (childSpace is PartialRender) + return new PartialRender(targetSpace); + + throw new ArgumentException(); + } + + internal override void Draw(Size availableSpace) + { + var skiaCanvas = (Canvas as Drawing.SkiaCanvasBase)?.Canvas; + + 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); + + if (NormalizedTurnCount == 1 || NormalizedTurnCount == 3) + availableSpace = new Size(availableSpace.Height, availableSpace.Width); + + Child?.Draw(availableSpace); + skiaCanvas.SetMatrix(currentMatrix); + } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/Unconstrained.cs b/QuestPDF/Elements/Unconstrained.cs new file mode 100644 index 0000000..eb9c43b --- /dev/null +++ b/QuestPDF/Elements/Unconstrained.cs @@ -0,0 +1,27 @@ +using System; +using QuestPDF.Drawing.SpacePlan; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements +{ + internal class Unconstrained : ContainerElement + { + internal override ISpacePlan Measure(Size availableSpace) + { + var childSize = Child?.Measure(Size.Max) ?? new FullRender(Size.Zero); + + if (childSize is PartialRender) + return new PartialRender(Size.Zero); + + if (childSize is FullRender) + return new FullRender(Size.Zero); + + return childSize; + } + + internal override void Draw(Size availableSpace) + { + Child?.Draw(Size.Max); + } + } +} \ No newline at end of file diff --git a/QuestPDF/Fluent/ElementExtensions.cs b/QuestPDF/Fluent/ElementExtensions.cs index 488ed66..df4e006 100644 --- a/QuestPDF/Fluent/ElementExtensions.cs +++ b/QuestPDF/Fluent/ElementExtensions.cs @@ -162,5 +162,10 @@ namespace QuestPDF.Fluent { return element.Element(new Box()); } + + public static IContainer Unconstrained(this IContainer element) + { + return element.Element(new Unconstrained()); + } } } diff --git a/QuestPDF/Fluent/RotateExtensions.cs b/QuestPDF/Fluent/RotateExtensions.cs index eff3b2d..cd68cac 100644 --- a/QuestPDF/Fluent/RotateExtensions.cs +++ b/QuestPDF/Fluent/RotateExtensions.cs @@ -6,9 +6,9 @@ namespace QuestPDF.Fluent { public static class RotateExtensions { - private static IContainer Rotate(this IContainer element, Action handler) + private static IContainer SimpleRotate(this IContainer element, Action handler) { - var scale = element as Rotate ?? new Rotate(); + var scale = element as SimpleRotate ?? new SimpleRotate(); handler(scale); return element.Element(scale); @@ -16,12 +16,21 @@ namespace QuestPDF.Fluent public static IContainer RotateLeft(this IContainer element) { - return element.Rotate(x => x.TurnCount--); + return element.SimpleRotate(x => x.TurnCount--); } public static IContainer RotateRight(this IContainer element) { - return element.Rotate(x => x.TurnCount++); + return element.SimpleRotate(x => x.TurnCount++); + } + + /// In degrees + public static IContainer Rotate(this IContainer element, float angle) + { + return element.Element(new Rotate + { + Angle = angle + }); } } } \ No newline at end of file diff --git a/QuestPDF/Fluent/TranslateExtensions.cs b/QuestPDF/Fluent/TranslateExtensions.cs index 975a478..401eade 100644 --- a/QuestPDF/Fluent/TranslateExtensions.cs +++ b/QuestPDF/Fluent/TranslateExtensions.cs @@ -13,12 +13,7 @@ namespace QuestPDF.Fluent return element.Element(translate); } - - public static IContainer Translate(this IContainer element, float value) - { - return element.TranslateX(value).TranslateY(value); - } - + public static IContainer TranslateX(this IContainer element, float value) { return element.Translate(x => x.TranslateX = value);