diff --git a/QuestPDF.Examples/RelativePaddingExamples.cs b/QuestPDF.Examples/RelativePaddingExamples.cs new file mode 100644 index 0000000..31b434f --- /dev/null +++ b/QuestPDF.Examples/RelativePaddingExamples.cs @@ -0,0 +1,36 @@ +using NUnit.Framework; +using QuestPDF.Examples.Engine; +using QuestPDF.Fluent; +using QuestPDF.Helpers; + +namespace QuestPDF.Examples +{ + public class RelativePaddingExamples + { + [Test] + public void ItemTypes() + { + RenderingTest + .Create() + .ProduceImages() + .PageSize(250, 250) + .ShowResults() + .Render(container => + { + container + .Width(250) + .Height(250) + + .Padding(50) + .Background(Colors.Grey.Lighten2) + + .RelativePaddingLeft(0.1f) + .RelativePaddingTop(0.2f) + .RelativePaddingRight(0.3f) + .RelativePaddingBottom(0.4f) + + .Background(Colors.Grey.Darken2); + }); + } + } +} \ No newline at end of file diff --git a/QuestPDF/Elements/RelativePadding.cs b/QuestPDF/Elements/RelativePadding.cs new file mode 100644 index 0000000..df01113 --- /dev/null +++ b/QuestPDF/Elements/RelativePadding.cs @@ -0,0 +1,65 @@ +using System; +using QuestPDF.Drawing; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Elements +{ + internal class RelativePadding : ContainerElement + { + public float Top { get; set; } + public float Right { get; set; } + public float Bottom { get; set; } + public float Left { get; set; } + + internal override SpacePlan Measure(Size availableSpace) + { + if (Child == null) + return SpacePlan.FullRender(0, 0); + + var internalSpace = InternalSpace(availableSpace); + + if (internalSpace.Width < 0 || internalSpace.Height < 0) + return SpacePlan.Wrap(); + + var measure = base.Measure(internalSpace); + + if (measure.Type == SpacePlanType.Wrap) + return SpacePlan.Wrap(); + + if (measure.Type == SpacePlanType.PartialRender) + return SpacePlan.PartialRender(availableSpace); + + if (measure.Type == SpacePlanType.FullRender) + return SpacePlan.FullRender(availableSpace); + + throw new NotSupportedException(); + } + + internal override void Draw(Size availableSpace) + { + if (Child == null) + return; + + var internalOffset = InternalOffset(availableSpace); + var internalSpace = InternalSpace(availableSpace); + + Canvas.Translate(internalOffset); + base.Draw(internalSpace); + Canvas.Translate(internalOffset.Reverse()); + } + + private Position InternalOffset(Size availableSpace) + { + return new Position( + availableSpace.Width * Left, + availableSpace.Height * Top); + } + + private Size InternalSpace(Size availableSpace) + { + return new Size( + availableSpace.Width * (1f - Left - Right), + availableSpace.Height * (1f - Top - Bottom)); + } + } +} \ No newline at end of file diff --git a/QuestPDF/Fluent/RelativePaddingExtensions.cs b/QuestPDF/Fluent/RelativePaddingExtensions.cs new file mode 100644 index 0000000..15f02c0 --- /dev/null +++ b/QuestPDF/Fluent/RelativePaddingExtensions.cs @@ -0,0 +1,37 @@ +using System; +using QuestPDF.Elements; +using QuestPDF.Infrastructure; + +namespace QuestPDF.Fluent +{ + public static class RelativePaddingExtensions + { + private static IContainer RelativePadding(this IContainer element, Action handler) + { + var relativePadding = element as RelativePadding ?? new RelativePadding(); + handler(relativePadding); + + return element.Element(relativePadding); + } + + public static IContainer RelativePaddingTop(this IContainer element, float value) + { + return element.RelativePadding(x => x.Top += value); + } + + public static IContainer RelativePaddingBottom(this IContainer element, float value) + { + return element.RelativePadding(x => x.Bottom += value); + } + + public static IContainer RelativePaddingLeft(this IContainer element, float value) + { + return element.RelativePadding(x => x.Left += value); + } + + public static IContainer RelativePaddingRight(this IContainer element, float value) + { + return element.RelativePadding(x => x.Right += value); + } + } +} \ No newline at end of file