TX Text Control .NET for WPF

PDF/A

Topic

When documents from a WPF application go into an archive, such as signed contracts, invoices or records that must be kept for years, PDF/A is the format to save them in. The TextControl of a window and a ServerTextControl write it with StreamType.AdobePDFA. Before the save succeeds, the document has to follow the rules of the standard, above all for its fonts.

Create a PDF/A Document in Getting Started saves a first PDF/A file from the editor and one from a copy, without changing the editor's font settings. PDF/A requires the Enterprise edition; see Editions and Feature Availability.

What PDF/A Is

PDF/A, ISO 19005, is the standard for the long-term archiving of electronic documents. Everything needed to display a PDF/A file is inside it, including its fonts. Audio, video, JavaScript, other executable content and encryption aren't allowed.

Of the parts of the standard, PDF/A-3 allows embedded files of any format, for example the XML data of an electronic invoice. The conformance level "a" adds a logical structure with tags for assistive technologies, so a PDF/A-3a document is accessible as well.

What TX Text Control Writes

  • Since version 34.0, StreamType.AdobePDFA saves PDF/A-3a. The tagged structure is also what PDF/UA requires, so a document can conform to PDF/A-3a and PDF/UA at the same time, as Create an Accessible PDF (PDF/UA) describes.
  • Before version 34.0, TX Text Control wrote PDF/A-1b, and since version 29.0, documents with attachments as PDF/A-3b.

According to StreamType, AdobePDFA is a format for saving only, and only complete documents can be saved with it. To load a PDF/A file, use StreamType.AdobePDF. Any document the window can show can be saved as PDF/A, whether it was typed, loaded from DOCX, RTF or HTML, merged from a template or imported from a PDF.

The Rules of PDF/A

TX Text Control applies the rules of the standard when it saves. For your code, they mean:

  • Embeddable fonts only. FontSettings.EmbeddableFontsOnly must be true before the save; the default is false. Fonts that can't be embedded are then replaced, as Font Embedding and Substitution explains.
  • No passwords. Encryption isn't allowed, so a PDF/A document has no user password, master password or permissions.
  • No JavaScript. SaveSettings.DocumentLevelJavaScriptActions is ignored for PDF/A.
  • Pages from the page layout. The technical article on PDF import and export in the reference lists ViewMode PageView as the first step, so that the PDF gets the page size of the document. In FloatingText mode, page size and margins are ignored.
  • Attachments are allowed in PDF/A-3, as Attachments describes.

Save the Window's Document as PDF/A

Add a button with the handler ArchiveButton_Click to MainWindow.xaml. The following code in MainWindow.xaml.cs saves the document of textControl1 as PDF/A and writes each replaced font to the Output window of Visual Studio:

private void ArchiveButton_Click(object sender, RoutedEventArgs e)
{
    // Report every font that is replaced
    textControl1.FontSettings.AdaptFontEvent = true;
    textControl1.AdaptFont += TextControl1_AdaptFont;

    // Only fonts that can be embedded; all others are replaced
    textControl1.FontSettings.EmbeddableFontsOnly = true;

    textControl1.ViewMode = ViewMode.PageView;

    try
    {
        textControl1.Save("contract-archive.pdf", StreamType.AdobePDFA,
            new SaveSettings() { DocumentTitle = "Service Contract" });
    }
    finally
    {
        textControl1.AdaptFont -= TextControl1_AdaptFont;
    }
}

private void TextControl1_AdaptFont(object sender, AdaptFontEventArgs e)
{
    Debug.WriteLine(e.FontName + " is replaced with " + e.AdaptedFontName);
}

The file needs using System.Diagnostics;, using System.Windows; and using TXTextControl;. The code works as follows:

  • Restricting the fonts is one of the moments the AdaptFont event occurs, so the handler is connected first. Choose the Replacement Fonts explains the event and how to pick the replacement yourself.
  • ViewMode is an enumeration of the TXTextControl namespace, although the property belongs to the WPF TextControl.
  • The SaveSettings give the archived document a title.

EmbeddableFontsOnly remains true after the save, and the user continues with the replaced fonts. To avoid that, save the PDF/A file from a copy, as Create a PDF/A Document shows.

Archive a Folder of Documents

The following handler converts every DOCX file of a folder the user picks into PDF/A with a ServerTextControl and lists the files whose fonts can't be embedded:

private void ArchiveFolderButton_Click(object sender, RoutedEventArgs e)
{
    OpenFolderDialog dialog = new OpenFolderDialog();

    if (dialog.ShowDialog(this) != true)
    {
        return;
    }

    List<string> failed = new List<string>();

    foreach (string file in Directory.GetFiles(dialog.FolderName, "*.docx"))
    {
        using (ServerTextControl tx = new ServerTextControl())
        {
            tx.Create();

            // Set before Load, so that it applies to the fonts of the document
            tx.FontSettings.EmbeddableFontsOnly = true;

            tx.Load(file, StreamType.WordprocessingML);

            try
            {
                tx.Save(System.IO.Path.ChangeExtension(file, ".pdf"), StreamType.AdobePDFA);
            }
            catch (FilterException exception) when
                (exception.Reason == FilterException.FilterError.NonEmbeddableFont)
            {
                failed.Add(System.IO.Path.GetFileName(file));
            }
        }
    }

    if (failed.Count > 0)
    {
        MessageBox.Show(this, "Fonts that can't be embedded:\n" + string.Join("\n", failed), "PDF/A");
    }
}

The handler also needs using System.IO; and using Microsoft.Win32;, the namespace of OpenFolderDialog. A document that still contains a font that can't be embedded throws a FilterException with the Reason NonEmbeddableFont. A Document Can't Be Saved as PDF/A lists the messages and what to do.

Check the Result

Adobe Acrobat lists the standards a PDF claims to conform to. For a document saved with AdobePDFA in version 34.0, these are PDF/A-3A and PDF/UA-1:

Adobe Acrobat with a PDF saved by TX Text Control, a note that the file claims PDF/A compliance, and the Standards panel listing PDF/A-3A and PDF/UA-1.

Acrobat opens the file read-only to prevent changes, as the note at the top says. The panel shows what the file claims; its status is "not yet verified" until a validation checks it. PDF/A conformance is validated with a PDF/A validator such as veraPDF. Text Control's TXTextControl.PDF.Validation package validates PDF/UA, the accessibility side, and reports only whether a PDF/A declaration exists, as Validate the Accessible PDF describes.

Electronic Invoices and Signatures

The blog article PDF/UA vs. PDF/A-3a: Which Format Should You Use for Your Business Application? compares the two standards.

Next Steps