PdfA.vb
''
'' This code is part of Document Solutions for PDF 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-3u conformant document.
Public Class PdfA
    Sub CreatePDF(ByVal stream As Stream)
        Dim doc = New GcPdfDocument()
        Dim thedate = New DateTime(1961, 4, 12, 6, 7, 0, DateTimeKind.Utc)

        '' Mark the document as PDF/A-3u conformant:
        doc.ConformanceLevel = PdfAConformanceLevel.PdfA3u

        Dim fnt = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arial.ttf"))
        Dim gap = 36

        '' PDF/A-3a requires all content to be tagged so create and populate StructElement 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
            '' add page
            Dim Page = doc.Pages.Add()
            Dim g = Page.Graphics
            Dim y = 72.0F
            If doc.Pages.Count = 1 Then
                '' Create paragraph element:
                Dim seParagraph = New StructElement("P") With {.DefaultPage = Page}
                '' Add it to Part element:
                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-3A Document")

                '' PerformLayout is done automatically in a new TextLayout or after a Clear():
                ''tl.PerformLayout(True)

                '' Draw 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
                '' Create paragraph element:
                Dim seParagraph = New StructElement("P") With {.DefaultPage = Page}
                '' Add it to Part element:
                sePart.Children.Add(seParagraph)

                Dim sb = New StringBuilder()
                sb.Append(String.Format("Paragraph {0} on page {1}: ", i, 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)

                '' Draw TextLayout within tagged content:
                g.BeginMarkedContent(New TagMcid("P", i))
                g.DrawTextLayout(tl, PointF.Empty)
                g.EndMarkedContent()

                y += tl.ContentHeight + gap

                '' Add content item to paragraph StructElement:
                seParagraph.ContentItems.Add(New McidContentItemLink(i))

                '' PDF/A-3 allows embedding files into document, but they should be associated with some document element
                '' add embedded file associated with seParagraph:
                Dim ef1 = EmbeddedFileStream.FromBytes(doc, Encoding.UTF8.GetBytes(para))
                '' ModificationDate and MimeType should be specified in case of PDF/A:
                ef1.ModificationDate = thedate
                ef1.MimeType = "text/plain"
                Dim fn = String.Format("Page{0}_Paragraph{1}.txt", pageNo, i)
                Dim fs1 = FileSpecification.FromEmbeddedStream(fn, ef1)
                '' Relationship should be specified in case of PDF/A:
                fs1.Relationship = AFRelationship.Unspecified
                doc.EmbeddedFiles.Add(fn, fs1)
                seParagraph.AssociatedFiles.Add(fs1)
            Next
        Next

        '' PDF/A-3 allows transparency drawing in 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-3 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-3 allows using embedded files, but each embedded file must be associated with a document's 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.Relationship = AFRelationship.Unspecified
        doc.EmbeddedFiles.Add("ProcurementLetter.docx", fs)
        '' Associate embedded file with the document:
        doc.AssociatedFiles.Add(fs)

        '' Add an attachment associated with an annotation:
        Dim sa = New StampAnnotation() With
            {
                .UserName = "Minerva",
                .Font = fnt,
                .Rect = New RectangleF(300, 36, 220, 72)
            }
        sa.Flags = sa.Flags And 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 Annotation" + vbLf + "associated with minerva.jpg", 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.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 PDF/A document:
        doc.Metadata.Title = "DsPdf Document"
        doc.ViewerPreferences.DisplayDocTitle = True

        '' Done:
        doc.Save(stream)
    End Sub
End Class