diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b.slnx b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b.slnx
new file mode 100644
index 00000000..8ce4d7b9
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Convert-PDF-to-PDF-A-2b.csproj b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Convert-PDF-to-PDF-A-2b.csproj
new file mode 100644
index 00000000..e6c6669e
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Convert-PDF-to-PDF-A-2b.csproj
@@ -0,0 +1,21 @@
+
+
+
+ Exe
+ net8.0
+ Convert_PDF_to_PDF_A_2b
+ enable
+ enable
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Data/Input.pdf b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Data/Input.pdf
new file mode 100644
index 00000000..68aff2e3
Binary files /dev/null and b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Data/Input.pdf differ
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Output/.gitkeep b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Output/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Program.cs b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Program.cs
new file mode 100644
index 00000000..d65bed56
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-2b/.NET/Convert-PDF-to-PDF-A-2b/Program.cs
@@ -0,0 +1,47 @@
+using SkiaSharp;
+using Syncfusion.Pdf;
+using Syncfusion.Pdf.Graphics;
+using Syncfusion.Pdf.Parsing;
+
+// Load the PDF document
+using (PdfLoadedDocument loadedDocument = new PdfLoadedDocument(Path.GetFullPath(@"Data/Input.pdf")))
+{
+ // Handle font substitution during PDF/A conversion
+ loadedDocument.SubstituteFont += LoadedDocument_SubstituteFont;
+ // Convert the document to PDF/A-2B format
+ loadedDocument.ConvertToPDFA(PdfConformanceLevel.Pdf_A2B);
+ // Save the PDF document
+ loadedDocument.Save(Path.GetFullPath(@"Output/Output.pdf"));
+}
+
+// Event handler to substitute missing fonts during conversion
+void LoadedDocument_SubstituteFont(object sender, PdfFontEventArgs args)
+{
+ // Extract the font name (ignoring style suffixes)
+ string fontName = args.FontName.Split(',')[0];
+ // Determine the font style
+ PdfFontStyle fontStyle = args.FontStyle;
+ SKFontStyle skFontStyle = SKFontStyle.Normal;
+ // Map PDF font styles to SkiaSharp font styles
+ if (fontStyle == PdfFontStyle.Bold)
+ skFontStyle = SKFontStyle.Bold;
+ else if (fontStyle == PdfFontStyle.Italic)
+ skFontStyle = SKFontStyle.Italic;
+ else if (fontStyle == (PdfFontStyle.Bold | PdfFontStyle.Italic))
+ skFontStyle = SKFontStyle.BoldItalic;
+ // Load the typeface using SkiaSharp
+ SKTypeface typeface = SKTypeface.FromFamilyName(fontName, skFontStyle);
+ SKStreamAsset typeFaceStream = typeface.OpenStream();
+
+ // Create a memory stream from the font data
+ MemoryStream memoryStream = null;
+ if (typeFaceStream != null && typeFaceStream.Length > 0)
+ {
+ byte[] fontData = new byte[typeFaceStream.Length];
+ typeFaceStream.Read(fontData, fontData.Length);
+ typeFaceStream.Dispose();
+ memoryStream = new MemoryStream(fontData);
+ }
+ // Assign the font stream to the event arguments
+ args.FontStream = memoryStream;
+}
\ No newline at end of file
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b.slnx b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b.slnx
new file mode 100644
index 00000000..1627037d
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Convert-PDF-to-PDF-A-3b.csproj b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Convert-PDF-to-PDF-A-3b.csproj
new file mode 100644
index 00000000..b691847a
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Convert-PDF-to-PDF-A-3b.csproj
@@ -0,0 +1,24 @@
+
+
+
+ Exe
+ net8.0
+ Convert_PDF_to_PDF_A_3b
+ enable
+ enable
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+
+
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Data/Input.pdf b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Data/Input.pdf
new file mode 100644
index 00000000..68aff2e3
Binary files /dev/null and b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Data/Input.pdf differ
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Data/ZUGFeRD_invoice.xml b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Data/ZUGFeRD_invoice.xml
new file mode 100644
index 00000000..5f2cfbe7
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Data/ZUGFeRD_invoice.xml
@@ -0,0 +1,45 @@
+
+
+
+ CA-1098
+ AWC Logo Cap
+ 8.99
+
+
+
+
+ LJ-0192-M
+ Long-Sleeve Logo Jersey, M
+ 49.99
+
+
+
+
+ SO-B909-M
+ Mountain Bike Socks, M
+ 9.50
+
+
+
+
+ LJ-0192-M
+ Long-Sleeve Logo Jersey, M
+ 49.99
+
+
+
+
+ FK-5136
+ ML Fork
+ 175.49
+
+
+
+
+ HL-U509
+ Sport-100 Helmet, Black
+ 34.99
+
+
+
+
\ No newline at end of file
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Output/.gitkeep b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Output/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Program.cs b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Program.cs
new file mode 100644
index 00000000..63c307a0
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-3b/.NET/Convert-PDF-to-PDF-A-3b/Program.cs
@@ -0,0 +1,64 @@
+using SkiaSharp;
+using Syncfusion.Pdf;
+using Syncfusion.Pdf.Graphics;
+using Syncfusion.Pdf.Interactive;
+using Syncfusion.Pdf.Parsing;
+
+// Load the PDF document
+using (PdfLoadedDocument loadedDocument = new PdfLoadedDocument(Path.GetFullPath(@"Data/Input.pdf")))
+{
+ // Handle font substitution during PDF/A conversion
+ loadedDocument.SubstituteFont += LoadedDocument_SubstituteFont;
+ //Create an attachment
+ PdfAttachment attachment = new PdfAttachment(Path.GetFullPath("Data/ZUGFeRD_invoice.xml"))
+ {
+ //Add the attachment relationship
+ Relationship = PdfAttachmentRelationship.Alternative,
+ //Set modification date
+ ModificationDate = DateTime.Now,
+ //Set description and mime type
+ Description = "ZUGFeRD_invoice",
+ MimeType = "text/xml"
+ };
+ // Create the attachments section if it does not exist
+ if (loadedDocument.Attachments == null)
+ loadedDocument.CreateAttachment();
+ //Add the attachment to the existing document.
+ loadedDocument.Attachments.Add(attachment);
+ // Convert the document to PDF/A-3B format
+ loadedDocument.ConvertToPDFA(PdfConformanceLevel.Pdf_A3B);
+ // Save the PDF document
+ loadedDocument.Save(Path.GetFullPath(@"Output/Output.pdf"));
+}
+
+// Event handler to substitute missing fonts during conversion
+void LoadedDocument_SubstituteFont(object sender, PdfFontEventArgs args)
+{
+ // Extract the font name (ignoring style suffixes)
+ string fontName = args.FontName.Split(',')[0];
+ // Determine the font style
+ PdfFontStyle fontStyle = args.FontStyle;
+ SKFontStyle skFontStyle = SKFontStyle.Normal;
+ // Map PDF font styles to SkiaSharp font styles
+ if (fontStyle == PdfFontStyle.Bold)
+ skFontStyle = SKFontStyle.Bold;
+ else if (fontStyle == PdfFontStyle.Italic)
+ skFontStyle = SKFontStyle.Italic;
+ else if (fontStyle == (PdfFontStyle.Bold | PdfFontStyle.Italic))
+ skFontStyle = SKFontStyle.BoldItalic;
+ // Load the typeface using SkiaSharp
+ SKTypeface typeface = SKTypeface.FromFamilyName(fontName, skFontStyle);
+ SKStreamAsset typeFaceStream = typeface.OpenStream();
+
+ // Create a memory stream from the font data
+ MemoryStream memoryStream = null;
+ if (typeFaceStream != null && typeFaceStream.Length > 0)
+ {
+ byte[] fontData = new byte[typeFaceStream.Length];
+ typeFaceStream.Read(fontData, fontData.Length);
+ typeFaceStream.Dispose();
+ memoryStream = new MemoryStream(fontData);
+ }
+ // Assign the font stream to the event arguments
+ args.FontStream = memoryStream;
+}
\ No newline at end of file
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4.slnx b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4.slnx
new file mode 100644
index 00000000..389214d0
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4.slnx
@@ -0,0 +1,3 @@
+
+
+
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Convert-PDF-to-PDF-A-4.csproj b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Convert-PDF-to-PDF-A-4.csproj
new file mode 100644
index 00000000..b21472d5
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Convert-PDF-to-PDF-A-4.csproj
@@ -0,0 +1,21 @@
+
+
+
+ Exe
+ net8.0
+ Convert_PDF_to_PDF_A_4
+ enable
+ enable
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Data/Input.pdf b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Data/Input.pdf
new file mode 100644
index 00000000..68aff2e3
Binary files /dev/null and b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Data/Input.pdf differ
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Output/.gitkeep b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Output/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Program.cs b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Program.cs
new file mode 100644
index 00000000..25a1a5c0
--- /dev/null
+++ b/PDF Conformance/Convert-PDF-to-PDF-A-4/.NET/Convert-PDF-to-PDF-A-4/Program.cs
@@ -0,0 +1,47 @@
+using SkiaSharp;
+using Syncfusion.Pdf;
+using Syncfusion.Pdf.Graphics;
+using Syncfusion.Pdf.Parsing;
+
+// Load the PDF document
+using (PdfLoadedDocument loadedDocument = new PdfLoadedDocument(Path.GetFullPath(@"Data/Input.pdf")))
+{
+ // Handle font substitution during PDF/A conversion
+ loadedDocument.SubstituteFont += LoadedDocument_SubstituteFont;
+ // Convert the document to PDF/A-4 format
+ loadedDocument.ConvertToPDFA(PdfConformanceLevel.Pdf_A4);
+ // Save the PDF document
+ loadedDocument.Save(Path.GetFullPath(@"Output/Output.pdf"));
+}
+
+// Event handler to substitute missing fonts during conversion
+void LoadedDocument_SubstituteFont(object sender, PdfFontEventArgs args)
+{
+ // Extract the font name (ignoring style suffixes)
+ string fontName = args.FontName.Split(',')[0];
+ // Determine the font style
+ PdfFontStyle fontStyle = args.FontStyle;
+ SKFontStyle skFontStyle = SKFontStyle.Normal;
+ // Map PDF font styles to SkiaSharp font styles
+ if (fontStyle == PdfFontStyle.Bold)
+ skFontStyle = SKFontStyle.Bold;
+ else if (fontStyle == PdfFontStyle.Italic)
+ skFontStyle = SKFontStyle.Italic;
+ else if (fontStyle == (PdfFontStyle.Bold | PdfFontStyle.Italic))
+ skFontStyle = SKFontStyle.BoldItalic;
+ // Load the typeface using SkiaSharp
+ SKTypeface typeface = SKTypeface.FromFamilyName(fontName, skFontStyle);
+ SKStreamAsset typeFaceStream = typeface.OpenStream();
+
+ // Create a memory stream from the font data
+ MemoryStream memoryStream = null;
+ if (typeFaceStream != null && typeFaceStream.Length > 0)
+ {
+ byte[] fontData = new byte[typeFaceStream.Length];
+ typeFaceStream.Read(fontData, fontData.Length);
+ typeFaceStream.Dispose();
+ memoryStream = new MemoryStream(fontData);
+ }
+ // Assign the font stream to the event arguments
+ args.FontStream = memoryStream;
+}
\ No newline at end of file