diff --git a/source/X39.Solutions.PdfTemplate/DocumentOptions.cs b/source/X39.Solutions.PdfTemplate/DocumentOptions.cs index 06ef29a..03f15a7 100644 --- a/source/X39.Solutions.PdfTemplate/DocumentOptions.cs +++ b/source/X39.Solutions.PdfTemplate/DocumentOptions.cs @@ -1,3 +1,5 @@ +using X39.Solutions.PdfTemplate.Data; + namespace X39.Solutions.PdfTemplate; /// @@ -53,4 +55,14 @@ public float DotsPerMillimeter /// The product that is converting this document to PDF. /// public string Producer { get; set; } = ""; + + /// + /// The margin of the document. + /// + /// + /// Margin is removed from the page size, not added to it. + /// This implies that a margin of 100pt... or 10pt... will result in the same page size, + /// but the content will be moved by 100pt... or 10pt... respectively. + /// + public Thickness Margin { get; init; } = new(0, 0, 0, 0); } \ No newline at end of file diff --git a/source/X39.Solutions.PdfTemplate/Generator.cs b/source/X39.Solutions.PdfTemplate/Generator.cs index a625b53..7c9486a 100644 --- a/source/X39.Solutions.PdfTemplate/Generator.cs +++ b/source/X39.Solutions.PdfTemplate/Generator.cs @@ -165,18 +165,20 @@ public async Task> GenerateBitmapsAsync( { SKCanvas? canvas = null; await GenerateAsync( - () => - { - var bitmap = new SKBitmap((int) Math.Ceiling(pageSize.Width), (int) Math.Ceiling(pageSize.Height)); - bitmaps.Add(bitmap); - canvas = new SKCanvas(bitmap); - canvas.Clear(SKColors.White); - return canvas; - }, - reader, - cultureInfo, - options, - cancellationToken) + () => + { + var bitmap = new SKBitmap( + (int) Math.Ceiling(pageSize.Width), + (int) Math.Ceiling(pageSize.Height)); + bitmaps.Add(bitmap); + canvas = new SKCanvas(bitmap); + canvas.Clear(SKColors.White); + return canvas; + }, + reader, + cultureInfo, + options, + cancellationToken) .ConfigureAwait(false); canvas?.Dispose(); return bitmaps.AsReadOnly(); @@ -206,6 +208,16 @@ private async Task GenerateAsync( var pageSize = new Size( options.DotsPerMillimeter * options.PageWidthInMillimeters, options.DotsPerMillimeter * options.PageHeightInMillimeters); + var marginLeft = options.Margin.Left.ToPixels(pageSize.Width, options.DotsPerInch); + var marginTop = options.Margin.Top.ToPixels(pageSize.Height, options.DotsPerInch); + pageSize = new Size( + pageSize.Width + - marginLeft + - options.Margin.Right.ToPixels(pageSize.Width, options.DotsPerInch), + pageSize.Height + - marginTop + - options.Margin.Bottom.ToPixels(pageSize.Height, options.DotsPerInch) + ); #region Measure @@ -234,7 +246,7 @@ private async Task GenerateAsync( var footerPageSize = pageSize with {Height = pageSize.Height * 0.25F}; foreach (var control in template.FooterControls) { - var size = control.Arrange(options.DotsPerInch,pageSize, footerPageSize, footerPageSize, cultureInfo); + var size = control.Arrange(options.DotsPerInch, pageSize, footerPageSize, footerPageSize, cultureInfo); footerSizes.Add(size); } @@ -247,7 +259,7 @@ private async Task GenerateAsync( var bodyPageSize = pageSize with {Height = pageSize.Height - headerPageSize.Height - footerPageSize.Height}; foreach (var control in template.BodyControls) { - var size = control.Arrange(options.DotsPerInch,pageSize, bodyPageSize, bodyPageSize, cultureInfo); + var size = control.Arrange(options.DotsPerInch, pageSize, bodyPageSize, bodyPageSize, cultureInfo); bodySizes.Add(size); } @@ -294,6 +306,8 @@ private async Task GenerateAsync( for (var i = 0; i < pageCount; i++) { using var canvas = nextCanvas(); + canvas.Save(); + canvas.Translate(marginLeft, marginTop); canvas.Save(); canvas.ClipRect( @@ -316,6 +330,8 @@ private async Task GenerateAsync( footerCanvasAbstraction.Render(canvas); canvas.Restore(); currentHeight += bodyPageSize.Height; + + canvas.Restore(); } #endregion