''
'' This code is part of Document Solutions for PDF .NET demos.
'' Copyright (c) MESCIUS inc. All rights reserved.
''
Imports System.IO
Imports System.Drawing
Imports System.Text
Imports GrapeCity.Documents.Text
Imports GrapeCity.Documents.Common
Imports GrapeCity.Documents.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Pdf.Structure
Imports GrapeCity.Documents.Pdf.MarkedContent
Imports GrapeCity.Documents.Pdf.Graphics
Imports GrapeCity.Documents.Pdf.Annotations
Imports GCTEXT = GrapeCity.Documents.Text
Imports GCDRAW = GrapeCity.Documents.Drawing
'' This sample shows how to create a PDF/A-4f compliant document.
Public Class PdfA4
Function CreatePDF(ByVal stream As Stream) As Integer
Dim doc = New GcPdfDocument()
Dim thedate = New DateTime(1961, 4, 12, 6, 7, 0, DateTimeKind.Utc)
'' PDF/A-4 is based on PDF 2.0:
doc.PdfVersion = "2.0"
'' Mark the document as PDF/A-4f conformant:
doc.Metadata.PdfA = PdfAConformanceLevel.PdfA4f
'' PDF/A-4 requires the "revision" year of the ISO 19005-4:2020 standard itself (not the document's date):
doc.Metadata.PdfRev = "2020"
Dim fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "NotoSans-Regular.ttf"))
Dim gap = 36
'' PDF/A-4 requires all content to be tagged, so create and populate StructElements when rendering:
Dim sePart = New StructElement("Part")
doc.StructTreeRoot.Children.Add(sePart)
Dim tl As TextLayout = Nothing
'' Add 3 pages with sample content tagged according to PDF/A rules:
For pageNo = 1 To 3
Dim page = doc.Pages.Add()
Dim g = page.Graphics
Dim y = 72.0F
If doc.Pages.Count = 1 Then
'' Create paragraph element and add it to the Part element:
Dim seParagraph = New StructElement("P") With {.DefaultPage = page}
sePart.Children.Add(seParagraph)
tl = g.CreateTextLayout()
tl.MarginAll = 72
tl.MaxWidth = page.Size.Width
tl.DefaultFormat.Font = fnt
tl.DefaultFormat.FontBold = True
tl.DefaultFormat.FontSize = 20
tl.Append("PDF/A-4 Document")
'' Draw the TextLayout within tagged content:
g.BeginMarkedContent(New TagMcid("P", 0))
g.DrawTextLayout(tl, PointF.Empty)
g.EndMarkedContent()
y = tl.ContentRectangle.Bottom + gap
seParagraph.ContentItems.Add(New McidContentItemLink(0))
End If
'' Add some sample paragraphs tagged according to PDF/A rules:
For i = 1 To 3
Dim seParagraph = New StructElement("P") With {.DefaultPage = page}
sePart.Children.Add(seParagraph)
Dim sb = New StringBuilder()
sb.Append($"Paragraph {i} on page {pageNo}. ")
sb.Append(Util.LoremIpsum(1, 2, 4, 5, 10))
Dim para = sb.ToString()
tl.Clear()
tl.DefaultFormat.FontSize = 14
tl.DefaultFormat.FontBold = False
tl.MarginTop = y
tl.Append(para)
g.BeginMarkedContent(New TagMcid("P", i))
g.DrawTextLayout(tl, PointF.Empty)
g.EndMarkedContent()
y += tl.ContentHeight + gap
seParagraph.ContentItems.Add(New McidContentItemLink(i))
Next
Next
'' PDF/A-4 allows transparency drawing in the PDF file, add some:
Dim gpage = doc.Pages(0).Graphics
gpage.FillRectangle(New RectangleF(20, 20, 200, 200), Color.FromArgb(40, Color.Red))
'' PDF/A-4 allows using FormXObjects, add one with transparency:
Dim r = New RectangleF(0, 0, 144, 72)
Dim fxo = New FormXObject(doc, r)
Dim gfxo = fxo.Graphics
gfxo.FillRectangle(r, Color.FromArgb(40, Color.Violet))
Dim tf = New TextFormat() With
{
.Font = fnt,
.FontSize = 16,
.ForeColor = Color.FromArgb(100, Color.Black)
}
gfxo.DrawString("FormXObject", tf, r, TextAlignment.Center, ParagraphAlignment.Center)
gfxo.DrawRectangle(r, Color.Blue, 3)
gpage.DrawForm(fxo, New RectangleF(300, 250, r.Width, r.Height), Nothing, ImageAlign.ScaleImage)
'' PDF/A-4f allows embedding arbitrary files, but each one must be associated with a document element:
Dim ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "WordDocs", "ProcurementLetter.docx"))
'' ModificationDate and MimeType should be specified for EmbeddedFile in PDF/A:
ef.ModificationDate = thedate
ef.MimeType = "application/msword"
Dim fs = FileSpecification.FromEmbeddedFile(ef)
fs.UnicodeFile.FileName = fs.File.FileName
fs.Relationship = AFRelationship.Unspecified
doc.EmbeddedFiles.Add("ProcurementLetter.docx", fs)
'' Associate embedded file with the document:
doc.AssociatedFiles.Add(fs)
'' Add a stamp annotation with an attachment of its own.
'' Note: RichMediaAnnotation is only allowed under PDF/A-4e, so a StampAnnotation is used here instead:
Dim sa = New StampAnnotation() With
{
.UserName = "User",
.Font = fnt,
.Rect = New RectangleF(300, 36, 220, 72)
}
'' The Print flag must be set, as required by the PDF/A specification:
sa.Flags = sa.Flags Or AnnotationFlags.Print
'' Use a FormXObject to represent the stamp annotation:
Dim stampFxo = New FormXObject(doc, New RectangleF(PointF.Empty, sa.Rect.Size))
Dim gstampFxo = stampFxo.Graphics
gstampFxo.FillRectangle(stampFxo.Bounds, Color.FromArgb(40, Color.Green))
gstampFxo.DrawString("Stamp", tf, stampFxo.Bounds, TextAlignment.Center, ParagraphAlignment.Center)
gstampFxo.DrawRectangle(stampFxo.Bounds, Color.Green, 3)
sa.AppearanceStreams.Normal.Default = stampFxo
doc.Pages(0).Annotations.Add(sa)
ef = EmbeddedFileStream.FromFile(doc, Path.Combine("Resources", "Images", "minerva.jpg"))
ef.ModificationDate = thedate
ef.MimeType = "image/jpeg"
fs = FileSpecification.FromEmbeddedFile(ef)
fs.UnicodeFile.FileName = fs.File.FileName
fs.Relationship = AFRelationship.Unspecified
doc.EmbeddedFiles.Add("minerva.jpg", fs)
sa.AssociatedFiles.Add(fs)
'' Mark the document as conforming to Tagged PDF conventions (required for PDF/A):
doc.MarkInfo.Marked = True
'' Metadata.CreatorTool and DocumentInfo.Creator should be the same for a PDF/A document:
doc.Metadata.CreatorTool = doc.DocumentInfo.Creator
'' A title should be specified for a PDF/A document:
doc.Metadata.Title = "PDF/A-4 compliant document"
doc.ViewerPreferences.DisplayDocTitle = True
'' PDF/A-4 does not allow a legacy DocumentInfo dictionary, so it must be removed
'' (do this last, since DocumentInfo.Creator was used above):
doc.DocumentInfo = Nothing
doc.Save(stream)
Return doc.Pages.Count
End Function
End Class