Jelajahi Sumber

Add support for choosing PDF/A and PDF/UA conformance levels

Marcin Ziąbek 2 bulan lalu
induk
melakukan
de48b88a11

+ 30 - 1
Source/QuestPDF/Drawing/DocumentCanvases/PdfDocumentCanvas.cs

@@ -51,8 +51,10 @@ namespace QuestPDF.Drawing.DocumentCanvases
                 CreationDate = new SkDateTime(DocumentMetadata.CreationDate),
                 ModificationDate = new SkDateTime(DocumentMetadata.ModifiedDate),
                 
+                PDFA_Conformance = GetPDFAConformanceLevel(DocumentSettings.PDFA_Conformance),
+                PDFUA_Conformance = GetPDFUAConformanceLevel(DocumentSettings.PDFUA_Conformance),
+                
                 RasterDPI = DocumentSettings.ImageRasterDpi,
-                SupportPDFA = DocumentSettings.PdfA,
                 CompressDocument = DocumentSettings.CompressDocument,
                 
                 SemanticNodeRoot = SemanticTag?.Instance ?? IntPtr.Zero
@@ -67,6 +69,33 @@ namespace QuestPDF.Drawing.DocumentCanvases
                 throw new InitializationException("PDF", exception);
             }
         }
+
+        static Skia.PDFA_Conformance GetPDFAConformanceLevel(Infrastructure.PDFA_Conformance conformanceLevel)
+        {
+            return conformanceLevel switch
+            {
+                Infrastructure.PDFA_Conformance.None => Skia.PDFA_Conformance.None,
+                // Infrastructure.PDFA_Conformance.PDFA_1A => Skia.PDFA_Conformance.PDFA_1A,
+                // Infrastructure.PDFA_Conformance.PDFA_1B => Skia.PDFA_Conformance.PDFA_1B,
+                Infrastructure.PDFA_Conformance.PDFA_2A => Skia.PDFA_Conformance.PDFA_2A,
+                Infrastructure.PDFA_Conformance.PDFA_2B => Skia.PDFA_Conformance.PDFA_2B,
+                Infrastructure.PDFA_Conformance.PDFA_2U => Skia.PDFA_Conformance.PDFA_2U,
+                Infrastructure.PDFA_Conformance.PDFA_3A => Skia.PDFA_Conformance.PDFA_3A,
+                Infrastructure.PDFA_Conformance.PDFA_3B => Skia.PDFA_Conformance.PDFA_3B,
+                Infrastructure.PDFA_Conformance.PDFA_3U => Skia.PDFA_Conformance.PDFA_3U,
+                _ => throw new ArgumentOutOfRangeException(nameof(conformanceLevel), conformanceLevel, "Unsupported PDF/A conformance level")
+            };
+        }
+        
+        static Skia.PDFUA_Conformance GetPDFUAConformanceLevel(Infrastructure.PDFUA_Conformance conformanceLevel)
+        {
+            return conformanceLevel switch
+            {
+                Infrastructure.PDFUA_Conformance.None => Skia.PDFUA_Conformance.None,
+                Infrastructure.PDFUA_Conformance.PDFUA_1 => Skia.PDFUA_Conformance.PDFUA_1,
+                _ => throw new ArgumentOutOfRangeException(nameof(conformanceLevel), conformanceLevel, "Unsupported PDF/UA conformance level")
+            };
+        }
         
         #region IDisposable
         

+ 39 - 6
Source/QuestPDF/Infrastructure/DocumentSettings.cs

@@ -1,16 +1,30 @@
-namespace QuestPDF.Infrastructure
+using System;
+
+namespace QuestPDF.Infrastructure
 {
     public sealed class DocumentSettings
     {
         public const int DefaultRasterDpi = 72;
-        
+
+        [Obsolete("Please use the ConformanceLevel property instead.")]
+        public bool PdfA
+        {
+            get => PDFA_Conformance != PDFA_Conformance.None;
+            set => PDFA_Conformance = value ? PDFA_Conformance.PDFA_3B : PDFA_Conformance.None;
+        }
+
         /// <summary>
-        /// Gets or sets a value indicating whether or not make the document PDF/A-3b 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-3b conformance.
+        /// Gets or sets the PDF/A conformance level for the document.
+        /// This property determines the adherence of the generated PDF to specific archival standards.
         /// </summary>
-        public bool PdfA { get; set; } = false;
+        public PDFA_Conformance PDFA_Conformance { get; set; } = PDFA_Conformance.None;
 
+        /// <summary>
+        /// Gets or sets the conformance level for PDF/UA (Universal Accessibility) compliance.
+        /// Warning: this setting makes the document non-reproducable.
+        /// </summary>
+        public PDFUA_Conformance PDFUA_Conformance { get; set; } = PDFUA_Conformance.None;
+        
         /// <summary>
         /// Gets or sets a value indicating whether the generated document should be additionally compressed. May greatly reduce file size with a small increase in generation time.
         /// </summary>
@@ -40,4 +54,23 @@
         
         public static DocumentSettings Default => new DocumentSettings();
     }
+    
+    public enum PDFA_Conformance
+    {
+        None = 0,
+        // PDFA_1A = 1,
+        // PDFA_1B = 2,
+        PDFA_2A = 3,
+        PDFA_2B = 4,
+        PDFA_2U = 5,
+        PDFA_3A = 6,
+        PDFA_3B = 7,
+        PDFA_3U = 8
+    }
+    
+    public enum PDFUA_Conformance
+    {
+        None = 0,
+        PDFUA_1 = 1
+    }
 }

+ 23 - 1
Source/QuestPDF/Skia/SkPdfDocument.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Runtime.InteropServices;
+using System.Xml;
 
 namespace QuestPDF.Skia;
 
@@ -17,13 +18,34 @@ internal struct SkPdfDocumentMetadata
     public SkDateTime CreationDate;
     public SkDateTime ModificationDate;
 
-    [MarshalAs(UnmanagedType.I1)] public bool SupportPDFA;
+    public PDFA_Conformance PDFA_Conformance;
+    public PDFUA_Conformance PDFUA_Conformance;
+    
     [MarshalAs(UnmanagedType.I1)] public bool CompressDocument;
     public float RasterDPI;
 
     public IntPtr SemanticNodeRoot;
 }
 
+internal enum PDFA_Conformance
+{
+    None = 0,
+    PDFA_1A = 1,
+    PDFA_1B = 2,
+    PDFA_2A = 3,
+    PDFA_2B = 4,
+    PDFA_2U = 5,
+    PDFA_3A = 6,
+    PDFA_3B = 7,
+    PDFA_3U = 8
+}
+
+internal enum PDFUA_Conformance
+{
+    None = 0,
+    PDFUA_1 = 1
+}
+
 internal static class SkPdfDocument
 {
     public static SkDocument Create(SkWriteStream stream, SkPdfDocumentMetadata metadata)