From 6d1cd81a1d804fc37cddc8796a206d8934385663 Mon Sep 17 00:00:00 2001 From: MarcinZiabek Date: Sun, 7 May 2023 02:28:07 +0200 Subject: [PATCH] Introduced DocumentSettings concept --- Source/QuestPDF/Drawing/DocumentGenerator.cs | 11 ++--- Source/QuestPDF/Drawing/ImageCanvas.cs | 8 ++-- Source/QuestPDF/Drawing/PdfCanvas.cs | 17 ++++---- Source/QuestPDF/Drawing/XpsCanvas.cs | 9 +++-- Source/QuestPDF/Fluent/MinimalApi.cs | 8 ++++ .../DocumentMetadata.cs | 24 +++++++---- .../Infrastructure/DocumentSettings.cs | 31 ++++++++++++++ Source/QuestPDF/Infrastructure/IDocument.cs | 7 ++++ .../QuestPDF/Infrastructure/ImageQuality.cs | 40 +++++++++++++++++++ .../QuestPDF/Previewer/ExceptionDocument.cs | 5 +++ 10 files changed, 131 insertions(+), 29 deletions(-) rename Source/QuestPDF/{Drawing => Infrastructure}/DocumentMetadata.cs (69%) create mode 100644 Source/QuestPDF/Infrastructure/DocumentSettings.cs create mode 100644 Source/QuestPDF/Infrastructure/ImageQuality.cs diff --git a/Source/QuestPDF/Drawing/DocumentGenerator.cs b/Source/QuestPDF/Drawing/DocumentGenerator.cs index f792cd7..8d031d6 100644 --- a/Source/QuestPDF/Drawing/DocumentGenerator.cs +++ b/Source/QuestPDF/Drawing/DocumentGenerator.cs @@ -21,7 +21,8 @@ namespace QuestPDF.Drawing CheckIfStreamIsCompatible(stream); var metadata = document.GetMetadata(); - var canvas = new PdfCanvas(stream, metadata); + var settings = document.GetSettings(); + var canvas = new PdfCanvas(stream, metadata, settings); RenderDocument(canvas, document); } @@ -30,8 +31,8 @@ namespace QuestPDF.Drawing ValidateLicense(); CheckIfStreamIsCompatible(stream); - var metadata = document.GetMetadata(); - var canvas = new XpsCanvas(stream, metadata); + var settings = document.GetSettings(); + var canvas = new XpsCanvas(stream, settings); RenderDocument(canvas, document); } @@ -48,8 +49,8 @@ namespace QuestPDF.Drawing { ValidateLicense(); - var metadata = document.GetMetadata(); - var canvas = new ImageCanvas(metadata); + var settings = document.GetSettings(); + var canvas = new ImageCanvas(settings); RenderDocument(canvas, document); return canvas.Images; diff --git a/Source/QuestPDF/Drawing/ImageCanvas.cs b/Source/QuestPDF/Drawing/ImageCanvas.cs index 64037bf..1fa6984 100644 --- a/Source/QuestPDF/Drawing/ImageCanvas.cs +++ b/Source/QuestPDF/Drawing/ImageCanvas.cs @@ -7,14 +7,14 @@ namespace QuestPDF.Drawing { internal class ImageCanvas : SkiaCanvasBase { - private DocumentMetadata Metadata { get; } + private DocumentSettings Settings { get; } private SKSurface Surface { get; set; } internal ICollection Images { get; } = new List(); - public ImageCanvas(DocumentMetadata metadata) + public ImageCanvas(DocumentSettings settings) { - Metadata = metadata; + Settings = settings; } public override void BeginDocument() @@ -30,7 +30,7 @@ namespace QuestPDF.Drawing public override void BeginPage(Size size) { - var scalingFactor = Metadata.RasterDpi / (float) PageSizes.PointsPerInch; + var scalingFactor = Settings.RasterDpi / (float) PageSizes.PointsPerInch; var imageInfo = new SKImageInfo((int) (size.Width * scalingFactor), (int) (size.Height * scalingFactor)); Surface = SKSurface.Create(imageInfo); diff --git a/Source/QuestPDF/Drawing/PdfCanvas.cs b/Source/QuestPDF/Drawing/PdfCanvas.cs index cdc6a2d..380a7c5 100644 --- a/Source/QuestPDF/Drawing/PdfCanvas.cs +++ b/Source/QuestPDF/Drawing/PdfCanvas.cs @@ -2,23 +2,24 @@ using System.IO; using QuestPDF.Drawing.Exceptions; using QuestPDF.Helpers; +using QuestPDF.Infrastructure; using SkiaSharp; namespace QuestPDF.Drawing { internal class PdfCanvas : SkiaDocumentCanvasBase { - public PdfCanvas(Stream stream, DocumentMetadata documentMetadata) - : base(CreatePdf(stream, documentMetadata)) + public PdfCanvas(Stream stream, DocumentMetadata documentMetadata, DocumentSettings documentSettings) + : base(CreatePdf(stream, documentMetadata, documentSettings)) { } - private static SKDocument CreatePdf(Stream stream, DocumentMetadata documentMetadata) + private static SKDocument CreatePdf(Stream stream, DocumentMetadata documentMetadata, DocumentSettings documentSettings) { try { - return SKDocument.CreatePdf(stream, MapMetadata(documentMetadata)); + return SKDocument.CreatePdf(stream, MapMetadata(documentMetadata, documentSettings)); } catch (TypeInitializationException exception) { @@ -26,7 +27,7 @@ namespace QuestPDF.Drawing } } - private static SKDocumentPdfMetadata MapMetadata(DocumentMetadata metadata) + private static SKDocumentPdfMetadata MapMetadata(DocumentMetadata metadata, DocumentSettings documentSettings) { return new SKDocumentPdfMetadata { @@ -40,9 +41,9 @@ namespace QuestPDF.Drawing Creation = metadata.CreationDate, Modified = metadata.ModifiedDate, - RasterDpi = metadata.RasterDpi, - EncodingQuality = metadata.ImageQuality, - PdfA = metadata.PdfA + RasterDpi = documentSettings.RasterDpi, + EncodingQuality = documentSettings.ImageQuality, + PdfA = documentSettings.PdfA }; } } diff --git a/Source/QuestPDF/Drawing/XpsCanvas.cs b/Source/QuestPDF/Drawing/XpsCanvas.cs index 2d08f48..afbe3f3 100644 --- a/Source/QuestPDF/Drawing/XpsCanvas.cs +++ b/Source/QuestPDF/Drawing/XpsCanvas.cs @@ -2,23 +2,24 @@ using System.IO; using QuestPDF.Drawing.Exceptions; using QuestPDF.Helpers; +using QuestPDF.Infrastructure; using SkiaSharp; namespace QuestPDF.Drawing { internal class XpsCanvas : SkiaDocumentCanvasBase { - public XpsCanvas(Stream stream, DocumentMetadata documentMetadata) - : base(CreateXps(stream, documentMetadata)) + public XpsCanvas(Stream stream, DocumentSettings documentSettings) + : base(CreateXps(stream, documentSettings)) { } - private static SKDocument CreateXps(Stream stream, DocumentMetadata documentMetadata) + private static SKDocument CreateXps(Stream stream, DocumentSettings documentSettings) { try { - return SKDocument.CreateXps(stream, documentMetadata.RasterDpi); + return SKDocument.CreateXps(stream, documentSettings.RasterDpi); } catch (TypeInitializationException exception) { diff --git a/Source/QuestPDF/Fluent/MinimalApi.cs b/Source/QuestPDF/Fluent/MinimalApi.cs index a37110d..05e0e57 100644 --- a/Source/QuestPDF/Fluent/MinimalApi.cs +++ b/Source/QuestPDF/Fluent/MinimalApi.cs @@ -8,6 +8,7 @@ namespace QuestPDF.Fluent { private Action ContentSource { get; } private DocumentMetadata Metadata { get; set; } = DocumentMetadata.Default; + private DocumentSettings Settings { get; set; } = DocumentSettings.Default; private Document(Action contentSource) { @@ -25,9 +26,16 @@ namespace QuestPDF.Fluent return this; } + public Document WithSettings(DocumentSettings settings) + { + Settings = settings ?? Settings; + return this; + } + #region IDocument public DocumentMetadata GetMetadata() => Metadata; + public DocumentSettings GetSettings() => Settings; public void Compose(IDocumentContainer container) => ContentSource(container); #endregion diff --git a/Source/QuestPDF/Drawing/DocumentMetadata.cs b/Source/QuestPDF/Infrastructure/DocumentMetadata.cs similarity index 69% rename from Source/QuestPDF/Drawing/DocumentMetadata.cs rename to Source/QuestPDF/Infrastructure/DocumentMetadata.cs index 43420f6..a7c56f6 100644 --- a/Source/QuestPDF/Drawing/DocumentMetadata.cs +++ b/Source/QuestPDF/Infrastructure/DocumentMetadata.cs @@ -1,14 +1,9 @@ using System; -using QuestPDF.Infrastructure; -namespace QuestPDF.Drawing +namespace QuestPDF.Infrastructure { public class DocumentMetadata { - public int ImageQuality { get; set; } = 101; - public int RasterDpi { get; set; } = 72; - public bool PdfA { get; set; } - public string? Title { get; set; } public string? Author { get; set; } public string? Subject { get; set; } @@ -19,6 +14,10 @@ namespace QuestPDF.Drawing public DateTime CreationDate { get; set; } = DateTime.Now; public DateTime ModifiedDate { get; set; } = DateTime.Now; + public static DocumentMetadata Default => new DocumentMetadata(); + + #region Deprecated properties + [Obsolete("This API has been moved since version 2022.9. Please use the QuestPDF.Settings.DocumentLayoutExceptionThreshold static property.")] public int DocumentLayoutExceptionThreshold { @@ -39,7 +38,16 @@ namespace QuestPDF.Drawing get => Settings.EnableDebugging; set => Settings.EnableDebugging = value; } - - public static DocumentMetadata Default => new DocumentMetadata(); + + [Obsolete("This API has been moved since version 2023.5. Please use the QuestPDF.Infrastructure.DocumentSettings API.")] + public int? ImageQuality { get; set; } + + [Obsolete("This API has been moved since version 2023.5. Please use the QuestPDF.Infrastructure.DocumentSettings API.")] + public int? RasterDpi { get; set; } + + [Obsolete("This API has been moved since version 2023.5. Please use the QuestPDF.Infrastructure.DocumentSettings API.")] + public bool? PdfA { get; set; } + + #endregion } } \ No newline at end of file diff --git a/Source/QuestPDF/Infrastructure/DocumentSettings.cs b/Source/QuestPDF/Infrastructure/DocumentSettings.cs new file mode 100644 index 0000000..adf7455 --- /dev/null +++ b/Source/QuestPDF/Infrastructure/DocumentSettings.cs @@ -0,0 +1,31 @@ +using ImageQualityEnum = QuestPDF.Infrastructure.ImageQuality; + +namespace QuestPDF.Infrastructure +{ + public class DocumentSettings + { + /// + /// Gets or sets a value indicating whether or not make the document PDF/A-2b conformant. + /// If true, include XMP metadata, a document UUID, and sRGB output intent information. + /// This adds length to the document and makes it non-reproducable, but are necessary features for PDF/A-2b conformance. + /// + public bool PdfA { get; set; } = false; + + /// + /// Encoding quality controls the trade-off between size and quality. + /// The value 101 corresponds to lossless encoding. + /// If this value is set to a value between 1 and 100, and the image is opaque, it will be encoded using the JPEG format with that quality setting. + /// The default value is 90 (very high quality). + /// + public int ImageQuality { get; set; } = (int)ImageQualityEnum.VeryHigh; + + /// + /// The DPI (pixels-per-inch) at which images and features without native PDF support will be rasterized. + /// A larger DPI would create a PDF that reflects the original intent with better fidelity, but it can make for larger PDF files too, which would use more memory while rendering, and it would be slower to be processed or sent online or to printer. + /// When generating images, this parameter also controls the resolution of the generated content. + /// + public int RasterDpi { get; set; } = 72; + + public static DocumentSettings Default => new DocumentSettings(); + } +} \ No newline at end of file diff --git a/Source/QuestPDF/Infrastructure/IDocument.cs b/Source/QuestPDF/Infrastructure/IDocument.cs index 564b659..79dab3f 100644 --- a/Source/QuestPDF/Infrastructure/IDocument.cs +++ b/Source/QuestPDF/Infrastructure/IDocument.cs @@ -4,7 +4,14 @@ namespace QuestPDF.Infrastructure { public interface IDocument { +#if NETCOREAPP2_1_OR_GREATER + public DocumentMetadata GetMetadata() => DocumentMetadata.Default; + public DocumentSettings GetSettings() => DocumentSettings.Default; +#else DocumentMetadata GetMetadata(); + DocumentSettings GetSettings(); +#endif + void Compose(IDocumentContainer container); } } \ No newline at end of file diff --git a/Source/QuestPDF/Infrastructure/ImageQuality.cs b/Source/QuestPDF/Infrastructure/ImageQuality.cs new file mode 100644 index 0000000..07772e4 --- /dev/null +++ b/Source/QuestPDF/Infrastructure/ImageQuality.cs @@ -0,0 +1,40 @@ +namespace QuestPDF.Infrastructure +{ + public enum ImageQuality + { + /// + /// PNG format with alpha support + /// + Lossless = 101, + + /// + /// JPEG format with compression set to 100 out of 100 + /// + Max = 100, + + /// + /// JPEG format with compression set to 90 out of 100 + /// + VeryHigh = 90, + + /// + /// JPEG format with compression set to 80 out of 100 + /// + High = 80, + + /// + /// JPEG format with compression set to 60 out of 100 + /// + Medium = 60, + + /// + /// JPEG format with compression set to 40 out of 100 + /// + Low = 40, + + /// + /// JPEG format with compression set to 20 out of 100 + /// + VeryLow = 20 + } +} \ No newline at end of file diff --git a/Source/QuestPDF/Previewer/ExceptionDocument.cs b/Source/QuestPDF/Previewer/ExceptionDocument.cs index 8e2793e..7a0a9b6 100644 --- a/Source/QuestPDF/Previewer/ExceptionDocument.cs +++ b/Source/QuestPDF/Previewer/ExceptionDocument.cs @@ -20,6 +20,11 @@ namespace QuestPDF.Previewer { return DocumentMetadata.Default; } + + public DocumentSettings GetSettings() + { + return DocumentSettings.Default; + } public void Compose(IDocumentContainer document) {