Skip to main content
Version: Version 1.9

Toolbox add-on code samples

Start using the Toolbox add-on library with code samples. Integrate low-level access to the content of PDF files into your application in Java, .NET, and C.

info

Select a code sample in a specific language and download it. The code samples illustrate how to integrate the SDK into your projects for specific use cases. Each code sample includes a README file that gives instructions on how to run the code sample to process one or multiple files.

tip

Do you miss a specific sample and want us to include it here? Let us know through the Contact page, and we'll add it to our sample backlog.

Annotations

Add annotations to PDF

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    // Create output document
6    using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
7    using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
8
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Copy first page and add annotations
16    Page outPage = CopyAndAddAnnotations(outDoc, inDoc.Pages[0], copyOptions);
17
18    // Add the page to the output document's page list
19    outDoc.Pages.Add(outPage);
20
21    // Copy the remaining pages and add to the output document's page list
22    PageList inPages = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
23    PageList outPages = PageList.Copy(outDoc, inPages, copyOptions);
24    outDoc.Pages.AddRange(outPages);
25}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static Page CopyAndAddAnnotations(Document outDoc, Page inPage, PageCopyOptions copyOptions)
2{
3    // Copy page to output document
4    Page outPage = Page.Copy(outDoc, inPage, copyOptions);
5
6    // Make a RGB color space
7    ColorSpace rgb = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
8
9    // Get the page size for positioning annotations
10    Size pageSize = outPage.Size;
11
12    // Get the output page's list of annotations for adding annotations
13    AnnotationList annotations = outPage.Annotations;
14
15    // Create a sticky note and add to output page's annotations
16    Paint green = Paint.Create(outDoc, rgb, new double[] { 0, 1, 0 }, null);
17    Point stickyNoteTopLeft = new Point() { X = 10, Y = pageSize.Height - 10 };
18    StickyNote stickyNote = StickyNote.Create(outDoc, stickyNoteTopLeft, "Hello world!", green);
19    annotations.Add(stickyNote);
20
21    // Create an ellipse and add to output page's annotations
22    Paint blue = Paint.Create(outDoc, rgb, new double[] { 0, 0, 1 }, null);
23    Paint yellow = Paint.Create(outDoc, rgb, new double[] { 1, 1, 0 }, null);
24    Rectangle ellipseBox = new Rectangle() { Left = 10, Bottom = pageSize.Height - 60, Right = 70, Top = pageSize.Height - 20 };
25    EllipseAnnotation ellipse = EllipseAnnotation.Create(outDoc, ellipseBox, new Stroke(blue, 1.5), yellow);
26    annotations.Add(ellipse);
27
28    // Create a free text and add to output page's annotations
29    Paint yellowTransp = Paint.Create(outDoc, rgb, new double[] { 1, 1, 0 }, new Transparency(0.5));
30    Rectangle freeTextBox = new Rectangle() { Left = 10, Bottom = pageSize.Height - 170, Right = 120, Top = pageSize.Height - 70 };
31    FreeText freeText = FreeText.Create(outDoc, freeTextBox, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", yellowTransp);
32    annotations.Add(freeText);
33
34    // A highlight and a web-link to be fitted on existing page content elements
35    Highlight highlight = null;
36    WebLink webLink = null;
37    // Extract content elements from the input page
38    ContentExtractor extractor = new ContentExtractor(inPage.Content);
39    foreach (ContentElement element in extractor)
40    {
41        // Take the first text element
42        if (highlight == null && element is TextElement textElement)
43        {
44            // Get the quadrilaterals of this text element
45            QuadrilateralList quadrilaterals = new QuadrilateralList();
46            foreach (TextFragment fragment in textElement.Text)
47                quadrilaterals.Add(fragment.Transform.TransformRectangle(fragment.BoundingBox));
48
49            // Create a highlight and add to output page's annotations
50            highlight = Highlight.CreateFromQuadrilaterals(outDoc, quadrilaterals, yellow);
51            annotations.Add(highlight);
52        }
53
54        // Take the first image element
55        if (webLink == null && element is ImageElement)
56        {
57            // Get the quadrilateral of this image
58            QuadrilateralList quadrilaterals = new QuadrilateralList();
59            quadrilaterals.Add(element.Transform.TransformRectangle(element.BoundingBox));
60
61            // Create a web-link and add to the output page's links
62            webLink = WebLink.CreateFromQuadrilaterals(outDoc, quadrilaterals, "https://www.pdf-tools.com");
63            Paint red = Paint.Create(outDoc, rgb, new double[] { 1, 0, 0 }, null);
64            webLink.BorderStyle = new Stroke(red, 1.5);
65            outPage.Links.Add(webLink);
66        }
67
68        // Exit loop if highlight and webLink have been created
69        if (highlight != null && webLink != null)
70            break;
71    }
72
73    // return the finished page
74    return outPage;
75}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    // Create file stream
5    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
6    try (// Create output document
7        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
8
9        // Copy document-wide data
10        copyDocumentData(inDoc, outDoc);
11
12        // Define page copy options
13        PageCopyOptions copyOptions = new PageCopyOptions();
14
15        // Copy first page and add annotations
16        Page outPage = copyAndAddAnnotations(outDoc, inDoc.getPages().get(0), copyOptions);
17
18        // Add the page to the output document's page list
19        outDoc.getPages().add(outPage);
20
21        // Copy the remaining pages and add to the output document's page list
22        PageList inPages = inDoc.getPages().subList(1, inDoc.getPages().size());
23        PageList outPages = PageList.copy(outDoc, inPages, copyOptions);
24        outDoc.getPages().addAll(outPages);
25    }
26}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static Page copyAndAddAnnotations(Document outDoc, Page inPage, PageCopyOptions copyOptions) throws ConformanceException, CorruptException, IOException, UnsupportedFeatureException {
2    // Copy page to output document
3    Page outPage = Page.copy(outDoc, inPage, copyOptions);
4
5    // Make a RGB color space
6    ColorSpace rgb = ColorSpace.createProcessColorSpace(outDoc, ProcessColorSpaceType.RGB);
7
8    // Get the page size for positioning annotations
9    Size pageSize = outPage.getSize();
10
11    // Get the output page's list of annotations for adding annotations
12    AnnotationList annotations = outPage.getAnnotations();
13
14    // Create a sticky note and add to output page's annotations
15    Paint green = Paint.create(outDoc, rgb, new double[] { 0, 1, 0 }, null);
16    Point stickyNoteTopLeft = new Point(10, pageSize.height - 10 );
17    StickyNote stickyNote = StickyNote.create(outDoc, stickyNoteTopLeft, "Hello world!", green);
18    annotations.add(stickyNote);
19
20    // Create an ellipse and add to output page's annotations
21    Paint blue = Paint.create(outDoc, rgb, new double[] { 0, 0, 1 }, null);
22    Paint yellow = Paint.create(outDoc, rgb, new double[] { 1, 1, 0 }, null);
23    Rectangle ellipseBox = new Rectangle(10, pageSize.height - 60, 70, pageSize.height - 20);
24    EllipseAnnotation ellipse = EllipseAnnotation.create(outDoc, ellipseBox, new Stroke(blue, 1.5), yellow);
25    annotations.add(ellipse);
26
27    // Create a free text and add to output page's annotations
28    Paint yellowTransp = Paint.create(outDoc, rgb, new double[] { 1, 1, 0 }, new Transparency(0.5));
29    Rectangle freeTextBox = new Rectangle(10, pageSize.height - 170, 120, pageSize.height - 70);
30    FreeText freeText = FreeText.create(outDoc, freeTextBox, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", yellowTransp);
31    annotations.add(freeText);
32
33    // A highlight and a web-link to be fitted on existing page content elements
34    Highlight highlight = null;
35    WebLink webLink = null;
36    // Extract content elements from the input page
37    ContentExtractor extractor = new ContentExtractor(inPage.getContent());
38    for (ContentElement element : extractor) {
39        // Take the first text element
40        if (highlight == null && element instanceof TextElement) {
41            TextElement textElement = (TextElement)element;
42            // Get the quadrilaterals of this text element
43            QuadrilateralList quadrilaterals = new QuadrilateralList();
44            for (TextFragment fragment : textElement.getText())
45                quadrilaterals.add(fragment.getTransform().transformRectangle(fragment.getBoundingBox()));
46
47                // Create a highlight and add to output page's annotations
48                highlight = Highlight.createFromQuadrilaterals(outDoc, quadrilaterals, yellow);
49                annotations.add(highlight);
50            }
51
52        // Take the first image element
53        if (webLink == null && element instanceof ImageElement) {
54            // Get the quadrilateral of this image
55            QuadrilateralList quadrilaterals = new QuadrilateralList();
56            quadrilaterals.add(element.getTransform().transformRectangle(element.getBoundingBox()));
57
58            // Create a web-link and add to the output page's links
59            webLink = WebLink.createFromQuadrilaterals(outDoc, quadrilaterals, "https://www.pdf-tools.com");
60            Paint red = Paint.create(outDoc, rgb, new double[] { 1, 0, 0 }, null);
61            webLink.setBorderStyle(new Stroke(red, 1.5));
62            outPage.getLinks().add(webLink);
63        }
64
65        // Exit loop if highlight and webLink have been created
66        if (highlight != null && webLink != null)
67            break;
68    }
69
70    // return the finished page
71    return outPage;
72}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def copy_and_add_annotations(out_doc: Document, in_page: Page, copy_options: PageCopyOptions):
2    # Copy page to output document
3    out_page = Page.copy(out_doc, in_page, copy_options)
4
5    # Make a RGB color space
6    rgb = ColorSpace.create_process_color_space(out_doc, ProcessColorSpaceType.RGB)
7
8    # Get the page size for positioning annotations
9    page_size = out_page.size
10
11    # Get the output page's list of annotations for adding annotations
12    annotations = out_page.annotations
13
14    # Create a sticky note and add to output page's annotations
15    green = Paint.create(out_doc, rgb, [0.0, 1.0, 0.0], None)
16    sticky_note_top_left = Point(x=10.0, y=page_size.height - 10.0)
17    sticky_note = StickyNote.create(out_doc, sticky_note_top_left, "Hello world!", green)
18    annotations.append(sticky_note)
19
20    # Create an ellipse and add to output page's annotations
21    blue = Paint.create(out_doc, rgb, [0.0, 0.0, 1.0], None)
22    yellow = Paint.create(out_doc, rgb, [1.0, 1.0, 0.0], None)
23    ellipse_box = Rectangle(left=10.0, bottom=page_size.height - 60.0, right=70.0, top=page_size.height - 20.0)
24    ellipse = EllipseAnnotation.create(out_doc, ellipse_box, Stroke(blue, 1.5), yellow)
25    annotations.append(ellipse)
26
27    # Create a free text and add to output page's annotations
28    yellow_transp = Paint.create(out_doc, rgb, [1.0, 1.0, 0.0], Transparency(0.5))
29    free_text_box = Rectangle(left=10.0, bottom=page_size.height - 170.0, right=120.0, top=page_size.height - 70.0)
30    free_text = FreeText.create(out_doc, free_text_box, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", yellow_transp)
31    annotations.append(free_text)
32
33    # A highlight and a web-link to be fitted on existing page content elements
34    highlight = None
35    web_link = None
36    # Extract content elements from the input page
37    extractor = ContentExtractor(in_page.content)
38    for element in extractor:
39        # Take the first text element
40        if highlight is None and isinstance(element, TextElement):
41            # Get the quadrilaterals of this text element
42            quadrilaterals = QuadrilateralList()
43            for fragment in element.text:
44                quadrilaterals.append(fragment.transform.transform_rectangle(fragment.bounding_box))
45
46            # Create a highlight and add to output page's annotations
47            highlight = Highlight.create_from_quadrilaterals(out_doc, quadrilaterals, yellow)
48            annotations.append(highlight)
49
50        # Take the first image element
51        if web_link is None and isinstance(element, ImageElement):
52            # Get the quadrilateral of this image
53            quadrilaterals = QuadrilateralList()
54            quadrilaterals.append(element.transform.transform_rectangle(element.bounding_box))
55
56            # Create a web-link and add to the output page's links
57            web_link = WebLink.create_from_quadrilaterals(out_doc, quadrilaterals, "https://www.pdf-tools.com")
58            red = Paint.create(out_doc, rgb, [1.0, 0.0, 0.0], None)
59            web_link.border_style = Stroke(red, 1.5)
60            out_page.links.append(web_link)
61
62        # Exit loop if highlight and web-link have been created
63        if highlight is not None and web_link is not None:
64            break
65
66    return out_page

Update annotations to PDF

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Stream inFdfStream = new FileStream(inFdfPath, FileMode.Open, FileAccess.Read))
4using (Document inDoc = Document.OpenWithFdf(inStream, inFdfStream, null))
5{
6    // Create output document
7    using var outStream = new FileStream(outPath, FileMode.Create, FileAccess.Write);
8    using var outFdfStream = new FileStream(outFdfPath, FileMode.Create, FileAccess.Write);
9    using var outDoc = Document.CreateWithFdf(outStream, outFdfStream, inDoc.Conformance, null);
10
11    // Copy document-wide data
12    CopyDocumentData(inDoc, outDoc);
13
14    FilterAnnotations(inDoc, outDoc);
15}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void FilterAnnotations(Document inDoc, Document outDoc)
2{
3    // Define page copy options
4    var copyOptions = new PageCopyOptions
5    {
6        // Remove all annotations: we will add the filtered ones later
7        Annotations = CopyStrategy.Remove
8    };
9
10    foreach (var inPage in inDoc.Pages)
11    {
12        // Copy page to output document
13        var outPage = Page.Copy(outDoc, inPage, copyOptions);
14
15        // Hold the annotations from the input document
16        var inAnnotations = inPage.Annotations;
17
18        // Selectively copy annotations (excluding EllipseAnnotations - like Circle)
19        foreach (var inAnnotation in inAnnotations)
20        {
21            // Skip if the annotation is an EllipseAnnotation
22            if (inAnnotation is EllipseAnnotation)
23            {
24                continue;
25            }
26
27            outPage.Annotations.Add(Annotation.Copy(outDoc, inAnnotation));
28        }
29
30        // Add the page to the output document
31        outDoc.Pages.Add(outPage);
32    }
33}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def filter_annotations(in_doc: Document, out_doc: Document):
2    """Filter annotations and remove 'Ellipse' annotations."""
3    # Define page copy options
4    copy_options = PageCopyOptions()
5    # Remove all annotations: we will add the filtered ones later
6    copy_options.annotations = CopyStrategy.REMOVE
7
8    for in_page in in_doc.pages:
9        # Copy page to the output document
10        out_page = Page.copy(out_doc, in_page, copy_options)
11
12        # Hold the annotations from the input document
13        in_annotations = in_page.annotations
14
15        # Selectively copy annotations (excluding EllipseAnnotations - like Circle)
16        for in_annotation in in_annotations:
17            if not isinstance(in_annotation, EllipseAnnotation):
18                out_page.annotations.append(Annotation.copy(out_doc, in_annotation))
19
20        # Add the page to the output document
21        out_doc.pages.append(out_page)

Annotations and Form Fields

Add Form Field

Download code sample
1using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
2using (Document inDoc = Document.Open(inStream, null))
3
4// Create output document
5using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
6using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
7{
8    // Copy document-wide data
9    CopyDocumentData(inDoc, outDoc);
10
11    // Copy all form fields
12    FieldNodeMap inFormFields = inDoc.FormFields;
13    FieldNodeMap outFormFields = outDoc.FormFields;
14    foreach (KeyValuePair<string, FieldNode> inPair in inFormFields)
15    {
16        FieldNode outFormFieldNode = FieldNode.Copy(outDoc, inPair.Value);
17        outFormFields.Add(inPair.Key, outFormFieldNode);
18    }
19
20    // Define page copy options
21    PageCopyOptions copyOptions = new PageCopyOptions
22    {
23        FormFields = FormFieldCopyStrategy.CopyAndUpdateWidgets,
24        UnsignedSignatures = CopyStrategy.Remove,
25    };
26
27    // Copy first page
28    Page inPage = inDoc.Pages[0];
29    Page outPage = Page.Copy(outDoc, inPage, copyOptions);
30
31    // Add different types of form fields to the output page
32    AddCheckBox(outDoc, "Check Box ID", true, outPage, new Rectangle { Left = 50, Bottom = 300, Right = 70, Top = 320 });
33    AddComboBox(outDoc, "Combo Box ID", new string[] { "item 1", "item 2" }, "item 1", outPage, new Rectangle { Left = 50, Bottom = 260, Right = 210, Top = 280 });
34    AddListBox(outDoc, "List Box ID", new string[] { "item 1", "item 2", "item 3" }, new string[] { "item 1", "item 3" }, outPage, new Rectangle { Left = 50, Bottom = 160, Right = 210, Top = 240 });
35    AddRadioButtonGroup(outDoc, "Radio Button ID", new string[] { "A", "B", "C" }, 0, outPage, new Rectangle { Left = 50, Bottom = 120, Right = 210, Top = 140 });
36    AddGeneralTextField(outDoc, "Text ID", "Text", outPage, new Rectangle { Left = 50, Bottom = 80, Right = 210, Top = 100 });
37
38    // Add page to output document
39    outDoc.Pages.Add(outPage);
40
41    // Copy remaining pages and append to output document
42    PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
43    PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
44    outDoc.Pages.AddRange(copiedPages);
45}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddCheckBox(Document doc, string id, bool isChecked, Page page, Rectangle rectangle)
2{
3    // Create a check box
4    CheckBox checkBox = CheckBox.Create(doc);
5
6    // Add the check box to the document
7    doc.FormFields.Add(id, checkBox);
8
9    // Set the check box's state
10    checkBox.Checked = isChecked;
11
12    // Create a widget and add it to the page's widgets
13    page.Widgets.Add(checkBox.AddNewWidget(rectangle));
14}
1private static void AddComboBox(Document doc, string id, string[] itemNames, string value, Page page, Rectangle rectangle)
2{
3    // Create a combo box
4    ComboBox comboBox = ComboBox.Create(doc);
5
6    // Add the combo box to the document
7    doc.FormFields.Add(id, comboBox);
8
9    // Loop over all given item names
10    foreach (string itemName in itemNames)
11    {
12        // Create a new choice item
13        ChoiceItem item = comboBox.AddNewItem(itemName);
14
15        // Check whether this is the chosen item name
16        if (value.Equals(itemName))
17            comboBox.ChosenItem = item;
18    }
19    if (comboBox.ChosenItem == null && !string.IsNullOrEmpty(value))
20    {
21        // If no item has been chosen then assume we want to set the editable item
22        comboBox.CanEdit = true;
23        comboBox.EditableItemName = value;
24    }
25
26    // Create a widget and add it to the page's widgets
27    page.Widgets.Add(comboBox.AddNewWidget(rectangle));
28}
1private static void AddListBox(Document doc, string id, string[] itemNames, string[] chosenNames, Page page, Rectangle rectangle)
2{
3    // Create a list box
4    ListBox listBox = ListBox.Create(doc);
5
6    // Add the list box to the document
7    doc.FormFields.Add(id, listBox);
8
9    // Allow multiple selections
10    listBox.AllowMultiSelect = true;
11    ChoiceItemList chosenItems = listBox.ChosenItems;
12
13    // Loop over all given item names
14    foreach (string itemName in itemNames)
15    {
16        // Create a new choice item
17        ChoiceItem item = listBox.AddNewItem(itemName);
18
19        // Check whether to add to the chosen items
20        if (chosenNames.Contains(itemName))
21            chosenItems.Add(item);
22    }
23
24    // Create a widget and add it to the page's widgets
25    page.Widgets.Add(listBox.AddNewWidget(rectangle));
26}
1private static void AddRadioButtonGroup(Document doc, string id, string[] buttonNames, int chosen, Page page, Rectangle rectangle)
2{
3    // Create a radio button group
4    RadioButtonGroup group = RadioButtonGroup.Create(doc);
5
6    // Get the page's widgets
7    WidgetList widgets = page.Widgets;
8
9    // Add the radio button group to the document
10    doc.FormFields.Add(id, group);
11
12    // We partition the given rectangle horizontally into sub-rectangles, one for each button
13    // Compute the width of the sub-rectangles
14    double buttonWidth = (rectangle.Right - rectangle.Left) / buttonNames.Length;
15
16    // Loop over all button names
17    for (int i = 0; i < buttonNames.Length; i++)
18    {
19        // Compute the sub-rectangle for this button
20        Rectangle buttonRectangle = new Rectangle()
21        {
22            Left = rectangle.Left + i * buttonWidth,
23            Bottom = rectangle.Bottom,
24            Right = rectangle.Left + (i + 1) * buttonWidth,
25            Top = rectangle.Top
26        };
27
28        // Create the button and an associated widget
29        RadioButton button = group.AddNewButton(buttonNames[i]);
30        Widget widget = button.AddNewWidget(buttonRectangle);
31
32        // Check if this is the chosen button
33        if (i == chosen)
34            group.ChosenButton = button;
35
36        // Add the widget to the page's widgets
37        widgets.Add(widget);
38    }
39}
1private static void AddGeneralTextField(Document doc, string id, string value, Page page, Rectangle rectangle)
2{
3    // Create a general text field
4    GeneralTextField field = GeneralTextField.Create(doc);
5
6    // Add the field to the document
7    doc.FormFields.Add(id, field);
8
9    // Set the text value
10    field.Text = value;
11
12    // Create a widget and add it to the page's widgets
13    page.Widgets.Add(field.AddNewWidget(rectangle));
14}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Copy all form fields
12        FieldNodeMap inFormFields = inDoc.getFormFields();
13        FieldNodeMap outFormFields = outDoc.getFormFields();
14        for (Entry<String, FieldNode> entry : inFormFields.entrySet())
15            outFormFields.put(entry.getKey(), FieldNode.copy(outDoc, entry.getValue()));
16
17        // Define page copy options
18        PageCopyOptions copyOptions = new PageCopyOptions();
19        copyOptions.setFormFields(FormFieldCopyStrategy.COPY_AND_UPDATE_WIDGETS);
20        copyOptions.setUnsignedSignatures(CopyStrategy.REMOVE);
21
22        // Copy first page
23        Page inPage = inDoc.getPages().get(0);
24        Page outPage = Page.copy(outDoc, inPage, copyOptions);
25
26        // Add different types of form fields to the output page
27        addCheckBox(outDoc, "Check Box ID", true, outPage, new Rectangle(50, 300, 70, 320));
28        addComboBox(outDoc, "Combo Box ID", new String[] { "item 1", "item 2" }, "item 1", outPage,
29                new Rectangle(50, 260, 210, 280));
30        addListBox(outDoc, "List Box ID", new String[] { "item 1", "item 2", "item 3" },
31                new String[] { "item 1", "item 3" }, outPage, new Rectangle(50, 160, 210, 240));
32        addRadioButtonGroup(outDoc, "Radio Button ID", new String[] { "A", "B", "C" }, 0, outPage,
33                new Rectangle(50, 120, 210, 140));
34        addGeneralTextField(outDoc, "Text ID", "Text", outPage, new Rectangle(50, 80, 210, 100));
35
36        // Add page to output document
37        outDoc.getPages().add(outPage);
38
39        // Copy remaining pages and append to output document
40        PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
41        PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
42        outDoc.getPages().addAll(copiedPages);
43    }
44}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void addCheckBox(Document doc, String id, boolean isChecked, Page page, Rectangle rectangle)
2        throws ToolboxException {
3    // Create a check box
4    CheckBox checkBox = CheckBox.create(doc);
5
6    // Add the check box to the document
7    doc.getFormFields().put(id, checkBox);
8
9    // Set the check box's state
10    checkBox.setChecked(isChecked);
11
12    // Create a widget and add it to the page's widgets
13    page.getWidgets().add(checkBox.addNewWidget(rectangle));
14}
15
1private static void addListBox(Document doc, String id, String[] itemNames, String[] chosenNames, Page page,
2        Rectangle rectangle) throws ToolboxException {
3    List<String> chosenNamesList = Arrays.asList(chosenNames);
4
5    // Create a list box
6    ListBox listBox = ListBox.create(doc);
7
8    // Add the list box to the document
9    doc.getFormFields().put(id, listBox);
10
11    // Allow multiple selections
12    listBox.setAllowMultiSelect(true);
13
14    // Get the list of chosen items
15    ChoiceItemList chosenItems = listBox.getChosenItems();
16
17    // Loop over all given item names
18    for (String itemName : itemNames) {
19        ChoiceItem item = listBox.addNewItem(itemName);
20        // Check whether to add to the chosen items
21        if (chosenNamesList.contains(itemName))
22            chosenItems.add(item);
23    }
24
25    // Create a widget and add it to the page's widgets
26    page.getWidgets().add(listBox.addNewWidget(rectangle));
27}
28
1private static void addComboBox(Document doc, String id, String[] itemNames, String value, Page page,
2        Rectangle rectangle) throws ToolboxException {
3    // Create a combo box
4    ComboBox comboBox = ComboBox.create(doc);
5
6    // Add the combo box to the document
7    doc.getFormFields().put(id, comboBox);
8
9    // Loop over all given item names
10    for (String itemName : itemNames) {
11        ChoiceItem item = comboBox.addNewItem(itemName);
12        // Check whether to add to the chosen items
13        if (value.equals(itemName))
14            comboBox.setChosenItem(item);
15    }
16    if (comboBox.getChosenItem() == null && !(value == null || value.isEmpty())) {
17        // If no item has been chosen then assume we want to set the editable item
18        comboBox.setCanEdit(true);
19        comboBox.setEditableItemName(value);
20    }
21
22    // Create a widget and add it to the page's widgets
23    page.getWidgets().add(comboBox.addNewWidget(rectangle));
24}
25
1private static void addRadioButtonGroup(Document doc, String id, String[] buttonNames, int chosen, Page page,
2        Rectangle rectangle) throws ToolboxException {
3    // Create a radio button group
4    RadioButtonGroup group = RadioButtonGroup.create(doc);
5
6    // Add the radio button group to the document
7    doc.getFormFields().put(id, group);
8
9    // We partition the given rectangle horizontally into sub-rectangles, one for
10    // each button
11    // Compute the width of the sub-rectangles
12    double buttonWidth = (rectangle.right - rectangle.left) / buttonNames.length;
13
14    // Get the page's widgets
15    WidgetList widgets = page.getWidgets();
16
17    // Loop over all button names
18    for (int i = 0; i < buttonNames.length; i++) {
19        // Compute the sub-rectangle for this button
20        Rectangle buttonRectangle = new Rectangle(rectangle.left + i * buttonWidth, rectangle.bottom,
21                rectangle.left + (i + 1) * buttonWidth, rectangle.top);
22
23        // Create the button and an associated widget
24        RadioButton button = group.addNewButton(buttonNames[i]);
25        Widget widget = button.addNewWidget(buttonRectangle);
26
27        // Check if this is the chosen button
28        if (i == chosen)
29            group.setChosenButton(button);
30
31        // Add the widget to the page's widgets
32        widgets.add(widget);
33    }
34}
35
1private static void addGeneralTextField(Document doc, String id, String value, Page page, Rectangle rectangle)
2        throws ToolboxException {
3    // Create a general text field
4    GeneralTextField field = GeneralTextField.create(doc);
5
6    // Add the field to the document
7    doc.getFormFields().put(id, field);
8
9    // Set the check box's state
10    field.setText(value);
11
12    // Create a widget and add it to the page's widgets
13    page.getWidgets().add(field.addNewWidget(rectangle));
14}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_check_box(doc: Document, field_id: str, is_checked: bool, page: Page, rectangle: Rectangle):
2    # Create a check box
3    check_box = CheckBox.create(doc)
4
5    # Add the check box to the document
6    doc.form_fields[field_id] = check_box
7
8    # Set the check box's state
9    check_box.checked = is_checked
10
11    # Create a widget and add it to the page's widgets
12    page.widgets.append(check_box.add_new_widget(rectangle))
1def add_combo_box(doc: Document, field_id: str, item_names: list[str], value: str, page: Page, rectangle: Rectangle):
2    # Create a combo box
3    combo_box = ComboBox.create(doc)
4
5    # Add the combo box to the document
6    doc.form_fields[field_id] = combo_box
7
8    # Loop over all given item names
9    for item_name in item_names:
10        # Create a new choice item
11        item = combo_box.add_new_item(item_name)
12
13        # Check whether this is the chosen item name
14        if value == item_name:
15            combo_box.chosen_item = item
16
17    if combo_box.chosen_item is None and value:
18        # If no item has been chosen then assume we want to set the editable item
19        combo_box.can_edit = True
20        combo_box.editable_item_name = value
21
22    # Create a widget and add it to the page's widgets
23    page.widgets.append(combo_box.add_new_widget(rectangle))
1def add_list_box(doc: Document, field_id: str, item_names: list[str], chosen_names: list[str], page: Page, rectangle: Rectangle):
2    # Create a list box
3    list_box = ListBox.create(doc)
4
5    # Add the list box to the document
6    doc.form_fields[field_id] = list_box
7
8    # Allow multiple selections
9    list_box.allow_multi_select = True
10    chosen_items = list_box.chosen_items
11
12    # Loop over all given item names
13    for item_name in item_names:
14        # Create a new choice item
15        item = list_box.add_new_item(item_name)
16
17        # Check whether to add to the chosen items
18        if item_name in chosen_names:
19            chosen_items.append(item)
20
21    # Create a widget and add it to the page's widgets
22    page.widgets.append(list_box.add_new_widget(rectangle))
1def add_radio_button_group(doc: Document, field_id: str, button_names: list[str], chosen: int, page: Page, rectangle: Rectangle):
2    # Create a radio button group
3    group = RadioButtonGroup.create(doc)
4
5    # Get the page's widgets
6    widgets = page.widgets
7
8    # Add the radio button group to the document
9    doc.form_fields[field_id] = group
10
11    # We partition the given rectangle horizontally into sub-rectangles, one for each button
12    #  Compute the width of the sub-rectangles
13    button_width = (rectangle.right - rectangle.left) / len(button_names)
14
15    # Loop over all button names
16    for i, button_name in enumerate(button_names):
17        # Compute the sub-rectangle for this button
18        button_rectangle = Rectangle(
19            left = rectangle.left + i * button_width,
20            bottom = rectangle.bottom,
21            right = rectangle.left + (i + 1) * button_width,
22            top = rectangle.top
23        )
24
25        # Create the button and associated widget
26        button = group.add_new_button(button_name)
27        widget = button.add_new_widget(button_rectangle)
28
29        # Check if this is the chosen button
30        if i == chosen:
31            group.chosen_button = button
32
33        # Add the widget to the page's widgets
34        widgets.append(widget)
1def add_general_text_field(doc: Document, field_id: str, value: str, page: Page, rectangle: Rectangle):
2    # Create a general text field
3    text_field = GeneralTextField.create(doc)
4
5    # Add the field to the document
6    doc.form_fields[field_id] = text_field
7
8    # Set the text value
9    text_field.text = value
10
11    # Create a widget and add it to the page's widgets
12    page.widgets.append(text_field.add_new_widget(rectangle))

Fill Form Fields

Download code sample
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    // Objects that need releasing or closing
4    TPtxPdfContent_IccBasedColorSpace* pInOutputIntent    = NULL;
5    TPtxPdfContent_IccBasedColorSpace* pOutOutputIntent   = NULL;
6    TPtxPdf_Metadata*                  pInMetadata        = NULL;
7    TPtxPdf_Metadata*                  pOutMetadata       = NULL;
8    TPtxPdfNav_ViewerSettings*         pInViewerSettings  = NULL;
9    TPtxPdfNav_ViewerSettings*         pOutViewerSettings = NULL;
10    TPtxPdf_FileReferenceList*         pInFileRefList     = NULL;
11    TPtxPdf_FileReferenceList*         pOutFileRefList    = NULL;
12    TPtxPdf_FileReference*             pInFileRef         = NULL;
13    TPtxPdf_FileReference*             pOutFileRef        = NULL;
14
15    iReturnValue = 0;
16
17    // Output intent
18    pInOutputIntent = PtxPdf_Document_GetOutputIntent(pInDoc);
19    if (pInOutputIntent != NULL)
20    {
21        pOutOutputIntent = PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, pInOutputIntent);
22        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutOutputIntent,
23                                         _T("Failed to copy ICC-based color space. %s (ErrorCode: 0x%08x)\n"),
24                                         szErrorBuff, Ptx_GetLastError());
25        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetOutputIntent(pOutDoc, pOutOutputIntent),
26                                          _T("Failed to set output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
27                                          Ptx_GetLastError());
28    }
29    else
30        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
31                                          Ptx_GetLastError());
32
33    // Metadata
34    pInMetadata = PtxPdf_Document_GetMetadata(pInDoc);
35    if (pInMetadata != NULL)
36    {
37        pOutMetadata = PtxPdf_Metadata_Copy(pOutDoc, pInMetadata);
38        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutMetadata, _T("Failed to copy metadata. %s (ErrorCode: 0x%08x)\n"),
39                                         szErrorBuff, Ptx_GetLastError());
40        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetMetadata(pOutDoc, pOutMetadata),
41                                          _T("Failed to set metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
42                                          Ptx_GetLastError());
43    }
44    else
45        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
46                                          Ptx_GetLastError());
47
48    // Viewer settings
49    pInViewerSettings = PtxPdf_Document_GetViewerSettings(pInDoc);
50    if (pInViewerSettings != NULL)
51    {
52        pOutViewerSettings = PtxPdfNav_ViewerSettings_Copy(pOutDoc, pInViewerSettings);
53        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutViewerSettings,
54                                         _T("Failed to copy viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
55                                         Ptx_GetLastError());
56        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetViewerSettings(pOutDoc, pOutViewerSettings),
57                                          _T("Failed to set viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
58                                          Ptx_GetLastError());
59    }
60    else
61        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get viewer settings. %s (ErrorCode: 0x%08x)"), szErrorBuff,
62                                          Ptx_GetLastError());
63
64    // Associated files (for PDF/A-3 and PDF 2.0 only)
65    pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
66    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of input document. %s (ErrorCode: 0x%08x)\n"),
67                                      szErrorBuff, Ptx_GetLastError());
68    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
69    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of output document. %s (ErrorCode: 0x%08x)\n"),
70                                      szErrorBuff, Ptx_GetLastError());
71    int nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
72    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of associated files. %s (ErrorCode: 0x%08x)\n"),
73                                      szErrorBuff, Ptx_GetLastError());
74    for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
75    {
76        pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
77        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"),
78                                         szErrorBuff, Ptx_GetLastError());
79        pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
80        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"),
81                                         szErrorBuff, Ptx_GetLastError());
82        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef),
83                                          _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
84                                          Ptx_GetLastError());
85        Ptx_Release(pInFileRef);
86        pInFileRef = NULL;
87        Ptx_Release(pOutFileRef);
88        pOutFileRef = NULL;
89    }
90    Ptx_Release(pInFileRefList);
91    pInFileRefList = NULL;
92    Ptx_Release(pOutFileRefList);
93    pOutFileRefList = NULL;
94
95    // Plain embedded files
96    pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
97    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
98        pInFileRefList, _T("Failed to get plain embedded files of input document %s (ErrorCode: 0x%08x)\n"),
99        szErrorBuff, Ptx_GetLastError());
100    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
101    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
102        pInFileRefList, _T("Failed to get plain embedded files of output document %s (ErrorCode: 0x%08x)\n"),
103        szErrorBuff, Ptx_GetLastError());
104    nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
105    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of plain embedded files. %s (ErrorCode: 0x%08x)\n"),
106                                      szErrorBuff, Ptx_GetLastError());
107    for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
108    {
109        pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
110        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"),
111                                         szErrorBuff, Ptx_GetLastError());
112        pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
113        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"),
114                                         szErrorBuff, Ptx_GetLastError());
115        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef),
116                                          _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
117                                          Ptx_GetLastError());
118        Ptx_Release(pInFileRef);
119        pInFileRef = NULL;
120        Ptx_Release(pOutFileRef);
121        pOutFileRef = NULL;
122    }
123
124cleanup:
125    if (pInOutputIntent != NULL)
126        Ptx_Release(pInOutputIntent);
127    if (pOutOutputIntent != NULL)
128        Ptx_Release(pOutOutputIntent);
129    if (pInMetadata != NULL)
130        Ptx_Release(pInMetadata);
131    if (pOutMetadata != NULL)
132        Ptx_Release(pOutMetadata);
133    if (pInViewerSettings != NULL)
134        Ptx_Release(pInViewerSettings);
135    if (pOutViewerSettings != NULL)
136        Ptx_Release(pOutViewerSettings);
137    if (pInFileRefList != NULL)
138        Ptx_Release(pInFileRefList);
139    if (pOutFileRefList != NULL)
140        Ptx_Release(pOutFileRefList);
141    if (pInFileRef != NULL)
142        Ptx_Release(pInFileRef);
143    if (pOutFileRef != NULL)
144        Ptx_Release(pOutFileRef);
145    return iReturnValue;
146}
1int copyFields(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    // Objects that need releasing or closing
4    TPtxPdfForms_FieldNodeMap* pInFields     = NULL;
5    TPtxPdfForms_FieldNodeMap* pOutFields    = NULL;
6    TCHAR*                     szFieldKey    = NULL;
7    TPtxPdfForms_FieldNode*    pInFieldNode  = NULL;
8    TPtxPdfForms_FieldNode*    pOutFieldNode = NULL;
9
10    iReturnValue = 0;
11
12    pInFields = PtxPdf_Document_GetFormFields(pInDoc);
13    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFields,
14                                     _T("Failed to get form fields of the input document. %s (ErrorCode: 0x%08x).\n"),
15                                     szErrorBuff, Ptx_GetLastError());
16
17    pOutFields = PtxPdf_Document_GetFormFields(pOutDoc);
18    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFields,
19                                     _T("Failed to get form fields of the output document. %s (ErrorCode: 0x%08x).\n"),
20                                     szErrorBuff, Ptx_GetLastError());
21
22    for (int iField = PtxPdfForms_FieldNodeMap_GetBegin(pInFields);
23         iField != PtxPdfForms_FieldNodeMap_GetEnd(pInFields);
24         iField = PtxPdfForms_FieldNodeMap_GetNext(pInFields, iField))
25    {
26        if (iField == 0)
27            GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get form field. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
28                                              Ptx_GetLastError());
29        // Get key
30        size_t nKey = PtxPdfForms_FieldNodeMap_GetKey(pInFields, iField, szFieldKey, 0);
31        GOTO_CLEANUP_IF_ZERO(nKey, _T("Failed to get form field key\n"));
32        szFieldKey = (TCHAR*)malloc(nKey * sizeof(TCHAR*));
33        GOTO_CLEANUP_IF_NULL(szFieldKey, _T("Failed to allocate memory for field key\n"));
34        if (PtxPdfForms_FieldNodeMap_GetKey(pInFields, iField, szFieldKey, nKey) != nKey)
35        {
36            GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get form field key. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
37                                              Ptx_GetLastError());
38        }
39        // Get input field node
40        pInFieldNode = PtxPdfForms_FieldNodeMap_GetValue(pInFields, iField);
41        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFieldNode, _T("Failed to get form field. %s (ErrorCode: 0x%08x)\n"),
42                                         szErrorBuff, Ptx_GetLastError());
43        // Copy field node to output document
44        pOutFieldNode = PtxPdfForms_FieldNode_Copy(pOutDoc, pInFieldNode);
45        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFieldNode, _T("Failed to copy form field. %s (ErrorCode: 0x%08x)\n"),
46                                         szErrorBuff, Ptx_GetLastError());
47        // Add copied field node to output fields
48        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfForms_FieldNodeMap_Set(pOutFields, szFieldKey, pOutFieldNode),
49                                          _T("Failed to add form field \"%s\". %s (ErrorCode: 0x%08x)\n"), szFieldKey,
50                                          szErrorBuff, Ptx_GetLastError());
51        // Clean up for next iteration
52        free(szFieldKey);
53        szFieldKey = NULL;
54        Ptx_Release(pOutFieldNode);
55        pOutFieldNode = NULL;
56        Ptx_Release(pInFieldNode);
57        pInFieldNode = NULL;
58    }
59
60cleanup:
61    if (pOutFieldNode != NULL)
62        Ptx_Release(pOutFieldNode);
63    if (pInFieldNode != NULL)
64        Ptx_Release(pInFieldNode);
65    if (szFieldKey != NULL)
66        free(szFieldKey);
67    if (pOutFields != NULL)
68        Ptx_Release(pOutFields);
69    if (pInFields != NULL)
70        Ptx_Release(pInFields);
71    return iReturnValue;
72}
1int fillFormField(TPtxPdfForms_Field* pField, const TCHAR* szValue)
2{
3    // Objects that need releasing or closing
4    TPtxPdfForms_RadioButtonList* pButtonList     = NULL;
5    TPtxPdfForms_RadioButton*     pButton         = NULL;
6    TPtxPdfForms_ChoiceItemList*  pChoiceItemList = NULL;
7    TPtxPdfForms_ChoiceItem*      pItem           = NULL;
8    TCHAR*                        szName          = NULL;
9
10    // Other variables
11    TPtxPdfForms_FieldType         iType             = 0;
12    TPtxPdfForms_CheckBox*         pCheckBox         = NULL;
13    TPtxPdfForms_RadioButtonGroup* pRadioButtonGroup = NULL;
14
15    iReturnValue = 0;
16    iType        = PtxPdfForms_Field_GetType(pField);
17
18    if (iType == ePtxPdfForms_FieldType_GeneralTextField || iType == ePtxPdfForms_FieldType_CombTextField)
19    {
20        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfForms_TextField_SetText((TPtxPdfForms_TextField*)pField, szValue),
21                                          _T("Failed to set text field value. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
22                                          Ptx_GetLastError());
23    }
24    else if (iType == ePtxPdfForms_FieldType_CheckBox)
25    {
26        pCheckBox = (TPtxPdfForms_CheckBox*)pField;
27        if (_tcscmp(szValue, _T("on")) == 0)
28        {
29            GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfForms_CheckBox_SetChecked(pCheckBox, TRUE),
30                                              _T("Failed to set check box. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
31                                              Ptx_GetLastError());
32        }
33        else
34        {
35            GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfForms_CheckBox_SetChecked(pCheckBox, FALSE),
36                                              _T("Failed to set check box. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
37                                              Ptx_GetLastError());
38        }
39    }
40    else if (iType == ePtxPdfForms_FieldType_RadioButtonGroup)
41    {
42        pRadioButtonGroup = (TPtxPdfForms_RadioButtonGroup*)pField;
43        pButtonList       = PtxPdfForms_RadioButtonGroup_GetButtons(pRadioButtonGroup);
44        for (int iButton = 0; iButton < PtxPdfForms_RadioButtonList_GetCount(pButtonList); iButton++)
45        {
46            pButton = PtxPdfForms_RadioButtonList_Get(pButtonList, iButton);
47            GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pButton, _T("Failed to get radio button. %s (ErrorCode: 0x%08x)\n"),
48                                             szErrorBuff, Ptx_GetLastError())
49            size_t nName = PtxPdfForms_RadioButton_GetExportName(pButton, szName, 0);
50            GOTO_CLEANUP_IF_ZERO(nName, _T("Failed to get radio button name\n"));
51            szName = (TCHAR*)malloc(nName * sizeof(TCHAR*));
52            GOTO_CLEANUP_IF_NULL(szName, _T("Failed to allocate memory for radio button name\n"));
53            if (PtxPdfForms_RadioButton_GetExportName(pButton, szName, nName) != nName)
54            {
55                GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get radio button name. %s (ErrorCode: 0x%08x)\n"),
56                                                  szErrorBuff, Ptx_GetLastError());
57            }
58            if (_tcscmp(szValue, szName) == 0)
59            {
60                GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
61                    PtxPdfForms_RadioButtonGroup_SetChosenButton(pRadioButtonGroup, pButton),
62                    _T("Failed to set radio button. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
63            }
64            free(szName);
65            szName = NULL;
66            Ptx_Release(pButton);
67            pButton = NULL;
68        }
69    }
70    else if (iType == ePtxPdfForms_FieldType_ComboBox || iType == ePtxPdfForms_FieldType_ListBox)
71    {
72        pChoiceItemList = PtxPdfForms_ChoiceField_GetItems((TPtxPdfForms_ChoiceField*)pField);
73        for (int iItem = 0; iItem < PtxPdfForms_ChoiceItemList_GetCount(pChoiceItemList); iItem++)
74        {
75            pItem = PtxPdfForms_ChoiceItemList_Get(pChoiceItemList, iItem);
76            GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pItem,
77                                             _T("Failed to get item from choice field. %s (ErrorCode: 0x%08x)\n"),
78                                             szErrorBuff, Ptx_GetLastError());
79            size_t nName = PtxPdfForms_ChoiceItem_GetDisplayName(pItem, szName, 0);
80            GOTO_CLEANUP_IF_ZERO(nName, _T("Failed to get choice item name\n"));
81            szName = (TCHAR*)malloc(nName * sizeof(TCHAR*));
82            GOTO_CLEANUP_IF_NULL(szName, _T("Failed to allocate memory for choice item name\n"));
83            if (PtxPdfForms_ChoiceItem_GetDisplayName(pItem, szName, nName) != nName)
84            {
85                GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get choice item name. %s (ErrorCode: 0x%08x)\n"),
86                                                  szErrorBuff, Ptx_GetLastError());
87            }
88            if (_tcscmp(szValue, szName) == 0)
89            {
90                break;
91            }
92            free(szName);
93            szName = NULL;
94            Ptx_Release(pItem);
95            pItem = NULL;
96        }
97        if (pItem != NULL)
98        {
99            free(szName);
100            szName = NULL;
101            if (iType == ePtxPdfForms_FieldType_ComboBox)
102            {
103                GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
104                    PtxPdfForms_ComboBox_SetChosenItem((TPtxPdfForms_ComboBox*)pField, pItem),
105                    _T("Failed to set choice item for combo box. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
106                    Ptx_GetLastError());
107            }
108            else // iType == ePtxPdfForms_FieldType_ListBox
109            {
110                Ptx_Release(pChoiceItemList);
111                pChoiceItemList = PtxPdfForms_ListBox_GetChosenItems((TPtxPdfForms_ListBox*)pField);
112                GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
113                    pChoiceItemList, _T("Failed to get list of chosen items for list box. %s (ErrorCode: 0x%08x)\n"),
114                    szErrorBuff, Ptx_GetLastError());
115                GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
116                    PtxPdfForms_ChoiceItemList_Clear(pChoiceItemList),
117                    _T("Failed to clear list of chosen items for list box. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
118                    Ptx_GetLastError());
119                GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
120                    PtxPdfForms_ChoiceItemList_Add(pChoiceItemList, pItem),
121                    _T("Failed to add item to list of chosen items for list box. %s (ErrorCode: 0x%08x)\n"),
122                    szErrorBuff, Ptx_GetLastError());
123            }
124        }
125    }
126
127cleanup:
128    if (szName != NULL)
129        free(szName);
130    if (pItem == NULL)
131        Ptx_Release(pItem);
132    if (pChoiceItemList == NULL)
133        Ptx_Release(pChoiceItemList);
134    if (pButton != NULL)
135        Ptx_Release(pButton);
136    if (pButtonList != NULL)
137        Ptx_Release(pButton);
138
139    return iReturnValue;
140}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    FieldNodeMap outFields = outDoc.FormFields;
13
14    // Copy all form fields
15    FieldNodeMap inFields = inDoc.FormFields;
16    foreach (var inPair in inFields)
17    {
18        FieldNode inFieldNode = inPair.Value;
19        FieldNode outFormFieldNode = FieldNode.Copy(outDoc, inFieldNode);
20        outFields.Add(inPair.Key, outFormFieldNode);
21    }
22
23    // Find the given field, exception thrown if not found
24    var selectedNode = outFields.Lookup(fieldIdentifier);
25    if (selectedNode is Field selectedField)
26        FillFormField(selectedField, fieldValue);
27
28    // Configure copying options for updating existing widgets and removing signature fields
29    PageCopyOptions copyOptions = new PageCopyOptions
30    {
31        FormFields = FormFieldCopyStrategy.CopyAndUpdateWidgets,
32        UnsignedSignatures = CopyStrategy.Remove,
33    };
34
35    // Copy all pages and append to output document
36    PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
37    outDoc.Pages.AddRange(copiedPages);
38}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1static void FillFormField(Field formField, string value)
2{
3    // Apply the value, depending on the field type
4    if (formField is TextField textField)
5    {
6        // Set the text
7        textField.Text = value;
8    }
9    else if (formField is CheckBox checkBox)
10    {
11        // Check or un-check
12        checkBox.Checked = "on".Equals(value, StringComparison.CurrentCultureIgnoreCase);
13    }
14    else if (formField is RadioButtonGroup group)
15    {
16        // Search the buttons for given name
17        foreach (var button in group.Buttons)
18        {
19            if (value.Equals(button.ExportName))
20            {
21                // Found: Select this button
22                group.ChosenButton = button;
23                break;
24            }
25        }
26    }
27    else if (formField is ComboBox comboBox)
28    {
29        // Search for the given item
30        foreach (var item in comboBox.Items)
31        {
32            if (value.Equals(item.DisplayName))
33            {
34                // Found: Select this item.
35                comboBox.ChosenItem = item;
36                break;
37            }
38        }
39    }
40    else if (formField is ListBox listBox)
41    {
42        // Search for the given item
43        foreach (var item in listBox.Items)
44        {
45            if (value.Equals(item.DisplayName))
46            {
47                // Found: Set this item as the only selected item
48                var itemList = listBox.ChosenItems;
49                itemList.Clear();
50                itemList.Add(item);
51                break;
52            }
53        }
54    }
55}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Copy all form fields
12        FieldNodeMap inFormFields = inDoc.getFormFields();
13        FieldNodeMap outFormFields = outDoc.getFormFields();
14        for (Entry<String, FieldNode> entry : inFormFields.entrySet())
15            outFormFields.put(entry.getKey(), FieldNode.copy(outDoc, entry.getValue()));
16
17        // Find the given field, exception thrown if not found
18        Field selectedField = (Field) outFormFields.lookup(fieldIdentifier);
19        fillFormField(selectedField, fieldValue);
20
21        // Configure copying options for updating existing widgets and removing signature fields
22        PageCopyOptions copyOptions = new PageCopyOptions();
23        copyOptions.setFormFields(FormFieldCopyStrategy.COPY_AND_UPDATE_WIDGETS);
24        copyOptions.setUnsignedSignatures(CopyStrategy.REMOVE);
25
26        // Copy all pages and append to output document
27        PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
28        outDoc.getPages().addAll(copiedPages);
29    }
30}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void fillFormField(Field formField, String value) throws ToolboxException {
2    // Apply the value, depending on the field type
3    if (formField instanceof TextField) {
4        // Set the text
5        TextField textField = (TextField) formField;
6        textField.setText(value);
7    } else if (formField instanceof CheckBox) {
8        // Check or un-check
9        CheckBox checkBox = (CheckBox) formField;
10        checkBox.setChecked(value.equalsIgnoreCase("on"));
11    } else if (formField instanceof RadioButtonGroup) {
12        // Search the buttons for given name
13        RadioButtonGroup group = (RadioButtonGroup) formField;
14        for (RadioButton button : group.getButtons()) {
15            if (value.equals(button.getExportName())) {
16                // Found: Select this button
17                group.setChosenButton(button);
18                break;
19            }
20        }
21    } else if (formField instanceof ComboBox) {
22        // Search for the given item
23        ComboBox comboBox = (ComboBox) formField;
24        for (ChoiceItem item : comboBox.getItems()) {
25            if (value.equals(item.getDisplayName())) {
26                // Found: Select this item
27                comboBox.setChosenItem(item);
28                break;
29            }
30        }
31    } else if (formField instanceof ListBox) {
32        // Search for the given item
33        ListBox listBox = (ListBox) formField;
34        for (ChoiceItem item : listBox.getItems()) {
35            if (value.equals(item.getDisplayName())) {
36                // Found: Set this item as the only selected item
37                ChoiceItemList itemList = listBox.getChosenItems();
38                itemList.clear();
39                itemList.add(item);
40                break;
41            }
42        }
43    }
44}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def fill_form_field(form_field: Field, value: str):
2    """Set the value of a form field based on its type."""
3    if isinstance(form_field, TextField):
4        form_field.text = value
5    elif isinstance(form_field, CheckBox):
6        form_field.checked = value.lower() == "on"
7    elif isinstance(form_field, RadioButtonGroup):
8        for button in form_field.buttons:
9            if button.export_name == value:
10                form_field.chosen_button = button
11                break
12    elif isinstance(form_field, ComboBox):
13        for item in form_field.items:
14            if item.display_name == value:
15                form_field.chosen_item = item
16                break
17    elif isinstance(form_field, ListBox):
18        for item in form_field.items:
19            if item.display_name == value:
20                form_field.chosen_items.clear()
21                form_field.chosen_items.append(item)
22                break

Content Addition

Add barcode to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create file stream
10pFontStream = _tfopen(szFontPath, _T("rb"));
11GOTO_CLEANUP_IF_NULL(pFontStream, _T("Failed to open font file."));
12PtxSysCreateFILEStreamDescriptor(&fontDescriptor, pFontStream, 0);
13
14// Create output document
15pOutStream = _tfopen(szOutPath, _T("wb+"));
16GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
17PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
18iConformance = PtxPdf_Document_GetConformance(pInDoc);
19pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
20GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
21                                 szOutPath, szErrorBuff, Ptx_GetLastError());
22pFont = PtxPdfContent_Font_Create(pOutDoc, &fontDescriptor, TRUE);
23GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
24                                 Ptx_GetLastError());
25
26// Copy document-wide data
27GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
28                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
29                                  Ptx_GetLastError());
30
31// Configure copy options
32pCopyOptions = PtxPdf_PageCopyOptions_New();
33
34// Get page lists of input and output document
35pInPageList = PtxPdf_Document_GetPages(pInDoc);
36GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
37                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
38                                 szErrorBuff, Ptx_GetLastError());
39pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
40GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
41                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
42                                 szErrorBuff, Ptx_GetLastError());
43
44// Copy first page
45pInPage = PtxPdf_PageList_Get(pInPageList, 0);
46GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"),
47                                 szErrorBuff, Ptx_GetLastError());
48pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
49GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
50                                 Ptx_GetLastError());
51
52// Add barcode image to copied page
53if (addBarcode(pOutDoc, pOutPage, szBarcode, pFont, 50) != 0)
54    goto cleanup;
55
56// Add page to output document
57GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
58                                  _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
59                                  szErrorBuff, Ptx_GetLastError());
60
61// Get remaining pages from input
62pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
63GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
64                                 _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
65                                 szErrorBuff, Ptx_GetLastError());
66
67// Copy remaining pages to output
68pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
69GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
70                                 _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
71                                 szErrorBuff, Ptx_GetLastError());
72
73// Add the copied pages to the output document
74GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
75                                  _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
76                                  szErrorBuff, Ptx_GetLastError());
77
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addBarcode(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szBarcode, TPtxPdfContent_Font* pFont,
2               double dFontSize)
3{
4    TPtxPdfContent_Content*          pContent       = NULL;
5    TPtxPdfContent_ContentGenerator* pGenerator     = NULL;
6    TPtxPdfContent_Text*             pBarcodeText   = NULL;
7    TPtxPdfContent_TextGenerator*    pTextGenerator = NULL;
8
9    pContent = PtxPdf_Page_GetContent(pOutPage);
10
11    // Create content generator
12    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
13    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
14                                     szErrorBuff, Ptx_GetLastError());
15
16    // Create text object
17    pBarcodeText = PtxPdfContent_Text_Create(pOutDoc);
18    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pBarcodeText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"),
19                                     szErrorBuff, Ptx_GetLastError());
20
21    // Create text generator
22    pTextGenerator = PtxPdfContent_TextGenerator_New(pBarcodeText, pFont, dFontSize, NULL);
23    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"),
24                                     szErrorBuff, Ptx_GetLastError());
25
26    // Calculate position
27    TPtxGeomReal_Size size;
28    PtxPdf_Page_GetSize(pOutPage, &size);
29    TPtxGeomReal_Point position;
30    double             dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szBarcode);
31    GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dTextWidth, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
32    double dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
33    GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dFontAscent, _T("%s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
34    double dFontDescent = PtxPdfContent_Font_GetDescent(pFont);
35    GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dFontDescent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff,
36                                         Ptx_GetLastError());
37    position.dX = size.dWidth - (dTextWidth + dBorder);
38    position.dY = size.dHeight - (dFontSize * (dFontAscent + dFontDescent) + dBorder);
39
40    // Move to position
41    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position),
42                                      _T("Failed to move to position %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
43                                      Ptx_GetLastError());
44    // Add given barcode string
45    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szBarcode),
46                                      _T("Failed to add barcode string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
47                                      Ptx_GetLastError());
48
49    // Close text generator
50    if (pTextGenerator != NULL)
51        PtxPdfContent_TextGenerator_Close(pTextGenerator);
52
53    // Paint the positioned barcode text
54    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pBarcodeText),
55                                      _T("Failed to paint the positioned barcode text. %s (ErrorCode: 0x%08x).\n"),
56                                      szErrorBuff, Ptx_GetLastError());
57
58cleanup:
59    if (pGenerator != NULL)
60        PtxPdfContent_ContentGenerator_Close(pGenerator);
61
62    return iReturnValue;
63}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create file stream
6using (Stream fontStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read))
7
8// Create output document
9using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
10using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
11{
12    // Copy document-wide data
13    CopyDocumentData(inDoc, outDoc);
14
15    // Create embedded font in output document
16    Font font = Font.Create(outDoc, fontStream, true);
17
18    // Define page copy options
19    PageCopyOptions copyOptions = new PageCopyOptions();
20
21    // Copy first page, add barcode, and append to output document
22    Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
23    AddBarcode(outDoc, outPage, barcode, font, 50);
24    outDoc.Pages.Add(outPage);
25
26    // Copy remaining pages and append to output document
27    PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
28    PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
29    outDoc.Pages.AddRange(copiedPages);
30}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddBarcode(Document outputDoc, Page outPage, string barcode,
2    Font font, double fontSize)
3{
4    // Create content generator 
5    using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
6
7    // Create text object
8    Text barcodeText = Text.Create(outputDoc);
9
10    // Create text generator
11    using (TextGenerator textGenerator = new TextGenerator(barcodeText, font, fontSize, null))
12    {
13        // Calculate position
14        Point position = new Point
15        {
16            X = outPage.Size.Width - (textGenerator.GetWidth(barcode) + Border),
17            Y = outPage.Size.Height - (fontSize * (font.Ascent + font.Descent) + Border)
18        };
19
20        // Move to position
21        textGenerator.MoveTo(position);
22        // Add given barcode string
23        textGenerator.ShowLine(barcode);
24    }
25    // Paint the positioned barcode text
26    gen.PaintText(barcodeText);
27}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    // Create file stream
5    FileStream fontStream = new FileStream(fontPath, FileStream.Mode.READ_ONLY);
6    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
7    try (// Create output document
8        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
9
10        // Copy document-wide data
11        copyDocumentData(inDoc, outDoc);
12
13        // Create embedded font in output document
14        Font font = Font.create(outDoc, fontStream, true);
15
16        // Define page copy options
17        PageCopyOptions copyOptions = new PageCopyOptions();
18
19        // Copy first page, add barcode, and append to output document
20        Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
21        addBarcode(outDoc, outPage, barcode, font, 50);
22        outDoc.getPages().add(outPage);
23
24        // Copy remaining pages and append to output document
25        PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
26        PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
27        outDoc.getPages().addAll(copiedPages);
28    }
29}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void addBarcode(Document outputDoc, Page outPage, String barcode, Font font, double fontSize) throws ToolboxException, IOException {
2    try (// Create content generator
3        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
4        // Create text object
5        Text barcodeText = Text.create(outputDoc);
6
7        // Create a text generator
8        TextGenerator textgenerator = new TextGenerator(barcodeText, font, fontSize, null);
9
10        // Calculate position
11        Point position = new Point(outPage.getSize().width - (textgenerator.getWidth(barcode) + Border),
12                outPage.getSize().height - (fontSize * (font.getAscent() + font.getDescent()) + Border));
13
14        // Move to position
15        textgenerator.moveTo(position);
16        // Add given barcode string
17        textgenerator.showLine(barcode);
18        // Close text generator
19        textgenerator.close();
20
21        // Paint the positioned barcode text
22        generator.paintText(barcodeText);
23    }
24}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_barcode(out_doc: Document, out_page: Page, barcode: str, font: Font, font_size: float):
2    # Create content generator
3    with ContentGenerator(out_page.content, False) as gen:
4        # Create text object
5        barcode_text = Text.create(out_doc)
6
7        #  Create text generator
8        with TextGenerator(barcode_text, font, font_size, None) as text_generator:
9            # Calculate position
10            position = Point(x=out_page.size.width - (text_generator.get_width(barcode) + border), 
11                             y=out_page.size.height - (font_size * (font.ascent + font.descent) + border))
12
13            # Move to position
14            text_generator.move_to(position)
15            # Add given barcode string
16            text_generator.show_line(barcode)
17
18        # Paint the positioned barcode text
19        gen.paint_text(barcode_text)

Add Data Matrix to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Create embedded font in output document
19pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
20GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                 Ptx_GetLastError());
22
23// Copy document-wide data
24GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
25                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
26                                  Ptx_GetLastError());
27
28// Configure copy options
29pCopyOptions = PtxPdf_PageCopyOptions_New();
30
31// Get page lists of input and output document
32pInPageList = PtxPdf_Document_GetPages(pInDoc);
33GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
34                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
35                                 szErrorBuff, Ptx_GetLastError());
36pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
37GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
38                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
39                                 szErrorBuff, Ptx_GetLastError());
40
41// Copy first page
42pInPage = PtxPdf_PageList_Get(pInPageList, 0);
43GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"),
44                                 szErrorBuff, Ptx_GetLastError());
45pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
46GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
47                                 Ptx_GetLastError());
48
49// Add datamatrix image to copied page
50if (addDataMatrix(pOutDoc, pOutPage, szDatamatrixPath) != 0)
51    goto cleanup;
52
53// Add page to output document
54GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
55                                  _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
56                                  szErrorBuff, Ptx_GetLastError());
57
58// Get remaining pages from input
59pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
60GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
61                                 _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
62                                 szErrorBuff, Ptx_GetLastError());
63
64// Copy remaining pages to output
65pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
66GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
67                                 _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
68                                 szErrorBuff, Ptx_GetLastError());
69
70// Add the copied pages to the output document
71GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
72                                  _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
73                                  szErrorBuff, Ptx_GetLastError());
74
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addDataMatrix(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szDataMatrixPath)
2{
3    TPtxPdfContent_Content*          pContent   = NULL;
4    TPtxPdfContent_ContentGenerator* pGenerator = NULL;
5    TPtxSys_StreamDescriptor         datamatrixDescriptor;
6    FILE*                            pDatamatrixStream = NULL;
7    TPtxPdfContent_Image*            pDatamatrix       = NULL;
8
9    pContent = PtxPdf_Page_GetContent(pOutPage);
10
11    // Create content generator
12    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
13    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
14                                     szErrorBuff, Ptx_GetLastError());
15
16    // Import data matrix
17    pDatamatrixStream = _tfopen(szDataMatrixPath, _T("rb"));
18    GOTO_CLEANUP_IF_NULL(pDatamatrixStream, _T("Failed to open data matrix file \"%s\".\n"), szDataMatrixPath);
19    PtxSysCreateFILEStreamDescriptor(&datamatrixDescriptor, pDatamatrixStream, 0);
20
21    // Create image object for data matrix
22    pDatamatrix = PtxPdfContent_Image_Create(pOutDoc, &datamatrixDescriptor);
23    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pDatamatrix, _T("Failed to create image object. %s (ErrorCode: 0x%08x).\n"),
24                                     szErrorBuff, Ptx_GetLastError());
25
26    // Data matrix size
27    double dDatamatrixSize = 85.0;
28
29    // Calculate Rectangle for data matrix
30    TPtxGeomReal_Size size;
31    PtxPdf_Page_GetSize(pOutPage, &size);
32    TPtxGeomReal_Rectangle rect;
33    rect.dLeft   = dBorder;
34    rect.dBottom = size.dHeight - (dDatamatrixSize + dBorder);
35    rect.dRight  = dDatamatrixSize + dBorder;
36    rect.dTop    = size.dHeight - dBorder;
37
38    // Paint image of data matrix into the specified rectangle
39    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
40        PtxPdfContent_ContentGenerator_PaintImage(pGenerator, pDatamatrix, &rect),
41        _T("Failed to paint data matrix into the specified rectangle. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
42        Ptx_GetLastError());
43
44cleanup:
45    if (pGenerator != NULL)
46        PtxPdfContent_ContentGenerator_Close(pGenerator);
47    if (pContent != NULL)
48        Ptx_Release(pContent);
49
50    return iReturnValue;
51}
Download code sample
1// Open input document 
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Copy first page, add datamatrix image, and append to output document
16    Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
17    AddDataMatrix(outDoc, outPage, datamatrixPath);
18    outDoc.Pages.Add(outPage);
19
20    // Copy remaining pages and append to output document
21    PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
22    PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
23    outDoc.Pages.AddRange(copiedPages);
24}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddDataMatrix(Document document, Page page, string datamatrixPath)
2{
3    // Create content generator
4    using ContentGenerator generator = new ContentGenerator(page.Content, false);
5
6    // Import data matrix
7    using Stream inMatrix = new FileStream(datamatrixPath, FileMode.Open, FileAccess.Read);
8
9    // Create image object for data matrix
10    Image datamatrix = Image.Create(document, inMatrix);
11
12    // Data matrix size
13    double datamatrixSize = 85;
14
15    // Calculate Rectangle for data matrix
16    Rectangle rect = new Rectangle
17    {
18        Left = Border,
19        Bottom = page.Size.Height - (datamatrixSize + Border),
20        Right = datamatrixSize + Border,
21        Top = page.Size.Height - Border
22    };
23
24    // Paint image of data matrix into the specified rectangle 
25    generator.PaintImage(datamatrix, rect);
26}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define page copy options
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Copy first page, add data matrix image, and append to output document
15        Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
16        addDatamatrix(outDoc, outPage, datamatrixPath);
17        outDoc.getPages().add(outPage);
18
19        // Copy remaining pages and append to output document
20        PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
21        PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
22        outDoc.getPages().addAll(copiedPages);
23    }
24}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void addDatamatrix(Document document, Page page, String datamatrixPath)
2        throws ToolboxException, IOException {
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(page.getContent(), false);
5        // Import data matrix
6        FileStream inMatrix = new FileStream(datamatrixPath, FileStream.Mode.READ_ONLY)) {
7
8        // Create image object for data matrix
9        Image datamatrix = Image.create(document, inMatrix);
10
11        // Data matrix size
12        double datamatrixSize = 85;
13
14        // Calculate Rectangle for data matrix
15        Rectangle rect = new Rectangle(Border, page.getSize().height - (datamatrixSize + Border),
16                datamatrixSize + Border, page.getSize().height - Border);
17
18        // Paint image of data matrix into the specified rectangle
19        generator.paintImage(datamatrix, rect);
20    }
21}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_data_matrix(document: Document, page: Page, data_matrix_path: str):
2    # Create content generator
3    with ContentGenerator(out_page.content, False) as generator:
4
5        #  Import data matrix
6        with io.FileIO(data_matrix_path, 'rb') as in_matrix_stream:
7
8            # Create image object for data matrix
9            data_matrix = Image.create(document, in_matrix_stream)
10
11            # Data matrix size
12            data_matrix_size = 85
13
14            # Calculate Rectangle for data matrix
15            rect = Rectangle(left=border, bottom=page.size.height - (data_matrix_size + border), right=data_matrix_size + border, top=page.size.height - border)
16
17        # Paint the positioned barcode text
18        generator.paint_image(data_matrix, rect)

Add image to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Configure copy options
24pCopyOptions = PtxPdf_PageCopyOptions_New();
25
26// Get input and output page lists
27pInPageList = PtxPdf_Document_GetPages(pInDoc);
28GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
29                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
30                                 szErrorBuff, Ptx_GetLastError());
31pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
32GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
33                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
34                                 szErrorBuff, Ptx_GetLastError());
35
36// Copy pages preceding selected page
37pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 0, iPageNumber - 1);
38GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range. %s (ErrorCode: 0x%08x).\n"),
39                                 szErrorBuff, Ptx_GetLastError());
40pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
41GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range. %s (ErrorCode: 0x%08x).\n"),
42                                 szErrorBuff, Ptx_GetLastError());
43GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
44                                  _T("Failed to add page range. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
45                                  Ptx_GetLastError());
46Ptx_Release(pInPageRange);
47pInPageRange = NULL;
48Ptx_Release(pOutPageRange);
49pOutPageRange = NULL;
50
51// Copy selected page an add image
52pInPage = PtxPdf_PageList_Get(pInPageList, iPageNumber - 1);
53GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
54                                 Ptx_GetLastError());
55pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
56GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
57                                 Ptx_GetLastError());
58if (addImage(pOutDoc, pOutPage, szImagePath, 150.0, 150.0) != 0)
59    goto cleanup;
60GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
61                                  _T("Failed to add page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
62                                  Ptx_GetLastError());
63
64// Copy remaining pages
65pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
66GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
67                                 _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
68                                 szErrorBuff, Ptx_GetLastError());
69pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
70GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
71                                 _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
72                                 szErrorBuff, Ptx_GetLastError());
73GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
74                                  _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
75                                  szErrorBuff, Ptx_GetLastError());
76
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addImage(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szImagePath, double x, double y)
2{
3    TPtxPdfContent_Content*          pContent   = NULL;
4    TPtxPdfContent_ContentGenerator* pGenerator = NULL;
5    TPtxSys_StreamDescriptor         imageDescriptor;
6    FILE*                            pImageStream = NULL;
7    TPtxPdfContent_Image*            pImage       = NULL;
8
9    pContent = PtxPdf_Page_GetContent(pOutPage);
10
11    // Create content generator
12    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
13
14    // Load image from input path
15    pImageStream = _tfopen(szImagePath, _T("rb"));
16    PtxSysCreateFILEStreamDescriptor(&imageDescriptor, pImageStream, 0);
17
18    // Create image object
19    pImage = PtxPdfContent_Image_Create(pOutDoc, &imageDescriptor);
20
21    double dResolution = 150.0;
22
23    TPtxGeomInt_Size size;
24    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Image_GetSize(pImage, &size),
25                                      _T("Failed to get image size. %s(ErrorCode: 0x%08x).\n"), szErrorBuff,
26                                      Ptx_GetLastError());
27
28    // Calculate Rectangle for data matrix
29    TPtxGeomReal_Rectangle rect;
30    rect.dLeft   = x;
31    rect.dBottom = y;
32    rect.dRight  = x + (double)size.iWidth * 72.0 / dResolution;
33    rect.dTop    = y + (double)size.iHeight * 72.0 / dResolution;
34
35    // Paint image into the specified rectangle
36    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintImage(pGenerator, pImage, &rect),
37                                      _T("Failed to paint image. %s(ErrorCode: 0x%08x).\n"), szErrorBuff,
38                                      Ptx_GetLastError());
39
40cleanup:
41    if (pGenerator != NULL)
42        PtxPdfContent_ContentGenerator_Close(pGenerator);
43    if (pContent != NULL)
44        Ptx_Release(pContent);
45
46    return iReturnValue;
47}
Download code sample
1// Open input document 
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Copy pages preceding selected page and append to output document
16    PageList inPageRange = inDoc.Pages.GetRange(0, pageNumber - 1);
17    PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
18    outDoc.Pages.AddRange(copiedPages);
19
20    // Copy selected page, add image, and append to output document
21    Page outPage = Page.Copy(outDoc, inDoc.Pages[pageNumber - 1], copyOptions);
22    AddImage(outDoc, outPage, imagePath, 150, 150);
23    outDoc.Pages.Add(outPage);
24
25    // Copy remaining pages and append to output document
26    inPageRange = inDoc.Pages.GetRange(pageNumber, inDoc.Pages.Count - pageNumber);
27    copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
28    outDoc.Pages.AddRange(copiedPages);
29}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddImage(Document document, Page page, string imagePath, double x, double y)
2{
3    // Create content generator 
4    using ContentGenerator generator = new ContentGenerator(page.Content, false);
5
6    // Load image from input path
7    using Stream inImage = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
8
9    // Create image object
10    Image image = Image.Create(document, inImage);
11    double resolution = 150;
12
13    // Calculate rectangle for image 
14    PdfTools.Toolbox.Geometry.Integer.Size size = image.Size;
15    Rectangle rect = new Rectangle
16    {
17        Left = x,
18        Bottom = y,
19        Right = x + size.Width * 72 / resolution,
20        Top = y + size.Height * 72 / resolution
21    };
22
23    // Paint image into the specified rectangle 
24    generator.PaintImage(image, rect);
25}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define page copy options
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Copy pages preceding selected page and append to output document
15        PageList inPageRange = inDoc.getPages().subList(0, pageNumber - 1);
16        PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
17        outDoc.getPages().addAll(copiedPages);
18
19        // Copy selected page, add image, and append to output document
20        Page outPage = Page.copy(outDoc, inDoc.getPages().get(pageNumber - 1), copyOptions);
21        addImage(outDoc, outPage, imagePath, 150, 150);
22        outDoc.getPages().add(outPage);
23
24        // Copy remaining pages and append to output document
25        inPageRange = inDoc.getPages().subList(pageNumber, inDoc.getPages().size());
26        copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
27        outDoc.getPages().addAll(copiedPages);
28    }
29}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void addImage(Document document, Page outPage, String imagePath, double x, double y)
2        throws ToolboxException, IOException {
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false);
5        // Load image from input path
6        FileStream inImage = new FileStream(imagePath, FileStream.Mode.READ_ONLY)) {
7        // Create image object
8        Image image = Image.create(document, inImage);
9
10        double resolution = 150;
11
12        // Calculate rectangle for image
13        Size size = image.getSize();
14        Rectangle rect = new Rectangle(x, y, x + size.getWidth() * 72 / resolution,
15                y + size.getHeight() * 72 / resolution);
16
17        // Paint image into the specified rectangle
18        generator.paintImage(image, rect);
19    }
20}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_image(document: Document, page: Page, image_path: str, x: float, y: float):
2    # Create content generator
3    with ContentGenerator(page.content, False) as generator:
4
5        # Load image from input path
6        with io.FileIO(image_path, 'rb') as in_image_stream:
7            # Create image object
8            image = Image.create(document, in_image_stream)
9            resolution = 150
10
11            # Calculate rectangle for image
12            size = image.size
13            rect = Rectangle(
14                left=x,
15                bottom=y,
16                right=x + size.width * 72 / resolution,
17                top=y + size.height * 72 / resolution
18            )
19
20            # Paint image into the specified rectangle
21            generator.paint_image(image, rect)

Add image mask to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(_T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
7                                 Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(_T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
16                                 Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Get the device color space
24TPtxPdfContent_ColorSpace* pColorSpace =
25    PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
26GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pColorSpace, _T("Failed to get the device color space. %s (ErrorCode: 0x%08x).\n"),
27                                 szErrorBuff, Ptx_GetLastError());
28
29// Chose the RGB color value
30double color[] = {1.0, 0.0, 0.0};
31size_t nColor  = sizeof(color) / sizeof(double);
32
33// Create paint object
34pPaint = PtxPdfContent_Paint_Create(pOutDoc, pColorSpace, color, nColor, NULL);
35GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pPaint, _T("Failed to create a transparent paint. %s (ErrorCode: 0x%08x).\n"),
36                                 szErrorBuff, Ptx_GetLastError());
37
38// Configure copy options
39pCopyOptions = PtxPdf_PageCopyOptions_New();
40
41// Get input and output page lists
42pInPageList = PtxPdf_Document_GetPages(pInDoc);
43GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
44                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
45                                 szErrorBuff, Ptx_GetLastError());
46pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
47GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
48                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
49                                 szErrorBuff, Ptx_GetLastError());
50
51// Copy first page an add image mask
52pInPage = PtxPdf_PageList_Get(pInPageList, 0);
53GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
54                                 Ptx_GetLastError());
55pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
56GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
57                                 Ptx_GetLastError());
58if (addImageMask(pOutDoc, pOutPage, szImageMaskPath, 250, 150) != 0)
59    goto cleanup;
60GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
61                                  _T("Failed to add page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
62                                  Ptx_GetLastError());
63
64// Copy remaining pages
65pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
66GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
67                                 _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
68                                 szErrorBuff, Ptx_GetLastError());
69pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
70GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
71                                 _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
72                                 szErrorBuff, Ptx_GetLastError());
73GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
74                                  _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
75                                  szErrorBuff, Ptx_GetLastError());
76
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addImageMask(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szImageMaskPath, double x, double y)
2{
3    TPtxPdfContent_Content*          pContent     = NULL;
4    TPtxPdfContent_ContentGenerator* pGenerator   = NULL;
5    FILE*                            pImageStream = NULL;
6    TPtxSys_StreamDescriptor         imageDescriptor;
7    TPtxPdfContent_ImageMask*        pImageMask = NULL;
8
9    pContent = PtxPdf_Page_GetContent(pOutPage);
10
11    // Create content generator
12    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
13    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
14                                     szErrorBuff, Ptx_GetLastError());
15
16    // Load image from input path
17    pImageStream = _tfopen(szImageMaskPath, _T("rb"));
18    GOTO_CLEANUP_IF_NULL(pImageStream, _T("Failed to open image mask file \"%s\".\n"), szImageMaskPath);
19    PtxSysCreateFILEStreamDescriptor(&imageDescriptor, pImageStream, 0);
20
21    // Create image mask object
22    pImageMask = PtxPdfContent_ImageMask_Create(pOutDoc, &imageDescriptor);
23    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pImageMask, _T("Failed to create image mask obejct. %s (ErrorCode: 0x%08x).\n"),
24                                     szErrorBuff, Ptx_GetLastError());
25
26    double           dResolution = 150.0;
27    TPtxGeomInt_Size size;
28    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ImageMask_GetSize(pImageMask, &size),
29                                      _T("Failed to get image mask size. %s(ErrorCode: 0x%08x).\n"), szErrorBuff,
30                                      Ptx_GetLastError());
31
32    // Calculate Rectangle for data matrix
33    TPtxGeomReal_Rectangle rect;
34    rect.dLeft   = x;
35    rect.dBottom = y;
36    rect.dRight  = x + (double)size.iWidth * 72.0 / dResolution;
37    rect.dTop    = y + (double)size.iHeight * 72.0 / dResolution;
38
39    // Paint image mask into the specified rectangle
40    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
41        PtxPdfContent_ContentGenerator_PaintImageMask(pGenerator, pImageMask, &rect, pPaint),
42        _T("Failed to paint image mask. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
43
44cleanup:
45    if (pGenerator != NULL)
46        PtxPdfContent_ContentGenerator_Close(pGenerator);
47    if (pContent != NULL)
48        Ptx_Release(pContent);
49
50    return iReturnValue;
51}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Get the device color space
13    ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
14
15    // Create paint object
16    paint = Paint.Create(outDoc, colorSpace, new double[] { 1.0, 0.0, 0.0 }, null);
17
18    // Define page copy options
19    PageCopyOptions copyOptions = new PageCopyOptions();
20
21    // Copy first page, add image mask, and append to output document
22    Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
23    AddImageMask(outDoc, outPage, imageMaskPath, 250, 150);
24    outDoc.Pages.Add(outPage);
25
26    // Copy remaining pages and append to output document
27    PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
28    PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
29    outDoc.Pages.AddRange(copiedPages);
30}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1    private static void AddImageMask(Document document, Page outPage, string imagePath, 
2        double x, double y)
3    {
4        // Create content generator 
5        using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
6
7        // Load image from input path
8        using Stream inImage = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
9
10        // Create image mask object
11        ImageMask imageMask = ImageMask.Create(document, inImage);
12        double resolution = 150;
13
14        // Calculate rectangle for image 
15        PdfTools.Toolbox.Geometry.Integer.Size size = imageMask.Size;
16        Rectangle rect = new Rectangle
17        {
18            Left = x,
19            Bottom = y,
20            Right = x + size.Width * 72 / resolution,
21            Top = y + size.Height * 72 / resolution
22        };
23
24        // Paint image mask into the specified rectangle
25        generator.PaintImageMask(imageMask, rect, paint);
26    }
27}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define page copy options
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Get the device color space
15        ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outDoc, ProcessColorSpaceType.RGB);
16
17        // Create paint object
18        paint = Paint.create(outDoc, colorSpace, new double[] { 1.0, 0.0, 0.0 }, null);
19
20        // Copy first page, add image mask, and append to output document
21        Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
22        addImageMask(outDoc, outPage, imageMaskPath, 250, 150);
23        outDoc.getPages().add(outPage);
24
25        // Copy remaining pages and append to output document
26        PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
27        PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
28        outDoc.getPages().addAll(copiedPages);
29    }
30}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void addImageMask(Document document, Page outPage, String imagePath, double x, double y)
2        throws ToolboxException, IOException {
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false);
5        // Load image from input path
6        FileStream inImage = new FileStream(imagePath, FileStream.Mode.READ_ONLY)) {
7        // Create image mask object
8        ImageMask imageMask = ImageMask.create(document, inImage);
9
10        double resolution = 150;
11
12        // Calculate rectangle for image
13        Size size = imageMask.getSize();
14        Rectangle rect = new Rectangle(x, y, x + size.getWidth() * 72 / resolution,
15                y + size.getHeight() * 72 / resolution);
16
17        // Paint image mask into the specified rectangle
18        generator.paintImageMask(imageMask, rect, paint);
19    }
20}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_image_mask(document: Document, page: Page, image_path: str, x: float, y: float):
2    # Create content generator
3    with ContentGenerator(page.content, False) as generator:
4
5        # Load image from input path
6        with io.FileIO(image_path, 'rb') as in_image_stream:
7            # Create image mask object
8            image_mask = ImageMask.create(document, in_image_stream)
9            resolution = 150
10
11            # Calculate rectangle for image
12            size = image_mask.size
13            rect = Rectangle(
14                left=x,
15                bottom=y,
16                right=x + size.width * 72 / resolution,
17                top=y + size.height * 72 / resolution
18            )
19
20            # Paint image mask into the specified rectangle
21            generator.paint_image_mask(image_mask, rect, paint)

Add line numbers to PDF

Download code sample
1        // Open input document
2        using Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read);
3        using Document inDoc = Document.Open(inStream, null);
4
5        // Create output document
6        using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
7        using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
8        // Copy document-wide data
9        CopyDocumentData(inDoc, outDoc);
10
11        // Create a font for the line numbers
12        var lineNumberFont = Font.CreateFromSystem(outDoc, "Arial", null, true);
13
14        // Define page copy options
15        PageCopyOptions pageCopyOptions = new();
16
17        // Copy all pages from input to output document
18        var inPages = inDoc.Pages;
19        var outPages = PageList.Copy(outDoc, inPages, pageCopyOptions);
20
21        // Iterate over all input-output page pairs
22        var pages = inPages.Zip(outPages);
23        foreach (var pair in pages)
24            AddLineNumbers(outDoc, lineNumberFont, pair);
25
26        // Add the finished pages to the output document's page list
27        outDoc.Pages.AddRange(outPages);
28    }
29    catch (Exception ex)
30    {
31        Console.WriteLine(ex.Message);
32    }
33}
34
1private static void AddLineNumbers(Document outDoc, Font lineNumberFont, (Page first, Page second) pair)
2{
3    // Add line numbers to all text found in the input page to the output page
4
5    // The input and output page
6    var inPage = pair.first;
7    var outPage = pair.second;
8
9    // Extract all text fragments
10    var extractor = new ContentExtractor(inPage.Content)
11    {
12        Ungrouping = UngroupingSelection.All
13    };
14
15    // The left-most horizontal position of all text fragments
16    double leftX = inPage.Size.Width;
17
18    // A comparison for doubles that considers distances smaller than the font size as equal
19    var comparison = new Comparison<double>(
20        (a, b) =>
21        {
22            var d = b - a;
23            if (Math.Abs(d) < fontSize)
24                return 0;
25            return Math.Sign(d);
26        });
27
28    // A container to hold the vertical positions of all text fragments, sorted and without duplicates
29    SortedSet<double> lineYPositions = new(Comparer<double>.Create(comparison));
30
31    // Iterate over all content elements of the input page
32    foreach (var element in extractor)
33    {
34        // Process only text elements
35        if (element is TextElement textElement)
36        {
37            // Iterate over all text fragments
38            foreach (var fragment in textElement.Text)
39            {
40                // Get the fragments base line starting point
41                var point = fragment.Transform.TransformPoint(new Point { X = fragment.BoundingBox.Left, Y = 0 });
42
43                // Update the left-most position
44                leftX = Math.Min(leftX, point.X);
45
46                // Add the vertical position
47                lineYPositions.Add(point.Y);
48            }
49        }
50    }
51
52    // If at least text fragment was found: add line numbers
53    if (lineYPositions.Count > 0)
54    {
55        // Create a text object and use a text generator
56        var text = Text.Create(outDoc);
57        using (var textGenerator = new TextGenerator(text, lineNumberFont, fontSize, null))
58        {
59            // Iterate over all vertical positions found in the input
60            foreach (var y in lineYPositions)
61            {
62                // The line number string
63                var lineNumberString = string.Format("{0}", ++lineNumber);
64
65                // The width of the line number string when shown on the page
66                var width = textGenerator.GetWidth(lineNumberString);
67
68                // Position line numbers right aligned
69                // with a given distance to the right-most horizontal position
70                // and at the vertical position of the current text fragment
71                textGenerator.MoveTo(new Point { X = leftX - width - distance, Y = y });
72
73                // Show the line number string
74                textGenerator.Show(lineNumberString);
75            }
76        }
77
78        // Use a content generator to paint the text onto the page
79        using var contentGenerator = new ContentGenerator(outPage.Content, false);
80        contentGenerator.PaintText(text);
81    }
82}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
6        // Copy document-wide data
7        copyDocumentData(inDoc, outDoc);
8
9        // Create embedded font in output document
10        Font font = Font.createFromSystem(outDoc, "Arial", null, true);
11
12        // Define page copy options
13        PageCopyOptions copyOptions = new PageCopyOptions();
14
15        // Copy all pages from input to output document
16        PageList inPages = inDoc.getPages();
17        PageList outPages = PageList.copy(outDoc, inPages, copyOptions);
18
19        // Iterate over all input-output page pairs and add line numbers
20        for (int i = 0; i < inPages.size(); ++i) {
21            addLineNumbers(outDoc, font, new SimpleEntry<>(inPages.get(i), outPages.get(i)));
22        }
23
24        // Add the finished pages to the output document's page list
25        outDoc.getPages().addAll(outPages);
26    }
27}
1private static void addLineNumbers(Document outDoc, Font lineNumberFont, Entry<Page, Page> pair) throws IOException, ToolboxException {
2    // Add line numbers to all text found in the input page to the output page
3
4    // The input and output page
5    Page inPage = pair.getKey();
6    Page outPage = pair.getValue();
7
8    // Extract all text fragments
9    ContentExtractor extractor = new ContentExtractor(inPage.getContent());
10    extractor.setUngrouping(UngroupingSelection.ALL);
11    // The left-most horizontal position of all text fragments
12    double leftX = inPage.getSize().getWidth();
13
14    Comparator<Double> comparator = new Comparator<Double>() {
15        @Override
16        public int compare(Double d1, Double d2) {
17            Double diff = d2 - d1;
18            if (Math.abs(diff) < fontSize)
19                return 0;
20            return (int) Math.signum(diff);
21        }
22    };
23
24    SortedSet<Double> lineYPositions = new TreeSet<>(comparator);
25
26    for (ContentElement element : extractor) {
27
28        // Process only text elements
29        if (element instanceof TextElement) {
30            TextElement textElement = (TextElement) element;
31            // Iterate over all text fragments
32            for (TextFragment fragment : textElement.getText()) {
33
34                // Get the fragments base line starting point
35                Point point = fragment.getTransform().transformPoint(new Point(fragment.getBoundingBox().left, 0));
36
37                // Update the left-most position
38                leftX = Math.min(leftX, point.x);
39
40                // Add the vertical position
41                lineYPositions.add(point.y);
42            }
43        }
44    }
45
46    // If at least one text fragment was found: add line numbers
47    if (lineYPositions.size() > 0) {
48
49        // Create a text object and use a text generator
50        Text text = Text.create(outDoc);
51        try (TextGenerator textGenerator = new TextGenerator(text, lineNumberFont, fontSize, null)) {
52            // Iterate over all vertical positions found in the input
53            for(double y : lineYPositions) {
54                // The line number string
55                String lineNumberString = String.valueOf(++lineNumber);
56
57                // The width of the line number string when shown on the page
58                double width = textGenerator.getWidth(lineNumberString);
59
60                // Position line numbers right aligned
61                // with a given distance to the right-most horizontal position
62                // and at the vertical position of the current text fragment
63                textGenerator.moveTo(new Point (leftX - width - distance, y));
64
65                // Show the line number string
66                textGenerator.show(lineNumberString);
67            }
68        }
69        try (ContentGenerator contentGenerator = new ContentGenerator(outPage.getContent(), false)) {
70            // Use a content generator to paint the text onto the page
71            contentGenerator.paintText(text);
72        }
73    }
74}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1# Class needed for a sorted list of unique values. 
2# The tolerance defines how 2 values are considered different
3class TolerantSortedSet:
4    def add(self, value: float):
5        for existing in self.data:
6            if abs(existing - value) < self.tolerance:
7                return  # Do not add duplicate-like value
8
9        self.data.append(value)
10        self.data.sort(reverse=self.sort_reverse)
11
12    def iterator(self):
13        return iter(self.data)
14
15    def display(self):
16        return str(self.data)
1def create_tolerant_sorted_set(tolerance: float, sort_reverse: bool):
2    tolerant_sorted_set = TolerantSortedSet()
3
4    tolerant_sorted_set.tolerance = tolerance
5    tolerant_sorted_set.sort_reverse = sort_reverse
6    tolerant_sorted_set.data = []
7
8    return tolerant_sorted_set
1def add_line_numbers(out_doc: Document, line_number_font: Font, pair: tuple):
2
3    global line_number
4
5    # Add line numbers to all text found in the input page to the output page
6
7    # The input and output page
8    in_page, out_page = pair
9
10    # Extract all text fragments
11    extractor = ContentExtractor(in_page.content)
12    extractor.ungrouping = UngroupingSelection.ALL
13
14    # The left-most horizontal position of all text fragments
15    left_x = in_page.size.width
16
17    # A comparison for doubles that considers distances smaller than the font size as equal
18    def comparison(a, b):
19        d = b - a
20        if abs(d) < font_size:
21            return 0
22        return (d > 0) - (d < 0)    # return 1 if d > 0, -1 if d < 0, 0 otherwise
23
24    # A sorted set to hold the vertical positions of all text fragments
25    # Keep the data sorted in reverse oder as the coordinates are reverse in a PDF
26    line_y_positions = create_tolerant_sorted_set(tolerance=font_size, sort_reverse=True)
27
28    # Iterate over all content elements of the input page
29    for element in extractor:
30        # Process only text elements
31        if isinstance(element, TextElement):
32            # Iterate over all text fragments
33            for fragment in element.text:
34                # Get the fragment's baseline starting point
35                point = fragment.transform.transform_point(
36                    Point(fragment.bounding_box.left, 0)
37                )
38
39                # Update the left-most position
40                left_x = min(left_x, point.x)
41
42                # Add the vertical position
43                line_y_positions.add(point.y)
44
45    # If at least one text fragment was found, add line numbers
46    if line_y_positions:
47        # Create a text object and use a text generator
48        text = Text.create(out_doc)
49        with TextGenerator(text, line_number_font, font_size, None) as text_generator:
50            # Iterate over all vertical positions found in the input
51            for y in line_y_positions.iterator():
52                # The line number string
53                line_number += 1
54                line_number_string = str(line_number)
55
56                # The width of the line number string when shown on the page
57                width = text_generator.get_width(line_number_string)
58
59                # Position line numbers right-aligned
60                # with a given distance to the right-most horizontal position
61                # and at the vertical position of the current text fragment
62                text_generator.move_to(Point(left_x - width - distance, y))
63
64                # Show the line number string
65                text_generator.show(line_number_string)
66
67        # Use a content generator to paint the text onto the page
68        with ContentGenerator(out_page.content, False) as content_generator:
69            content_generator.paint_text(text)

Add stamp to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&inDescriptor, pInStream, FALSE);
5pInDoc = PtxPdf_Document_Open(&inDescriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file %s.\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file %s cannot be closed. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Create embedded font in output document
19pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
20GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Embedded font cannot be created. %s (ErrorCode: 0x%08x).\n"),
21                                 szErrorBuff, Ptx_GetLastError());
22
23// Copy document-wide data
24GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
25                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
26                                  Ptx_GetLastError());
27
28// Get the color space
29TPtxPdfContent_ColorSpace* pColorSpace =
30    PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
31GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pColorSpace, _T("Failed to get the color space. %s (ErrorCode: 0x%08x).\n"),
32                                 szErrorBuff, Ptx_GetLastError());
33
34// Chose the RGB color values
35double color[] = {1.0, 0.0, 0.0};
36size_t nColor  = sizeof(color) / sizeof(double);
37pTransparency  = PtxPdfContent_Transparency_New(dAlpha);
38
39// Create paint object
40pPaint = PtxPdfContent_Paint_Create(pOutDoc, pColorSpace, color, nColor, pTransparency);
41GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pPaint, _T("Failed to create a transparent paint. %s (ErrorCode: 0x%08x).\n"),
42                                 szErrorBuff, Ptx_GetLastError());
43
44// Configure copy options
45pCopyOptions = PtxPdf_PageCopyOptions_New();
46
47// Loop through all pages of input
48pInPageList = PtxPdf_Document_GetPages(pInDoc);
49GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
50                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
51                                 szErrorBuff, Ptx_GetLastError());
52pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
53GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
54                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
55                                 szErrorBuff, Ptx_GetLastError());
56for (int i = 0; i < PtxPdf_PageList_GetCount(pInPageList); i++)
57{
58    // Get a list of pages
59    pInPage = PtxPdf_PageList_Get(pInPageList, i);
60
61    // Copy page from input to output
62    pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
63    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
64                                     _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"),
65                                     szErrorBuff, Ptx_GetLastError());
66
67    // Add stamp to page
68    if (addStamp(pOutDoc, pOutPage, szStampString, pFont, 50) == 1)
69    {
70        goto cleanup;
71    }
72
73    // Add page to output document
74    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
75                                      _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
76                                      szErrorBuff, Ptx_GetLastError());
77
78    if (pOutPage != NULL)
79    {
80        Ptx_Release(pOutPage);
81        pOutPage = NULL;
82    }
83
84    if (pInPage != NULL)
85    {
86        Ptx_Release(pInPage);
87        pInPage = NULL;
88    }
89}
90
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addStamp(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szStampString, TPtxPdfContent_Font* pFont,
2             double dFontSize)
3{
4    TPtxPdfContent_ContentGenerator* pGenerator     = NULL;
5    TPtxPdfContent_Text*             pText          = NULL;
6    TPtxPdfContent_TextGenerator*    pTextGenerator = NULL;
7    TPtxGeomReal_AffineTransform     trans;
8    TPtxGeomReal_Point               rotationCenter;
9    double                           dTextWidth;
10    double                           dFontAscent;
11
12    TPtxPdfContent_Content* pContent = PtxPdf_Page_GetContent(pOutPage);
13
14    // Create content generator
15    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
16    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
17                                     szErrorBuff, Ptx_GetLastError());
18
19    // Create text object
20    pText = PtxPdfContent_Text_Create(pOutDoc);
21    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"),
22                                     szErrorBuff, Ptx_GetLastError());
23
24    // Create a text generator
25    pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, dFontSize, NULL);
26    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"),
27                                     szErrorBuff, Ptx_GetLastError());
28
29    // Get output page size
30    TPtxGeomReal_Size size;
31    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size),
32                                      _T("Failed to read page size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
33                                      Ptx_GetLastError());
34
35    // Calculate point and angle of rotation
36    rotationCenter.dX     = size.dWidth / 2.0;
37    rotationCenter.dY     = size.dHeight / 2.0;
38    double dRotationAngle = atan2(size.dHeight, size.dWidth) / M_PI * 180.0;
39
40    // Rotate textinput around the calculated position
41    PtxGeomReal_AffineTransform_GetIdentity(&trans);
42    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
43        PtxGeomReal_AffineTransform_Rotate(&trans, dRotationAngle, &rotationCenter),
44        _T("Failed to rotate textinput around the calculated position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
45        Ptx_GetLastError());
46    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_Transform(pGenerator, &trans),
47                                      _T("Failed to modify the current transformation. %s (ErrorCode: 0x%08x).\n"),
48                                      szErrorBuff, Ptx_GetLastError());
49
50    // Calculate position
51    TPtxGeomReal_Point position;
52    dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampString);
53    GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dTextWidth, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
54    dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
55    GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dFontAscent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
56    position.dX = (size.dWidth - dTextWidth) / 2.0;
57    position.dY = (size.dHeight - dFontAscent * dFontSize) / 2.0;
58
59    // Move to position
60    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position),
61                                      _T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
62                                      Ptx_GetLastError());
63    // Set text rendering
64    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_SetFill(pTextGenerator, pPaint),
65                                      _T("Failed to set fill paint. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
66                                      Ptx_GetLastError());
67    // Add given stamp string
68    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szStampString),
69                                      _T("Failed to add stamp. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
70                                      Ptx_GetLastError());
71
72    // Close text generator
73    if (pTextGenerator != NULL)
74    {
75        PtxPdfContent_TextGenerator_Close(pTextGenerator);
76        pTextGenerator = NULL;
77    }
78
79    // Paint the positioned text
80    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText),
81                                      _T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
82                                      Ptx_GetLastError());
83
84cleanup:
85    if (pTextGenerator != NULL)
86        PtxPdfContent_TextGenerator_Close(pTextGenerator);
87    if (pText != NULL)
88        Ptx_Release(pText);
89    if (pGenerator != NULL)
90        PtxPdfContent_ContentGenerator_Close(pGenerator);
91    if (pContent != NULL)
92        Ptx_Release(pContent);
93
94    return iReturnValue;
95}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
13
14    // Get the color space
15    ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
16
17    // Choose the RGB color value
18    double[] color = { 1.0, 0.0, 0.0 };
19    Transparency transparency = new Transparency(alpha);
20
21    // Create paint object with the choosen RGB color
22    paint = Paint.Create(outDoc, colorSpace, color, transparency);
23
24    // Define copy options
25    PageCopyOptions copyOptions = new PageCopyOptions();
26
27    // Copy all pages from input document
28    foreach (Page inPage in inDoc.Pages)
29    {
30        // Copy page from input to output
31        Page outPage = Page.Copy(outDoc, inPage, copyOptions);
32
33        // Add text to page
34        AddStamp(outDoc, outPage, stampString);
35
36        // Add page to document
37        outDoc.Pages.Add(outPage);
38    }
39}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddStamp(Document outputDoc, Page outPage, string stampString)
2{
3    // Create content generator and text object
4    using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
5    Text text = Text.Create(outputDoc);
6
7    // Create text generator
8    using (TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null))
9    {
10        // Calculate point and angle of rotation
11        Point rotationCenter = new Point
12        {
13            X = outPage.Size.Width / 2.0,
14            Y = outPage.Size.Height / 2.0
15        };
16        double rotationAngle = Math.Atan2(outPage.Size.Height,
17            outPage.Size.Width) / Math.PI * 180.0;
18
19        // Rotate text input around the calculated position
20        AffineTransform trans = AffineTransform.Identity;
21        trans.Rotate(rotationAngle, rotationCenter);
22        gen.Transform(trans);
23
24        // Calculate position
25        Point position = new Point
26        {
27            X = (outPage.Size.Width - textgenerator.GetWidth(stampString)) / 2.0,
28            Y = (outPage.Size.Height - font.Ascent * fontSize) / 2.0
29        };
30
31        // Move to position
32        textgenerator.MoveTo(position);
33
34        // Set text paint
35        textgenerator.Fill = paint;
36
37        // Add given stamp string
38        textgenerator.ShowLine(stampString);
39    }
40    // Paint the positioned text
41    gen.PaintText(text);
42}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7        // Copy document-wide data
8        copyDocumentData(inDoc, outDoc);
9
10        // Create embedded font in output document
11        font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
12
13        // Get the color space
14        ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outDoc, ProcessColorSpaceType.RGB);
15
16        // Choose the RGB color value
17        double[] color = { 1.0, 0.0, 0.0 };
18        Transparency transparency = new Transparency(alpha);
19
20        // Create paint object
21        paint = Paint.create(outDoc, colorSpace, color, transparency);
22
23        // Define page copy options
24        PageCopyOptions copyOptions = new PageCopyOptions();
25
26        // Loop throw all pages of input
27        for (Page inPage : inDoc.getPages()) {
28            // Copy page from input to output
29            Page outPage = Page.copy(outDoc, inPage, copyOptions);
30
31            // Add text to page
32            addStamp(outDoc, outPage, stampString);
33
34            // Add page to document
35            outDoc.getPages().add(outPage);
36        }
37    }
38}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void addStamp(Document outputDoc, Page outPage, String stampString)
2        throws ToolboxException, IOException {
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
5        // Create text object
6        Text text = Text.create(outputDoc);
7        try (// Create text generator
8            TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null)) {
9            // Calculate point and angle of rotation
10            Point rotationCenter = new Point(outPage.getSize().width / 2.0, outPage.getSize().height / 2.0);
11
12            // Calculate rotation angle
13            double rotationAngle = Math.atan2(outPage.getSize().height, outPage.getSize().width) / Math.PI * 180.0;
14
15            // Rotate text input around the calculated position
16            AffineTransform trans = AffineTransform.getIdentity();
17            trans.rotate(rotationAngle, rotationCenter);
18            generator.transform(trans);
19
20            // Calculate position
21            Point position = new Point((outPage.getSize().width - textgenerator.getWidth(stampString)) / 2.0,
22                    (outPage.getSize().height - font.getAscent() * fontSize) / 2.0);
23
24            // Move to position
25            textgenerator.moveTo(position);
26
27            // Set text paint
28            textgenerator.setFill(paint);
29
30            // Add given stamp string
31            textgenerator.showLine(stampString);
32        }
33
34        // Paint the positioned text
35        generator.paintText(text);
36    }
37}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_stamp(output_doc: Document, out_page: Page, stamp_string: str):
2    # Create content generator and text object
3    with ContentGenerator(out_page.content, False) as gen:
4        text = Text.create(output_doc)
5
6        # Create text generator
7        with TextGenerator(text, font, font_size, None) as text_generator:
8            # Calculate point and angle of rotation
9            rotation_center = Point(
10                x=out_page.size.width / 2.0,
11                y=out_page.size.height / 2.0
12            )
13            rotation_angle = math.atan2(out_page.size.height, out_page.size.width) / math.pi * 180.0
14
15            # Rotate text input around the calculated position
16            trans = AffineTransform.get_identity()
17            trans.rotate(rotation_angle, rotation_center)
18            gen.transform(trans)
19
20            # Calculate position
21            position = Point(
22                x=(out_page.size.width - text_generator.get_width(stamp_string)) / 2.0,
23                y=(out_page.size.height - font.ascent * font_size) / 2.0
24            )
25
26            # Move to position
27            text_generator.move_to(position)
28
29            # Set text paint
30            text_generator.fill = paint
31
32            # Add given stamp string
33            text_generator.show_line(stamp_string)
34
35        # Paint the positioned text
36        gen.paint_text(text)

Add text to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Create embedded font in output document
19pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
20GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                 Ptx_GetLastError());
22
23// Copy document-wide data
24GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
25                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
26                                  Ptx_GetLastError());
27
28// Configure copy options
29pCopyOptions = PtxPdf_PageCopyOptions_New();
30
31// Get page lists of input and output document
32pInPageList = PtxPdf_Document_GetPages(pInDoc);
33GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
34                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
35                                 szErrorBuff, Ptx_GetLastError());
36pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
37GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
38                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
39                                 szErrorBuff, Ptx_GetLastError());
40
41// Copy first page
42pInPage = PtxPdf_PageList_Get(pInPageList, 0);
43GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"),
44                                 szErrorBuff, Ptx_GetLastError());
45pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
46GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
47                                 Ptx_GetLastError());
48
49// Add text to copied page
50if (addText(pOutDoc, pOutPage, szTextString, pFont, 15) != 0)
51    goto cleanup;
52
53// Add page to output document
54GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
55                                  _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
56                                  szErrorBuff, Ptx_GetLastError());
57
58// Get remaining pages from input
59pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
60GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
61                                 _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"),
62                                 szErrorBuff, Ptx_GetLastError());
63
64// Copy remaining pages to output
65pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
66GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange,
67                                 _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"),
68                                 szErrorBuff, Ptx_GetLastError());
69
70// Add the copied pages to the output document
71GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
72                                  _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"),
73                                  szErrorBuff, Ptx_GetLastError());
74
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addText(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szTextString, TPtxPdfContent_Font* pFont,
2            double dFontSize)
3{
4    TPtxPdfContent_Content*          pContent       = NULL;
5    TPtxPdfContent_ContentGenerator* pGenerator     = NULL;
6    TPtxPdfContent_Text*             pText          = NULL;
7    TPtxPdfContent_TextGenerator*    pTextGenerator = NULL;
8    TPtxGeomReal_Size                size;
9    TPtxGeomReal_Point               position;
10    double                           dFontAscent;
11
12    pContent = PtxPdf_Page_GetContent(pOutPage);
13    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pContent, _T("Failed to get content of output file. %s (ErrorCode: 0x%08x).\n"),
14                                     szErrorBuff, Ptx_GetLastError());
15
16    // Create content generator
17    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
18    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
19                                     szErrorBuff, Ptx_GetLastError());
20
21    // Create text object
22    pText = PtxPdfContent_Text_Create(pOutDoc);
23    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create text object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
24                                     Ptx_GetLastError());
25
26    // Create a text generator
27    pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, dFontSize, NULL);
28    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"),
29                                     szErrorBuff, Ptx_GetLastError());
30
31    // Get output page size
32    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size),
33                                      _T("Failed to read page size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
34                                      Ptx_GetLastError());
35
36    dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
37    GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dFontAscent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
38
39    // Calculate position
40    position.dX = dBorder;
41    position.dY = size.dHeight - dBorder - dFontSize * dFontAscent;
42
43    // Move to position
44    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position),
45                                      _T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
46                                      Ptx_GetLastError());
47    // Add given text string
48    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szTextString),
49                                      _T("Failed to add text string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
50                                      Ptx_GetLastError());
51    // Close text generator
52    PtxPdfContent_TextGenerator_Close(pTextGenerator);
53    pTextGenerator = NULL;
54
55    // Paint the positioned text
56    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText),
57                                      _T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
58                                      Ptx_GetLastError());
59
60cleanup:
61    if (pTextGenerator != NULL)
62        PtxPdfContent_TextGenerator_Close(pTextGenerator);
63    if (pText != NULL)
64        Ptx_Release(pText);
65    if (pGenerator != NULL)
66        PtxPdfContent_ContentGenerator_Close(pGenerator);
67    if (pContent != NULL)
68        Ptx_Release(pContent);
69
70    return iReturnValue;
71}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Create a font
13    font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
14
15    // Define page copy options
16    PageCopyOptions copyOptions = new PageCopyOptions();
17
18    // Copy first page, add text, and append to output document
19    Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
20    AddText(outDoc, outPage, textString);
21    outDoc.Pages.Add(outPage);
22
23    // Copy remaining pages and append to output document
24    PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
25    PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
26    outDoc.Pages.AddRange(copiedPages);
27}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddText(Document outputDoc, Page outPage, string textString)
2{
3    // Create content generator and text object
4    using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
5    Text text = Text.Create(outputDoc);
6
7    // Create text generator
8    using (TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null))
9    {
10        // Calculate position
11        Point position = new Point
12        {
13            X = border,
14            Y = outPage.Size.Height - border - fontSize * font.Ascent
15        };
16
17        // Move to position
18        textGenerator.MoveTo(position);
19        // Add given text string
20        textGenerator.ShowLine(textString);
21    }
22    // Paint the positioned text
23    gen.PaintText(text);
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7        // Copy document-wide data
8        copyDocumentData(inDoc, outDoc);
9
10        // Create embedded font in output document
11        font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
12
13        // Define page copy options
14        PageCopyOptions copyOptions = new PageCopyOptions();
15
16        // Copy first page, add text, and append to output document
17        Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
18        addText(outDoc, outPage, textString);
19        outDoc.getPages().add(outPage);
20
21        // Copy remaining pages and append to output document
22        PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
23        PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
24        outDoc.getPages().addAll(copiedPages);
25    }
26}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data (excluding metadata)
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Viewer settings
9    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
10
11    // Associated files (for PDF/A-3 and PDF 2.0 only)
12    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
13    for (FileReference inFileRef : inDoc.getAssociatedFiles())
14        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
15
16    // Plain embedded files
17    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
18    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
19        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
20}
1private static void addText(Document outputDoc, Page outPage, String textString)
2        throws ToolboxException, IOException {
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
5        // Create text object
6        Text text = Text.create(outputDoc);
7
8        try (// Create a text generator
9            TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null)) {
10            // Calculate position
11            Point position = new Point(border, outPage.getSize().height - border - fontSize * font.getAscent());
12
13            // Move to position
14            textgenerator.moveTo(position);
15            // Add given text string
16            textgenerator.showLine(textString);
17        }
18
19        // Paint the positioned text
20        generator.paintText(text);
21    }
22}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_text(output_doc: Document, output_page: Page, text_string: str):
2    # Create content generator and text object
3    with ContentGenerator(output_page.content, False) as gen:
4        text = Text.create(output_doc)
5
6        # Create text generator
7        with TextGenerator(text, font, font_size, None) as textGenerator:
8            # Calculate position
9            position = Point(border, output_page.size.height - border - font_size * font.ascent)
10
11            # Move to position
12            textGenerator.move_to(position)
13            # Add given text string
14            textGenerator.show_line(text_string)
15
16        # Paint the positioned text
17        gen.paint_text(text)

Add vector graphic to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Configure copy options
24pCopyOptions = PtxPdf_PageCopyOptions_New();
25
26// Loop through all pages of input
27pInPageList = PtxPdf_Document_GetPages(pInDoc);
28GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
29                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
30                                 szErrorBuff, Ptx_GetLastError());
31pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
32GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
33                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
34                                 szErrorBuff, Ptx_GetLastError());
35for (int iPage = 1; iPage <= PtxPdf_PageList_GetCount(pInPageList); iPage++)
36{
37    pInPage = PtxPdf_PageList_Get(pInPageList, iPage - 1);
38
39    // Copy page from input to output
40    pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
41    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
42                                     _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"),
43                                     szErrorBuff, Ptx_GetLastError());
44    PtxPdf_Page_GetSize(pOutPage, &size);
45
46    // Add text on first page
47    if (addLine(pOutDoc, pOutPage) == 1)
48    {
49        goto cleanup;
50    }
51
52    // Add page to output document
53    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
54                                      _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
55                                      szErrorBuff, Ptx_GetLastError());
56
57    if (pOutPage != NULL)
58    {
59        Ptx_Release(pOutPage);
60        pOutPage = NULL;
61    }
62
63    if (pInPage != NULL)
64    {
65        Ptx_Release(pInPage);
66        pInPage = NULL;
67    }
68}
69
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addLine(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage)
2{
3    TPtxPdfContent_Content*          pContent             = NULL;
4    TPtxPdfContent_ContentGenerator* pGenerator           = NULL;
5    TPtxPdfContent_Path*             pPath                = NULL;
6    TPtxPdfContent_PathGenerator*    pPathGenerator       = NULL;
7    TPtxPdfContent_ColorSpace*       pDeviceRgbColorSpace = NULL;
8    double                           aColor[3];
9    TPtxPdfContent_Paint*            pPaint = NULL;
10    TPtxPdfContent_Stroke*           pStroke;
11    TPtxGeomReal_Size                pageSize;
12    TPtxGeomReal_Point               point;
13
14    pContent = PtxPdf_Page_GetContent(pOutPage);
15    PtxPdf_Page_GetSize(pOutPage, &pageSize);
16
17    // Create content generator
18    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
19    GOTO_CLEANUP_IF_NULL(pGenerator, szErrorBuff, Ptx_GetLastError());
20
21    // Create a path
22    pPath = PtxPdfContent_Path_New();
23    GOTO_CLEANUP_IF_NULL(pPath, szErrorBuff, Ptx_GetLastError());
24
25    // Create a path generator
26    pPathGenerator = PtxPdfContent_PathGenerator_New(pPath);
27    GOTO_CLEANUP_IF_NULL(pPathGenerator, szErrorBuff, Ptx_GetLastError());
28
29    // Draw a line diagonally across the page
30    point.dX = 10.0;
31    point.dY = 10.0;
32    GOTO_CLEANUP_IF_FALSE(PtxPdfContent_PathGenerator_MoveTo(pPathGenerator, &point), szErrorBuff, Ptx_GetLastError());
33    point.dX = pageSize.dWidth - 10.0;
34    point.dY = pageSize.dHeight - 10.0;
35    GOTO_CLEANUP_IF_FALSE(PtxPdfContent_PathGenerator_LineTo(pPathGenerator, &point), szErrorBuff, Ptx_GetLastError());
36
37    // Close the path generator in order to finish the path
38    PtxPdfContent_PathGenerator_Close(pPathGenerator);
39    pPathGenerator = NULL;
40
41    // Create a RGB color space
42    pDeviceRgbColorSpace =
43        PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
44    GOTO_CLEANUP_IF_NULL(pDeviceRgbColorSpace, szErrorBuff, Ptx_GetLastError());
45
46    // Initialize a red color
47    aColor[0] = 1.0;
48    aColor[1] = 0.0;
49    aColor[2] = 0.0;
50
51    // Create a paint
52    pPaint =
53        PtxPdfContent_Paint_Create(pOutDoc, pDeviceRgbColorSpace, aColor, sizeof(aColor) / sizeof(aColor[0]), NULL);
54    GOTO_CLEANUP_IF_NULL(pPaint, szErrorBuff, Ptx_GetLastError());
55
56    // Setup stroking parameters with given paint and line width
57    pStroke = PtxPdfContent_Stroke_New(pPaint, 10.0);
58    GOTO_CLEANUP_IF_NULL(pStroke, szErrorBuff, Ptx_GetLastError());
59
60    // Draw the path onto the page
61    GOTO_CLEANUP_IF_FALSE(PtxPdfContent_ContentGenerator_PaintPath(pGenerator, pPath, NULL, pStroke), szErrorBuff,
62                          Ptx_GetLastError());
63
64cleanup:
65    if (pPathGenerator != NULL)
66        PtxPdfContent_PathGenerator_Close(pPathGenerator);
67    if (pGenerator != NULL)
68        PtxPdfContent_ContentGenerator_Close(pGenerator);
69    if (pContent != NULL)
70        Ptx_Release(pContent);
71
72    return iReturnValue;
73}
Download code sample
1// Open input document 
2using (System.IO.Stream inStream = new System.IO.FileStream(inPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (System.IO.Stream outStream = new System.IO.FileStream(outPath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Copy all pages from input document
16    foreach (Page inPage in inDoc.Pages)
17    {
18        Page outPage = Page.Copy(outDoc, inPage, copyOptions);
19
20        // Add a line
21        AddLine(outDoc, outPage);
22
23        // Add page to output document 
24        outDoc.Pages.Add(outPage);
25    }
26}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddLine(Document document, Page page)
2{
3    // Create content generator 
4    using ContentGenerator generator = new ContentGenerator(page.Content, false);
5
6    // Create a path
7    Path path = new Path();
8    using (PathGenerator pathGenerator = new PathGenerator(path))
9    {
10        // Draw a line diagonally across the page
11        Size pageSize = page.Size;
12        pathGenerator.MoveTo(new Point() { X = 10.0, Y = 10.0 });
13        pathGenerator.LineTo(new Point() { X = pageSize.Width - 10.0, Y = pageSize.Height - 10.0 });
14    }
15
16    // Create a RGB color space
17    ColorSpace deviceRgbColorSpace = ColorSpace.CreateProcessColorSpace(document, ProcessColorSpaceType.Rgb);
18
19    // Create a red color
20    double[] color = new double[] { 1.0, 0.0, 0.0 };
21
22    // Create a paint
23    Paint paint = Paint.Create(document, deviceRgbColorSpace, color, null);
24
25    // Create stroking parameters with given paint and line width
26    Stroke stroke = new Stroke(paint, 10.0);
27
28    // Draw the path onto the page
29    generator.PaintPath(path, null, stroke);
30}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define page copy options
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Copy all pages
15        for (Page inPage : inDoc.getPages()) {
16            // Copy page from input to output
17            Page outPage = Page.copy(outDoc, inPage, copyOptions);
18
19            // Add a line
20            addLine(outDoc, outPage);
21
22            // Add page to output document
23            outDoc.getPages().add(outPage);
24        }
25    }
26}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void addLine(Document document, Page outPage)
2        throws ToolboxException, IOException {
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
5
6        // Create a path
7        Path path = new Path();
8        try (// Create a path generator
9            PathGenerator pathGenerator = new PathGenerator(path)) {
10            // Draw a line diagonally across the page
11            Size pageSize = outPage.getSize();
12            pathGenerator.moveTo(new Point(10.0, 10.0));
13            pathGenerator.lineTo(new Point(pageSize.width - 10.0, pageSize.height - 10.0));
14        }
15
16        // Create a RGB color space
17        ColorSpace deviceRgbColorSpace = ColorSpace.createProcessColorSpace(document, ProcessColorSpaceType.RGB);
18
19        // Create a red color
20        double[] color = new double[] { 1.0, 0.0, 0.0 };
21
22        // Create a paint
23        Paint paint = Paint.create(document, deviceRgbColorSpace, color, null);
24
25        // Create stroking parameters with given paint and line width
26        Stroke stroke = new Stroke(paint, 10.0);
27
28        // Draw the path onto the page
29        generator.paintPath(path, null, stroke);
30    }
31}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_line(out_doc: Document, page: Page):
2    # Extract content generator
3    with ContentGenerator(page.content, False) as generator:
4
5        # Create a path
6        path = Path()
7        with PathGenerator(path) as path_generator:
8            # Draw a line diagonally across the page
9            page_size = page.size
10            path_generator.move_to(Point(x = 10.0, y = 10.0))
11            path_generator.line_to(Point(x = page_size.width - 10.0, y=page_size.height - 10.0))
12
13        # Create a RGB color space
14        device_rgb_color_space = ColorSpace.create_process_color_space(out_doc, ProcessColorSpaceType.RGB)
15
16        # Create a red color
17        red = [1.0, 0.0, 0.0]
18
19        #  Create a paint
20        paint = Paint.create(out_doc, device_rgb_color_space, red, None)
21
22        # Create stroking parameters with given paint and line width
23        stroke = Stroke(paint, 10.0)
24
25        # Draw the path onto the page
26        generator.paint_path(path, None, stroke)

Layout text on PDF page

Download code sample
1// Create output document
2using (Stream outStream = new FileStream(outPath, FileMode.CreateNew, FileAccess.ReadWrite))
3using (Document outDoc = Document.Create(outStream, null, null))
4{
5    Font font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
6
7    // Create page
8    Page outPage = Page.Create(outDoc, PageSize);
9
10    // Add text as justified text
11    LayoutText(outDoc, outPage, textPath, font, 20);
12
13    // Add page to document
14    outDoc.Pages.Add(outPage);
15}
1private static void LayoutText(Document outputDoc, Page outPage, string textPath, Font font,
2    double fontSize)
3{
4    // Create content generator 
5    using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
6
7    // Create text object
8    Text text = Text.Create(outputDoc);
9
10    // Create text generator
11    using TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null);
12
13    // Calculate position
14    Point position = new Point
15    {
16        X = Border,
17        Y = outPage.Size.Height - Border
18    };
19
20    // Move to position
21    textGenerator.MoveTo(position);
22
23    // Loop through all lines of the textinput
24    string[] lines = File.ReadAllLines(textPath, Encoding.Default);
25    foreach (string line in lines)
26    {
27        // Split string in substrings
28        string[] substrings = line.Split(new char[] { ' ' }, StringSplitOptions.None);
29        string currentLine = null;
30        double maxWidth = outPage.Size.Width - Border * 2;
31        int wordcount = 0;
32
33        // Loop through all words of input strings
34        foreach (string word in substrings)
35        {
36            string tempLine;
37
38            // Concatenate substrings to line
39            if (currentLine != null)
40                tempLine = currentLine + " " + word;
41            else
42                tempLine = word;
43
44            // Calculate the current width of line
45            double width = textGenerator.GetWidth(currentLine);
46            if (textGenerator.GetWidth(tempLine) > maxWidth)
47            {
48                // Calculate the word spacing
49                textGenerator.WordSpacing = (maxWidth - width) / (wordcount - 1);
50                // Paint on new line
51                textGenerator.ShowLine(currentLine);
52                textGenerator.WordSpacing = 0;
53                currentLine = word;
54                wordcount = 1;
55            }
56            else
57            {
58                currentLine = tempLine;
59                wordcount++;
60            }
61        }
62        textGenerator.WordSpacing = 0;
63        // Add given stamp string
64        textGenerator.ShowLine(currentLine);
65    }
66    // Paint the positioned text
67    gen.PaintText(text);
68}
Download code sample
1try (
2    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
3    try (// Create output document
4        Document outDoc = Document.create(outStream, null, null)) {
5        // Create embedded font in output document
6        Font font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
7
8        // Create page
9        Page outPage = Page.create(outDoc, new Size(595, 842));
10
11        // Add text to document
12        layoutText(outDoc, outPage, textPath, font, 20);
13
14        // Add page to output document
15        outDoc.getPages().add(outPage);
16    }
17}
1private static void layoutText(Document outputDoc, Page outPage, String textPath, Font font, double fontSize)
2        throws ToolboxException, IOException {
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
5        // Create text object
6        Text text = Text.create(outputDoc);
7
8        try (// Create a text generator
9            TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null)) {
10
11            // Calculate position
12            Point position = new Point(Border, outPage.getSize().height - Border);
13
14            // Move to position
15            textGenerator.moveTo(position);
16
17            // Loop throw all lines of the textinput
18            List<String> lines = Files.readAllLines(Paths.get(textPath), Charset.defaultCharset());
19            for (String line : lines) {
20                // Split string in substrings
21                String[] substrings = line.split(" ");
22                String currentLine = null;
23                double maxWidth = outPage.getSize().width - (Border * 2);
24
25                int wordCount = 0;
26
27                // Loop throw all words of input strings
28                for (String word : substrings) {
29                    String tempLine;
30
31                    // Concatenate substrings to line
32                    if (currentLine != null) {
33                        tempLine = currentLine + " " + word;
34                    } else {
35                        tempLine = word;
36                    }
37
38                    // Calculate the current width of line
39                    double width = textGenerator.getWidth(currentLine);
40
41                    if ((textGenerator.getWidth(tempLine) > maxWidth)) {
42                        // Calculate the word spacing
43                        textGenerator.setWordSpacing((maxWidth - width) / (double) (wordCount - 1));
44
45                        // Paint on new line
46                        textGenerator.showLine(currentLine);
47                        textGenerator.setWordSpacing(0);
48                        currentLine = word;
49                        wordCount = 1;
50                    } else {
51                        currentLine = tempLine;
52                        wordCount++;
53                    }
54                }
55                textGenerator.setWordSpacing(0);
56                // Add given stamp string
57                textGenerator.showLine(currentLine);
58            }
59        }
60        // Paint the positioned text
61        generator.paintText(text);
62    }
63}
Download code sample
1
2
3# Create output document
4with io.FileIO(output_file_path, "wb+") as out_stream:
5    with Document.create(out_stream, None, None) as out_doc:
6
7        font = Font.create_from_system(out_doc, "Arial", "Italic", True)
8
9        # Create page
10        out_page = Page.create(out_doc, PAGE_SIZE)
11
12        # Add text as justified text
13        layout_text(out_doc, out_page, input_text_path, font, font_size=20)
14
15        # Add page to document
16        out_doc.pages.append(out_page)
17
1def layout_text(output_doc: Document, out_page: Page, text_path: str, font: Font, font_size: float):
2    """
3    Layout and justify text on the PDF page.
4    """
5    # Create content generator
6    with ContentGenerator(out_page.content, False) as generator:
7
8        # Create text object
9        text = Text.create(output_doc)
10
11        # Create text generator
12        with TextGenerator(text, font, font_size, None) as text_generator:
13
14            # Calculate starting position
15            position = Point(x=BORDER, y=out_page.size.height - BORDER)
16
17            # Move to position
18            text_generator.move_to(position)
19
20            with open(text_path, "r", encoding="utf-8") as file:
21                lines = file.readlines()
22
23            # Loop through all lines of the textinput
24            for line in lines:
25                # Split string in substrings
26                substrings = line.split(" ")
27                current_line = ""
28                max_width = out_page.size.width - BORDER * 2
29                word_count = 0
30
31                # Loop through all words of input strings
32                for word in substrings:
33                    # Concatenate substrings to line
34                    temp_line = f"{current_line} {word}".strip()
35
36                    # Calculate the current width of line
37                    current_width = text_generator.get_width(current_line)
38
39                    if text_generator.get_width(temp_line) > max_width:
40                        # Calculate the word spacing
41                        text_generator.word_spacing = (max_width - current_width) / (word_count - 1)
42                        text_generator.show_line(current_line)
43                        text_generator.word_spacing = 0
44                        current_line = word
45                        word_count = 1
46                    else:
47                        current_line = temp_line
48                        word_count += 1
49
50                text_generator.word_spacing = 0
51                # Add given stamp string
52                text_generator.show_line(current_line)
53
54        # Paint the positioned text
55        generator.paint_text(text)

Stamp page number to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Create embedded font in output document
19pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T(""), TRUE);
20GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                 Ptx_GetLastError());
22
23// Copy document-wide data
24GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
25                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
26                                  Ptx_GetLastError());
27
28// Configure copy options
29pCopyOptions = PtxPdf_PageCopyOptions_New();
30
31// Copy all pages
32pInPageList = PtxPdf_Document_GetPages(pInDoc);
33GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
34                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
35                                 szErrorBuff, Ptx_GetLastError());
36pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
37GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
38                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"),
39                                 szErrorBuff, Ptx_GetLastError());
40for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
41{
42    pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
43
44    // Copy page from input to output
45    pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
46    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
47                                     _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"),
48                                     szErrorBuff, Ptx_GetLastError());
49    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size),
50                                      _T("Failed to get size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
51                                      Ptx_GetLastError());
52
53    // Stamp page number on current page of output document
54    if (addPageNumber(pOutDoc, pOutPage, pFont, iPage + 1) == 1)
55    {
56        goto cleanup;
57    }
58
59    // Add page to output document
60    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
61                                      _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
62                                      szErrorBuff, Ptx_GetLastError());
63
64    if (pOutPage != NULL)
65    {
66        Ptx_Release(pOutPage);
67        pOutPage = NULL;
68    }
69
70    if (pInPage != NULL)
71    {
72        Ptx_Release(pInPage);
73        pInPage = NULL;
74    }
75}
76
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
1int addPageNumber(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TPtxPdfContent_Font* pFont, int nPageNumber)
2{
3    TPtxPdfContent_Content*          pContent       = NULL;
4    TPtxPdfContent_ContentGenerator* pGenerator     = NULL;
5    TPtxPdfContent_Text*             pText          = NULL;
6    TPtxPdfContent_TextGenerator*    pTextGenerator = NULL;
7
8    pContent = PtxPdf_Page_GetContent(pOutPage);
9
10    // Create content generator
11    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
12    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
13                                     szErrorBuff, Ptx_GetLastError());
14
15    // Create text object
16    pText = PtxPdfContent_Text_Create(pOutDoc);
17    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"),
18                                     szErrorBuff, Ptx_GetLastError());
19
20    // Create a text generator with the given font, size and position
21    pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, 8, NULL);
22    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"),
23                                     szErrorBuff, Ptx_GetLastError());
24
25    // Generate string to be stamped as page number
26    char szStampBuffer[50];
27    snprintf(szStampBuffer, sizeof(szStampBuffer), _T("Page %d"), nPageNumber);
28    TCHAR* szStampText = szStampBuffer;
29
30    double dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampText);
31    GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dTextWidth, _T("Failed to get text width. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
32                                     Ptx_GetLastError());
33
34    // Calculate position
35    TPtxGeomReal_Point position;
36    position.dX = (size.dWidth / 2) - (dTextWidth / 2);
37    position.dY = 10;
38
39    // Move to position
40    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position),
41                                      _T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
42                                      Ptx_GetLastError());
43    // Add given text string
44    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szStampText),
45                                      _T("Failed to add given text string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
46                                      Ptx_GetLastError());
47
48    // Close text generator
49    PtxPdfContent_TextGenerator_Close(pTextGenerator);
50    pTextGenerator = NULL;
51
52    // Paint the positioned text
53    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText),
54                                      _T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
55                                      Ptx_GetLastError());
56
57cleanup:
58    if (pTextGenerator != NULL)
59        PtxPdfContent_TextGenerator_Close(pTextGenerator);
60    if (pGenerator != NULL)
61        PtxPdfContent_ContentGenerator_Close(pGenerator);
62    if (pText != NULL)
63        Ptx_Release(pText);
64    if (pContent != NULL)
65        Ptx_Release(pContent);
66
67    return iReturnValue;
68}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Create embedded font in output document 
16    Font font = Font.CreateFromSystem(outDoc, "Arial", string.Empty, true);
17
18    // Copy all pages from input document
19    int currentPageNumber = 1;
20    foreach (Page inPage in inDoc.Pages)
21    {
22        // Copy page from input to output
23        Page outPage = Page.Copy(outDoc, inPage, copyOptions);
24
25        // Stamp page number on current page of output document
26        AddPageNumber(outDoc, outPage, font, currentPageNumber++);
27
28        // Add page to output document
29        outDoc.Pages.Add(outPage);
30    }
31}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void AddPageNumber(Document outDoc, Page outPage, Font font, int pageNumber)
2{
3    // Create content generator
4    using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
5
6    // Create text object
7    Text text = Text.Create(outDoc);
8
9    // Create a text generator with the given font, size and position
10    using (TextGenerator textgenerator = new TextGenerator(text, font, 8, null))
11    {
12        // Generate string to be stamped as page number
13        string stampText = string.Format("Page {0}", pageNumber);
14
15        // Calculate position for centering text at bottom of page
16        Point position = new Point
17        {
18            X = (outPage.Size.Width / 2) - (textgenerator.GetWidth(stampText) / 2),
19            Y = 10
20        };
21
22        // Position the text
23        textgenerator.MoveTo(position);
24        // Add page number
25        textgenerator.Show(stampText);
26    }
27    // Paint the positioned text
28    generator.PaintText(text);
29}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define page copy options
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Copy pages from input to output
15        int pageNo = 1;
16
17        // Create embedded font in output document
18        Font font = Font.createFromSystem(outDoc, "Arial", "", true);
19
20        // Loop through all pages of input
21        for (Page inPage : inDoc.getPages()) {
22            // Copy page from input to output
23            Page outPage = Page.copy(outDoc, inPage, copyOptions);
24
25            // Stamp page number on current page of output document
26            applyStamps(outDoc, outPage, font, pageNo++);
27
28            // Add page to output document
29            outDoc.getPages().add(outPage);
30        }
31    }
32}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void applyStamps(Document doc, Page page, Font font, int pageNo) throws ToolboxException, IOException {
2
3    try (// Create content generator
4        ContentGenerator generator = new ContentGenerator(page.getContent(), false)) {
5        // Create text object
6        Text text = Text.create(doc);
7
8        try (// Create a text generator with the given font, size and position
9            TextGenerator textgenerator = new TextGenerator(text, font, 8, null)) {
10
11            // Generate string to be stamped as page number
12            String stampText = String.format("Page %d", pageNo);
13
14            // Calculate position for centering text at bottom of page
15            Point position = new Point((page.getSize().width / 2) - (textgenerator.getWidth(stampText) / 2), 10);
16
17            // Position the text
18            textgenerator.moveTo(position);
19            // Add page number
20            textgenerator.show(stampText);
21        }
22
23        // Paint the positioned text
24        generator.paintText(text);
25    }
26}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def add_page_number(out_doc, out_page, font, page_number):
2    """Stamp the page number on the specified page."""
3    # Create content generator
4    with ContentGenerator(out_page.content, False) as generator:
5        # Create text object
6        text = Text.create(out_doc)
7
8        # Create a text generator with the given font, size, and position
9        with TextGenerator(text, font, 8, None) as text_generator:
10            # Generate string to be stamped as the page number
11            stamp_text = f"Page {page_number}"
12
13            # Calculate position for centering text at the bottom of the page
14            position = Point(
15                x=(out_page.size.width / 2) - (text_generator.get_width(stamp_text) / 2),
16                y=10
17            )
18
19            # Position the text
20            text_generator.move_to(position)
21            # Add page number
22            text_generator.show(stamp_text)
23
24        # Paint the positioned text
25        generator.paint_text(text)

Content Modification

Remove glyphs

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Process each page
13    foreach (var inPage in inDoc.Pages)
14    {
15        // Create empty output page
16        Page outPage = Page.Create(outDoc, inPage.Size);
17        // Copy page content from input to output and remove glyphs
18        CopyContentAndRemoveGlyphs(inPage.Content, outPage.Content, outDoc);
19        // Add the new page to the output document's page list
20        outDoc.Pages.Add(outPage);
21    }
22}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void CopyContentAndRemoveGlyphs(Content inContent, Content outContent, Document outDoc)
2{
3    // Use a content extractor and a content generator to copy content
4    ContentExtractor extractor = new ContentExtractor(inContent);
5    using ContentGenerator generator = new ContentGenerator(outContent, false);
6
7    // Iterate over all content elements
8    foreach (ContentElement inElement in extractor)
9    {
10        ContentElement outElement;
11        // Special treatment for group elements
12        if (inElement is GroupElement inGroupElement)
13        {
14            // Create empty output group element
15            GroupElement outGroupElement = GroupElement.CopyWithoutContent(outDoc, inGroupElement);
16            outElement = outGroupElement;
17            // Call CopyContentAndRemoveGlyphs() recursively for the group element's content
18            CopyContentAndRemoveGlyphs(inGroupElement.Group.Content, outGroupElement.Group.Content, outDoc);
19        }
20        else
21        {
22            // Copy the content element to the output document
23            outElement = ContentElement.Copy(outDoc, inElement);
24            if (outElement is TextElement outTextElement)
25            {
26                // Special treatment for text element
27                Text text = outTextElement.Text;
28                // Remove the first two glyphs from each text fragment
29                foreach (var fragment in text)
30                {
31                    // Ensure that the fragment has more than two glyphs
32                    if (fragment.Count > 2)
33                    {
34                        // Call RemoveAt twice
35                        fragment.RemoveAt(0);
36                        fragment.RemoveAt(0);
37                    }
38                }
39            }
40        }
41        // Append the finished output element to the content generator
42        generator.AppendContentElement(outElement);
43    }
44}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Process each page
12        for (Page inPage : inDoc.getPages()) {
13            // Create empty output page
14            Page outPage = Page.create(outDoc, inPage.getSize());
15            // Copy page content from input to output and remove glyphs
16            copyContentAndRemoveGlyphs(inPage.getContent(), outPage.getContent(), outDoc);
17            // Add the new page to the output document's page list
18            outDoc.getPages().add(outPage);
19        }
20    }
21}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void copyContentAndRemoveGlyphs(Content inContent, Content outContent, Document outDoc) throws ToolboxException, IOException {
2    // Use a content extractor and a content generator to copy content
3    ContentExtractor extractor = new ContentExtractor(inContent);
4    try (ContentGenerator generator = new ContentGenerator(outContent, false)) {
5        // Iterate over all content elements
6        for (ContentElement inElement : extractor) {
7            ContentElement outElement = null;
8            // Special treatment for group elements
9            if (inElement instanceof GroupElement) {
10                GroupElement inGroupElement = (GroupElement)inElement;
11                // Create empty output group element
12                GroupElement outGroupElement = GroupElement.copyWithoutContent(outDoc, inGroupElement);
13                outElement = outGroupElement;
14                // Call copyContentAndRemoveGlyphs() recursively for the group element's content
15                copyContentAndRemoveGlyphs(inGroupElement.getGroup().getContent(), outGroupElement.getGroup().getContent(), outDoc);
16            } else {
17                // Copy the content element to the output document
18                outElement = ContentElement.copy(outDoc, inElement);
19                if (outElement instanceof TextElement) {
20                    // Special treatment for text element
21                    TextElement outTextElement = (TextElement)outElement;
22                    Text text = outTextElement.getText();
23                    // Remove the first two glyphs from each text fragment
24                    for (int iFragment = 0; iFragment < text.size(); ++iFragment) {
25                        // Ensure that the fragment has more than two glyphs
26                        if (text.get(iFragment).size() > 2) {
27                            // Call remove twice
28                            text.get(iFragment).remove(0);
29                            text.get(iFragment).remove(0);
30                        }
31                    }
32                }
33            }
34            // Append the finished output element to the content generator
35            generator.appendContentElement(outElement);
36        }
37    }
38}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def copy_content_and_remove_glyphs(in_content: Content, out_content: Content, out_doc: Document):
2    """Process content to remove the first two glyphs from text fragments."""
3    # Use a content extractor and a content generator to copy content
4    extractor = ContentExtractor(in_content)
5    with ContentGenerator(out_content, False) as generator:
6
7        # Iterate over all content elements
8        for in_element in extractor:
9            # Special treatment for group elements
10            if isinstance(in_element, GroupElement):
11                # Create empty output group element
12                out_group_element = GroupElement.copy_without_content(out_doc, in_element)
13                out_element = out_group_element
14                copy_content_and_remove_glyphs(in_element.group.content, out_group_element.group.content, out_doc)
15            else:
16                # Copy the content element to the output document
17                out_element = ContentElement.copy(out_doc, in_element)
18                if isinstance(out_element, TextElement):
19                    # Special treatment for text element
20                    text = out_element.text
21                    # Remove the first two glyphs from each text fragment
22                    for fragment in text:
23                        # Ensure that the fragment has more than two glyphs
24                        if len(fragment) > 2:
25                            # Call RemoveAt twice
26                            fragment.remove(0)
27                            fragment.remove(0)
28
29            # Append the finished output element to the content generator
30            generator.append_content_element(out_element)

Remove White Text from PDF

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Process each page
13    foreach (var inPage in inDoc.Pages)
14    {
15        // Create empty output page
16        Page outPage = Page.Create(outDoc, inPage.Size);
17        // Copy page content from input to output
18        CopyContent(inPage.Content, outPage.Content, outDoc);
19        // Add the new page to the output document's page list
20        outDoc.Pages.Add(outPage);
21    }
22}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void CopyContent(Content inContent, Content outContent, Document outDoc)
2{
3    // Use a content extractor and a content generator to copy content
4    ContentExtractor extractor = new ContentExtractor(inContent);
5    using ContentGenerator generator = new ContentGenerator(outContent, false);
6
7    // Iterate over all content elements
8    foreach (ContentElement inElement in extractor)
9    {
10        ContentElement outElement;
11        // Special treatment for group elements
12        if (inElement is GroupElement inGroupElement)
13        {
14            // Create empty output group element
15            GroupElement outGroupElement = GroupElement.CopyWithoutContent(outDoc, inGroupElement);
16            outElement = outGroupElement;
17            // Call CopyContent() recursively for the group element's content
18            CopyContent(inGroupElement.Group.Content, outGroupElement.Group.Content, outDoc);
19        }
20        else
21        {
22            // Copy the content element to the output document
23            outElement = ContentElement.Copy(outDoc, inElement);
24            if (outElement is TextElement outTextElement)
25            {
26                // Special treatment for text element
27                Text text = outTextElement.Text;
28                // Remove all those text fragments whose fill and stroke paint is white
29                for (int iFragment = text.Count - 1; iFragment >= 0; iFragment--)
30                {
31                    TextFragment fragment = text[iFragment];
32                    if ((fragment.Fill == null || IsWhite(fragment.Fill.Paint)) &&
33                        (fragment.Stroke == null || IsWhite(fragment.Stroke.Paint)))
34                        text.RemoveAt(iFragment);
35                }
36                // Prevent appending an empty text element
37                if (text.Count == 0)
38                    outElement = null;
39            }
40        }
41        // Append the finished output element to the content generator
42        if (outElement != null)
43            generator.AppendContentElement(outElement);
44    }
45}
1private static bool IsWhite(Paint paint)
2{
3    ColorSpace colorSpace = paint.ColorSpace;
4    if (colorSpace is DeviceGrayColorSpace || colorSpace is CalibratedGrayColorSpace ||
5        colorSpace is DeviceRgbColorSpace || colorSpace is CalibratedRgbColorSpace)
6    {
7        // These color spaces are additive: white is 1.0
8        return paint.Color.Min() == 1.0;
9    }
10    if (colorSpace is DeviceCmykColorSpace)
11    {
12        // This color space is subtractive: white is 0.0
13        return paint.Color.Max() == 0.0;
14    }
15    return false;
16}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Process each page
12        for (Page inPage : inDoc.getPages()) {
13            // Create empty output page
14            Page outPage = Page.create(outDoc, inPage.getSize());
15            // Copy page content from input to output
16            copyContent(inPage.getContent(), outPage.getContent(), outDoc);
17            // Add page to output document
18            outDoc.getPages().add(outPage);
19        }
20    }
21}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void copyContent(Content inContent, Content outContent, Document outDoc) throws ToolboxException, IOException {
2    // Use a content extractor and a content generator to copy content
3    ContentExtractor extractor = new ContentExtractor(inContent);
4    try (ContentGenerator generator = new ContentGenerator(outContent, false)) {
5        // Iterate over all content elements
6        for (ContentElement inElement : extractor) {
7            ContentElement outElement = null;
8            // Special treatment for group elements
9            if (inElement instanceof GroupElement) {
10                GroupElement inGroupElement = (GroupElement)inElement;
11                // Create empty output group element
12                GroupElement outGroupElement = GroupElement.copyWithoutContent(outDoc, inGroupElement);
13                outElement = outGroupElement;
14                // Call copyContent() recursively for the group element's content
15                copyContent(inGroupElement.getGroup().getContent(), outGroupElement.getGroup().getContent(), outDoc);
16            } else {
17                // Copy the content element to the output document
18                outElement = ContentElement.copy(outDoc, inElement);
19                if (outElement instanceof TextElement) {
20                    // Special treatment for text element
21                    TextElement outTextElement = (TextElement)outElement;
22                    Text text = outTextElement.getText();
23                    // Remove all those text fragments whose fill and stroke paint is white
24                    for (int iFragment = text.size() - 1; iFragment >= 0; iFragment--) {
25                        TextFragment fragment = text.get(iFragment);
26                        if ((fragment.getFill() == null || isWhite(fragment.getFill().getPaint())) &&
27                            (fragment.getStroke() == null || isWhite(fragment.getStroke().getPaint())))
28                            text.remove(iFragment);
29                    }
30                    // Prevent appending an empty text element
31                    if (text.size() == 0)
32                        outElement = null;
33                }
34            }
35            // Append the finished output element to the content generator
36            if (outElement != null)
37                generator.appendContentElement(outElement);
38        }
39    }
40}
1private static boolean isWhite(Paint paint) {
2    double[] color = paint.getColor();
3    ColorSpace colorSpace = paint.getColorSpace();
4    if (colorSpace instanceof DeviceGrayColorSpace || colorSpace instanceof CalibratedGrayColorSpace ||
5            colorSpace instanceof DeviceRgbColorSpace || colorSpace instanceof CalibratedRgbColorSpace) {
6        // These color spaces are additive: white is 1.0
7        for (double value : color)
8            if (value != 1.0)
9                return false;
10        return true;
11    }
12    if (colorSpace instanceof DeviceCmykColorSpace) {
13        // This color space is subtractive: white is 0.0
14        for (double value : color)
15            if (value != 0.0)
16                return false;
17        return true;
18    }
19    return false;
20}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def is_white(paint: Paint) -> bool:
2    """Determine if a paint is white based on its color space."""
3    color_space = paint.color_space
4    color = paint.color
5
6    if isinstance(color_space, (DeviceGrayColorSpace, CalibratedGrayColorSpace, DeviceRgbColorSpace, CalibratedRgbColorSpace)):
7        # These color spaces are additive: white is 1.0
8        return min(color) == 1.0
9    if isinstance(color_space, DeviceCmykColorSpace):
10        # This color space is subtractive: white is 0.0
11        return max(color) == 0.0
12
13    return False
1def copy_content_and_remove_white_text(in_content: Content, out_content: Content, out_doc: Document):
2    """Process content to remove white text fragments."""
3    # Use a content extractor and a content generator to copy content
4    extractor = ContentExtractor(in_content)
5    with ContentGenerator(out_content, False) as generator:
6
7        # Iterate over all content elements
8        for in_element in extractor:
9            # Special treatment for group elements
10            if isinstance(in_element, GroupElement):
11                # Create empty output group element
12                out_group_element = GroupElement.copy_without_content(out_doc, in_element)
13                out_element = out_group_element
14                copy_content_and_remove_white_text(in_element.group.content, out_group_element.group.content, out_doc)
15            else:
16                # Copy the content element to the output document
17                out_element = ContentElement.copy(out_doc, in_element)
18                if isinstance(out_element, TextElement):
19                    text = out_element.text
20                    # Remove all those text fragments whose fill and stroke paint is white
21                    for i_fragment in range(len(text) - 1, -1, -1):
22                        fragment = text[i_fragment]
23                        if ((fragment.fill is None or is_white(fragment.fill.paint)) and
24                            (fragment.stroke is None or is_white(fragment.stroke.paint))):
25                            text.remove(i_fragment)
26                    # Prevent appending an empty text element
27                    if len(text) == 0:
28                        out_element = None
29
30            # Append the finished output element to the content generator
31            if out_element:
32                generator.append_content_element(out_element)

Replace Text Fragment in PDF

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Process each page
13    foreach (var inPage in inDoc.Pages)
14    {
15        // Create empty output page
16        Page outPage = Page.Create(outDoc, inPage.Size);
17        // Copy page content from input to output and search for string
18        CopyContent(inPage.Content, outPage.Content, outDoc, searchString);
19        // If the text was found and deleted, add the replacement text
20        if (fragment != null)
21            AddText(outDoc, outPage, replString);
22        // Add the new page to the output document's page list
23        outDoc.Pages.Add(outPage);
24    }
25}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void CopyContent(Content inContent, Content outContent, Document outDoc, string searchString)
2{
3    // Use a content extractor and a content generator to copy content
4    ContentExtractor extractor = new ContentExtractor(inContent);
5    using ContentGenerator generator = new ContentGenerator(outContent, false);
6
7    // Iterate over all content elements
8    foreach (ContentElement inElement in extractor)
9    {
10        ContentElement outElement;
11        // Special treatment for group elements
12        if (inElement is GroupElement inGroupElement)
13        {
14            // Create empty output group element
15            GroupElement outGroupElement = GroupElement.CopyWithoutContent(outDoc, inGroupElement);
16            outElement = outGroupElement;
17            // Save transform for later restore
18            AffineTransform currentTransform = overallTransform;
19            // Update the transform
20            overallTransform.Concatenate(inGroupElement.Transform);
21            // Call CopyContent() recursively for the group element's content
22            CopyContent(inGroupElement.Group.Content, outGroupElement.Group.Content, outDoc, searchString);
23            // Restore the transform
24            overallTransform = currentTransform;
25        }
26        else
27        {
28            // Copy the content element to the output document
29            outElement = ContentElement.Copy(outDoc, inElement);
30            if (fragment == null && outElement is TextElement outTextElement)
31            {
32                // Special treatment for text element
33                Text text = outTextElement.Text;
34                // Find text fragment with string to replace
35                for (int iFragment = text.Count - 1; iFragment >= 0; iFragment--)
36                {
37                    // In this sample, the fragment text must match in its entirety
38                    if (text[iFragment].Text == searchString)
39                    {
40                        // Keep the found fragment for later use
41                        fragment = text[iFragment];
42                        // Update the transform
43                        overallTransform.Concatenate(fragment.Transform);
44                        // Remove the found text fragment from the output
45                        text.RemoveAt(iFragment);
46                        break;
47                    }
48                }
49                // Prevent appending an empty text element
50                if (text.Count == 0)
51                    outElement = null;
52            }
53        }
54        // Append the finished output element to the content generator
55        if (outElement != null)
56            generator.AppendContentElement(outElement);
57    }
58}
1private static void AddText(Document doc, Page page, string replString)
2{
3    // Create a new text object
4    Text text = Text.Create(doc);
5    // Heuristic to map the extracted font base name to a font name and font family
6    string[] parts = fragment.Font.BaseFont.Split('-');
7    string family = parts[0];
8    string style = parts.Length > 1 ? parts[1] : null;
9    // Create a new font object
10    Font font = Font.CreateFromSystem(doc, family, style, true);
11    // Create a text generator and set the original fragment's properties
12    using (TextGenerator textGenerator = new TextGenerator(text, font, fragment.FontSize, null))
13    {
14        textGenerator.CharacterSpacing = fragment.CharacterSpacing;
15        textGenerator.WordSpacing = fragment.WordSpacing;
16        textGenerator.HorizontalScaling = fragment.HorizontalScaling;
17        textGenerator.Rise = fragment.Rise;
18        textGenerator.Show(replString);
19    }
20    // Create a content generator
21    using ContentGenerator contentGenerator = new ContentGenerator(page.Content, false);
22    // Apply the computed transform
23    contentGenerator.Transform(overallTransform);
24    // Paint the new text
25    contentGenerator.PaintText(text);
26}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Process each page
12        for (Page inPage : inDoc.getPages()) {
13            // Create empty output page
14            Page outPage = Page.create(outDoc, inPage.getSize());
15            // Copy page content from input to output and search for string
16            copyContent(inPage.getContent(), outPage.getContent(), outDoc, searchString);
17            // If the text was found and deleted, add the replacement text
18            if (fragment != null)
19                addText(outDoc, outPage, replString);
20            // Add page to output document
21            outDoc.getPages().add(outPage);
22        }
23    }
24}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void copyContent(Content inContent, Content outContent, Document outDoc, String searchString) throws ToolboxException, IOException {
2    // Use a content extractor and a content generator to copy content
3    ContentExtractor extractor = new ContentExtractor(inContent);
4    try (ContentGenerator generator = new ContentGenerator(outContent, false)) {
5        // Iterate over all content elements
6        for (ContentElement inElement : extractor) {
7            ContentElement outElement = null;
8            // Special treatment for group elements
9            if (inElement instanceof GroupElement) {
10                GroupElement inGroupElement = (GroupElement)inElement;
11                // Create empty output group element
12                GroupElement outGroupElement = GroupElement.copyWithoutContent(outDoc, inGroupElement);
13                outElement = outGroupElement;
14                // Save transform for later restor
15                AffineTransform currentTransform = overallTransform;
16                // Update the transform
17                overallTransform.concatenate(inGroupElement.getTransform());
18                // Call copyContent() recursively for the group element's content
19                copyContent(inGroupElement.getGroup().getContent(), outGroupElement.getGroup().getContent(), outDoc, searchString);
20                // Restor the transform
21                overallTransform = currentTransform;
22            } else {
23                // Copy the content element to the output document
24                outElement = ContentElement.copy(outDoc, inElement);
25                if (fragment == null && outElement instanceof TextElement) {
26                    // Special treatment for text element
27                    TextElement outTextElement = (TextElement)outElement;
28                    Text text = outTextElement.getText();
29                    // Find text fragment with string to replace
30                    for (int iFragment = text.size() - 1; iFragment >= 0; iFragment--) {
31                        // In this sample, the fragment text must match in its entirety
32                        if (text.get(iFragment).getText().equals(searchString)) {
33                            // Keep the found fragment for later use
34                            fragment = text.get(iFragment);
35                            // Update the transform
36                            overallTransform.concatenate(fragment.getTransform());
37                            // Remove the found text fragment from the output
38                            text.remove(iFragment);
39                            break;
40                        }
41                    }
42                    // Prevent appending an empty text element
43                    if (text.size() == 0)
44                        outElement = null;
45                }
46            }
47            // Append the finished output element to the content generator
48            if (outElement != null)
49                generator.appendContentElement(outElement);
50        }
51    }
52}
1private static void addText(Document doc, Page page, String replString) throws CorruptException, ToolboxException, IOException {
2    // Create a new text object
3    Text text = Text.create(doc);
4    // Heuristic to map the extracted fon base name to a font family and font style
5    String[] parts = fragment.getFont().getBaseFont().split("-");
6    String family = parts[0];
7    String style = parts.length > 1 ? parts[1] : null;
8    // Create a new font object
9    Font font = Font.createFromSystem(doc, family, style, true);
10    // Create a text generator and set the original fragment's properties
11    try (TextGenerator textGenerator = new TextGenerator(text, font, fragment.getFontSize(), null)) {
12        textGenerator.setCharacterSpacing(fragment.getCharacterSpacing());
13        textGenerator.setWordSpacing(fragment.getWordSpacing());
14        textGenerator.setHorizontalScaling(fragment.getHorizontalScaling());
15        textGenerator.setRise(fragment.getRise());
16        textGenerator.show(replString);
17    }
18    // Create a content generator
19    try (ContentGenerator contentGenerator = new ContentGenerator(page.getContent(), false)) {
20        // Apply the computed transform
21        contentGenerator.transform(overallTransform);
22        // Paint the new text
23        contentGenerator.paintText(text);
24    }
25}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def copy_content_and_remove_text(in_content: Content, out_content: Content, out_doc: Document, search_text: str):
2    """Process content to find and remove a specific text fragment."""
3    global overall_transform, fragment
4
5    # Use a content extractor and a content generator to copy content
6    extractor = ContentExtractor(in_content)
7    with ContentGenerator(out_content, False) as generator:
8
9        # Iterate over all content elements
10        for in_element in extractor:
11            # Special treatment for group elements
12            if isinstance(in_element, GroupElement):
13                out_group_element = GroupElement.copy_without_content(out_doc, in_element)
14                out_element = out_group_element
15                # Save transform for later restore
16                current_transform = overall_transform
17                # Update the transform
18                copy_content_and_remove_text(in_element.group.content, out_group_element.group.content, out_doc, search_text)
19                # Restore the transform
20                overall_transform = current_transform
21            else:
22                # Copy the content element to the output document
23                out_element = ContentElement.copy(out_doc, in_element)
24                if isinstance(out_element, TextElement) and fragment is None:
25                    # Special treatment for text element
26                    text = out_element.text
27                    # Find text fragment with string to replace
28                    for index_fragment in range(len(text) - 1, -1, -1):
29                        # In this sample, the fragment text must match in its entirety (Text might contain null characters)
30                        if text[index_fragment].text.replace("\x00", "") == search_text:
31                            # Keep the found fragment for later use
32                            fragment = text[index_fragment]
33                            # Update the transform
34                            overall_transform.concatenate(fragment.transform)
35                            # Remove the fragment from the text element
36                            text.remove(index_fragment)
37
38                    # Prevent appending an empty text element
39                    if len(text) == 0:
40                        out_element = None
41
42            # Append the finished output element to the content generator
43            if out_element:
44                generator.append_content_element(out_element)
1def add_text(out_doc: Document, page, replacement_text):
2    """Add the replacement text at the location of the removed fragment."""
3    # Create a new text object
4    text = Text.create(out_doc)
5    # Heuristic to map the extracted font base name to a font name and font family
6    font_parts = fragment.font.base_font.split("-")
7    font_family = font_parts[0]
8    font_style = font_parts[1] if len(font_parts) > 1 else None
9
10    # Create a new font object
11    font = Font.create_from_system(out_doc, font_family, font_style, True)
12
13    # Create a text generator and set the original fragment's properties
14    with TextGenerator(text, font, fragment.font_size, None) as text_gen:
15        text_gen.character_spacing = fragment.character_spacing
16        text_gen.word_spacing = fragment.word_spacing
17        text_gen.horizontal_scaling = fragment.horizontal_scaling
18        text_gen.rise = fragment.rise
19        text_gen.show(replacement_text)
20
21    # Create a content generator
22    with ContentGenerator(page.content, False) as content_gen:
23        # Apply the computed transform
24        content_gen.transform(overall_transform)
25        # Paint the new text
26        content_gen.paint_text(text)

Custom Validation

Validate custom properties of a PDF file

Download code sample
1var iniFile = new IniFile(args[1]);
2var password = args.Length == 3 ? args[2] : null;
3var documentValidator = new DocumentValidator(iniFile, args[0], password);
4
5try
6{
7    if (documentValidator.ValidateDocument())
8        Console.WriteLine("\nThe document does conform the specified properties.");
9    else
10        Console.WriteLine("\nThe document does not conform the specified properties.");
11}
12catch (Exception ex)
13{
14    Console.WriteLine("The document could not be validated. The following error happened: " + ex.Message);
15    return;
16}
1public class IniFile
2{
3    private Dictionary<string, Dictionary<string, string>> _data;
4
5    public IniFile(string path)
6    {
7        _data = new Dictionary<string, Dictionary<string, string>>();
8        Load(path);
9    }
10
11    private void Load(string path)
12    {
13        var lines = File.ReadAllLines(path);
14        var currentSection = "";
15
16        foreach (var line in lines)
17        {
18            var trimmedLine = line.Trim();
19
20            if (string.IsNullOrEmpty(trimmedLine) || trimmedLine.StartsWith(";") || trimmedLine.StartsWith("#"))
21            {
22                continue; // Skip empty lines and comments
23            }
24
25            if (trimmedLine.StartsWith("[") && trimmedLine.EndsWith("]"))
26            {
27                currentSection = trimmedLine.Substring(1, trimmedLine.Length - 2).Trim();
28                if (!_data.ContainsKey(currentSection))
29                {
30                    _data[currentSection] = new Dictionary<string, string>();
31                }
32                else
33                {
34                    throw new FormatException("Duplicate section: " + currentSection);
35                }
36            }
37            else if (currentSection != null)
38            {
39                var keyValuePair = trimmedLine.Split(new[] { '=' });
40                if (keyValuePair.Length == 2)
41                {
42                    var key = keyValuePair[0].Trim();
43                    var value = keyValuePair[1].Trim();
44                    _data[currentSection][key] = value;
45                }
46            }
47        }
48    }
49
50    public string? GetValue(string section, string key, string? defaultValue = null)
51    {
52        if (_data.TryGetValue(section, out var sectionData))
53        {
54            if (sectionData.TryGetValue(key, out var value))
55            {
56                return value;
57            }
58        }
59        return defaultValue;
60    }
61
62    public List<string> GetKeysMatchingPattern(string section, string pattern)
63    {
64        var matchingKeys = new List<string>();
65
66        if (_data.TryGetValue(section, out var sectionData))
67        {
68            foreach (var key in sectionData.Keys)
69            {
70                if (Regex.IsMatch(key, pattern, RegexOptions.IgnoreCase))
71                {
72                    matchingKeys.Add(sectionData[key]);
73                }
74            }
75        }
76
77        return matchingKeys;
78    }
79}
1public class DocumentValidator
2{
3    private readonly IniFile _iniFile;
4    private readonly string _inputPath;
5    private readonly string? _pdfPassword;
6
7    // Tolerance used for size comparison: default 3pt
8    private string _sizeTolerance = "3.0";
9    private string? _iniMaxPageSize;
10    private string? _iniMaxPdfVersionStr;
11    private string? _iniEncryption;
12    private string? _iniFileSize;
13    private string? _iniEmbedding;
14    private readonly List<string> _embeddingExceptionFonts;
15
16    public DocumentValidator(IniFile iniFile, string inputPath, string? pdfPassword = null)
17    {
18        _iniFile = iniFile;
19        _inputPath = inputPath;
20        _pdfPassword = pdfPassword;
21
22        // Extract values from INI file
23        string? iniSizeTolerance = iniFile.GetValue("Pages", "SizeTolerance");
24        _sizeTolerance = !string.IsNullOrEmpty(iniSizeTolerance) ? iniSizeTolerance : _sizeTolerance;
25        _iniMaxPageSize = _iniFile.GetValue("Pages", "MaxPageSize");
26        _iniMaxPdfVersionStr = _iniFile.GetValue("File", "MaxPdfVersion");
27        _iniEncryption = _iniFile.GetValue("File", "Encryption");
28        _iniFileSize = _iniFile.GetValue("File", "FileSize");
29        _iniEmbedding = _iniFile.GetValue("Fonts", "Embedding");
30        _embeddingExceptionFonts = _iniFile.GetKeysMatchingPattern("Fonts", @"EmbeddingExcFont\d+");
31    }
32
33    public bool ValidateDocument()
34    {
35        var isValid = ValidateFileSize();
36
37        try
38        {
39            using var inpath = File.OpenRead(_inputPath);
40            using var inDoc = Document.Open(inpath, _pdfPassword);
41
42            isValid &= ValidateConformance(inDoc.Conformance);
43            isValid &= ValidateEncryption(inDoc.Permissions);
44            isValid &= ValidatePagesSize(inDoc);
45            isValid &= ValidateFonts(inDoc);
46        }
47        catch (PasswordException)
48        {
49            if (_pdfPassword == null)
50                Console.WriteLine("The content of the document could not be validated as it is password protected. Please provide a password.");
51            else
52                Console.WriteLine("The content of the document could not be validated as the password provided is not correct.");
53
54            return false;
55        }
56
57        return isValid;
58    }
59
60    private bool ValidateFileSize()
61    {
62        var fileInfo = new FileInfo(_inputPath);
63        var fileSizeInMB = fileInfo.Length / (1024.0 * 1024.0);
64
65        if (_iniFileSize != null)
66        {
67            var iniFileSizeInMB = Convert.ToDouble(_iniFileSize);
68            if (fileSizeInMB <= iniFileSizeInMB)
69            {
70                Console.WriteLine("The PDF file size does not exceed the specified custom limit.");
71
72                return true;
73            }
74            else
75            {
76                Console.WriteLine("The PDF file size exceeds the specified custom limit.");
77
78                return false;
79            }
80        }
81
82        return true;
83    }
84
85    private bool ValidateConformance(Conformance currentConformance)
86    {
87        if (_iniMaxPdfVersionStr != null)
88        {
89            if (ConformanceValidator.ValidateConformance(_iniMaxPdfVersionStr, currentConformance))
90            {
91                Console.WriteLine("The PDF version does not exceed the specified custom maximum version.");
92
93                return true;
94            }
95            else
96            {
97                Console.WriteLine("The PDF version exceeds the specified custom maximum version.");
98
99                return false;
100            }
101        }
102
103        return true;
104    }
105
106    private bool ValidateEncryption(Permission? permissions)
107    {
108        if (_iniEncryption != null)
109        {
110            if (_iniEncryption.ToLower() == "true" && permissions == null)
111            {
112                Console.WriteLine("Encryption not conform: the PDF file is not encrypted. The custom encryption value specifies that the PDF file should be encrypted.");
113
114                return false;
115            }
116            else if (_iniEncryption.ToLower() == "false" && permissions != null)
117            {
118                Console.WriteLine("Encryption not conform: the PDF file is encrypted. The custom encryption value specifies that the PDF file should not be encrypted.");
119
120                return false;
121            }
122            else
123            {
124                Console.WriteLine("The PDF encryption is conform to the specified custom value.");
125
126                return true;
127            }
128        }
129
130        return true;
131    }
132
133    private bool ValidatePagesSize(Document inDoc)
134    {
135        var isValid = true;
136
137        if (_iniMaxPageSize != null)
138        {
139            var pageNumber = 0;
140            foreach (var page in inDoc.Pages)
141            {
142                pageNumber++;
143                var sizeWithInt = new Size { Width = (int)page.Size.Width, Height = (int)page.Size.Height };
144
145                isValid &= ValidatePageSize(pageNumber, sizeWithInt);
146            }
147        }
148
149        return isValid;
150    }
151
152    private bool ValidatePageSize(int pageNumber, Size pageSize)
153    {
154        if (_iniMaxPageSize != null)
155        {
156            var validator = new PageSizeValidator(_iniMaxPageSize, _sizeTolerance);
157            if (validator.ValidatePageSize(pageNumber, pageSize))
158            {
159                Console.WriteLine("The size of page " + pageNumber + " is within the specified custom maximum page size value.");
160
161                return true;
162            }
163            else
164            {
165                Console.WriteLine("The size of page " + pageNumber + " exceeds the specified custom maximum page size value.");
166
167                return false;
168            }
169        }
170
171        return true;
172    }
173
174    private bool ValidateFonts(Document inDoc)
175    {
176        var isValid = true;
177
178        if (_iniEmbedding != null)
179        {
180            var embeddingRequired = _iniEmbedding.ToLower() == "true";
181            var pageNumber = 0;
182
183            foreach (var page in inDoc.Pages)
184            {
185                pageNumber++;
186                var extractor = new ContentExtractor(page.Content)
187                {
188                    Ungrouping = UngroupingSelection.SafelyUngroupable
189                };
190
191                foreach (ContentElement element in extractor)
192                {
193                    if (element is TextElement textElement)
194                    {
195                        foreach (var fragment in textElement.Text)
196                        {
197                            var fontName = fragment.Font.BaseFont;
198                            var isEmbedded = fragment.Font.IsEmbedded;
199
200                            // Check if the font is in the exception list
201                            var isCurrentFontAnException = _embeddingExceptionFonts.Exists(exception => Regex.IsMatch(fontName, exception.Replace("*", ".*"), RegexOptions.IgnoreCase));
202
203                            // Validate based on the embedding setting
204                            // _iniEmbedding = true => The font has to be embedded or it should appear in the exception list
205                            // _iniEmbedding = false => The font cannot be embedded or it should appear in the exception list
206                            if ((embeddingRequired && !isEmbedded && !isCurrentFontAnException) || (!embeddingRequired && isEmbedded && !isCurrentFontAnException))
207                            {
208                                isValid = false;
209                                var statusText = embeddingRequired ? "be embedded" : "not be embedded";
210                                Console.WriteLine("The font '" + fontName + "' on page " + pageNumber + " should " + statusText + " as specified by the property 'Embedding' or it should be added to the list of exceptions.");
211                            }
212                            else
213                            {
214                                var statusText = embeddingRequired != isEmbedded ? "in the exception list" : isEmbedded ? "embedded" : "not embedded";
215                                Console.WriteLine("The font '" + fontName + "' on page " + pageNumber + " is conform to the 'Embedding' property as it is " + statusText + ".");
216                            }
217                        }
218                    }
219                }
220            }
221        }
222
223        return isValid;
224    }
225}
1public class PageSizeValidator
2{
3    private readonly Size maxSize;
4    private readonly double sizeTolerance;
5
6    // Named page sizes like "Letter", "A4", etc.
7    private static readonly Dictionary<string, Size> NamedPageSizes = new Dictionary<string, Size>(StringComparer.OrdinalIgnoreCase)
8    {
9        { "Letter", new Size { Width = 612, Height = 792 } }, // 8.5 x 11 inches in points
10        { "A0", new Size { Width = 2384, Height = 3370 } },
11        { "A1", new Size { Width = 1684, Height = 2384 } },
12        { "A2", new Size { Width = 1191, Height = 1684 } },
13        { "A3", new Size { Width = 842, Height = 1191 } },
14        { "A4", new Size { Width = 595, Height = 842 } },    // 210 x 297 mm in points
15        { "A5", new Size { Width = 420, Height = 595 } },
16        { "A6", new Size { Width = 298, Height = 420 } },
17        { "A7", new Size { Width = 210, Height = 298 } },
18        { "A8", new Size { Width = 147, Height = 210 } },
19        { "A9", new Size { Width = 105, Height = 147 } },
20        { "A10", new Size { Width = 74, Height = 105 } },
21        { "DL", new Size { Width = 283, Height = 595 } }    // 99 x 210 mm in points
22    };
23
24    public PageSizeValidator(string maxPageSizeStr, string sizeToleranceStr)
25    {
26        maxSize = ParsePageSize(maxPageSizeStr);
27        sizeTolerance = ParseSizeTolerance(sizeToleranceStr);
28    }
29
30    private Size ParsePageSize(string maxPageSize)
31    {
32        // First, check if it's a named size
33        if (NamedPageSizes.TryGetValue(maxPageSize, out var namedSize))
34        {
35            return namedSize;
36        }
37
38        // If not a named size, try to parse it as a custom size
39        var match = Regex.Match(maxPageSize, @"(\d+(\.\d+)?)\s*x\s*(\d+(\.\d+)?)(\s*(pt|in|cm|mm))?", RegexOptions.IgnoreCase);
40        if (!match.Success) throw new ArgumentException("Invalid MaxPageSize format: " + maxPageSize);
41
42        double width = double.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
43        double height = double.Parse(match.Groups[3].Value, CultureInfo.InvariantCulture);
44        string unit = match.Groups[6].Value.ToLower();
45
46        return unit switch
47        {
48            "in" => new Size { Width = (int)(width * 72), Height = (int)(height * 72) },
49            "cm" => new Size { Width = (int)(width * 28.3465), Height = (int)(height * 28.3465) },
50            "mm" => new Size { Width = (int)(width * 2.83465), Height = (int)(height * 2.83465) },
51            "pt" or "" => new Size { Width = (int)width, Height = (int)height },
52            _ => throw new ArgumentException("Unsupported unit: " + unit),
53        };
54    }
55
56    private double ParseSizeTolerance(string sizeToleranceStr)
57    {
58        if (string.IsNullOrEmpty(sizeToleranceStr)) return 3; // Default tolerance in points
59
60        var match = Regex.Match(sizeToleranceStr, @"(\d+(\.\d+)?)\s*(%)?", RegexOptions.IgnoreCase);
61        if (!match.Success) throw new ArgumentException("Invalid SizeTolerance format: " + sizeToleranceStr);
62
63        double value = double.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
64        return match.Groups[3].Success ? value / 100.0 : value; // Percentage tolerance or direct value
65    }
66
67    public bool ValidatePageSize(int pageNumber, Size actualSize)
68    {
69        // Check both portrait and landscape orientations
70        bool isValid = (actualSize.Width <= maxSize.Width + sizeTolerance && actualSize.Height <= maxSize.Height + sizeTolerance) ||
71                       (actualSize.Height <= maxSize.Width + sizeTolerance && actualSize.Width <= maxSize.Height + sizeTolerance);
72
73        return isValid;
74    }
75}
1public class ConformanceValidator
2{
3    private static readonly Dictionary<string, Conformance> VersionMap = new Dictionary<string, Conformance>(StringComparer.OrdinalIgnoreCase)
4    {
5        { "1.0", Conformance.Pdf10 },
6        { "1.1", Conformance.Pdf11 },
7        { "1.2", Conformance.Pdf12 },
8        { "1.3", Conformance.Pdf13 },
9        { "1.4", Conformance.Pdf14 },
10        { "1.5", Conformance.Pdf15 },
11        { "1.6", Conformance.Pdf16 },
12        { "1.7", Conformance.Pdf17 },
13        { "2.0", Conformance.Pdf20 }
14    };
15
16    public static Conformance ParseVersionString(string version)
17    {
18        // Split the version string into parts based on the '.' delimiter
19        string[] versionParts = version.Split('.');
20
21        // Ensure there are only two parts (major and minor)
22        if (versionParts.Length == 2)
23        {
24            // Construct the major.minor version string (e.g., "1.7")
25            string majorMinorVersion = versionParts[0] + "." + versionParts[1];
26
27            // Try to get the corresponding Conformance enum value from the dictionary
28            if (VersionMap.TryGetValue(majorMinorVersion, out Conformance conformance))
29            {
30                return conformance;
31            }
32        }
33
34        // If the version is not supported, throw an exception
35        throw new ArgumentException("Unsupported version or conformance level: " + version);
36    }
37
38    public static bool ValidateConformance(string maxPdfVersionStr, Conformance currentConformance)
39    {
40        var maxPdfConformance = ParseVersionString(maxPdfVersionStr);
41        // Convert the current conformance level to the corresponding PDF version (Major.Minor) as it can be based on the PDF/A version
42        var currentConformanceVersion = GetVersionFromConformance(currentConformance);
43
44        return (int)currentConformanceVersion <= (int)maxPdfConformance;
45    }
46
47    public static Conformance GetVersionFromConformance(Conformance conformance)
48    {
49        if (VersionMap.ContainsValue(conformance))
50        {
51            return conformance;
52        }
53
54        switch (conformance)
55        {
56            case Conformance.PdfA1A:
57            case Conformance.PdfA1B:
58                return Conformance.Pdf14; // PDF/A-1 is based on PDF 1.4
59
60            case Conformance.PdfA2A:
61            case Conformance.PdfA2B:
62            case Conformance.PdfA2U:
63            case Conformance.PdfA3A:
64            case Conformance.PdfA3B:
65            case Conformance.PdfA3U:
66                return Conformance.Pdf17; // PDF/A-2 and PDF/A-3 are based on PDF 1.7
67
68            default:
69                throw new ArgumentException("Unsupported conformance level: " + conformance.ToString());
70        }
71    }
72}
Download code sample
1String pdfPath = args[0];
2String iniPath = args[1];
3String password = null;
4if (args.length == 3)
5	password = args[2];
6
7IniFile iniFile = new IniFile(iniPath);
8DocumentValidator documentValidator = new DocumentValidator(iniFile, pdfPath, password);
9
10try {
11   if (documentValidator.validateDocument())
12        System.out.println("\nThe document does conform the specified properties.");
13    else
14        System.out.println("\nThe document does not conform the specified properties.");
15}
16catch(Exception e) {
17	System.out.println("The document could not be validated. The following error happened: " + e.getMessage());
18
19    System.exit(-1);
20}
21
1public static class IniFile {
2    private final Map<String, Map<String, String>> sections = new LinkedHashMap<>();
3
4    public IniFile(String path) throws IOException {
5        load(path);
6    }
7
8    private void load(String path) throws IOException {
9        try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
10            String currentSection = null;
11            String line;
12
13            while ((line = reader.readLine()) != null) {
14                line = line.trim();
15
16                if (line.isEmpty() || line.startsWith(";") || line.startsWith("#")) {
17                    // Skip empty lines and comments
18                    continue;
19                }
20
21                if (line.startsWith("[") && line.endsWith("]")) {
22                    // New section
23                    currentSection = line.substring(1, line.length() - 1).trim();
24                    sections.putIfAbsent(currentSection, new LinkedHashMap<>());
25                } else if (currentSection != null) {
26                    // Key-value pair within a section
27                    String[] keyValue = line.split("=", 2);
28                    if (keyValue.length == 2) {
29                        sections.get(currentSection).put(keyValue[0].trim(), keyValue[1].trim());
30                    }
31                }
32            }
33        }
34    }
35
36    public String getValue(String section, String key, String defaultValue) {
37        Map<String, String> sectionData = sections.get(section);
38        if (sectionData != null) {
39            return sectionData.getOrDefault(key, defaultValue);
40        }
41        return defaultValue;
42    }
43
44    public String getValue(String section, String key) {
45        return getValue(section, key, null);
46    }
47
48    public List<String> getKeysMatchingPattern(String section, String pattern) {
49        List<String> matchingKeys = new ArrayList<>();
50
51        Map<String, String> sectionData = sections.get(section);
52        if (sectionData != null) {
53            Pattern regexPattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
54            for (String key : sectionData.keySet()) {
55                Matcher matcher = regexPattern.matcher(key);
56                if (matcher.find()) {
57                    matchingKeys.add(sectionData.get(key));
58                }
59            }
60        }
61
62        return matchingKeys;
63    }
64}
1    public static class DocumentValidator {
2
3        private final String inputPath;
4        private String pdfPassword;
5
6        // Tolerance used for size comparison: default 3pt
7        private String sizeTolerance = "3.0";
8        private String iniMaxPageSize;
9        private String iniMaxPdfVersionStr;
10        private String iniEncryption;
11        private String iniFileSize;
12        private String iniEmbedding;
13        private final List<String> embeddingExceptionFonts;
14
15
16        public DocumentValidator(IniFile iniFile, String inputPath, String pdfPassword) {
17            this.inputPath = inputPath;
18            this.pdfPassword = pdfPassword;
19
20            // Extract values from INI file
21            String iniSizeTolerance = iniFile.getValue("Pages", "SizeTolerance");
22            this.sizeTolerance = (iniSizeTolerance != null && !iniSizeTolerance.isEmpty()) ? iniSizeTolerance : this.sizeTolerance;
23            this.iniMaxPageSize = iniFile.getValue("Pages", "MaxPageSize");
24            this.iniMaxPdfVersionStr = iniFile.getValue("File", "MaxPdfVersion");
25            this.iniEncryption = iniFile.getValue("File", "Encryption");
26            this.iniFileSize = iniFile.getValue("File", "FileSize");
27            this.iniEmbedding = iniFile.getValue("Fonts", "Embedding");
28            this.embeddingExceptionFonts = iniFile.getKeysMatchingPattern("Fonts", "EmbeddingExcFont\\d+");
29        }
30
31        public boolean validateDocument() throws IOException, CorruptException, ConformanceException, UnsupportedFeatureException, ToolboxException {
32            boolean isValid = validateFileSize(inputPath);
33
34            try (FileStream inStream = new FileStream(inputPath, FileStream.Mode.READ_ONLY);
35                Document inDoc = Document.open(inStream, pdfPassword)) {
36
37                isValid &= validateConformance(inDoc.getConformance());
38                isValid &= validateEncryption(inDoc.getPermissions());
39                isValid &= validatePagesSize(inDoc);
40                isValid &= validateFonts(inDoc);
41            }
42            catch(PasswordException e) {
43            	if (pdfPassword == null)
44            		System.out.println("The content of the document could not be validated as it is password protected. Please provide a password.");
45            	else
46            		System.out.println("The content of the document could not be validated as the password provided is not correct.");
47
48                return false;
49            }
50
51            return isValid;
52        }
53
54        private boolean validateFileSize(String inputPath) {
55            File file = new File(inputPath);
56            double fileSizeInMB = file.length() / (1024.0 * 1024.0);
57
58            if (iniFileSize != null) {
59                double iniFileSizeInMB = Double.parseDouble(iniFileSize);
60                if (fileSizeInMB <= iniFileSizeInMB) {
61                    System.out.println("The PDF file size does not exceed the specified custom limit.");
62                    return true;
63                } else {
64                    System.out.println("The PDF file size exceeds the specified custom limit.");
65                    return false;
66                }
67            }
68            return true;
69        }
70
71        private boolean validateConformance(Conformance currentConformance) {
72            if (iniMaxPdfVersionStr != null) {
73                if (ConformanceValidator.validateConformance(iniMaxPdfVersionStr, currentConformance)) {
74                    System.out.println("The PDF version does not exceed the specified custom maximum version.");
75                    return true;
76                } else {
77                    System.out.println("The PDF version exceeds the specified custom maximum version.");
78                    return false;
79                }
80            }
81
82            return true;
83        }
84
85        private boolean validateEncryption(EnumSet<Permission> enumSet) {
86            if (iniEncryption != null) {
87                boolean isEncrypted = enumSet != null;
88
89                if ("true".equalsIgnoreCase(iniEncryption) && !isEncrypted) {
90                    System.out.println("Encryption not conform: the PDF file is not encrypted. The custom encryption value specifies that the PDF file should be encrypted.");
91                    return false;
92                } else if ("false".equalsIgnoreCase(iniEncryption) && isEncrypted) {
93                    System.out.println("Encryption not conform: the PDF file is encrypted. The custom encryption value specifies that the PDF file should not be encrypted.");
94                    return false;
95                } else {
96                    System.out.println("The PDF encryption is conform to the specified custom value.");
97                    return true;
98                }
99            }
100            return true;
101        }
102
103        private boolean validatePagesSize(Document inDoc) {
104            boolean isValid = true;
105
106            if (iniMaxPageSize != null) {
107                int pageNumber = 0;
108                for (Page page : inDoc.getPages()) {
109                    pageNumber++;
110                    com.pdftools.toolbox.geometry.real.Size pageSize = page.getSize();
111                    isValid &= validatePageSize(pageNumber, pageSize);
112                }
113            }
114
115            return isValid;
116        }
117
118        private boolean validatePageSize(int pageNumber, com.pdftools.toolbox.geometry.real.Size pageSize) {
119            if (iniMaxPageSize != null) {
120                PageSizeValidator validator = new PageSizeValidator(iniMaxPageSize, sizeTolerance);
121                if (validator.validatePageSize(pageSize.getWidth(), pageSize.getHeight())) {
122                    System.out.println(String.format("The size of page %d is within the specified custom maximum page size value.", pageNumber));
123                    return true;
124                } else {
125                    System.out.println(String.format("The size of page %d exceeds the specified custom maximum page size value.", pageNumber));
126                    return false;
127                }
128            }
129
130            return true;
131        }
132
133        public boolean validateFonts(Document inDoc) throws CorruptException, IOException {
134            boolean isValid = true;
135
136            if (iniEmbedding != null)
137            {
138                boolean embeddingRequired = "true".equalsIgnoreCase(iniEmbedding);
139	            int pageNumber = 0;
140
141	            for (Page page : inDoc.getPages()) {
142	                pageNumber++;
143	                ContentExtractor extractor = new ContentExtractor(page.getContent());
144	                extractor.setUngrouping(UngroupingSelection.ALL);
145
146	                for (ContentElement element : extractor) {
147	                    if (element instanceof TextElement) {
148	                        TextElement textElement = (TextElement) element;
149	                        Text text = textElement.getText();
150
151	                        for (int iFragment = 0; iFragment < text.size(); iFragment++) {
152	                        	TextFragment currFragment = text.get(iFragment);
153	                            String fontName = currFragment.getFont().getBaseFont();
154	                            boolean isEmbedded = currFragment.getFont().getIsEmbedded();
155
156	                            // Check if the font is in the exception list
157	                            boolean isCurrentFontAnException = embeddingExceptionFonts.stream()
158	                                .anyMatch(exception -> Pattern.compile(exception.replace("*", ".*"), Pattern.CASE_INSENSITIVE).matcher(fontName).matches());
159
160                                // Validate based on the embedding setting
161                                // _iniEmbedding = true => The font has to be embedded or it should appear in the exception list
162                                // _iniEmbedding = false => The font cannot be embedded or it should appear in the exception list
163                                if ((embeddingRequired && !isEmbedded && !isCurrentFontAnException) || (!embeddingRequired && isEmbedded && !isCurrentFontAnException)) {
164                                    isValid = false;
165                                    String statusText = embeddingRequired ? "be embedded" : "not be embedded";
166                                    System.out.println("The font '" + fontName + "' on page " + pageNumber + " should " + statusText + " as specified by the property 'Embedding' or it should be added to the list of exceptions.");
167                                }
168                                else {
169                                    String statusText = embeddingRequired != isEmbedded ? "in the exception list" : isEmbedded ? "embedded" : "not embedded";
170                                    System.out.println("The font '" + fontName + "' on page " + pageNumber + " is conform to the 'Embedding' property as it is " + statusText + ".");
171                                }
172                            }
173	                    }
174	                }
175	            }
176            }
177
178            return isValid;
179        }
180    }
1public static class ConformanceValidator {
2    private static final Map<String, Conformance> versionMap = new HashMap<>();
3
4    static {
5        versionMap.put("1.0", Conformance.PDF10);
6        versionMap.put("1.1", Conformance.PDF11);
7        versionMap.put("1.2", Conformance.PDF12);
8        versionMap.put("1.3", Conformance.PDF13);
9        versionMap.put("1.4", Conformance.PDF14);
10        versionMap.put("1.5", Conformance.PDF15);
11        versionMap.put("1.6", Conformance.PDF16);
12        versionMap.put("1.7", Conformance.PDF17);
13        versionMap.put("2.0", Conformance.PDF20);
14    }
15
16    public static Conformance parseVersionString(String version) {
17        // Extract the major and minor version numbers (e.g., "1.7")
18        String[] versionParts = version.split("\\.");
19        if (versionParts.length == 2) {
20            String majorMinorVersion = versionParts[0] + "." + versionParts[1];
21            Conformance conformance = versionMap.get(majorMinorVersion);
22            if (conformance != null) {
23                return conformance;
24            }
25        }
26
27        throw new IllegalArgumentException("Unsupported version or conformance level: " + version);
28    }
29
30    public static boolean validateConformance(String maxPdfVersionStr, Conformance currentConformance) {
31        Conformance maxPdfConformance = parseVersionString(maxPdfVersionStr);
32        // Convert the current conformance level to the corresponding PDF version (Major.Minor) as it can be based on the PDF/A version
33        Conformance currentConformanceVersion = getVersionFromConformance(currentConformance);
34
35        return currentConformanceVersion.ordinal() <= maxPdfConformance.ordinal();
36    }
37
38    public static Conformance getVersionFromConformance(Conformance conformance) {
39     	if (versionMap.containsValue(conformance)) {
40    		return conformance;
41    	}
42
43       switch (conformance) {
44            case PDF_A1_A:
45            case PDF_A1_B:
46                return Conformance.PDF14; // PDF/A-1 is based on PDF 1.4
47
48            case PDF_A2_A:
49            case PDF_A2_B:
50            case PDF_A2_U:
51            case PDF_A3_A:
52            case PDF_A3_B:
53            case PDF_A3_U:
54                return Conformance.PDF17; // PDF/A-2 and PDF/A-3 are based on PDF 1.7
55
56            default:
57                throw new IllegalArgumentException("Unsupported conformance level: " + conformance);
58        }
59    }
60}
1public static class PageSizeValidator {
2    private final double maxWidth;
3    private final double maxHeight;
4    private final double sizeTolerance;
5
6    // Named page sizes like "Letter", "A4", etc.
7    private static final Map<String, double[]> NAMED_PAGE_SIZES = new HashMap<>();
8
9    static {
10        NAMED_PAGE_SIZES.put("Letter", new double[]{612, 792}); // 8.5 x 11 inches in points
11        NAMED_PAGE_SIZES.put("A0", new double[]{2384, 3370});
12        NAMED_PAGE_SIZES.put("A1", new double[]{1684, 2384});
13        NAMED_PAGE_SIZES.put("A2", new double[]{1191, 1684});
14        NAMED_PAGE_SIZES.put("A3", new double[]{842, 1191});
15        NAMED_PAGE_SIZES.put("A4", new double[]{595, 842});    // 210 x 297 mm in points
16        NAMED_PAGE_SIZES.put("A5", new double[]{420, 595});
17        NAMED_PAGE_SIZES.put("A6", new double[]{298, 420});
18        NAMED_PAGE_SIZES.put("A7", new double[]{210, 298});
19        NAMED_PAGE_SIZES.put("A8", new double[]{147, 210});
20        NAMED_PAGE_SIZES.put("A9", new double[]{105, 147});
21        NAMED_PAGE_SIZES.put("A10", new double[]{74, 105});
22        NAMED_PAGE_SIZES.put("DL", new double[]{283, 595});    // 99 x 210 mm in points
23    }
24
25    public PageSizeValidator(String maxPageSize, String sizeToleranceStr) {
26        double[] size = parsePageSize(maxPageSize);
27        this.maxWidth = size[0];
28        this.maxHeight = size[1];
29        this.sizeTolerance = parseSizeTolerance(sizeToleranceStr);
30    }
31
32    private double[] parsePageSize(String maxPageSize) {
33        if (maxPageSize == null || maxPageSize.isEmpty()) {
34            throw new IllegalArgumentException("MaxPageSize cannot be null or empty");
35        }
36
37        // First, check if it's a named size
38        if (NAMED_PAGE_SIZES.containsKey(maxPageSize)) {
39            return NAMED_PAGE_SIZES.get(maxPageSize);
40        }
41
42        // If not a named size, try to parse it as a custom size
43        Pattern pattern = Pattern.compile("(\\d+(\\.\\d+)?)\\s*x\\s*(\\d+(\\.\\d+)?)(\\s*(pt|in|cm|mm))?", Pattern.CASE_INSENSITIVE);
44        Matcher matcher = pattern.matcher(maxPageSize);
45        if (!matcher.matches()) {
46            throw new IllegalArgumentException("Invalid MaxPageSize format: " + maxPageSize);
47        }
48
49        double width = Double.parseDouble(matcher.group(1));
50        double height = Double.parseDouble(matcher.group(3));
51        String unit = matcher.group(6).toLowerCase();
52
53        switch (unit) {
54            case "in":
55                return new double[]{width * 72, height * 72};
56            case "cm":
57                return new double[]{width * 28.3465, height * 28.3465};
58            case "mm":
59                return new double[]{width * 2.83465, height * 2.83465};
60            case "pt":
61            default:
62                return new double[]{width, height};
63        }
64    }
65
66    private double parseSizeTolerance(String sizeToleranceStr) {
67        if (sizeToleranceStr == null || sizeToleranceStr.isEmpty()) {
68            return 3; // Default tolerance in points
69        }
70
71        Pattern pattern = Pattern.compile("(\\d+(\\.\\d+)?)\\s*(%)?", Pattern.CASE_INSENSITIVE);
72        Matcher matcher = pattern.matcher(sizeToleranceStr);
73        if (!matcher.matches()) {
74            throw new IllegalArgumentException("Invalid SizeTolerance format: " + sizeToleranceStr);
75        }
76
77        double value = Double.parseDouble(matcher.group(1));
78        return matcher.group(3) != null ? value / 100.0 : value; // Percentage tolerance or direct value
79    }
80
81    public boolean validatePageSize(double actualWidth, double actualHeight) {
82        // Check both portrait and landscape orientations
83        boolean isValid = (actualWidth <= maxWidth + sizeTolerance && actualHeight <= maxHeight + sizeTolerance) ||
84                          (actualHeight <= maxWidth + sizeTolerance && actualWidth <= maxHeight + sizeTolerance);
85
86        return isValid;
87    }
88}
Download code sample
1class IniFile:
2    def get_value(self, section: str, key: str, default_value: str = None) -> str:
3        return self.config.get(section, key, fallback=default_value)
4
5    def get_keys_matching_pattern(self, section: str, pattern: str) -> list:
6        matching_keys = []
7        if section in self.config:
8            for key in self.config[section]:
9                if re.match(pattern, key, re.IGNORECASE):
10                    matching_keys.append(self.config[section][key])
11        return matching_keys
1def open_ini_file(path: str) -> IniFile:
2    ini_file = IniFile()
3
4    ini_file.config = configparser.ConfigParser()
5    ini_file.config.read(path)
6
7    return ini_file
1class DocumentValidator:
2    def validate_document(self) -> bool:
3        is_valid = self.validate_file_size()
4
5        try:
6            with open(self.input_path, "rb") as in_stream:
7                with Document.open(in_stream, self.pdf_password) as in_doc:
8                    is_valid &= self.validate_conformance(in_doc.conformance)
9                    is_valid &= self.validate_encryption(in_doc.permissions)
10                    is_valid &= self.validate_pages_size(in_doc)
11                    is_valid &= self.validate_fonts(in_doc)
12        except PasswordError as e:
13            print(f"The document could not be validated. Error: {e}")
14            return False
15
16        return is_valid
17
18    def validate_file_size(self) -> bool:
19        file_size_in_mb = os.path.getsize(self.input_path) / (1024 * 1024)
20
21        if self.ini_file_size:
22            ini_file_size_in_mb = float(self.ini_file_size)
23            if file_size_in_mb > ini_file_size_in_mb:
24                print("The PDF file size exceeds the specified custom limit.")
25                return False
26            else:
27                print("The PDF file size does not exceed the specified custom limit.")
28                return True
29        return True
30
31    def validate_conformance(self, current_conformance: Conformance) -> bool:
32        if self.ini_max_pdf_version_str:
33            if ConformanceValidator.validate_conformance(self.ini_max_pdf_version_str, current_conformance):
34                print("The PDF version does not exceed the specified custom maximum version.")
35                return True
36            else:
37                print("The PDF version exceeds the specified custom maximum version.")
38                return False
39        return True
40
41    def validate_encryption(self, permissions: Permission) -> bool:
42        if self.ini_encryption:
43            encryption_required = self.ini_encryption.lower() == "true"
44            if encryption_required and not permissions:
45                print("Encryption not conform: the PDF file is not encrypted. The custom encryption value specifies that the PDF file should be encrypted.")
46                return False
47            elif not encryption_required and permissions:
48                print("Encryption not conform: the PDF file is encrypted. The custom encryption value specifies that the PDF file should not be encrypted.")
49                return False
50            else:
51                print("The PDF encryption is conform to the specified custom value.")
52                return True
53        return True
54
55    def validate_pages_size(self, in_doc: Document) -> bool:
56        is_valid = True
57
58        if self.ini_max_page_size is not None:
59            page_number = 0
60            for page in in_doc.pages:
61                page_number += 1
62                size_with_int = Size(
63                    width=int(page.size.width), height=int(page.size.height)
64                )
65                is_valid &= self.validate_page_size(page_number, size_with_int)
66
67        return is_valid
68
69
70    def validate_page_size(self, page_number: int, page_size: Size) -> bool:
71        if self.ini_max_page_size is not None:
72            validator = create_page_size_validator(self.ini_max_page_size, self.size_tolerance)
73            if validator.validate_page_size(page_size):
74                print(
75                    f"The size of page {page_number} is within the specified custom maximum page size value."
76                )
77                return True
78            else:
79                print(
80                    f"The size of page {page_number} exceeds the specified custom maximum page size value."
81                )
82                return False
83
84        return True
85
86    def validate_fonts(self, in_doc: Document) -> bool:
87        is_valid = True
88
89        if self.ini_embedding:
90            embedding_required = self.ini_embedding.lower() == "true"
91
92            for page_number in range(len(in_doc.pages)):
93                page_number += 1
94                page = in_doc.pages[page_number-1]
95
96                extractor = ContentExtractor(page.content)
97                extractor.ungrouping = UngroupingSelection.ALL
98
99                for element in extractor:
100                    if isinstance(element, TextElement):
101                        for fragment in element.text:
102                            font_name = fragment.font.base_font
103                            is_embedded = fragment.font.is_embedded
104
105                            # Check if the font is in the exception list
106                            is_current_font_an_exception = any(
107                                re.match(exc.replace("*", ".*"), font_name, re.IGNORECASE)
108                                for exc in self.embedding_exception_fonts
109                            )
110
111                            # Validate based on the embedding setting
112                            # _iniEmbedding = true => The font has to be embedded or it should appear in the exception list
113                            # _iniEmbedding = false => The font cannot be embedded or it should appear in the exception list
114                            if (embedding_required and not is_embedded and not is_current_font_an_exception) or (
115                                not embedding_required and is_embedded and not is_current_font_an_exception
116                            ):
117                                is_valid = False
118                                status_text = "be embedded" if embedding_required else "not be embedded"
119                                print(
120                                    f"The font '{font_name}' on page {page_number} should {status_text} as specified by the property 'Embedding' or it should be added to the list of exceptions."
121                                )
122                            else:
123                                status_text = (
124                                    "in the exception list" if embedding_required != is_embedded 
125                                    else "embedded" if is_embedded 
126                                    else "not be embedded"
127                                )
128                                print(
129                                    f"The font '{font_name}' on page {page_number} is conform to the 'Embedding' property as it is {status_text}."
130                                )
131        return is_valid
1def create_document_validator(ini_file: IniFile, input_path: str, pdf_password: str = None) -> DocumentValidator:
2    document_validator = DocumentValidator()
3
4    document_validator.ini_file = ini_file
5    document_validator.input_path = input_path
6    document_validator.pdf_password = pdf_password
7
8    # Extract values from INI file
9    # Tolerance used for size comparison: default 3pt
10    document_validator.size_tolerance = ini_file.get_value("Pages", "SizeTolerance", "3.0")
11    document_validator.ini_max_page_size = ini_file.get_value("Pages", "MaxPageSize")
12    document_validator.ini_max_pdf_version_str = ini_file.get_value("File", "MaxPdfVersion")
13    document_validator.ini_encryption = ini_file.get_value("File", "Encryption")
14    document_validator.ini_file_size = ini_file.get_value("File", "FileSize")
15    document_validator.ini_embedding = ini_file.get_value("Fonts", "Embedding")
16    document_validator.embedding_exception_fonts = ini_file.get_keys_matching_pattern("Fonts", r"EmbeddingExcFont\d+")
17
18    return document_validator
1class PageSizeValidator:
2    named_page_sizes = {
3        "Letter": Size(width=612, height=792),  # 8.5 x 11 inches in points
4        "A0": Size(width=2384, height=3370),
5        "A1": Size(width=1684, height=2384),
6        "A2": Size(width=1191, height=1684),
7        "A3": Size(width=842, height=1191),
8        "A4": Size(width=595, height=842),  # 210 x 297 mm in points
9        "A5": Size(width=420, height=595),
10        "A6": Size(width=298, height=420),
11        "A7": Size(width=210, height=298),
12        "A8": Size(width=147, height=210),
13        "A9": Size(width=105, height=147),
14        "A10": Size(width=74, height=105),
15        "DL": Size(width=283, height=595),  # 99 x 210 mm in points
16    }
17
18    def parse_page_size(self, max_page_size: str) -> Size:
19        # First, check if it's a named size
20        named_size = self.named_page_sizes.get(max_page_size)
21        if named_size:
22            return named_size
23
24        # If not a named size, try to parse it as a custom size
25        match = re.match(
26            r"(\d+(\.\d+)?)\s*x\s*(\d+(\.\d+)?)(\s*(pt|in|cm|mm))?", max_page_size, re.IGNORECASE
27        )
28        if not match:
29            raise ValueError(f"Invalid MaxPageSize format: {max_page_size}")
30
31        width = float(match.group(1))
32        height = float(match.group(3))
33        unit = match.group(6).lower() if match.group(6) else "pt"
34
35        if unit == "in":
36            return Size(width=int(width * 72), height=int(height * 72))
37        elif unit == "cm":
38            return Size(width=int(width * 28.3465), height=int(height * 28.3465))
39        elif unit == "mm":
40            return Size(width=int(width * 2.83465), height=int(height * 2.83465))
41        elif unit in ["pt", ""]:
42            return Size(width=int(width), height=int(height))
43        else:
44            raise ValueError(f"Unsupported unit: {unit}")
45
46    def parse_size_tolerance(self, size_tolerance_str: str) -> float:
47        if not size_tolerance_str:
48            return 3.0  # Default tolerance in points
49
50        match = re.match(r"(\d+(\.\d+)?)\s*(%)?", size_tolerance_str, re.IGNORECASE)
51        if not match:
52            raise ValueError(f"Invalid SizeTolerance format: {size_tolerance_str}")
53
54        value = float(match.group(1))  # Extract the numeric value
55        return value / 100.0 if match.group(3) else value  # Percentage tolerance or direct value
56
57    def validate_page_size(self, page_size: Size) -> bool:
58        is_valid = (
59            (page_size.width <= self.max_size.width + self.size_tolerance
60            and page_size.height <= self.max_size.height + self.size_tolerance
61            ) or 
62            (page_size.height <= self.max_size.width + self.size_tolerance
63            and page_size.width <= self.max_size.height + self.size_tolerance)
64        )
65        return is_valid
1def create_page_size_validator(max_page_size_str: str, size_tolerance_str: str) -> PageSizeValidator:
2    page_size_validator = PageSizeValidator()
3
4    page_size_validator.max_size = page_size_validator.parse_page_size(max_page_size_str)
5    page_size_validator.size_tolerance = page_size_validator.parse_size_tolerance(size_tolerance_str)
6
7    return page_size_validator
1class ConformanceValidator:
2    version_map = {
3        "1.0": Conformance.PDF10,
4        "1.1": Conformance.PDF11,
5        "1.2": Conformance.PDF12,
6        "1.3": Conformance.PDF13,
7        "1.4": Conformance.PDF14,
8        "1.5": Conformance.PDF15,
9        "1.6": Conformance.PDF16,
10        "1.7": Conformance.PDF17,
11        "2.0": Conformance.PDF20,
12        }
13
14    @staticmethod
15    def parse_version_string(version: str) -> Conformance:
16        # Split the version string into major and minor parts
17        version_parts = version.split(".")
18
19        # Ensure there are exactly two parts
20        if len(version_parts) == 2:
21            major_minor_version = f"{version_parts[0]}.{version_parts[1]}"
22
23            # Retrieve the corresponding Conformance value
24            conformance = ConformanceValidator.version_map.get(major_minor_version)
25            if conformance:
26                return conformance
27
28        # Raise an exception if the version is not supported
29        raise ValueError(f"Unsupported version or conformance level: {version}")
30
31    @staticmethod
32    def validate_conformance(max_pdf_version_str: str, current_conformance: Conformance) -> bool:
33        # Parse the maximum PDF version string into a Conformance enum
34        max_pdf_conformance = ConformanceValidator.parse_version_string(max_pdf_version_str)
35
36        # Convert current conformance level to a major.minor version
37        current_conformance_version = ConformanceValidator.get_version_from_conformance(current_conformance)
38
39        # Compare the integer values of the two Conformance enums
40        return current_conformance_version.value <= max_pdf_conformance.value
41
42
43    @staticmethod
44    def get_version_from_conformance(conformance: Conformance) -> Conformance:
45        # Return the exact match if available in the version_map values
46        if conformance in ConformanceValidator.version_map.values():
47            return conformance
48
49        # Map PDF/A conformance levels to their base PDF versions
50        if conformance in {Conformance.PDF_A1_A, Conformance.PDF_A1_B}:
51            return Conformance.PDF14  # PDF/A-1 is based on PDF 1.4
52
53        if conformance in {
54            Conformance.PDF_A2_A,
55            Conformance.PDF_A2_B,
56            Conformance.PDF_A2_U,
57            Conformance.PDF_A3_A,
58            Conformance.PDF_A3_B,
59            Conformance.PDF_A3_U,
60        }:
61            return Conformance.PDF17  # PDF/A-2 and PDF/A-3 are based on PDF 1.7
62
63        # Raise an exception for unsupported conformance levels
64        raise ValueError(f"Unsupported conformance level: {conformance}")

Document Setup

Add metadata to PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Configure copy options
24pCopyOptions = PtxPdf_PageCopyOptions_New();
25
26// Copy all pages
27pInPageList = PtxPdf_Document_GetPages(pInDoc);
28GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
29                                 _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"),
30                                 szErrorBuff, Ptx_GetLastError());
31pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
32GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
33                                 Ptx_GetLastError());
34
35// Add copied pages to output
36pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
37GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
38                                 _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
39                                 szErrorBuff, Ptx_GetLastError());
40GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages),
41                                  _T("Failed to add copied pages to output. %s (ErrorCode: 0x%08x).\n"),
42                                  szErrorBuff, Ptx_GetLastError());
43
44if (argc == 4)
45{
46    // Add metadata from a input file
47    pMdataStream = _tfopen(szMdatafile, _T("rb"));
48    GOTO_CLEANUP_IF_NULL(pMdataStream, _T("Failed to open metadata file \"%s\".\n"), szMdatafile);
49    PtxSysCreateFILEStreamDescriptor(&mdataDescriptor, pMdataStream, 0);
50
51    // Get file extension
52    TCHAR* szExt = _tcsrchr(szMdatafile, '.');
53    _tcscpy(szExtension, szExt);
54
55    if (_tcscmp(szExtension, _T(".pdf")) == 0)
56    {
57        // Use the metadata of another PDF file
58        TPtxPdf_Document* pMetaDoc = PtxPdf_Document_Open(&mdataDescriptor, _T(""));
59        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetaDoc, _T("Failed to open metadata file. %s (ErrorCode: 0x%08x).\n"),
60                                         szErrorBuff, Ptx_GetLastError());
61        TPtxPdf_Metadata* pMetadata = PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pMetaDoc));
62        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetadata, _T("Failed to copy metadata. %s (ErrorCode: 0x%08x)."),
63                                         szErrorBuff, Ptx_GetLastError());
64        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetMetadata(pOutDoc, pMetadata),
65                                          _T("Failed to set metadata. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
66                                          Ptx_GetLastError());
67    }
68    else
69    {
70        // Use the content of an XMP metadata file
71        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
72            PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Create(pOutDoc, &mdataDescriptor)),
73            _T("Failed to set metadata. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
74    }
75}
76else
77{
78    // Set some metadata properties
79    TPtxPdf_Metadata* pMetadata = PtxPdf_Document_GetMetadata(pOutDoc);
80    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetadata, _T("Failed to get metadata. %s (ErrorCode: 0x%08x).\n"),
81                                     szErrorBuff, Ptx_GetLastError());
82    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetAuthor(pMetadata, _T("Your Author")),
83                                      _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
84    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetTitle(pMetadata, _T("Your Title")),
85                                      _T("%s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
86    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetSubject(pMetadata, _T("Your Subject")),
87                                      _T("%s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
88    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetCreator(pMetadata, _T("Your Creator")),
89                                      _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
90}
91
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    // Copy document-wide data (excluding metadata)
4
5    TPtxPdf_FileReferenceList* pInFileRefList;
6    TPtxPdf_FileReferenceList* pOutFileRefList;
7
8    // Output intent
9    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
10        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
11                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
12            return FALSE;
13
14    // Viewer settings
15    if (PtxPdf_Document_SetViewerSettings(
16            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
17        return FALSE;
18
19    // Associated files (for PDF/A-3 and PDF 2.0 only)
20    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
21    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
22    if (pInFileRefList == NULL || pOutFileRefList == NULL)
23        return FALSE;
24    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
25        if (PtxPdf_FileReferenceList_Add(
26                pOutFileRefList,
27                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
28            return FALSE;
29
30    // Plain embedded files
31    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
32    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
33    if (pInFileRefList == NULL || pOutFileRefList == NULL)
34        return FALSE;
35    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
36        if (PtxPdf_FileReferenceList_Add(
37                pOutFileRefList,
38                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
39            return FALSE;
40
41    return TRUE;
42}
Download code sample
1// Open input document 
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Set Metadata
13    if (args.Length == 3)
14    {
15        Metadata mdata;
16
17        // Add metadata from a input file 
18        using FileStream metaStream = File.OpenRead(mdatafile);
19        if (mdatafile.EndsWith(".pdf"))
20        {
21            // Use the metadata of another PDF file
22            using Document metaDoc = Document.Open(metaStream, "");
23            mdata = Metadata.Copy(outDoc, metaDoc.Metadata);
24        }
25        else
26        {
27            // Use the content of an XMP metadata file 
28            mdata = Metadata.Create(outDoc, metaStream);
29        }
30        outDoc.Metadata = mdata;
31    }
32    else
33    {
34        // Set some metadata properties 
35        Metadata metadata = outDoc.Metadata;
36        metadata.Author = "Your Author";
37        metadata.Title = "Your Title";
38        metadata.Subject = "Your Subject";
39        metadata.Creator = "Your Creator";
40    }
41
42    // Define page copy options
43    PageCopyOptions copyOptions = new PageCopyOptions();
44
45    // Copy all pages and append to output document
46    PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
47    outDoc.Pages.AddRange(copiedPages);
48}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data (except metadata)
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Viewer settings
10    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
11
12    // Associated files (for PDF/A-3 and PDF 2.0 only)
13    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
14    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
15        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
16
17    // Plain embedded files
18    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
19    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
20        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
21}
Download code sample
1            try (// Open input document
2                FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3                Document inDoc = Document.open(inStream, null);
4                FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5                try (// Create output document
6                    Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8                    // Copy document-wide data
9                    copyDocumentData(inDoc, outDoc);
10
11                    // Define page copy options
12                    PageCopyOptions copyOptions = new PageCopyOptions();
13
14                    // Copy all pages and append to output document
15                    PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
16                    outDoc.getPages().addAll(copiedPages);
17
18                    if (args.length == 3) {
19                        Metadata mdata;
20
21                        // Add metadata from a input file
22                        try (
23                        	FileStream metaStream = new FileStream(mdatafile, FileStream.Mode.READ_ONLY)) {
24
25	                        if (mdatafile.toLowerCase().endsWith(".pdf")) {
26	                            // Use the metadata of another PDF file
27	                            try (
28	                            	Document metaDoc = Document.open(metaStream, null)) {
29
30	                            	mdata = Metadata.copy(outDoc, metaDoc.getMetadata());
31	                            }
32	                        } else {
33	                            // Use the content of an XMP metadata file
34	                            mdata = Metadata.create(outDoc, metaStream);
35	                        }
36                        }
37                        outDoc.setMetadata(mdata);
38                    } else {
39                        // Set some metadata properties
40                        Metadata metadata = outDoc.getMetadata();
41                        metadata.setAuthor("Your Author");
42                        metadata.setTitle("Your Title");
43                        metadata.setSubject("Your Subject");
44                        metadata.setCreator("Your Creator");
45                    }
46                }
47            }
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data (excluding metadata)
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Viewer settings
9    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
10
11    // Associated files (for PDF/A-3 and PDF 2.0 only)
12    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
13    for (FileReference inFileRef : inDoc.getAssociatedFiles())
14        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
15
16    // Plain embedded files
17    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
18    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
19        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
20}
Download code sample
1
2
3# Open input document
4with io.FileIO(input_file_path, 'rb') as content_pdf_stream:
5    with Document.open(content_pdf_stream, None) as content_pdf_document:
6
7        # Create output document
8        with io.FileIO(output_file_path, 'wb+') as output_stream:
9            with Document.create(output_stream, content_pdf_document.conformance, None) as output_document:
10                # Copy document-wide data
11                copy_document_data(content_pdf_document, output_document)
12
13                # Set Metadata
14                if metadata_file_path is not None:
15                    with io.FileIO(metadata_file_path, 'rb') as metadata_stream:
16                        if metadata_file_path.endswith(".pdf"):
17                            # Use the metadata of another PDF file
18                            with Document.open(metadata_stream, "") as meta_doc:
19                                mdata = Metadata.copy(output_document, meta_doc.metadata)
20                        else:
21                            # Use the content of an XMP metadata file
22                            mdata = Metadata.create(output_document, metadata_stream)
23                else:
24                    metadata = output_document.metadata
25                    metadata.author = "Your Author"
26                    metadata.title = "Your Title"
27                    metadata.subject = "Your Subject"
28                    metadata.creator = "Your Creator"
29
30                output_document.metadata = mdata
31
32                # Define page copy options
33                copy_options = PageCopyOptions()
34
35                #  Copy all pages and append to output document
36                copied_pages = PageList.copy(output_document, content_pdf_document.pages, copy_options)
37                output_document.pages.extend(copied_pages)
38
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data (excluding metadata)
3
4    # Output intent
5    if content_pdf_document.output_intent is not None:
6        content_pdf_document.output_intent = IccBasedColorSpace.copy(out_doc, content_pdf_document.output_intent)
7
8    # Viewer settings
9    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
10
11    # Associated files (for PDF/A-3 and PDF 2.0 only)
12    outAssociatedFiles = out_doc.associated_files
13    for in_file_ref in in_doc.associated_files:
14        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
15
16    # Plain embedded files
17    out_embedded_files = out_doc.plain_embedded_files
18    for in_file_ref in in_doc.plain_embedded_files:
19        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Encrypt PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9pEncryption =
10    PtxPdf_Encryption_New(szUserPwd, szOwnerPwd, ePtxPdf_Permission_Print | ePtxPdf_Permission_DigitalPrint);
11
12// Create output document
13pOutStream = _tfopen(szOutPath, _T("wb+"));
14GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
15PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
16iConformance = PtxPdf_Document_GetConformance(pInDoc);
17pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, pEncryption);
18GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
19                                 szOutPath, szErrorBuff, Ptx_GetLastError());
20
21// Copy document-wide data
22GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
23                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
24                                  Ptx_GetLastError());
25
26// Configure copy options
27pCopyOptions = PtxPdf_PageCopyOptions_New();
28
29// Copy all pages
30pInPageList = PtxPdf_Document_GetPages(pInDoc);
31GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
32                                 _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"),
33                                 szErrorBuff, Ptx_GetLastError());
34pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
35GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
36                                 Ptx_GetLastError());
37
38// Add copied pages to output
39pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
40GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
41                                 _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
42                                 szErrorBuff, Ptx_GetLastError());
43GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages),
44                                  _T("Failed to add copied pages to output. %s (ErrorCode: 0x%08x).\n"),
45                                  szErrorBuff, Ptx_GetLastError());
46
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
Download code sample
1// Create encryption parameters
2Encryption encryptionParams = new Encryption(UserPwd, OwnerPwd, Permission.Print | 
3    Permission.DigitalPrint);
4
5// Open input document
6using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
7using (Document inDoc = Document.Open(inStream, null))
8
9// Create output document and set a user and owner password
10using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
11using (Document outDoc = Document.Create(outStream, inDoc.Conformance, encryptionParams))
12{
13    // Copy document-wide data
14    CopyDocumentData(inDoc, outDoc);
15
16    // Define page copy options
17    PageCopyOptions copyOptions = new PageCopyOptions();
18
19    // Copy all pages and append to output document
20    PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
21    outDoc.Pages.AddRange(copiedPages);
22}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1// Create encryption parameters
2Encryption encryptionParams = new Encryption(userPwd, ownerPwd,
3        EnumSet.of(Permission.PRINT, Permission.DIGITAL_PRINT));
4
5try (// Open input document
6    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
7    Document inDoc = Document.open(inStream, null);
8    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
9    try (// Create output document and set a user and owner password
10        Document outDoc = Document.create(outStream, inDoc.getConformance(), encryptionParams)) {
11
12        // Copy document-wide data
13        copyDocumentData(inDoc, outDoc);
14
15        // Define page copy options
16        PageCopyOptions copyOptions = new PageCopyOptions();
17
18        // Copy all pages and append to output document
19        PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
20        outDoc.getPages().addAll(copiedPages);
21    }
22}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1
2
3# Open input document
4with io.FileIO(input_file_path, "rb") as in_stream:
5    with Document.open(in_stream, None) as in_doc:
6
7        # Create encryption parameters
8        encryption_params = Encryption(
9            user_pwd,
10            owner_pwd,
11            Permission.PRINT | Permission.DIGITAL_PRINT,
12        )
13
14        # Create output document and set a user and owner password
15        with io.FileIO(output_file_path, "wb+") as out_stream:
16            with Document.create(out_stream, in_doc.conformance, encryption_params) as out_doc:
17
18                # Copy document-wide data
19                copy_document_data(in_doc, out_doc)
20
21                # Define page copy options
22                copy_options = PageCopyOptions()
23
24                # Copy all pages and append to output document
25                copied_pages = PageList.copy(out_doc, in_doc.pages, copy_options)
26                out_doc.pages.extend(copied_pages)
27
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Flatten form fields in PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Configure copy options: enable form field flattening
24pCopyOptions = PtxPdf_PageCopyOptions_New();
25PtxPdf_PageCopyOptions_SetFormFields(pCopyOptions, ePtxPdfForms_FormFieldCopyStrategy_Flatten);
26
27// Copy all pages
28pInPageList = PtxPdf_Document_GetPages(pInDoc);
29GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
30                                 _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"),
31                                 szErrorBuff, Ptx_GetLastError());
32pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
33GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
34                                 Ptx_GetLastError());
35
36// Add copied pages to output
37pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
38GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
39                                 _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
40                                 szErrorBuff, Ptx_GetLastError());
41GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages),
42                                  _T("Failed to add copied pages to output. %s (ErrorCode: 0x%08x).\n"),
43                                  szErrorBuff, Ptx_GetLastError());
44
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define copy options including form field flattening
13    PageCopyOptions copyOptions = new PageCopyOptions();
14    copyOptions.FormFields = FormFieldCopyStrategy.Flatten;
15
16    // Copy all pages and append to output document
17    PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
18    outDoc.Pages.AddRange(copiedPages);
19}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define copy options including form field flattening
12        PageCopyOptions copyOptions = new PageCopyOptions();
13        copyOptions.setFormFields(FormFieldCopyStrategy.FLATTEN);
14
15        // Copy all pages and append to output document
16        PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
17        outDoc.getPages().addAll(copiedPages);
18    }
19}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1
2
3# Open input document
4with io.FileIO(input_file_path, "rb") as in_stream:
5    with Document.open(in_stream, None) as in_doc:
6
7        # Create output document
8        with io.FileIO(output_file_path, "wb+") as out_stream:
9            with Document.create(out_stream, in_doc.conformance, None) as out_doc:
10
11                # Copy document-wide data
12                copy_document_data(in_doc, out_doc)
13
14                # Set form field flattening options
15                copy_options = PageCopyOptions()
16                copy_options.form_fields = FormFieldCopyStrategy.FLATTEN
17
18                # Copy all pages with flattening options
19                copied_pages = PageList.copy(out_doc, in_doc.pages, copy_options)
20                out_doc.pages.extend(copied_pages)
21
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Merge multiple PDFs and create a table of contents page

Download code sample
1// Create output document
2using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
3using (Document outDoc = Document.Create(outStream, null, null))
4{
5    // Create embedded font in output document 
6    Font font = Font.CreateFromSystem(outDoc, "Arial", string.Empty, true);
7
8    // Define page copy options
9    PageCopyOptions pageCopyOptions = new PageCopyOptions();
10
11    var copiedPageLists = new List<Tuple<string, PageList>>(inPaths.Length);
12
13    // A page number counter
14    int pageNumber = 2;
15
16    // Copy all input documents pages
17    foreach (string inPath in inPaths)
18    {
19        // Open input document
20        using Stream inFs = new FileStream(inPath, FileMode.Open, FileAccess.Read);
21        using Document inDoc = Document.Open(inFs, null);
22
23        // Copy all pages and append to output document
24        PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, pageCopyOptions);
25
26        // Add page numbers to copied pages
27        foreach (var copiedPage in copiedPages)
28        {
29            AddPageNumber(outDoc, copiedPage, font, pageNumber++);
30        }
31
32        // Create outline item
33        string title = inDoc.Metadata.Title ?? System.IO.Path.GetFileNameWithoutExtension(inPath);
34        copiedPageLists.Add(new Tuple<string, PageList>(title, copiedPages));
35    }
36
37    // Create table of contents page
38    var contentsPage = CreateTableOfContents(outDoc, copiedPageLists);
39    AddPageNumber(outDoc, contentsPage, font, 1);
40
41    // Add pages to the output document
42    PageList outPages = outDoc.Pages;
43    outPages.Add(contentsPage);
44    foreach (var tuple in copiedPageLists)
45    {
46        outPages.AddRange(tuple.Item2);
47    }
1private static void AddPageNumber(Document outDoc, Page copiedPage, Font font, int pageNumber)
2{
3    // Create content generator
4    using ContentGenerator generator = new ContentGenerator(copiedPage.Content, false);
5
6    // Create text object
7    Text text = Text.Create(outDoc);
8
9    // Create a text generator with the given font, size and position
10    using (TextGenerator textgenerator = new TextGenerator(text, font, 8, null))
11    {
12        // Generate string to be stamped as page number
13        string stampText = string.Format("Page {0}", pageNumber);
14
15        // Calculate position for centering text at bottom of page
16        Point position = new Point
17        {
18            X = (copiedPage.Size.Width / 2) - (textgenerator.GetWidth(stampText) / 2),
19            Y = 10
20        };
21
22        // Position the text
23        textgenerator.MoveTo(position);
24        // Add page number
25        textgenerator.Show(stampText);
26    }
27    // Paint the positioned text
28    generator.PaintText(text);
29}
1private static Page CreateTableOfContents(Document outDoc, List<Tuple<string, PageList>> copiedPageLists)
2{
3    // Create a new page with size equal to the first page copied
4    var page = Page.Create(outDoc, copiedPageLists[0].Item2[0].Size);
5
6    // Create a font
7    var font = Font.CreateFromSystem(outDoc, "Arial", null, true);
8
9    // Parameters for layout computation
10    double border = 30;
11    double textWidth = page.Size.Width - 2 * border;
12    double chapterTitleSize = 24;
13    double titleSize = 12;
14
15    // The current text location
16    var location = new Point() { X = border, Y = page.Size.Height - border - chapterTitleSize };
17
18    // The page number of the current item in the table of content
19    int pageNumber = 2;
20
21    // Create a content generator for the table of contents page
22    using (var contentGenerator = new ContentGenerator(page.Content, false))
23    {
24        // Create a text object
25        var text = Text.Create(outDoc);
26
27        // Create a text generator to generate the table of contents. Initially, use the chapter title font size
28        using (var textGenerator = new TextGenerator(text, font, chapterTitleSize, location))
29        {
30            // Show a chapter title
31            textGenerator.ShowLine("Table of Contents");
32
33            // Advance the vertical position
34            location.Y -= 1.7 * chapterTitleSize;
35
36            // Select the font size for an entry in the table of contents
37            textGenerator.FontSize = titleSize;
38
39            // Iterate over all copied page ranges
40            foreach (var tuple in copiedPageLists)
41            {
42                // The title string for the current entry
43                string title = tuple.Item1;
44
45                // The page number string of the target page for this entry
46                string pageNumberString = string.Format("{0}", pageNumber);
47
48                // The width of the page number string
49                double pageNumberWidth = textGenerator.GetWidth(pageNumberString);
50
51                // Compute the number of filler dots to be displayed between the entry title and the page number
52                int numberOfDots = (int)Math.Floor((textWidth - textGenerator.GetWidth(title) - pageNumberWidth) / textGenerator.GetWidth("."));
53
54                // Move to the current location and show the entry's title and the filler dots
55                textGenerator.MoveTo(location);
56                textGenerator.Show(title + new string('.', numberOfDots));
57
58                // Show the page number
59                textGenerator.MoveTo(new Point() { X = page.Size.Width - border - pageNumberWidth, Y = location.Y });
60                textGenerator.Show(pageNumberString);
61
62                // Compute the rectangle for the link
63                var linkRectangle = new Rectangle()
64                {
65                    Left = border,
66                    Bottom = location.Y + font.Descent * titleSize,
67                    Right = border + textWidth,
68                    Top = location.Y + font.Ascent * titleSize
69                };
70
71                // Create a destination to the first page of the current page range and create a link for this destination
72                var pageList = tuple.Item2;
73                var targetPage = pageList[0];
74                var destination = LocationZoomDestination.Create(outDoc, targetPage, 0, targetPage.Size.Height, null);
75                var link = InternalLink.Create(outDoc, linkRectangle, destination);
76
77                // Add the link to the table of contents page
78                page.Links.Add(link);
79
80                // Advance the location for the next entry
81                location.Y -= 1.8 * titleSize;
82                pageNumber += pageList.Count;
83            }
84        }
85
86        // Paint the generated text
87        contentGenerator.PaintText(text);
88    }
89
90    // Return the finished table-of-contents page
91    return page;
92}
Download code sample
1try (
2    // Open input document
3    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
4    try (// Create output document
5        Document outDoc = Document.create(outStream, null, null)) {
6
7        // Create embedded font in output document 
8        Font font = Font.createFromSystem(outDoc, "Arial", "", true);
9
10        // Configure page copy options
11        PageCopyOptions copyOptions = new PageCopyOptions();
12
13        Set<Map.Entry<String, PageList>> copiedPageLists = new HashSet<>(inPaths.length);
14
15        // A page number counter
16        int pageNumber = 2;
17
18
19        // Copy all input documents pages
20        for (String inPath : inPaths) {
21            try (// Open input document
22                Stream inFs = new FileStream(inPath, FileStream.Mode.READ_ONLY);
23                Document inDoc = Document.open(inFs, null)) {
24
25                // Copy all pages and append to output document
26                PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
27
28                // Add page numbers to copied pages
29                for ( Page copiedPage : copiedPages)
30                {
31                    addPageNumber(outDoc, copiedPage, font, pageNumber++);
32                }
33
34                // Hold the file name without extension
35                if (inPath == null)
36                    continue;
37                // Get position of last '.'.
38                int pos = inPath.lastIndexOf(".");
39                // If there was a '.', hold the file name only
40                if (pos != -1) 
41                    inPath = inPath.substring(0, pos);
42
43                // Create outline item
44                String title = (inDoc.getMetadata().getTitle() == null ? inPath : inDoc.getMetadata().getTitle());
45                copiedPageLists.add(new AbstractMap.SimpleEntry<String, PageList>(title, copiedPages));
46            }
47        }
48
49        // Create table of contents page
50        Page contentsPage = createTableOfContents(outDoc, copiedPageLists);
51        addPageNumber(outDoc, contentsPage, font, 1);
52
53        // Add pages to the output document
54        PageList outPages = outDoc.getPages();
55        outPages.add(contentsPage);
56        for (Map.Entry<String, PageList> entry : copiedPageLists)
57        {
58            outPages.addAll(entry.getValue());
59        }
1private static void addPageNumber(Document outDoc, Page copiedPage, Font font, int pageNumber) throws ToolboxException, IOException
2{
3    // Create content generator
4    try (ContentGenerator generator = new ContentGenerator(copiedPage.getContent(), false)) {
5        // Create text object
6        Text text = Text.create(outDoc);
7
8        // Create a text generator with the given font, size and position
9        try (TextGenerator textgenerator = new TextGenerator(text, font, 8, null)) {
10            // Generate string to be stamped as page number
11            String stampText = String.format("Page %d", pageNumber);
12
13            // Calculate position for centering text at bottom of page
14            Point position = new Point();
15            position.x = (copiedPage.getSize().getWidth() / 2) - (textgenerator.getWidth(stampText) / 2);
16            position.y = 10;
17
18            // Position the text
19            textgenerator.moveTo(position);
20            // Add page number
21            textgenerator.show(stampText);
22        }
23
24        // Paint the positioned text
25        generator.paintText(text);
26    }
27}
1private static Page createTableOfContents(Document outDoc, Set<Map.Entry<String, PageList>> copiedPageLists) throws IOException, ToolboxException
2{
3    // Create a new page with size equal to the first page copied
4    Page page = Page.create(outDoc, copiedPageLists.iterator().next().getValue().get(0).getSize());
5
6    // Create a font
7    Font font = Font.createFromSystem(outDoc, "Arial", null, true);
8
9    // Parameters for layout computation
10    double border = 30;
11    double textWidth = page.getSize().getWidth() - 2 * border;
12    double chapterTitleSize = 24;
13    double titleSize = 12;
14
15    // The current text location
16    Point location = new Point();
17    location.x = border;
18    location.y = page.getSize().getHeight() - border - chapterTitleSize;
19
20    // The page number of the current item in the table of content
21    int pageNumber = 2;
22
23    // Creat a content generator for the table of contents page
24    try (ContentGenerator contentGenerator = new ContentGenerator(page.getContent(), false)) {
25        // Create a text object
26        Text text = Text.create(outDoc);
27
28        // Create a text generator to generate the table of contents. Initially, use the chapter title font size
29        try (TextGenerator textGenerator = new TextGenerator(text, font, chapterTitleSize, location)) {
30            // Show a chapter title
31            textGenerator.showLine("Table of Contents");
32
33            // Advance the vertical position
34            location.y -= 1.7 * chapterTitleSize;
35
36            // Select the font size for an entry in the table of contents
37            textGenerator.setFontSize(titleSize);
38
39            // Iterate over all copied page ranges
40            for (Map.Entry<String, PageList> entry : copiedPageLists)
41            {
42                // The title string for the current entry
43                String title = entry.getKey();
44
45                // The page number string of the target page for this entry
46                String pageNumberString = String.format("%d", pageNumber);
47
48                // The width of the page number string
49                double pageNumberWidth = textGenerator.getWidth(pageNumberString);
50
51                // Compute the number of filler dots to be displayed between the entry title and the page number
52                int numberOfDots = (int)Math.floor((textWidth - textGenerator.getWidth(title) - pageNumberWidth) / textGenerator.getWidth("."));
53
54                // Move to the current location and show the entry's title and the filler dots
55                textGenerator.moveTo(location);
56                String dots = new String();
57                for (int i = 0; i < numberOfDots; i++)
58                {
59                    dots += '.';
60                }
61                textGenerator.show(title + dots);
62
63                // Show the page number
64                Point point = new Point();
65                point.x = page.getSize().getWidth() - border - pageNumberWidth;
66                point.y = location.y;
67                textGenerator.moveTo(point);
68                textGenerator.show(pageNumberString);
69
70                // Compute the rectangle for the link
71                Rectangle linkRectangle = new Rectangle();
72                linkRectangle.setLeft(border);
73                linkRectangle.setBottom(location.y + font.getDescent() * titleSize);
74                linkRectangle.setRight(border + textWidth);
75                linkRectangle.setTop(location.y + font.getAscent() * titleSize);
76
77                // Create a destination to the first page of the current page range and create a link for this destination
78                PageList pageList = entry.getValue();
79                Page targetPage = pageList.get(0);
80                LocationZoomDestination destination = LocationZoomDestination.create(outDoc, targetPage, (double) 0, targetPage.getSize().getHeight(), null);
81                InternalLink link = InternalLink.create(outDoc, linkRectangle, destination);
82
83                // Add the link to the table of contents page
84                page.getLinks().add(link);
85
86                // Advance the location for the next entry
87                location.y -= 1.8 * titleSize;
88                pageNumber += pageList.size();
89            }
90        }
91
92        // Paint the generated text
93        contentGenerator.paintText(text);
94    }
95
96    // Return the finished table-of-contents page
97    return page;
98}
Download code sample
1def add_page_number(out_doc: Document, page: Page, font: Font, page_number: int):
2    """Add a page number to the bottom center of a page."""
3    # Create content generator
4    with ContentGenerator(page.content, False) as generator:
5
6        # Create text object
7        text = Text.create(out_doc)
8
9        # Create a text generator with the given font, size and position
10        with TextGenerator(text, font, 8, None) as text_generator:
11            # Generate string to be stamped as page number
12            stamp_text = f"Page {page_number}"
13
14            # Calculate position for centering text at bottom of page
15            position = Point(
16                x=(page.size.width / 2) - (text_generator.get_width(stamp_text) / 2),
17                y=10,
18            )
19
20            # Position the text
21            text_generator.move_to(position)
22            # Add page number
23            text_generator.show(stamp_text)
24
25        # Paint the positioned text
26        generator.paint_text(text)
1def create_table_of_contents(out_doc:Document, toc_entries: tuple, font: Font):
2    """Create a table of contents (TOC) page."""
3    # Create a new page with size equal to the first page copied
4    page = Page.create(out_doc, toc_entries[0][1][0].size)
5
6    # Parameters for layout computation
7    border = 30
8    text_width = page.size.width - 2 * border
9    chapter_title_size = 24
10    title_size = 12
11
12    # The current text location
13    location = Point(x=border, y=page.size.height - border - chapter_title_size)
14
15    # The page number of the current item in the table of content
16    page_number = 2
17
18    # Create a content generator for the table of contents page
19    with ContentGenerator(page.content, False) as content_generator:
20        #  Create a text object
21        text = Text.create(out_doc)
22
23        # Create a text generator to generate the table of contents. Initially, use the chapter title font size
24        with TextGenerator(text, font, chapter_title_size, location) as text_gen:
25            # Show a chapter title
26            text_gen.show_line("Table of Contents")
27
28            # Advance the vertical position
29            location.y -= 1.7 * chapter_title_size
30
31            # Select the font size for an entry in the table of contents
32            text_gen.font_size = title_size
33
34            # Iterate over all copied page ranges
35            for title, page_list in toc_entries:
36                # The title string for the current entry
37                title_text = title
38
39                # The page number string of the target page for this entry
40                page_number_text = f"{page_number}"
41
42                # The width of the page number string
43                page_number_width = text_gen.get_width(page_number_text)
44
45                # Compute the number of filler dots to be displayed between the entry title and the page number
46                filler_dots_count = int(
47                    (text_width - text_gen.get_width(title_text) - page_number_width)
48                    / text_gen.get_width(".")
49                )
50
51                # Move to the current location and show the entry's title and the filler dots
52                text_gen.move_to(location)
53                text_gen.show(title_text + "." * filler_dots_count)
54
55                # Show the page number
56                text_gen.move_to(Point(x=page.size.width - border - page_number_width, y=location.y))
57                text_gen.show(page_number_text)
58
59                # Compute the rectangle for the link
60                link_rectangle = Rectangle(
61                    left=border,
62                    bottom=location.y + font.descent * title_size,
63                    right=border + text_width,
64                    top=location.y + font.ascent * title_size,
65                )
66
67                # Create a destination to the first page of the current page range and create a link for this destination
68                target_page = page_list[0]
69                destination = LocationZoomDestination.create(out_doc, target_page, 0, target_page.size.height, None)
70                link = InternalLink.create(out_doc, link_rectangle, destination)
71
72                # Add the link to the table of contents page
73                page.links.append(link)
74
75                # Advance the location for the next entry
76                location.y -= 1.8 * title_size
77                page_number += len(page_list)
78
79        # Paint the generated text
80        content_generator.paint_text(text)
81
82    return page

Merge multiple PDFs

Download code sample
1// Create output document
2pOutStream = _tfopen(szOutPath, _T("wb+"));
3GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
4PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
5pOutDoc = PtxPdf_Document_Create(&outDescriptor, NULL, NULL);
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
7                                 szOutPath, szErrorBuff, Ptx_GetLastError());
8
9// Configure copy options
10pCopyOptions = PtxPdf_PageCopyOptions_New();
11
12// Get output page list
13pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
14GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
15                                 _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
16                                 szErrorBuff, Ptx_GetLastError());
17
18// Merge input documents
19for (int i = 1; i < argc - 1; i++)
20{
21    // Open input document
22    pInStream = _tfopen(szInPath[i], _T("rb"));
23    GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath[i]);
24    PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
25    pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
26    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
27                                     szInPath[i], szErrorBuff, Ptx_GetLastError());
28
29    // Configure copy options
30    pCopyOptions = PtxPdf_PageCopyOptions_New();
31
32    // Copy all pages
33    pInPageList = PtxPdf_Document_GetPages(pInDoc);
34    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
35                                     _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"),
36                                     szErrorBuff, Ptx_GetLastError());
37    pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
38    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"),
39                                     szErrorBuff, Ptx_GetLastError());
40
41    // Append copied pages
42    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages),
43                                      _T("Failed to add page range. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
44                                      Ptx_GetLastError());
45
46    Ptx_Release(pInPageList);
47    pInPageList = NULL;
48    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_Close(pInDoc),
49                                      _T("Failed to close input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
50                                      Ptx_GetLastError());
51    pInDoc = NULL;
52    fclose(pInStream);
53    pInStream = NULL;
54    Ptx_Release(pCopiedPages);
55    pCopiedPages = NULL;
56}
57
Download code sample
1// Create output document
2using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
3using (Document outDoc = Document.Create(outStream, null, null))
4{
5    // Define page copy options
6    PageCopyOptions copyOptions = new PageCopyOptions();
7
8    // Get output pages
9    PageList outPages = outDoc.Pages;
10
11    // Merge input documents 
12    for (int i = 0; i < args.Length - 1; i++)
13    {
14        // Open input document
15        using Stream inFs = new FileStream(inPath[i], FileMode.Open, FileAccess.Read);
16        using Document inDoc = Document.Open(inFs, null);
17
18        // Copy all pages and append to output document
19        PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
20        outPages.AddRange(copiedPages);
21    }
22}
23
Download code sample
1try (
2    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
3    try (// Create output document
4        Document outDoc = Document.create(outStream, null, null)) {
5
6        // Configure page copy options
7        PageCopyOptions copyOptions = new PageCopyOptions();
8
9        // Get output pages
10        PageList outPages = outDoc.getPages();
11
12        // Merge input document
13        for (int i = 0; i < args.length - 1; i++) {
14            try (// Open input document
15                FileStream inStream = new FileStream(inPath[i], FileStream.Mode.READ_ONLY);
16                Document inDoc = Document.open(inStream, null)) {
17
18                // Copy all pages and append to output document
19                PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
20                outPages.addAll(copiedPages);
21            }
22        }
23    }
24}
25
Download code sample
1# Create output document
2with open(output_path, "wb+") as out_stream:
3    with Document.create(out_stream, None, None) as out_doc:
4
5        # Define page copy options
6        page_copy_options = PageCopyOptions()
7
8        # Get output pages
9        out_pages = out_doc.pages
10
11        # Merge input documents
12        for input_path in input_paths:
13            # Open input document
14            with open(input_path, "rb") as in_stream:
15                with Document.open(in_stream, None) as in_doc:
16
17                    # Copy all pages and append to output document
18                    copied_pages = PageList.copy(out_doc, in_doc.pages, page_copy_options)
19                    out_pages.extend(copied_pages)
20

Merge multiple PDFs with outlines

Download code sample
1// Create output document
2using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
3using (Document outDoc = Document.Create(outStream, null, null))
4{
5    // Define page copy options, skip outline
6    PageCopyOptions pageCopyOptions = new PageCopyOptions
7    {
8        CopyOutlineItems = false
9    };
10
11    // Define outline copy options
12    OutlineCopyOptions outlineCopyOptions = new OutlineCopyOptions();
13
14    // Get output pages
15    PageList outPages = outDoc.Pages;
16
17    // Merge input documents
18    foreach (string inPath in inPaths)
19    {
20        // Open input document
21        using Stream inFs = new FileStream(inPath, FileMode.Open, FileAccess.Read);
22        using Document inDoc = Document.Open(inFs, null);
23
24        // Copy all pages and append to output document
25        PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, pageCopyOptions);
26        outPages.AddRange(copiedPages);
27
28        // Create outline item
29        string title = inDoc.Metadata.Title ?? Path.GetFileName(inPath);
30        Page firstCopiedPage = copiedPages[0];
31        Destination destination = LocationZoomDestination.Create(outDoc, firstCopiedPage, 0, firstCopiedPage.Size.Height, null);
32        OutlineItem outlineItem = OutlineItem.Create(outDoc, title, destination);
33        outDoc.Outline.Add(outlineItem);
34
35        // Add outline items from input document as children
36        OutlineItemList children = outlineItem.Children;
37        foreach (OutlineItem inputOutline in inDoc.Outline)
38            children.Add(OutlineItem.Copy(outDoc, inputOutline, outlineCopyOptions));
39    }
40}
41
Download code sample
1try (
2    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
3    try (// Create output document
4        Document outDoc = Document.create(outStream, null, null)) {
5        // Define page copy options, skip outline
6        PageCopyOptions pageCopyOptions = new PageCopyOptions();
7        pageCopyOptions.setCopyOutlineItems(false);
8
9        // Define outline copy options
10        OutlineCopyOptions outlineCopyOptions = new OutlineCopyOptions();
11
12        // Get output pages
13        PageList outPages = outDoc.getPages();
14
15        // Merge input document
16        for (String inPath : inPaths) {
17            try (// Open input document
18                FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
19                Document inDoc = Document.open(inStream, null)) {
20
21                // Copy all pages and append to output document
22                PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), pageCopyOptions);
23                outPages.addAll(copiedPages);
24
25                // Create outline item
26                String title = inDoc.getMetadata().getTitle();
27                if (title == null)
28                    title = Paths.get(inPath).getFileName().toString();
29                Page firstCopiedPage = copiedPages.get(0);
30                Destination destination = LocationZoomDestination.create(outDoc, firstCopiedPage, 0.0,
31                        firstCopiedPage.getSize().getHeight(), null);
32                OutlineItem outlineItem = OutlineItem.create(outDoc, title, destination);
33                outDoc.getOutline().add(outlineItem);
34
35                // Add outline items from input document as children
36                OutlineItemList children = outlineItem.getChildren();
37                for (OutlineItem inputOutline : inDoc.getOutline())
38                    children.add(OutlineItem.copy(outDoc, inputOutline, outlineCopyOptions));
39            }
40        }
41    }
42}
43
Download code sample
1# Create output document
2with open(output_path, "wb+") as out_stream:
3    with Document.create(out_stream, None, None) as out_doc:
4
5        # Define page copy options
6        page_copy_options = PageCopyOptions()
7        page_copy_options.copy_outline_items = False
8
9        # Define outline copy options
10        outline_copy_options = OutlineCopyOptions()
11
12        # Get output pages
13        out_pages = out_doc.pages
14
15        # Merge input documents
16        for input_path in input_paths:
17            # Open input document
18            with open(input_path, "rb") as in_stream:
19                with Document.open(in_stream, None) as in_doc:
20
21                    # Copy all pages and append to output document
22                    copied_pages = PageList.copy(out_doc, in_doc.pages, page_copy_options)
23                    out_pages.extend(copied_pages)
24
25                    # Create outline item
26                    title = in_doc.metadata.title or os.path.basename(input_path)
27                    first_copied_page = copied_pages[0]
28                    destination = LocationZoomDestination.create(out_doc, first_copied_page, 0, first_copied_page.size.height, None)
29                    outline_item = OutlineItem.create(out_doc, title, destination)
30                    out_doc.outline.append(outline_item)
31
32                    # Add outline items from input document as children
33                    children = outline_item.children
34                    for in_outline_item in in_doc.outline:
35                        children.append(OutlineItem.copy(out_doc, in_outline_item, outline_copy_options))
36

Overlay color of PDF

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Create transparency and set blend mode
13    Transparency transparency = new Transparency(colorAlpha)
14    {
15        BlendMode = BlendMode.Multiply
16    };
17
18    // Create colorspace
19    ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, colorType);
20
21    // Create a transparent paint for the given color
22    Paint paint = Paint.Create(outDoc, colorSpace, color, transparency);
23    Fill fill = new Fill(paint);
24
25    // Get output pages
26    PageList outPages = outDoc.Pages;
27
28    // Define page copy options
29    PageCopyOptions copyOptions = new PageCopyOptions();
30
31    // Loop through all pages
32    foreach (Page inPage in inDoc.Pages)
33    {
34        // Create a new page
35        Page outPage = Page.Copy(outDoc, inPage, copyOptions);
36        Size size = inPage.Size;
37
38        // Create a content generator
39        using (ContentGenerator generator = new ContentGenerator(outPage.Content, false))
40        {
41            // Make a rectangular path the same size as the page
42            PdfTools.Toolbox.Pdf.Content.Path path = new PdfTools.Toolbox.Pdf.Content.Path();
43            using (PathGenerator pathGenerator = new PathGenerator(path))
44            {
45                // Compute Rectangle
46                Rectangle pathRect = new Rectangle
47                {
48                    Left = 0,
49                    Bottom = 0,
50                    Right = size.Width,
51                    Top = size.Height
52                };
53                pathGenerator.AddRectangle(pathRect);
54            }
55            // Paint the path with the transparent paint
56            generator.PaintPath(path, fill, null);
57        }
58        // Add pages to output document
59        outPages.Add(outPage);
60    }
61}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Create transparency and set blend mode
12        Transparency transparency = new Transparency(colorAlpha);
13        transparency.setBlendMode(BlendMode.MULTIPLY);
14
15        // Create colorspace
16        ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outDoc, colorType);
17
18        // Create a transparent paint for the given color
19        Paint paint = Paint.create(outDoc, colorSpace, color, transparency);
20        Fill fill = new Fill(paint);
21
22        // Set copy options
23        PageCopyOptions copyOptions = new PageCopyOptions();
24
25        // Loop through all pages
26        for (Page inPage : inDoc.getPages()) {
27            // Create a new page
28            Size size = inPage.getSize();
29            Page outPage = Page.copy(outDoc, inPage, copyOptions);
30
31            try (// Create a content generator
32                ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
33                // Calculate rectangle
34                Rectangle rect = new Rectangle(0, 0, size.width, size.height);
35
36                // Make a rectangular path the same size as the page
37                Path path = new Path();
38                try (
39                    PathGenerator pathGenerator = new PathGenerator(path)) {
40                    pathGenerator.addRectangle(rect);
41                }
42
43                // Paint the path with the transparent paint
44                generator.paintPath(path, fill, null);
45            }
46
47            // Add pages to output document
48            outDoc.getPages().add(outPage);
49        }
50    }
51}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def parse_options(options: str) -> tuple:
2    """
3    Parse the options string to extract color, color type, and alpha.
4    """
5    # Default values
6    color_type = COLOR_TYPE
7    color = COLOR
8    alpha = COLOR_ALPHA
9
10    if options is None:
11        return color, color_type, alpha
12
13    # Split options into tokens
14    tokens = options.split()
15    if not tokens:
16        return color, color_type, alpha
17
18    # Parse options
19    i = 0
20    while i < len(tokens):
21        arg = tokens[i]
22        if arg.startswith("-"):
23            if len(arg) != 2:
24                raise ValueError(f"Invalid option: {arg}")
25
26            flag = arg[1]
27            i += 1  # Move to the next token
28
29            if flag == "k":  # Grayscale
30                if len(tokens) - i != 2:
31                    raise ValueError("Invalid arguments for -k. Requires (k) (a).")
32                color_type = ProcessColorSpaceType.GRAY
33                color = [float(tokens[i])]
34                alpha = float(tokens[i + 1])
35                i += 2
36            elif flag == "c":  # CMYK
37                if len(tokens) - i != 5:
38                    raise ValueError("Invalid arguments for -c. Requires (c) (m) (y) (k) (a).")
39                color_type = ProcessColorSpaceType.CMYK
40                color = [float(tokens[i]), float(tokens[i + 1]), float(tokens[i + 2]), float(tokens[i + 3])]
41                alpha = float(tokens[i + 4])
42                i += 5
43            elif flag == "r":  # RGB
44                if len(tokens) - i != 4:
45                    raise ValueError("Invalid arguments for -r. Requires (r) (g) (b) (a).")
46                color_type = ProcessColorSpaceType.RGB
47                color = [float(tokens[i]), float(tokens[i + 1]), float(tokens[i + 2])]
48                alpha = float(tokens[i + 3])
49                i += 4
50            else:
51                raise ValueError(f"Unsupported option: {flag}")
52        else:
53            raise ValueError(f"Unexpected token: {arg}")
54
55    # Validate color and alpha values
56    if not (0 <= alpha <= 1 and all(0 <= c <= 1 for c in color)):
57        raise ValueError("Color and alpha values must be between 0 and 1.")
58
59    return color, color_type, alpha
1def apply_overlay_to_pages(in_doc: Document, out_doc: Document, color: list, color_type: ProcessColorSpaceType, color_alpha: float):
2    """Apply the overlay color to all pages in the document."""
3
4    # Create transparency and set blend mode
5    transparency = Transparency(color_alpha)
6    transparency.blend_mode = BlendMode.MULTIPLY
7
8    # Create color space
9    color_space = ColorSpace.create_process_color_space(out_doc, color_type)
10
11    # Create a transparent paint for the given color
12    paint = Paint.create(out_doc, color_space, color, transparency)
13    fill = Fill(paint)
14
15    # Get output pages
16    out_pages = out_doc.pages
17
18    # Define page copy options
19    copy_options = PageCopyOptions()
20
21    # Loop through all pages
22    for in_page in in_doc.pages:
23        # Create a new page
24        out_page = Page.copy(out_doc, in_page, copy_options)
25
26        in_page_size = in_page.size
27
28        # Create a content generator
29        with ContentGenerator(out_page.content, False) as generator:
30
31            # Make a rectangular path the same size as the page
32            path = Path()
33            with PathGenerator(path) as path_generator:
34                # Compute Rectangle
35                path_rectangle = Rectangle(
36                        left=0,
37                        bottom=0,
38                        right=in_page_size.width,
39                        top=in_page_size.height,
40                    )
41
42                path_generator.add_rectangle(path_rectangle)
43
44            # Paint the path with the transparent overlay
45            generator.paint_path(path, fill, None)
46
47        out_pages.append(out_page)

Add info entries to PDF

Download code sample
1// Open input document 
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Copy all pages and append to output document
16    PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
17    outDoc.Pages.AddRange(copiedPages);
18
19    // Set info entry
20    Metadata metadata = Metadata.Copy(outDoc, inDoc.Metadata);
21    if (key == "Title")
22        metadata.Title = value;
23    else if (key == "Author")
24        metadata.Author = value;
25    else if (key == "Subject")
26        metadata.Subject = value;
27    else if (key == "Keywords")
28        metadata.Keywords = value;
29    else if (key == "CreationDate")
30        metadata.CreationDate = DateTimeOffset.Parse(value);
31    else if (key == "ModDate")
32        throw new Exception("ModDate cannot be set.");
33    else if (key == "Creator")
34        metadata.Creator = value;
35    else if (key == "Producer")
36        throw new Exception("Producer is set by means of the license key.");
37    else
38        metadata.CustomEntries[key] = value;
39    outDoc.Metadata = metadata;
40}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data (except metadata)
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Viewer settings
10    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
11
12    // Associated files (for PDF/A-3 and PDF 2.0 only)
13    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
14    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
15        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
16
17    // Plain embedded files
18    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
19    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
20        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
21}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define page copy options
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Copy all pages and append to output document
15        PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
16        outDoc.getPages().addAll(copiedPages);
17
18        // Set info entry
19        Metadata metadata = Metadata.copy(outDoc, inDoc.getMetadata());
20        if (key.equals("Title"))
21            metadata.setTitle(value);
22        else if (key.equals("Author"))
23            metadata.setAuthor(value);
24        else if (key.equals("Subject"))
25            metadata.setSubject(value);
26        else if (key.equals("Keywords"))
27            metadata.setKeywords(value);
28        else if (key.equals("CreationDate")) {
29            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd' 'HH:mm:ssZ");
30            OffsetDateTime creationDate = OffsetDateTime.parse(value, formatter);
31            metadata.setCreationDate(creationDate);
32        } else if (key.equals("ModDate"))
33            throw new Exception("ModDate cannot be set.");
34        else if (key.equals("Creator"))
35            metadata.setCreator(value);
36        else if (key.equals("Producer"))
37            throw new Exception("Producer is set by means of the license key.");
38        else
39            metadata.getCustomEntries().put(key, value);
40        outDoc.setMetadata(metadata);
41    }
42}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data (excluding metadata)
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Viewer settings
9    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
10
11    // Associated files (for PDF/A-3 and PDF 2.0 only)
12    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
13    for (FileReference inFileRef : inDoc.getAssociatedFiles())
14        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
15
16    // Plain embedded files
17    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
18    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
19        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
20}
Download code sample
1
2
3# Open input document
4with io.FileIO(input_path, "rb") as in_stream:
5    with Document.open(in_stream, None) as in_doc:
6
7        # Create output document
8        with io.FileIO(output_path, "wb+") as out_stream:
9            with Document.create(out_stream, in_doc.conformance, None) as out_doc:
10
11                # Copy document-wide data
12                copy_document_data(in_doc, out_doc)
13
14                # Define page copy options
15                page_copy_options = PageCopyOptions()
16
17                # Copy all pages and append to output document
18                copied_pages = PageList.copy(out_doc, in_doc.pages, page_copy_options)
19                out_doc.pages.extend(copied_pages)
20
21                # Set info entry
22                metadata = Metadata.copy(out_doc, in_doc.metadata)
23                if key == "Title":
24                    metadata.title = value
25                elif key == "Author":
26                    metadata.author = value
27                elif key == "Subject":
28                    metadata.subject = value
29                elif key == "Keywords":
30                    metadata.keywords = value
31                elif key == "CreationDate":
32                    # Use of the ISO 8601 format for the date
33                    date_format = "%Y-%m-%dT%H:%M:%S"
34                    parsed_date = datetime.strptime(value, date_format)
35
36                    metadata.creation_date = parsed_date
37                elif key == "ModDate":
38                    raise Exception("ModDate cannot be set.")
39                elif key == "Creator":
40                    metadata.creator = value
41                elif key == "Producer":
42                    raise Exception("Producer is set by means of the license key.")
43                else:
44                    metadata.custom_entries[key] = value
45
46                # Assign modified metadata to the output document
47                out_doc.metadata = metadata
48
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data (excluding metadata)
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Viewer settings
9    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
10
11    # Associated files (for PDF/A-3 and PDF 2.0 only)
12    outAssociatedFiles = out_doc.associated_files
13    for in_file_ref in in_doc.associated_files:
14        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
15
16    # Plain embedded files
17    out_embedded_files = out_doc.plain_embedded_files
18    for in_file_ref in in_doc.plain_embedded_files:
19        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Set the open-destination of a PDF

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    if (destinationPageNumber < 1 || destinationPageNumber > inDoc.Pages.Count)
6        throw new ArgumentOutOfRangeException("Given page number is invalid");
7
8    // Create output document
9    using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
10    using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
11
12    // Copy document-wide data
13    CopyDocumentData(inDoc, outDoc);
14
15    // Define page copy options
16    PageCopyOptions copyOptions = new PageCopyOptions();
17
18    // Copy all pages and append to output document
19    PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
20    outDoc.Pages.AddRange(copiedPages);
21
22    // Add open destination
23    Page outPage = copiedPages[destinationPageNumber - 1];
24    outDoc.OpenDestination = LocationZoomDestination.Create(outDoc, outPage, 0, outPage.Size.Height, null);
25}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Check given page number
9        if (destinationPageNumber < 1 || destinationPageNumber > inDoc.getPages().size()) {
10            System.out.println("Given pageNumber is invalid.");
11            return;
12        }
13
14        // Copy document-wide data
15        copyDocumentData(inDoc, outDoc);
16
17        // Define page copy options
18        PageCopyOptions copyOptions = new PageCopyOptions();
19
20        // Copy all pages and append to output document
21        PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
22        outDoc.getPages().addAll(copiedPages);
23
24        // Add open destination
25        Page outPage = outDoc.getPages().get(destinationPageNumber - 1);
26        LocationZoomDestination destination = LocationZoomDestination.create(outDoc, outPage, 0.0, outPage.getSize().getHeight(), null); 
27        outDoc.setOpenDestination(destination);
28    }
29}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1
2
3destination_page_number = int(page_number)
4
5# Open input document
6with io.FileIO(input_path, "rb") as in_stream:
7    with Document.open(in_stream, None) as in_doc:
8
9        if destination_page_number < 1 or destination_page_number > len(in_doc.pages):
10            raise ValueError("Given page number is invalid")
11
12        # Create output document
13        with io.FileIO(output_path, "wb+") as out_stream:
14            with Document.create(out_stream, in_doc.conformance, None) as out_doc:
15
16                # Copy document-wide data
17                copy_document_data(in_doc, out_doc)
18
19                # Define page copy options
20                page_copy_options = PageCopyOptions()
21
22                # Copy all pages and append to output document
23                copied_pages = PageList.copy(out_doc, in_doc.pages, page_copy_options)
24                out_doc.pages.extend(copied_pages)
25
26                # Add open destination
27                out_page = copied_pages[destination_page_number - 1]
28                out_doc.open_destination = LocationZoomDestination.create(out_doc, out_page, 0, out_page.size.height, None)
29
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Remove pages from PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9pInPageList = PtxPdf_Document_GetPages(pInDoc);
10GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
11                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
12                                 szErrorBuff, Ptx_GetLastError());
13int nInPages = PtxPdf_PageList_GetCount(pInPageList);
14iStartIndex  = MAX(MIN(nInPages - 1, iStartIndex), 0);
15nCount       = MIN(nInPages - iStartIndex, nCount);
16GOTO_CLEANUP_IF_FALSE(nCount > 0, _T("lastPage must be greater or equal to firstPage.\n"));
17
18// Create output document
19pOutStream = _tfopen(szOutPath, _T("wb+"));
20GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
21PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
22iConformance = PtxPdf_Document_GetConformance(pInDoc);
23pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
24GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
25                                 szOutPath, szErrorBuff, Ptx_GetLastError());
26
27// Copy document-wide data
28GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
29                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
30                                  Ptx_GetLastError());
31
32// Configure copy options
33pCopyOptions = PtxPdf_PageCopyOptions_New();
34
35// Get page range from input pages
36pInPageRange = PtxPdf_PageList_GetRange(pInPageList, iStartIndex, nCount);
37GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange,
38                                 _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x)\n"),
39                                 szErrorBuff, Ptx_GetLastError());
40
41// Copy page range to toutput document
42pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
43GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to copy page range. %s (ErrorCode: 0x%08x)\n"),
44                                 szErrorBuff, Ptx_GetLastError());
45
46// Get output pages
47pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
48GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
49                                 _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x)\n"),
50                                 szErrorBuff, Ptx_GetLastError());
51
52// Appende page range to output pages
53GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange),
54                                  _T("Failed to append page range. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
55                                  Ptx_GetLastError());
56
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    startIndex = Math.Max(Math.Min(inDoc.Pages.Count - 1, startIndex), 0);
6    count = Math.Min(inDoc.Pages.Count - startIndex, count);
7    if (count <= 0)
8    {
9        Console.WriteLine("lastPage must be greater or equal to firstPage");
10        return;
11    }
12
13    // Create output document
14    using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
15    using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
16
17    // Copy document-wide data
18    CopyDocumentData(inDoc, outDoc);
19
20    // Define page copy options
21    PageCopyOptions copyOptions = new PageCopyOptions();
22
23    // Get page range from input pages
24    PageList inPageRange = inDoc.Pages.GetRange(startIndex, count);
25
26    // Copy page range and append to output document
27    PageList outPageRange = PageList.Copy(outDoc, inPageRange, copyOptions);
28    outDoc.Pages.AddRange(outPageRange);
29}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null)) {
4    // Get pages from input document
5    PageList inPages = inDoc.getPages();
6
7    // Correct and check page indices
8    startIndex = Math.max(Math.min(inPages.size() - 1, startIndex), 0);
9    endIndex = Math.max(Math.min(inPages.size(), endIndex), 0);
10    if (startIndex >= endIndex) {
11        System.out.println("lastPage must be greater or equal to firstPage");
12        return;
13    }
14    try (
15        FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
16        try (// Create output document
17            Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
18
19            // Copy document-wide data
20            copyDocumentData(inDoc, outDoc);
21
22            // Define page copy options
23            PageCopyOptions copyOptions = new PageCopyOptions();
24
25            // Get page range from input pages
26            PageList inPageRange = inPages.subList(startIndex, endIndex);
27
28            // Copy page range and append to output document
29            PageList outPageRange = PageList.copy(outDoc, inPageRange, copyOptions);
30            outDoc.getPages().addAll(outPageRange);
31        }
32    }
33}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain mbedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1
2
3start_index = int(args.first_page) - 1
4last_page = int(args.last_page)
5count = int(args.last_page) - start_index
6
7# Open input document
8with io.FileIO(input_path, "rb") as in_stream:
9    with Document.open(in_stream, None) as in_doc:
10
11        # Validate page range
12        start_index = max(min(len(in_doc.pages) - 1, start_index), 0)
13        count = min(len(in_doc.pages) - start_index, count)
14        if count <= 0:
15            print("lastPage must be greater or equal to firstPage")
16            exit(1)
17
18        # Create output document
19        with io.FileIO(output_path, "wb+") as out_stream:
20            with Document.create(out_stream, in_doc.conformance, None) as out_doc:
21
22                # Copy document-wide data
23                copy_document_data(in_doc, out_doc)
24
25                # Define page copy options
26                page_copy_options = PageCopyOptions()
27
28                # Get page range from input pages
29                in_page_range = in_doc.pages[start_index:last_page]
30
31                # Copy page range and append to output document
32                out_page_range = PageList.copy(out_doc, in_page_range, page_copy_options)
33                out_doc.pages.extend(out_page_range)
34
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Split at Outlines

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    // Collect all outline items at the given level
6    List<OutlineItem> outlines = GetOutlines(inDoc.Outline, level);
7
8    // Collect all page ranges corresponding to the given outline items
9    List<Tuple<PageList, OutlineItem>> parts = GetParts(inDoc.Pages, outlines);
10
11    // Iterate over all collected parts
12    foreach (var part in parts)
13    {
14        // Turn the outline item's title into a valid file name
15        string fileName = part.Item2.Title;
16        foreach (char c in System.IO.Path.GetInvalidFileNameChars())
17        {
18            fileName = fileName.Replace(c, '_');
19        }
20        fileName += ".pdf";
21        fileName = System.IO.Path.Combine(outDir, fileName);
22
23        // Create output document
24        using Stream outStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
25        using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
26
27        // Copy document-wide data
28        CopyDocumentData(inDoc, outDoc);
29
30        // Define page copy options
31        PageCopyOptions pageCopyOptions = new PageCopyOptions();
32        pageCopyOptions.CopyOutlineItems = false;
33
34        // Copy the pages and add to the output document's page list
35        PageList outPages = PageList.Copy(outDoc, part.Item1, pageCopyOptions);
36        outDoc.Pages.AddRange(outPages);
37
38        // Copy child outline items
39        OutlineCopyOptions outlineCopyOptions = new OutlineCopyOptions();
40        foreach (var child in part.Item2.Children)
41        {
42            outDoc.Outline.Add(OutlineItem.Copy(outDoc, child, outlineCopyOptions));
43        }
44    }
45}
1private static List<OutlineItem> GetOutlines(OutlineItemList currentOutlines, int level, int currentLevel = 1)
2{
3    List<OutlineItem> matchingOutlines = new List<OutlineItem>();
4    // If the current level matches the specified level add the given outline items
5    if (level == currentLevel)
6    {
7        matchingOutlines.AddRange(currentOutlines);
8    }
9    else
10    {
11        // Otherwise recurse to next level
12        foreach (var outline in currentOutlines)
13        {
14            matchingOutlines.AddRange(GetOutlines(outline.Children, level, currentLevel + 1));
15        }
16    }
17    return matchingOutlines;
18}
1private static List<Tuple<PageList, OutlineItem>> GetParts(PageList inPages, List<OutlineItem> outlines)
2{
3    // Construct parts according to the given outlines
4    List<Tuple<PageList, OutlineItem>> parts = new List<Tuple<PageList, OutlineItem>>();
5
6    // No parts to be constructed if no outlines are found
7    if (outlines.Count == 0)
8        return parts;
9
10    // Keep both the last and the next outline items while iterating
11    OutlineItem lastOutline = null;
12    var outlineEnumerator = outlines.GetEnumerator();
13    outlineEnumerator.MoveNext();
14    OutlineItem nextOutline = outlineEnumerator.Current;
15
16    // Keep both, the last and the current page index while iterating
17    int lastPageIndex = 0;
18    for (int pageIndex = 0; pageIndex < inPages.Count; pageIndex++)
19    {
20        // Check if this page is the destination's page of the next outline
21        if (inPages[pageIndex].Equals(nextOutline.Destination.Target.Page))
22        {
23            // Create a new part if the last outline item is defined and if the page index has increased at least by 1
24            if (lastOutline != null && pageIndex - lastPageIndex > 0)
25                parts.Add(new Tuple<PageList, OutlineItem>(inPages.GetRange(lastPageIndex, pageIndex - lastPageIndex), lastOutline));
26
27            // Keep the current page index as the last page index used
28            lastPageIndex = pageIndex;
29
30            // Keep the current outline as the last outline used
31            lastOutline = nextOutline;
32
33            // Iterate to the next outline item and stop if none left
34            if (outlineEnumerator.MoveNext())
35                nextOutline = outlineEnumerator.Current;
36            else
37                break;
38        }
39    }
40    // Add the last part which is assumed to contain all the pages until the end of the document
41    parts.Add(new Tuple<PageList, OutlineItem>(inPages.GetRange(lastPageIndex, inPages.Count - lastPageIndex), lastOutline));
42    return parts;
43}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def get_outlines(current_outlines: OutlineItemList, level: int, current_level: int = 1) -> list:
2    """Recursively collect outline items at the specified level."""
3    matching_outlines = []
4    # If the current level matches the specified level add the given outline items
5    if level == current_level:
6        matching_outlines.extend(current_outlines)
7    else:
8        # Otherwise recurse to next level
9        for outline in current_outlines:
10            matching_outlines.extend(get_outlines(outline.children, level, current_level + 1))
11
12    return matching_outlines
1def get_parts(in_pages: PageList, outlines: list) -> list:
2    """Collect page ranges corresponding to the outlines."""
3    # Construct parts according to the given outlines
4    parts = []
5
6    # No parts to be constructed if no outlines are found
7    if not outlines or len(outlines) == 0:
8        return parts
9
10    # Keep both the last and the next outline items while iterating
11    last_outline = None
12    last_page_index = 0
13
14    for page_index, page in enumerate(in_pages):
15        # Check if this page is the destination's page of the next outline
16        if outlines and page == outlines[0].destination.target.page:
17            # Create a new part if the last outline item is defined and if the page index has increased at least by 1
18            if last_outline and page_index - last_page_index > 0:
19                parts.append((in_pages[last_page_index:page_index], last_outline))
20            last_outline = outlines.pop(0)
21
22            # Keep the current page index as the last page index used
23            last_page_index = page_index
24
25    # Add the last part which is assumed to contain all the pages until the end of the document
26    if last_outline:
27        parts.append((in_pages[last_page_index:], last_outline))
28
29    return parts

Imposition

Create a booklet from PDF

Download code sample
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    // Objects that need releasing or closing
4    TPtxPdfContent_IccBasedColorSpace* pInOutputIntent    = NULL;
5    TPtxPdfContent_IccBasedColorSpace* pOutOutputIntent   = NULL;
6    TPtxPdf_Metadata*                  pInMetadata        = NULL;
7    TPtxPdf_Metadata*                  pOutMetadata       = NULL;
8    TPtxPdfNav_ViewerSettings*         pInViewerSettings  = NULL;
9    TPtxPdfNav_ViewerSettings*         pOutViewerSettings = NULL;
10    TPtxPdf_FileReferenceList*         pInFileRefList     = NULL;
11    TPtxPdf_FileReferenceList*         pOutFileRefList    = NULL;
12    TPtxPdf_FileReference*             pInFileRef         = NULL;
13    TPtxPdf_FileReference*             pOutFileRef        = NULL;
14
15    iReturnValue = 0;
16
17    // Output intent
18    pInOutputIntent = PtxPdf_Document_GetOutputIntent(pInDoc);
19    if (pInOutputIntent != NULL)
20    {
21        pOutOutputIntent = PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, pInOutputIntent);
22        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutOutputIntent,
23                                         _T("Failed to copy ICC-based color space. %s (ErrorCode: 0x%08x)\n"),
24                                         szErrorBuff, Ptx_GetLastError());
25        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetOutputIntent(pOutDoc, pOutOutputIntent),
26                                          _T("Failed to set output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
27                                          Ptx_GetLastError());
28    }
29    else
30        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
31                                          Ptx_GetLastError());
32
33    // Metadata
34    pInMetadata = PtxPdf_Document_GetMetadata(pInDoc);
35    if (pInMetadata != NULL)
36    {
37        pOutMetadata = PtxPdf_Metadata_Copy(pOutDoc, pInMetadata);
38        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutMetadata, _T("Failed to copy metadata. %s (ErrorCode: 0x%08x)\n"),
39                                         szErrorBuff, Ptx_GetLastError());
40        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetMetadata(pOutDoc, pOutMetadata),
41                                          _T("Failed to set metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
42                                          Ptx_GetLastError());
43    }
44    else
45        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
46                                          Ptx_GetLastError());
47
48    // Viewer settings
49    pInViewerSettings = PtxPdf_Document_GetViewerSettings(pInDoc);
50    if (pInViewerSettings != NULL)
51    {
52        pOutViewerSettings = PtxPdfNav_ViewerSettings_Copy(pOutDoc, pInViewerSettings);
53        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutViewerSettings,
54                                         _T("Failed to copy viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
55                                         Ptx_GetLastError());
56        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetViewerSettings(pOutDoc, pOutViewerSettings),
57                                          _T("Failed to set viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
58                                          Ptx_GetLastError());
59    }
60    else
61        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get viewer settings. %s (ErrorCode: 0x%08x)"), szErrorBuff,
62                                          Ptx_GetLastError());
63
64    // Associated files (for PDF/A-3 and PDF 2.0 only)
65    pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
66    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of input document. %s (ErrorCode: 0x%08x)\n"),
67                                      szErrorBuff, Ptx_GetLastError());
68    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
69    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of output document. %s (ErrorCode: 0x%08x)\n"),
70                                      szErrorBuff, Ptx_GetLastError());
71    int nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
72    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of associated files. %s (ErrorCode: 0x%08x)\n"),
73                                      szErrorBuff, Ptx_GetLastError());
74    for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
75    {
76        pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
77        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"),
78                                         szErrorBuff, Ptx_GetLastError());
79        pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
80        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"),
81                                         szErrorBuff, Ptx_GetLastError());
82        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef),
83                                          _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
84                                          Ptx_GetLastError());
85        Ptx_Release(pInFileRef);
86        pInFileRef = NULL;
87        Ptx_Release(pOutFileRef);
88        pOutFileRef = NULL;
89    }
90    Ptx_Release(pInFileRefList);
91    pInFileRefList = NULL;
92    Ptx_Release(pOutFileRefList);
93    pOutFileRefList = NULL;
94
95    // Plain embedded files
96    pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
97    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
98        pInFileRefList, _T("Failed to get plain embedded files of input document %s (ErrorCode: 0x%08x)\n"),
99        szErrorBuff, Ptx_GetLastError());
100    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
101    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
102        pInFileRefList, _T("Failed to get plain embedded files of output document %s (ErrorCode: 0x%08x)\n"),
103        szErrorBuff, Ptx_GetLastError());
104    nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
105    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of plain embedded files. %s (ErrorCode: 0x%08x)\n"),
106                                      szErrorBuff, Ptx_GetLastError());
107    for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
108    {
109        pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
110        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"),
111                                         szErrorBuff, Ptx_GetLastError());
112        pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
113        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"),
114                                         szErrorBuff, Ptx_GetLastError());
115        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef),
116                                          _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
117                                          Ptx_GetLastError());
118        Ptx_Release(pInFileRef);
119        pInFileRef = NULL;
120        Ptx_Release(pOutFileRef);
121        pOutFileRef = NULL;
122    }
123
124cleanup:
125    if (pInOutputIntent != NULL)
126        Ptx_Release(pInOutputIntent);
127    if (pOutOutputIntent != NULL)
128        Ptx_Release(pOutOutputIntent);
129    if (pInMetadata != NULL)
130        Ptx_Release(pInMetadata);
131    if (pOutMetadata != NULL)
132        Ptx_Release(pOutMetadata);
133    if (pInViewerSettings != NULL)
134        Ptx_Release(pInViewerSettings);
135    if (pOutViewerSettings != NULL)
136        Ptx_Release(pOutViewerSettings);
137    if (pInFileRefList != NULL)
138        Ptx_Release(pInFileRefList);
139    if (pOutFileRefList != NULL)
140        Ptx_Release(pOutFileRefList);
141    if (pInFileRef != NULL)
142        Ptx_Release(pInFileRef);
143    if (pOutFileRef != NULL)
144        Ptx_Release(pOutFileRef);
145    return iReturnValue;
146}
1int StampPageNumber(TPtxPdf_Document* pDocument, TPtxPdfContent_Font* pFont,
2                    TPtxPdfContent_ContentGenerator* pGenerator, int nPageNo, BOOL bIsLeftPage)
3{
4    // Objects that need releasing or closing
5    TPtxPdfContent_Text*          pText          = NULL;
6    TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
7
8    // Create text object
9    pText = PtxPdfContent_Text_Create(pDocument);
10    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create text object. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
11                                     Ptx_GetLastError());
12
13    // Create text generator
14    pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, 8.0, NULL);
15    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create text generator. %s (ErrorCode: 0x%08x)\n"),
16                                     szErrorBuff, Ptx_GetLastError());
17
18    TCHAR szStampText[50];
19    _stprintf(szStampText, _T("Page %d"), nPageNo);
20
21    // Get width of stamp text
22    double dStampWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampText);
23    if (dStampWidth == 0.0)
24        GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get text width. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
25                                          Ptx_GetLastError());
26
27    // Compute position
28    TPtxGeomReal_Point point = {
29        .dX = bIsLeftPage ? dBorder + 0.5 * dCellWidth - dStampWidth / 2
30                          : 2 * dBorder + 1.5 * dCellWidth - dStampWidth / 2,
31        .dY = dBorder,
32    };
33
34    // Move to position
35    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &point),
36                                      _T("Failed to move to position. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
37                                      Ptx_GetLastError());
38    // Add page number
39    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_Show(pTextGenerator, szStampText),
40                                      _T("Failed to show text. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
41                                      Ptx_GetLastError());
42
43    BOOL bClose    = PtxPdfContent_TextGenerator_Close(pTextGenerator);
44    pTextGenerator = NULL;
45    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(bClose, _T("Failed to close text generator. %s (ErrorCode: 0x%08x)\n"),
46                                      szErrorBuff, Ptx_GetLastError());
47
48    // Paint the positioned text
49    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText),
50                                      _T("Failed to paint text. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
51                                      Ptx_GetLastError());
52
53cleanup:
54    if (pText != NULL)
55        Ptx_Release(pText);
56    if (pTextGenerator != NULL)
57        PtxPdfContent_TextGenerator_Close(pTextGenerator);
58    return iReturnValue;
59}
1void ComputeTargetRect(TPtxGeomReal_Rectangle* pRectangle, const TPtxGeomReal_Size* pBBox, BOOL bIsLeftPage)
2{
3    // Compute factor for fitting page into rectangle
4    double dScale       = MIN(dCellWidth / pBBox->dWidth, dCellHeight / pBBox->dHeight);
5    double dGroupWidth  = pBBox->dWidth * dScale;
6    double dGroupHeight = pBBox->dHeight * dScale;
7
8    // Compute x-value
9    double dGroupXPos =
10        bIsLeftPage ? dCellLeft + (dCellWidth - dGroupWidth) / 2 : dCellRight + (dCellWidth - dGroupWidth) / 2;
11
12    // Compute y-value
13    double dGroupYPos = dCellYPos + (dCellHeight - dGroupHeight) / 2;
14
15    // Set rectangle
16    pRectangle->dLeft   = dGroupXPos;
17    pRectangle->dBottom = dGroupYPos;
18    pRectangle->dRight  = dGroupXPos + dGroupWidth;
19    pRectangle->dTop    = dGroupYPos + dGroupHeight;
20}
1int CreateBooklet(TPtxPdf_PageList* pInDocList, TPtxPdf_Document* pOutDoc, TPtxPdf_PageList* pOutDocList,
2                  int nLeftPageIndex, int nRightPageIndex, TPtxPdfContent_Font* pFont)
3{
4    // Objects that need releasing or closing
5    TPtxPdf_PageCopyOptions*         pCopyOptions = NULL;
6    TPtxPdf_Page*                    pOutPage     = NULL;
7    TPtxPdfContent_Content*          pContent     = NULL;
8    TPtxPdfContent_ContentGenerator* pGenerator   = NULL;
9    TPtxPdf_Page*                    pInPage      = NULL;
10    TPtxPdfContent_Group*            pGroup       = NULL;
11
12    // Configure copy options
13    pCopyOptions = PtxPdf_PageCopyOptions_New();
14
15    // Create page object
16    pOutPage = PtxPdf_Page_Create(pOutDoc, &pageSize);
17    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to create page object. %s (ErrorCode: 0x%08x)\n"),
18                                     szErrorBuff, Ptx_GetLastError());
19
20    // Create content generator
21    pContent = PtxPdf_Page_GetContent(pOutPage);
22    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pContent, _T("Failed to get content. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
23                                     Ptx_GetLastError());
24    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
25    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create content generator. %s (ErrorCode: 0x%08x)\n"),
26                                     szErrorBuff, Ptx_GetLastError());
27
28    int nPageCount = PtxPdf_PageList_GetCount(pInDocList);
29    GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get page list count. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
30                                      Ptx_GetLastError());
31
32    // Left page
33    if (nLeftPageIndex < nPageCount)
34    {
35        // Get the input page
36        pInPage = PtxPdf_PageList_Get(pInDocList, nLeftPageIndex);
37        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
38                                         Ptx_GetLastError());
39
40        // Copy page from input to output
41        pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
42        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x)\n"),
43                                         szErrorBuff, Ptx_GetLastError());
44
45        // Compute group location
46        TPtxGeomReal_Size groupSize;
47        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize),
48                                          _T("Failed to get group size. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
49                                          Ptx_GetLastError());
50        TPtxGeomReal_Rectangle targetRect;
51        ComputeTargetRect(&targetRect, &groupSize, TRUE);
52
53        // Paint group at location
54        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
55            PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL),
56            _T("Failed to paint group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
57
58        // Add page number to page
59        if (StampPageNumber(pOutDoc, pFont, pGenerator, nLeftPageIndex + 1, TRUE) != 0)
60            goto cleanup;
61
62        Ptx_Release(pInPage);
63        pInPage = NULL;
64        Ptx_Release(pGroup);
65        pGroup = NULL;
66    }
67
68    // Right page
69    if (nRightPageIndex < nPageCount)
70    {
71        // Get the input Page
72        pInPage = PtxPdf_PageList_Get(pInDocList, nRightPageIndex);
73        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
74                                         Ptx_GetLastError());
75
76        // Copy page from input to output
77        pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
78        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x)\n"),
79                                         szErrorBuff, Ptx_GetLastError());
80
81        // Compute group location
82        TPtxGeomReal_Size groupSize;
83        PtxPdfContent_Group_GetSize(pGroup, &groupSize);
84        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize),
85                                          _T("Failed to get group size. %s (ErrorCode: 0x%08x)\n"), szErrorBuff,
86                                          Ptx_GetLastError());
87        TPtxGeomReal_Rectangle targetRect;
88        ComputeTargetRect(&targetRect, &groupSize, FALSE);
89
90        // Paint group on the Computed rectangle
91        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
92            PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL),
93            _T("Failed to paint group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
94
95        // Add page number to page
96        if (StampPageNumber(pOutDoc, pFont, pGenerator, nRightPageIndex + 1, FALSE) != 0)
97            goto cleanup;
98    }
99
100    BOOL bClose = PtxPdfContent_ContentGenerator_Close(pGenerator);
101    pGenerator  = NULL;
102    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(bClose, _T("Failed to close content generator. %s (ErrorCode: 0x%08x)\n"),
103                                      szErrorBuff, Ptx_GetLastError());
104
105    // Add page to output document
106    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutDocList, pOutPage),
107                                      _T("Failed to add page to output document. %s (ErrorCode: 0x%08x)\n"),
108                                      szErrorBuff, Ptx_GetLastError());
109
110cleanup:
111    if (pGenerator != NULL)
112        PtxPdfContent_ContentGenerator_Close(pGenerator);
113    if (pCopyOptions != NULL)
114        Ptx_Release(pCopyOptions);
115    if (pOutPage != NULL)
116        Ptx_Release(pOutPage);
117    if (pContent != NULL)
118        Ptx_Release(pContent);
119    if (pInPage != NULL)
120        Ptx_Release(pInPage);
121    if (pGroup != NULL)
122        Ptx_Release(pGroup);
123    return iReturnValue;
124}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document 
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Create a font
13    Font font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
14
15    // Copy pages
16    PageList inPages = inDoc.Pages;
17    PageList outPages = outDoc.Pages;
18    int numberOfSheets = (inPages.Count + 3) / 4;
19
20    for (int sheetNumber = 0; sheetNumber < numberOfSheets; ++sheetNumber)
21    {
22
23        // Add on front side
24        CreateBooklet(inPages, outDoc, outPages, 4 * numberOfSheets - 2 * sheetNumber - 1,
25            2 * sheetNumber, font);
26
27        // Add on back side
28        CreateBooklet(inPages, outDoc, outPages, 2 * sheetNumber + 1,
29            4 * numberOfSheets - 2 * sheetNumber - 2, font);
30    }
31}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void CreateBooklet(PageList inPages, Document outDoc, PageList outPages, int leftPageIndex,
2    int rightPageIndex, Font font)
3{
4    // Define page copy options
5    PageCopyOptions copyOptions = new PageCopyOptions();
6
7    // Create page object
8    Page outpage = Page.Create(outDoc, PageSize);
9
10    // Create content generator
11    using (ContentGenerator generator = new ContentGenerator(outpage.Content, false))
12    {
13        // Left page 
14        if (leftPageIndex < inPages.Count)
15        {
16            // Copy page from input to output
17            Page leftPage = inPages[leftPageIndex];
18            Group leftGroup = Group.CopyFromPage(outDoc, leftPage, copyOptions);
19
20            // Paint group on the calculated rectangle
21            generator.PaintGroup(leftGroup, ComputTargetRect(leftGroup.Size, true), null);
22
23            // Add page number to page
24            StampPageNumber(outDoc, font, generator, leftPageIndex + 1, true);
25        }
26
27        // Right page
28        if (rightPageIndex < inPages.Count)
29        {
30            // Copy page from input to output
31            Page rigthPage = inPages[rightPageIndex];
32            Group rightGroup = Group.CopyFromPage(outDoc, rigthPage, copyOptions);
33
34            // Paint group on the calculated rectangle
35            generator.PaintGroup(rightGroup, ComputTargetRect(rightGroup.Size, false), null);
36
37            // Add page number to page
38            StampPageNumber(outDoc, font, generator, rightPageIndex + 1, false);
39        }
40    }
41    // Add page to output document
42    outPages.Add(outpage);
43}
1private static Rectangle ComputTargetRect(Size bbox, bool isLeftPage)
2{
3    // Calculate factor for fitting page into rectangle
4    double scale = Math.Min(CellWidth / bbox.Width, CellHeight / bbox.Height);
5    double groupWidth = bbox.Width * scale;
6    double groupHeight = bbox.Height * scale;
7
8    // Calculate x-value
9    double groupXPos = isLeftPage ? CellLeft + (CellWidth - groupWidth) / 2 :
10                                    CellRight + (CellWidth - groupWidth) / 2;
11
12    // Calculate y-value
13    double groupYPos = CellYPos + (CellHeight - groupHeight) / 2;
14
15    // Calculate rectangle
16    return new Rectangle
17    {
18        Left = groupXPos,
19        Bottom = groupYPos,
20        Right = groupXPos + groupWidth,
21        Top = groupYPos + groupHeight
22    };
23}
1private static void StampPageNumber(Document document, Font font, ContentGenerator generator,
2    int PageNo, bool isLeftPage)
3{
4    // Create text object
5    Text text = Text.Create(document);
6
7    // Create text generator
8    using (TextGenerator textgenerator = new TextGenerator(text, font, 8, null))
9    {
10        string stampText = string.Format("Page {0}", PageNo);
11
12        // Get width of stamp text
13        double width = textgenerator.GetWidth(stampText);
14
15        // Calculate position
16        double x = isLeftPage ? Border + 0.5 * CellWidth - width / 2 :
17                                2 * Border + 1.5 * CellWidth - width / 2;
18        double y = Border;
19
20        // Move to position
21        textgenerator.MoveTo(new Point { X = x, Y = y});
22
23        // Add page number
24        textgenerator.Show(stampText);
25    }
26    // Paint the positioned text
27    generator.PaintText(text);
28}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7        Font font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
8
9        // Copy document-wide data
10        copyDocumentData(inDoc, outDoc);
11
12        // Copy pages
13        PageList inPages = inDoc.getPages();
14        PageList outPages = outDoc.getPages();
15        int numberOfSheets = (inPages.size() + 3) / 4;
16
17        for (int sheetNumber = 0; sheetNumber < numberOfSheets; ++sheetNumber) {
18            // Add on front side
19            createBooklet(inPages, outDoc, outPages, 4 * numberOfSheets - 2 * sheetNumber - 1,
20                    2 * sheetNumber, font);
21
22            // Add on back side
23            createBooklet(inPages, outDoc, outPages, 2 * sheetNumber + 1,
24                    4 * numberOfSheets - 2 * sheetNumber - 2, font);
25        }
26    }
27}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
1private static void createBooklet(PageList inPages, Document outDoc, PageList outPages, int leftPageIndex,
2        int rightPageIndex, Font font) throws ToolboxException, IOException {
3    // Define page copy options
4    PageCopyOptions copyOptions = new PageCopyOptions();
5
6    // Create page object
7    Page outPage = Page.create(outDoc,  new Size(PageWidth, PageHeight));
8
9    try (// Create content generator
10        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
11
12        // Left page
13        if (leftPageIndex < inPages.size()) {
14            Page leftPage = inPages.get(leftPageIndex);
15
16            // Copy page from input to output
17            Group leftGroup = Group.copyFromPage(outDoc, leftPage, copyOptions);
18
19            // Paint group on the calculated rectangle
20            generator.paintGroup(leftGroup, computeTargetRect(leftGroup.getSize(), true), null);
21
22            // Add page number to page
23            StampPageNumber(outDoc, font, generator, leftPageIndex + 1, true);
24        }
25
26        // Right page
27        if (rightPageIndex < inPages.size()) {
28            Page rightPage = inPages.get(rightPageIndex);
29
30            // Copy page from input to output
31            Group rightGroup = Group.copyFromPage(outDoc, rightPage, copyOptions);
32
33            // Paint group on the calculated rectangle
34            generator.paintGroup(rightGroup, computeTargetRect(rightGroup.getSize(), false), null);
35
36            // Add page number to page
37            StampPageNumber(outDoc, font, generator, rightPageIndex + 1, false);
38        }
39    }
40    // Add page to output document
41    outPages.add(outPage);
42}
1private static Rectangle computeTargetRect(Size bbox, Boolean isLeftPage) {
2    // Calculate factor for fitting page into rectangle
3    double scale = Math.min(CellWidth / bbox.width, CellHeight / bbox.height);
4    double groupWidth = bbox.width * scale;
5    double groupHeight = bbox.height * scale;
6
7    // Calculate x-value
8    double groupXPos = isLeftPage ? CellLeft + (CellWidth - groupWidth) / 2 :
9                                    CellRight + (CellWidth - groupWidth) / 2;
10
11    // Calculate y-value
12    double groupYPos = CellYPos + (CellHeight - groupHeight) / 2;
13
14    // Calculate rectangle
15    return new Rectangle(groupXPos, groupYPos, groupXPos + groupWidth, groupYPos + groupHeight);
16}
1private static void StampPageNumber(Document document, Font font, ContentGenerator generator, int pageNo,
2        boolean isLeftPage) throws ToolboxException, IOException {
3    // Create text object
4    Text text = Text.create(document);
5
6    try (// Create text generator
7        TextGenerator textgenerator = new TextGenerator(text, font, 8, null)) {
8        String stampText = String.format("Page %d", pageNo);
9
10        // Get width of stamp text
11        double width = textgenerator.getWidth(stampText);
12
13        // Calculate position
14        double x = isLeftPage ? Border + 0.5 * CellWidth - width / 2 :
15                                2 * Border + 1.5 * CellWidth - width / 2;
16        double y = Border;
17
18        // Move to position
19        textgenerator.moveTo(new Point(x, y));
20
21        // Add page number
22        textgenerator.show(stampText);
23    }
24
25    // Paint the positioned text
26    generator.paintText(text);
27}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def compute_target_rect(bbox: Size, is_left_page: bool) -> Rectangle:
2    # Calculate factor for fitting page into rectangle
3    scale = min(cell_width / bbox.width, cell_height / bbox.height)
4    group_width = bbox.width * scale
5    group_height = bbox.height * scale
6
7    # Calculate x-value
8    group_x_pos = cell_left + (cell_width - group_width) / 2 if is_left_page else cell_right + (cell_width - group_width) / 2
9
10    # Calculate y-value
11    group_y_pos = cell_y_pos + (cell_height - group_height) / 2
12
13    # Calculate rectangle
14    return Rectangle(
15        left=group_x_pos,
16        bottom=group_y_pos,
17        right=group_x_pos + group_width,
18        top=group_y_pos + group_height,
19    )
1def stamp_page_number(document: Document, font: Font, generator: ContentGenerator, page_no: int, is_left_page: bool):
2    # Create text object
3    text = Text.create(document)
4
5    # Create text generator
6    with TextGenerator(text, font, 8.0, None) as text_generator:
7        stamp_text = f"Page {page_no}"
8
9        # Get width of stamp text
10        width = text_generator.get_width(stamp_text)
11
12        # Calculate position
13        x = border + 0.5 * cell_width - width / 2 if is_left_page else 2 * border + 1.5 * cell_width - width / 2
14        y = border
15
16        # Move to position
17        text_generator.move_to(Point(x=x, y=y))
18
19        # Add page number
20        text_generator.show(stamp_text)
21
22    # Paint the positioned text
23    generator.paint_text(text)
1def create_booklet(in_pages: PageList, out_doc: Document, out_pages: PageList, left_page_index: int, right_page_index: int, font: Font):
2    # Define page copy options
3    copy_options = PageCopyOptions()
4
5    # Create page object
6    out_page = Page.create(out_doc, page_size)
7
8    # Create content generator
9    with ContentGenerator(out_page.content, False) as generator:
10        # Left page
11        if left_page_index < len(in_pages):
12            # Copy page from input to output
13            left_page = in_pages[left_page_index]
14            left_group = Group.copy_from_page(out_doc, left_page, copy_options)
15
16            # Paint group into target rectangle
17            generator.paint_group(left_group, compute_target_rect(left_group.size, True), None)
18
19            # Add page number to page
20            stamp_page_number(out_doc, font, generator, left_page_index + 1, True)
21
22        # Right page
23        if right_page_index < len(in_pages):
24            # Copy page from input to output
25            right_page = in_pages[right_page_index]
26            right_group = Group.copy_from_page(out_doc, right_page, copy_options)
27
28            # Paint group on the calculated rectangle
29            generator.paint_group(right_group, compute_target_rect(right_group.size, False), None)
30
31            # Add page number to page
32            stamp_page_number(out_doc, font, generator, right_page_index + 1, False)
33
34    # Add page to output document
35    out_pages.append(out_page)

Fit pages to specific page format

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Configure copy options
24pCopyOptions = PtxPdf_PageCopyOptions_New();
25
26// Copy all pages
27pInPageList = PtxPdf_Document_GetPages(pInDoc);
28GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
29                                 _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"),
30                                 szErrorBuff, Ptx_GetLastError());
31pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
32GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
33                                 _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
34                                 szErrorBuff, Ptx_GetLastError());
35for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
36{
37    TPtxGeomReal_Size pageSize;
38    TPtxGeomReal_Size rotatedSize;
39    BOOL              bRotate;
40
41    pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
42    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
43
44    pOutPage = NULL;
45    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pInPage, &pageSize), _T("%s (ErrorCode: 0x%08x).\n"),
46                                      szErrorBuff, Ptx_GetLastError());
47
48    bRotate = bAllowRotate && (pageSize.dHeight >= pageSize.dWidth) != (targetSize.dHeight >= targetSize.dWidth);
49    if (bRotate)
50    {
51        rotatedSize.dWidth  = pageSize.dHeight;
52        rotatedSize.dHeight = pageSize.dHeight;
53    }
54    else
55    {
56        rotatedSize = pageSize;
57    }
58
59    if (rotatedSize.dWidth == targetSize.dWidth && rotatedSize.dHeight == targetSize.dWidth)
60    {
61        // If size is correct, copy page only
62        pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
63        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
64                                         _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"),
65                                         szErrorBuff, Ptx_GetLastError());
66
67        if (bRotate)
68        {
69            GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_Rotate(pOutPage, ePtxGeom_Rotation_Clockwise),
70                                              _T("Failed to rotate page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
71                                              Ptx_GetLastError());
72        }
73    }
74    else
75    {
76        TPtxPdfContent_Group*        pGroup   = NULL;
77        TPtxPdfContent_Content*      pContent = NULL;
78        TPtxGeomReal_AffineTransform transform;
79        TPtxGeomReal_Point           position;
80        TPtxGeomReal_Point           point;
81
82        // Create a new page of correct size and fit existing page onto it
83        pOutPage = PtxPdf_Page_Create(pOutDoc, &targetSize);
84        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to create a new page. %s (ErrorCode: 0x%08x).\n"),
85                                         szErrorBuff, Ptx_GetLastError());
86
87        // Copy page as group
88        pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
89        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x).\n"),
90                                         szErrorBuff, Ptx_GetLastError());
91
92        // Calculate scaling and position of group
93        double scale = MIN(targetSize.dWidth / rotatedSize.dWidth, targetSize.dHeight / rotatedSize.dHeight);
94
95        // Calculate position
96        position.dX = (targetSize.dWidth - pageSize.dWidth * scale) / 2;
97        position.dY = (targetSize.dHeight - pageSize.dHeight * scale) / 2;
98
99        pContent = PtxPdf_Page_GetContent(pOutPage);
100
101        // Create content generator
102        pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
103        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator,
104                                         _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"),
105                                         szErrorBuff, Ptx_GetLastError());
106
107        // Calculate and apply transformation
108        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_GetIdentity(&transform),
109                                          _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
110        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
111            PtxGeomReal_AffineTransform_Translate(&transform, position.dX, position.dY),
112            _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
113        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Scale(&transform, scale, scale),
114                                          _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
115
116        point.dX = pageSize.dWidth / 2.0;
117        point.dY = pageSize.dHeight / 2.0;
118
119        // Rotate input file
120        if (bRotate)
121        {
122            GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Rotate(&transform, 90, &point),
123                                              _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
124        }
125        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_Transform(pGenerator, &transform),
126                                          _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
127
128        // Paint form
129        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, NULL, NULL),
130                                          _T("Failed to paint the group. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
131                                          Ptx_GetLastError());
132
133        PtxPdfContent_ContentGenerator_Close(pGenerator);
134        pGenerator = NULL;
135
136        if (pGenerator != NULL)
137            Ptx_Release(pGenerator);
138        if (pGroup != NULL)
139            Ptx_Release(pGroup);
140    }
141
142    // Add page to output document
143    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
144                                      _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
145                                      szErrorBuff, Ptx_GetLastError());
146
147    if (pOutPage != NULL)
148    {
149        Ptx_Release(pOutPage);
150        pOutPage = NULL;
151    }
152
153    if (pInPage != NULL)
154    {
155        Ptx_Release(pInPage);
156        pInPage = NULL;
157    }
158}
159
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document 
6using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Copy pages
16    foreach (Page inPage in inDoc.Pages)
17    {
18        Page outPage = null;
19        Size pageSize = inPage.Size;
20
21        bool rotate = AllowRotate &&
22            (pageSize.Height >= pageSize.Width) != (TargetSize.Height >= TargetSize.Width);
23        Size rotatedSize = pageSize;
24
25        if (rotate)
26            rotatedSize = new Size { Width = pageSize.Height, Height = pageSize.Width };
27
28        if (rotatedSize.Width == TargetSize.Width && rotatedSize.Height == TargetSize.Width)
29        {
30            // If size is correct, copy page only
31            outPage = Page.Copy(outDoc, inPage, copyOptions);
32
33            if (rotate)
34                outPage.Rotate(Rotation.Clockwise);
35        }
36        else
37        {
38            // Create new page of correct size and fit existing page onto it
39            outPage = Page.Create(outDoc, TargetSize);
40
41            // Copy page as group
42            Group group = Group.CopyFromPage(outDoc, inPage, copyOptions);
43            // Calculate scaling and position of group
44            double scale = Math.Min(TargetSize.Width / rotatedSize.Width,
45                TargetSize.Height / rotatedSize.Height);
46
47            // Calculate position
48            Point position = new Point
49            {
50                X = (TargetSize.Width - pageSize.Width * scale) / 2,
51                Y = (TargetSize.Height - pageSize.Height * scale) / 2
52            };
53
54            // Create content generator
55            using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
56
57            // Calculate and apply transformation
58            AffineTransform transform = AffineTransform.Identity;
59            transform.Translate(position.X, position.Y);
60            transform.Scale(scale, scale);
61
62            Point point = new Point()
63            {
64                X = pageSize.Width / 2.0,
65                Y = pageSize.Height / 2.0
66            };
67
68            // Rotate input file 
69            if (rotate)
70                transform.Rotate(90, point);
71            generator.Transform(transform);
72
73            // Paint group
74            generator.PaintGroup(group, null, null);
75        }
76        // Add page to output document 
77        outDoc.Pages.Add(outPage);
78    }
79}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Define page copy options
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Copy pages
15        for (Page inPage : inDoc.getPages()) {
16            Page outPage = null;
17            Size pageSize = inPage.getSize();
18
19            boolean rotate = AllowRotate &&
20                (pageSize.height >= pageSize.width) != (TargetHeight >= TargetWidth);
21            Size rotatedSize = pageSize;
22
23            if (rotate)
24                rotatedSize = new Size(pageSize.height, pageSize.width);
25
26            if (rotatedSize.width == TargetWidth && rotatedSize.height == TargetWidth) {
27                // If size is correct, copy page only
28                outPage = Page.copy(outDoc, inPage, copyOptions);
29
30                if (rotate)
31                    outPage.rotate(Rotation.CLOCKWISE);
32            } else {
33                // Create new page of correct size and fit existing page onto it
34                outPage = Page.create(outDoc, new Size(TargetWidth, TargetHeight));
35
36                // Copy page as group
37                Group group = Group.copyFromPage(outDoc, inPage, copyOptions);
38                // Calculate scaling and position of group
39                double scale = Math.min(TargetWidth / rotatedSize.width,
40                    TargetHeight / rotatedSize.height);
41
42                // Calculate position
43                Point position = new Point(
44                        (TargetWidth - pageSize.width * scale) / 2,
45                        (TargetHeight - pageSize.height * scale) / 2);
46
47                try(// Create content generator
48                    ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
49                    // Calculate and apply transformation
50                    AffineTransform transform = AffineTransform.getIdentity();
51                    transform.translate(position.x, position.y);
52                    transform.scale(scale, scale);
53
54                    Point point = new Point(pageSize.width / 2.0, pageSize.height / 2.0);
55
56                    // Rotate input file 
57                    if (rotate)
58                        transform.rotate(90, point);
59                    generator.transform(transform);
60
61                    // Paint group
62                    generator.paintGroup(group, null, null);
63                }
64            }
65            // Add page to output document 
66            outDoc.getPages().add(outPage);
67        }
68    }
69}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def scale_pages_to_fit(in_doc: Document, out_doc: Document):
2    copy_options = PageCopyOptions()
3
4    # Copy pages
5    for in_page in in_doc.pages:
6        page_size = in_page.size
7        rotate = (
8            ALLOW_ROTATE
9            and (page_size.height >= page_size.width) != (TARGET_SIZE.height >= TARGET_SIZE.width)
10        )
11
12        rotated_size = Size(
13            width=page_size.height, height=page_size.width
14        ) if rotate else page_size
15
16        if rotated_size.width == TARGET_SIZE.width and rotated_size.height == TARGET_SIZE.height:
17            # If size is correct, copy page only
18            out_page = Page.copy(out_doc, in_page, copy_options)
19
20            if rotate:
21                out_page.rotate(90)  # Clockwise rotation
22        else:
23            # Create new page of correct size and fit existing page onto it
24            out_page = Page.create(out_doc, TARGET_SIZE)
25
26            # Copy page as group
27            group = Group.copy_from_page(out_doc, in_page, copy_options)
28            # Calculate scaling and position of group
29            scale = min(TARGET_SIZE.width / rotated_size.width, TARGET_SIZE.height / rotated_size.height)
30
31            # Calculate position
32            position = Point(
33                x=(TARGET_SIZE.width - page_size.width * scale) / 2,
34                y=(TARGET_SIZE.height - page_size.height * scale) / 2,
35            )
36
37            # Create content generator
38            with ContentGenerator(out_page.content, False) as generator:
39
40                # Calculate and apply transformation
41                transform = AffineTransform.get_identity()
42                transform.translate(position.x, position.y)
43                transform.scale(scale, scale)
44
45                # Rotate input file 
46                if rotate:
47                    center_point = Point(x=page_size.width / 2, y=page_size.height / 2)
48                    transform.rotate(90, center_point)
49
50                # Paint group
51                generator.transform(transform)
52                generator.paint_group(group, None, None)
53
54        # Add the page to the output document
55        out_doc.pages.append(out_page)

Place multiple pages on one page

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Configure copy options
24pCopyOptions = PtxPdf_PageCopyOptions_New();
25
26// Copy all pages
27pInPageList = PtxPdf_Document_GetPages(pInDoc);
28GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
29                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
30                                 szErrorBuff, Ptx_GetLastError());
31pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
32GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList,
33                                 _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"),
34                                 szErrorBuff, Ptx_GetLastError());
35int nPageCount = 0;
36for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
37{
38    pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
39
40    if (nPageCount == nNx * nNy)
41    {
42        // Add to output document
43        PtxPdfContent_ContentGenerator_Close(pGenerator);
44        GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
45                                          _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
46                                          szErrorBuff, Ptx_GetLastError());
47        Ptx_Release(pOutPage);
48        pOutPage   = NULL;
49        nPageCount = 0;
50    }
51    if (pOutPage == NULL)
52    {
53        // Create a new output page
54        pOutPage = PtxPdf_Page_Create(pOutDoc, &PageSize);
55        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage,
56                                         _T("Failed to create a new output page. %s (ErrorCode: 0x%08x).\n"),
57                                         szErrorBuff, Ptx_GetLastError());
58        TPtxPdfContent_Content* pContent = PtxPdf_Page_GetContent(pOutPage);
59        pGenerator                       = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
60        GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator,
61                                         _T("Failed to create content generator. %s (ErrorCode: 0x%08x).\n"),
62                                         szErrorBuff, Ptx_GetLastError());
63    }
64
65    // Get area where group has to be
66    int x = nPageCount % nNx;
67    int y = nNy - (nPageCount / nNx) - 1;
68
69    // Calculate cell size
70    TPtxGeomReal_Size cellSize;
71    cellSize.dWidth  = (PageSize.dWidth - ((nNx + 1) * dBorder)) / nNx;
72    cellSize.dHeight = (PageSize.dHeight - ((nNy + 1) * dBorder)) / nNy;
73
74    // Calculate cell position
75    TPtxGeomReal_Point cellPosition;
76    cellPosition.dX = dBorder + x * (cellSize.dWidth + dBorder);
77    cellPosition.dY = dBorder + y * (cellSize.dHeight + dBorder);
78
79    // Copy page group from input to output
80    pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
81    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(
82        pGroup, _T("Failed to copy page group from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
83        Ptx_GetLastError());
84
85    // Calculate group position
86    TPtxGeomReal_Size groupSize;
87    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize),
88                                      _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
89    double dScale = MIN(cellSize.dWidth / groupSize.dWidth, cellSize.dHeight / groupSize.dHeight);
90
91    // Calculate target size
92    TPtxGeomReal_Size targetSize;
93    targetSize.dWidth  = groupSize.dWidth * dScale;
94    targetSize.dHeight = groupSize.dHeight * dScale;
95
96    // Calculate position
97    TPtxGeomReal_Point targetPos;
98    targetPos.dX = cellPosition.dX + ((cellSize.dWidth - targetSize.dWidth) / 2);
99    targetPos.dY = cellPosition.dY + ((cellSize.dHeight - targetSize.dHeight) / 2);
100
101    // Calculate rectangle
102    TPtxGeomReal_Rectangle targetRect;
103    targetRect.dLeft   = targetPos.dX;
104    targetRect.dBottom = targetPos.dY;
105    targetRect.dRight  = targetPos.dX + targetSize.dWidth;
106    targetRect.dTop    = targetPos.dY + targetSize.dHeight;
107
108    // Add group to page
109    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(
110        PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL),
111        _T("Failed to paint the group. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
112
113    if (pGroup != NULL)
114    {
115        Ptx_Release(pGroup);
116        pGroup = NULL;
117    }
118    if (pInPage != NULL)
119    {
120        Ptx_Release(pInPage);
121        pInPage = NULL;
122    }
123
124    nPageCount++;
125}
126
127// Add partially filled page
128if (pOutPage != NULL)
129{
130    PtxPdfContent_ContentGenerator_Close(pGenerator);
131    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage),
132                                      _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"),
133                                      szErrorBuff, Ptx_GetLastError());
134    Ptx_Release(pOutPage);
135    pOutPage = NULL;
136}
137
138
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    // Create output document 
6    using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
7    using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
8    PageList outPages = outDoc.Pages;
9    int pageCount = 0;
10    ContentGenerator generator = null;
11    Page outPage = null;
12
13    // Copy document-wide data
14    CopyDocumentData(inDoc, outDoc);
15
16    // Copy all pages from input document
17    foreach (Page inPage in inDoc.Pages)
18    {
19        if (pageCount == Nx * Ny)
20        {
21            // Add to output document
22            generator.Dispose();
23            outPages.Add(outPage);
24            outPage = null;
25            pageCount = 0;
26        }
27        if (outPage == null)
28        {
29            // Create a new output page
30            outPage = Page.Create(outDoc, PageSize);
31            generator = new ContentGenerator(outPage.Content, false);
32        }
33
34        // Get area where group has to be
35        int x = pageCount % Nx;
36        int y = Ny - (pageCount / Nx) - 1;
37
38        // Compute cell size
39        Size cellSize = new Size
40        {
41            Width = (PageSize.Width - ((Nx + 1) * Border)) / Nx,
42            Height = (PageSize.Height - ((Ny + 1) * Border)) / Ny
43        };
44
45        // Compute cell position
46        Point cellPosition = new Point
47        {
48            X = Border + x * (cellSize.Width + Border),
49            Y = Border + y * (cellSize.Height + Border)
50        };
51
52        // Define page copy options
53        PageCopyOptions copyOptions = new PageCopyOptions();
54
55        // Copy page as group from input to output
56        Group group = Group.CopyFromPage(outDoc, inPage, copyOptions);
57
58        // Compute group position 
59        Size groupSize = group.Size;
60        double scale = Math.Min(cellSize.Width / groupSize.Width,
61            cellSize.Height / groupSize.Height);
62
63        // Compute target size
64        Size targetSize = new Size
65        {
66            Width = groupSize.Width * scale,
67            Height = groupSize.Height * scale
68        };
69
70        // Compute position
71        Point targetPos = new Point
72        {
73            X = cellPosition.X + ((cellSize.Width - targetSize.Width) / 2),
74            Y = cellPosition.Y + ((cellSize.Height - targetSize.Height) / 2)
75        };
76
77        // Compute rectangle
78        Rectangle targetRect = new Rectangle
79        {
80            Left = targetPos.X,
81            Bottom = targetPos.Y,
82            Right = targetPos.X + targetSize.Width,
83            Top = targetPos.Y + targetSize.Height
84        };
85
86        // Add group to page
87        generator.PaintGroup(group, targetRect, null);
88        pageCount++;
89    }
90    // Add page
91    if (outPage != null)
92    {
93        generator.Dispose();
94        outPages.Add(outPage);
95    }
96}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null)) {
4    try (
5        FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
6        try (// Create output document
7            Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
8            PageList outPages = outDoc.getPages();
9            int pageCount = 0;
10            ContentGenerator generator = null;
11            Page outPage = null;
12
13            // A4 portrait
14            Size pageSize = new Size(595, 842);
15
16            // Copy document-wide data
17            copyDocumentData(inDoc, outDoc);
18
19            // Copy pages
20            for (Page inPage : inDoc.getPages()) {
21
22                if (pageCount == Nx * Ny) {
23                    // Add to output document
24                    generator.close();
25                    outPages.add(outPage);
26                    outPage = null;
27                    pageCount = 0;
28                }
29                if (outPage == null) {
30                    // Create a new output page
31                    outPage = Page.create(outDoc, pageSize);
32                    generator = new ContentGenerator(outPage.getContent(), false);
33                }
34
35                // Get area where group has to be
36                int x = pageCount % Nx;
37                int y = Ny - (pageCount / Nx) - 1;
38
39                // Calculate cell size
40                Size cellSize = new Size((pageSize.width - ((Nx + 1) * Border)) / Nx,
41                        (pageSize.height - ((Ny + 1) * Border)) / Ny);
42
43                // Calculate cell position
44                Point cellPosition = new Point(Border + x * (cellSize.width + Border),
45                        Border + y * (cellSize.height + Border));
46
47                // Set copy option
48                PageCopyOptions copyOptions = new PageCopyOptions();
49
50                // Copy page group from input to output
51                Group group = Group.copyFromPage(outDoc, inPage, copyOptions);
52
53                // Calculate group position
54                Size groupSize = group.getSize();
55                double scale = Math.min(cellSize.width / groupSize.width,
56                        cellSize.height / groupSize.height);
57
58                // Calculate target size
59                Size targetSize = new Size(groupSize.width * scale, groupSize.height * scale);
60
61                // Calculate position
62                Point targetPos = new Point(cellPosition.x + ((cellSize.width - targetSize.width) / 2),
63                        cellPosition.y + ((cellSize.height - targetSize.height) / 2));
64
65                // Calculate rectangle
66                Rectangle targetRect = new Rectangle(targetPos.x, targetPos.y,
67                        targetPos.x + targetSize.width, targetPos.y + targetSize.height);
68
69                // Add group to page
70                generator.paintGroup(group, targetRect, null);
71
72                pageCount++;
73            }
74            // Add page
75            if (outPage != null) {
76                generator.close();
77                outPages.add(outPage);
78            }
79        }
80    }
81}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1
2
3# Open input document
4with io.FileIO(input_file_path, 'rb') as in_stream:
5    with Document.open(in_stream, None) as input_document:
6
7        # Create output document
8        with io.FileIO(output_file_path, 'wb+') as output_stream:
9            with Document.create(output_stream, input_document.conformance, None) as output_document:
10                out_pages = output_document.pages
11                page_count = 0
12                generator = None
13                out_page = None
14
15                # Copy document-wide data
16                copy_document_data(input_document, output_document)
17
18                # Copy all pages from input document
19                for in_page in input_document.pages:
20                    if page_count == nx * ny:
21                        # Add to output document
22                        generator.__exit__(None, None, None)
23                        out_pages.append(out_page)
24                        out_page = None
25                        page_count = 0
26                    if out_page is None:
27                        # Create a new output page
28                        out_page = Page.create(output_document, page_size)
29                        generator = ContentGenerator(out_page.content, False)
30
31                    # Get area where group has to be (// calculates the floor of the division)
32                    x = int(page_count % nx)
33                    y = int(ny - (page_count // nx) - 1)
34
35                    # Compute cell size
36                    cell_width = (page_size.width - ((nx + 1) * border)) / nx
37                    cell_height = (page_size.height - ((ny + 1) * border)) / ny
38
39                    # Compute cell position
40                    cell_x = border + x * (cell_width + border)
41                    cell_y = border + y * (cell_height + border)
42
43                    # Define page copy options
44                    copy_options = PageCopyOptions()
45
46                    # Copy page as group from input to output
47                    group = Group.copy_from_page(output_document, in_page, copy_options)
48
49                    # Compute group position
50                    group_size = group.size
51                    scale = min(cell_width / group_size.width, cell_height / group_size.height)
52
53                    # Compute target size
54                    target_width = group_size.width * scale
55                    target_height = group_size.height * scale
56
57                    # Compute position
58                    target_x = cell_x + ((cell_width - target_width) / 2)
59                    target_y = cell_y + ((cell_height - target_height) / 2)
60
61                    # Compute rectangle
62                    target_rect = Rectangle()
63                    target_rect.left = target_x
64                    target_rect.bottom = target_y
65                    target_rect.right = target_x + target_width
66                    target_rect.top = target_y + target_height
67
68                    # Add group to page
69                    generator.paint_group(group, target_rect, None)
70                    page_count += 1
71
72                # Add page
73                if out_page:
74                    generator.__exit__(None, None, None)
75                    out_pages.append(out_page)
76
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Set page orientation

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Create output document
10pOutStream = _tfopen(szOutPath, _T("wb+"));
11GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
12PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
13iConformance = PtxPdf_Document_GetConformance(pInDoc);
14pOutDoc      = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
15GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"),
16                                 szOutPath, szErrorBuff, Ptx_GetLastError());
17
18// Copy document-wide data
19GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc),
20                                  _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
21                                  Ptx_GetLastError());
22
23// Configure copy options
24pCopyOptions = PtxPdf_PageCopyOptions_New();
25
26// Copy all pages
27pInPageList = PtxPdf_Document_GetPages(pInDoc);
28GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
29                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
30                                 szErrorBuff, Ptx_GetLastError());
31pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
32GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
33                                 Ptx_GetLastError());
34
35// Rotate given pages by 90 degrees
36for (int i = 0; i < ARRAY_SIZE(aPageNumbers); i++)
37{
38    pOutPage = PtxPdf_PageList_Get(pCopiedPages, aPageNumbers[i] - 1);
39    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to get copied page. %s (ErrorCode: 0x%08x).\n"),
40                                     szErrorBuff, Ptx_GetLastError());
41    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_Rotate(pOutPage, ePtxGeom_Rotation_Clockwise),
42                                      _T("Failed to rotate page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
43                                      Ptx_GetLastError());
44}
45
46// Add pages to output document
47pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
48GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages),
49                                  _T("Failed to add copied pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
50                                  Ptx_GetLastError());
51
1int copyDocumentData(TPtxPdf_Document* pInDoc, TPtxPdf_Document* pOutDoc)
2{
3    TPtxPdf_FileReferenceList* pInFileRefList;
4    TPtxPdf_FileReferenceList* pOutFileRefList;
5
6    // Output intent
7    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
8        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(
9                                                         pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
10            return FALSE;
11
12    // Metadata
13    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) ==
14        FALSE)
15        return FALSE;
16
17    // Viewer settings
18    if (PtxPdf_Document_SetViewerSettings(
19            pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
20        return FALSE;
21
22    // Associated files (for PDF/A-3 and PDF 2.0 only)
23    pInFileRefList  = PtxPdf_Document_GetAssociatedFiles(pInDoc);
24    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
25    if (pInFileRefList == NULL || pOutFileRefList == NULL)
26        return FALSE;
27    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
28        if (PtxPdf_FileReferenceList_Add(
29                pOutFileRefList,
30                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
31            return FALSE;
32
33    // Plain embedded files
34    pInFileRefList  = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
35    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
36    if (pInFileRefList == NULL || pOutFileRefList == NULL)
37        return FALSE;
38    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
39        if (PtxPdf_FileReferenceList_Add(
40                pOutFileRefList,
41                PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
42            return FALSE;
43
44    return TRUE;
45}
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4
5// Create output document
6using (Stream outFs = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
7using (Document outDoc = Document.Create(outFs, inDoc.Conformance, null))
8{
9    // Copy document-wide data
10    CopyDocumentData(inDoc, outDoc);
11
12    // Define page copy options
13    PageCopyOptions copyOptions = new PageCopyOptions();
14
15    // Copy all pages
16    PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
17
18    // Rotate selected pages by 90 degrees
19    foreach (var pageNumber in pageNumbers)
20    {
21        copiedPages[pageNumber - 1].Rotate(Rotation.Clockwise);
22    }
23
24    // Add pages to output document
25    outDoc.Pages.AddRange(copiedPages);
26}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    FileStream outStream = new FileStream(outPath, FileStream.Mode.READ_WRITE_NEW)) {
5    try (// Create output document
6        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
7
8        // Copy document-wide data
9        copyDocumentData(inDoc, outDoc);
10
11        // Set copy options and flatten annotations, form fields and signatures
12        PageCopyOptions copyOptions = new PageCopyOptions();
13
14        // Copy all pages
15        PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
16
17        // Rotate selected pages by 90 degrees
18        for (int pageNumber : pageNumbers) {
19            copiedPages.get(pageNumber - 1).rotate(Rotation.CLOCKWISE); 
20        }
21
22        // Add pages to output document
23        outDoc.getPages().addAll(copiedPages);
24    }
25}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Metadata
9    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
10
11    // Viewer settings
12    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
13
14    // Associated files (for PDF/A-3 and PDF 2.0 only)
15    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
16    for (FileReference inFileRef : inDoc.getAssociatedFiles())
17        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
18
19    // Plain embedded files
20    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
21    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
22        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
23}
Download code sample
1
2
3# Open input document
4with io.FileIO(input_path, "rb") as in_stream:
5    with Document.open(in_stream, None) as in_doc:
6
7        # Create output document
8        with io.FileIO(output_path, "wb+") as out_stream:
9            with Document.create(out_stream, in_doc.conformance, None) as out_doc:
10
11                # Copy document-wide data
12                copy_document_data(in_doc, out_doc)
13
14                # Define page copy options
15                page_copy_options = PageCopyOptions()
16
17                # Copy all pages
18                copied_pages = PageList.copy(out_doc, in_doc.pages, page_copy_options)
19
20                # Rotate selected pages by 90 degrees
21                for page_number in page_numbers:
22                    copied_pages[int(page_number) - 1].rotate(Rotation.CLOCKWISE)
23
24                # Add pages to output document
25                out_doc.pages.extend(copied_pages)
26
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))

Information Extraction

Embed files into a PDF

Download code sample
1
2// Open input document
3using (FileStream inStream = new FileStream(input, FileMode.Open, FileAccess.Read))
4using (Document inDoc = Document.Open(inStream, null))
5
6// Create output document
7using (FileStream outStream = new FileStream(output, FileMode.Create, FileAccess.ReadWrite))
8using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
9{
10    // Copy document-wide data
11    CopyDocumentData(inDoc, outDoc);
12
13    // Define page copy options
14    PageCopyOptions copyOptions = new PageCopyOptions();
15
16    // Copy all pages
17    PageList inPageRange = inDoc.Pages.GetRange(0, inDoc.Pages.Count);
18    PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
19    outDoc.Pages.AddRange(copiedPages);
20
21    EmbedFile(outDoc, new FileInfo(fileToEmbed), page);
22}
1private static void CopyDocumentData(Document inDoc, Document outDoc)
2{
3    // Copy document-wide data
4
5    // Output intent
6    if (inDoc.OutputIntent != null)
7        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
8
9    // Metadata
10    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
11
12    // Viewer settings
13    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
14
15    // Associated files (for PDF/A-3 and PDF 2.0 only)
16    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
17    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
18        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
19
20    // Plain embedded files
21    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
22    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
23        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
24}
1private static void EmbedFile(Document outputDoc, FileSystemInfo fileToEmbed, int pageNumber)
2{
3    // create file stream to read the file to embed
4    using (FileStream fileStream = new FileStream(fileToEmbed.FullName, FileMode.Open, FileAccess.Read))
5    {
6        // create a file type depending on the file ending (e.g. "application/pdf")
7        string fileEnding = fileToEmbed.Name.Substring(fileToEmbed.Name.LastIndexOf("."));
8        string type = "application/" + fileEnding;
9
10        // get the modified date from the file
11        DateTime dateTime = fileToEmbed.LastWriteTime;
12
13        // create a new FileReference
14        FileReference fr = FileReference.Create(outputDoc, fileStream, fileToEmbed.Name, type, "", dateTime);
15
16        // if a page is set, add a FileAttachment annotation to that page
17        // otherwise, attach the file to the document
18        if (pageNumber > 0 && pageNumber <= outputDoc.Pages.Count)
19        {
20            // get the page to create the annotation on
21            Page page = outputDoc.Pages[pageNumber - 1];
22
23            // Get the color space
24            ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outputDoc, ProcessColorSpaceType.Rgb);
25
26            // Choose the RGB color value
27            double[] color = { 1.0, 0.0, 0.0 };
28            Transparency transparency = new Transparency(1);
29
30            // Create paint object
31            Paint paint = Paint.Create(outputDoc, colorSpace, color, transparency);
32
33            // put the annotation in the center of the page
34            Point point = new Point
35            { 
36                X= page.Size.Width / 2,
37                Y= page.Size.Height / 2
38            };
39
40            // create a FileReference annotation and attach it to a page so the FireReference is visible on that page
41            FileAttachment fa = FileAttachment.Create(outputDoc, point, fr, paint);
42
43            // add FileAttachment annotation to page
44            page.Annotations.Add(fa);
45        }
46        else
47        {
48            // attach it to the document
49            outputDoc.PlainEmbeddedFiles.Add(fr);
50        }
51    }
52}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(input, Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4
5    // Create output document
6    FileStream outStream = new FileStream(output, Mode.READ_WRITE_NEW);
7    Document outDoc = Document.create(outStream, inDoc.getConformance(), null);
8    )
9{
10    // Copy document-wide data
11    copyDocumentData(inDoc, outDoc);
12
13    // Define page copy options
14    PageCopyOptions copyOptions = new PageCopyOptions();
15
16    // Copy all pages
17    PageList inPageRange = inDoc.getPages().subList(0, inDoc.getPages().size());
18    PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
19    outDoc.getPages().addAll(copiedPages);
20
21    embedFile(outDoc, new File(fileToEmbed), page);
22}
1private static void copyDocumentData(Document inDoc, Document outDoc) throws ToolboxException, IOException {
2    // Copy document-wide data (excluding metadata)
3
4    // Output intent
5    if (inDoc.getOutputIntent() != null)
6        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
7
8    // Viewer settings
9    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
10
11    // Associated files (for PDF/A-3 and PDF 2.0 only)
12    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
13    for (FileReference inFileRef : inDoc.getAssociatedFiles())
14        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
15
16    // Plain embedded files
17    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
18    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
19        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
20}
1private static void embedFile(Document outputDoc, File fileToEmbed, int pageNumber) throws Exception
2{
3    try(
4        // create file stream to read the file to embed
5        FileStream fileStream = new FileStream(fileToEmbed, Mode.READ_ONLY);
6        )
7    {
8        // create a file type depending on the file ending (e.g. "application/pdf")
9        String fileEnding = fileToEmbed.getName().substring(fileToEmbed.getName().lastIndexOf("."));
10        String type = "application/" + fileEnding;
11
12        // get the modified date from the file
13        Instant instant = Instant.ofEpochMilli(fileToEmbed.lastModified());
14        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
15        OffsetDateTime dateTime = OffsetDateTime.from(zonedDateTime);
16
17        // create a new FileReference
18        FileReference fr = FileReference.create(outputDoc, fileStream, fileToEmbed.getName(), type, "", dateTime);
19
20        // if a page is set, add a FileAttachment annotation to that page
21        // otherwise, attach the file to the document
22        if(pageNumber > 0 && pageNumber <= outputDoc.getPages().size())
23        {        
24            // get the page to create the annotation on
25            Page page = outputDoc.getPages().get(pageNumber - 1);
26
27            // Get the color space
28            ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outputDoc, ProcessColorSpaceType.RGB);
29
30            // Choose the RGB color value
31            double[] color = { 1.0, 0.0, 0.0 };
32            Transparency transparency = new Transparency(1);
33
34            // Create paint object
35            Paint paint = Paint.create(outputDoc, colorSpace, color, transparency);
36
37            // put the annotation in the center of the page
38            Point point = new Point(page.getSize().getWidth() / 2, page.getSize().getHeight() / 2);
39
40            // create a FileReference annotation and attach it to a page so the FireReference is visible on that page
41            FileAttachment fa = FileAttachment.create(outputDoc, point, fr, paint);
42
43            // add FileAttachment annotation to the page
44            page.getAnnotations().add(fa);
45        }
46        else
47        {
48            // attach it to the document
49            outputDoc.getPlainEmbeddedFiles().add(fr);
50        }
51    }
52}
Download code sample
1def copy_document_data(in_doc: Document, out_doc: Document):
2    # Copy document-wide data
3
4    # Output intent
5    if in_doc.output_intent is not None:
6        in_doc.output_intent = IccBasedColorSpace.copy(out_doc, in_doc.output_intent)
7
8    # Metadata
9    out_doc.metadata = Metadata.copy(out_doc, in_doc.metadata)
10
11    # Viewer settings
12    out_doc.viewer_settings = ViewerSettings.copy(out_doc, in_doc.viewer_settings)
13
14    # Associated files (for PDF/A-3 and PDF 2.0 only)
15    outAssociatedFiles = out_doc.associated_files
16    for in_file_ref in in_doc.associated_files:
17        outAssociatedFiles.append(FileReference.copy(out_doc, in_file_ref))
18
19    # Plain embedded files
20    out_embedded_files = out_doc.plain_embedded_files
21    for in_file_ref in in_doc.plain_embedded_files:
22        out_embedded_files.append(FileReference.copy(out_doc, in_file_ref))
1def embed_file(output_doc: Document, file_to_embed: str, page_number: int | None):
2    # Create file stream to read the file to embed
3    with open(file_to_embed, "rb") as file_stream:
4        # Create a file type depending on the file ending (e.g. "application/pdf")
5        file_to_embed_name = os.path.basename(file_to_embed)
6        file_type = "application/" + file_to_embed_name.split(".")[-1]
7
8        # Get the modified date from the file
9        last_modified = datetime.fromtimestamp(os.path.getmtime(file_to_embed))
10
11        # Create a new FileReference
12        file_ref = FileReference.create(output_doc, file_stream, file_to_embed_name, file_type, "", last_modified)
13
14        # If a page is set, add a FileAttachment annotation to that page
15        # otherwise, attach the file to the document
16        if page_number is not None and page_number > 0 and page_number <= len(output_doc.pages):
17            # Get the page to create the annotation on
18            page = output_doc.pages[page_number - 1]
19
20            # Get the color space
21            color_space = ColorSpace.create_process_color_space(output_doc, ProcessColorSpaceType.RGB)
22
23            # Choose the RGB color value
24            color = [1.0, 0.0, 0.0]  # Red color
25            transparency = Transparency(1)
26
27            # Create paint object
28            paint = Paint.create(output_doc, color_space, color, transparency)
29
30            # Put the annotation in the center of the page
31            point = Point(x = page.size.width/2, y = page.size.height/2)
32
33            # Create a FileReference annotation and attach it to a page so the FireReference is visible on that page
34            annotation = FileAttachment.create(output_doc, point, file_ref, paint)
35
36            # Add the annotation to the page
37            page.annotations.append(annotation)
38        else:
39            # Attach the file to the document
40            output_doc.plain_embedded_files.append(file_ref)

Extract files embedded from a PDF

Download code sample
1
2// Open input document
3using (FileStream inStream = new FileStream(inputFile, FileMode.Open, FileAccess.Read))
4using (Document inDoc = Document.Open(inStream, null))
5{
6    FileReferenceList frList = inDoc.AllEmbeddedFiles;
7
8    foreach(FileReference fr in frList)
9    {
10        ExtractFile(fr, outputDir);
11    }
12}
1private static void ExtractFile(FileReference fr, String outputDir)
2{
3    using (FileStream outStream = new FileStream(outputDir + "/" + fr.Name, FileMode.Create, FileAccess.ReadWrite))
4    {
5        fr.Data.CopyTo(outStream);
6    }
7}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inputFile, Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null);
4    )
5{
6    FileReferenceList frList = inDoc.getAllEmbeddedFiles();
7
8    for(FileReference fr: frList)
9    {
10        extractFile(fr, outputDir);
11    }
12}
1private static void extractFile(FileReference fr, String outputDir) throws Exception
2{
3    try(
4        FileStream outStream = new FileStream(outputDir + "/" + fr.getName(), Mode.READ_WRITE_NEW);
5        )
6    {
7        outStream.copy(fr.getData());
8    }
9}
Download code sample
1def copy_to_stream(data: io.IOBase, out_stream: io.IOBase, chunk_size: int = 4096):
2    """Copy data from an IO stream to another."""
3    while chunk := data.read(chunk_size):
4        out_stream.write(chunk)
1def extract_file(file_reference: FileReference, output_dir: str):
2    # Remove null characters
3    clean_file_name = file_reference.name.replace("\x00", "")
4    output_path = os.path.join(output_dir, clean_file_name)
5
6    if file_reference.data is None:
7        raise ValueError("The file_reference.data stream is None.")
8    if not file_reference.data.readable():
9        raise ValueError("The file_reference.data stream is not readable.")
10
11    # Ensure the output directory exists
12    os.makedirs(output_dir, exist_ok=True)
13
14    with io.FileIO(output_path, "wb") as out_file:
15        copy_to_stream(file_reference.data, out_file)

Extract all images and image masks from a PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Loop over all pages and extract images
10pInPageList = PtxPdf_Document_GetPages(pInDoc);
11GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList,
12                                 _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"),
13                                 szErrorBuff, Ptx_GetLastError());
14
15for (int iPageNo = 0; iPageNo < PtxPdf_PageList_GetCount(pInPageList); iPageNo++)
16{
17    pPage    = PtxPdf_PageList_Get(pInPageList, iPageNo);
18    pContent = PtxPdf_Page_GetContent(pPage);
19    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pContent, _T("Failed to get content from page %d. %s (ErrorCode: 0x%08x).\n"),
20                                     iPageNo + 1, szErrorBuff, Ptx_GetLastError());
21
22    pExtractor = PtxPdfContent_ContentExtractor_New(pContent);
23    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pExtractor,
24                                     _T("Failed to create content extractor. %s (ErrorCode: 0x%08x).\n"),
25                                     szErrorBuff, Ptx_GetLastError());
26
27    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(extractImages(pExtractor, iPageNo + 1, szOutputDir),
28                                      _T("Error occurred while extracting images. %s (ErrorCode: 0x%08x).\n"),
29                                      szErrorBuff, Ptx_GetLastError());
30
31    if (pPage != NULL)
32    {
33        Ptx_Release(pPage);
34        pPage = NULL;
35    }
36    if (pContent != NULL)
37    {
38        Ptx_Release(pContent);
39        pContent = NULL;
40    }
41}
42
43
1int extractImages(TPtxPdfContent_ContentExtractor* pExtractor, int iPageNo, const TCHAR* szOutputDir)
2{
3    int                                      iImgCount       = 0;
4    int                                      iImgMaskCount   = 0;
5    TPtxPdfContent_ContentExtractorIterator* pIterator       = NULL;
6    TPtxPdfContent_ContentElement*           pContentElement = NULL;
7    TPtxPdfContent_Image*                    pImage          = NULL;
8    TPtxPdfContent_ImageMask*                pImageMask      = NULL;
9    TCHAR*                                   szExtension     = NULL;
10    FILE*                                    pOutStream      = NULL;
11
12    pIterator = PtxPdfContent_ContentExtractor_GetIterator(pExtractor);
13    GOTO_CLEANUP_IF_NULL(pIterator, _T("Failed to get iterator.\n"));
14    PtxPdfContent_ContentExtractorIterator_MoveNext(pIterator);
15    while (pContentElement = PtxPdfContent_ContentExtractorIterator_GetValue(pIterator))
16    {
17        TPtxPdfContent_ContentElementType iType = PtxPdfContent_ContentElement_GetType(pContentElement);
18        if (iType == ePtxPdfContent_ContentElementType_ImageElement)
19        {
20            iImgCount++;
21            pImage = PtxPdfContent_ImageElement_GetImage((TPtxPdfContent_ImageElement*)pContentElement);
22            GOTO_CLEANUP_IF_NULL(pImage, _T("Failed to get image.\n"));
23
24            const TPtxPdfContent_ImageType iImageType = PtxPdfContent_Image_GetDefaultImageType(pImage);
25            if (iImageType == ePtxPdfContent_ImageType_Jpeg)
26                szExtension = _T(".jpg");
27            else
28                szExtension = _T(".tiff");
29
30            TCHAR szOutPath[256] = {'\0'};
31            _stprintf(szOutPath, _T("%s/image_page%d_%d%s"), szOutputDir, iPageNo, iImgCount, szExtension);
32
33            pOutStream = _tfopen(szOutPath, _T("wb+"));
34            GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
35
36            TPtxSys_StreamDescriptor outDescriptor;
37            PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
38            if (PtxPdfContent_Image_Extract(pImage, &outDescriptor, NULL) == FALSE)
39            {
40                if (Ptx_GetLastError() == ePtx_Error_Generic)
41                {
42                    nBufSize = Ptx_GetLastErrorMessage(NULL, 0);
43                    Ptx_GetLastErrorMessage(szErrorBuff, MIN(ARRAY_SIZE(szErrorBuff), nBufSize));
44                    _tprintf(szErrorBuff);
45                }
46                else
47                    return FALSE;
48            }
49
50            if (pImage != NULL)
51            {
52                Ptx_Release(pImage);
53                pImage = NULL;
54            }
55            if (pOutStream != NULL)
56            {
57                fclose(pOutStream);
58                pOutStream = NULL;
59            }
60        }
61        else if (iType == ePtxPdfContent_ContentElementType_ImageMaskElement)
62        {
63            iImgMaskCount++;
64            pImageMask = PtxPdfContent_ImageMaskElement_GetImageMask((TPtxPdfContent_ImageMaskElement*)pContentElement);
65            GOTO_CLEANUP_IF_NULL(pImageMask, _T("Failed to get image.\n"));
66
67            szExtension = _T(".tiff");
68
69            TCHAR szOutPath[256] = {'\0'};
70            _stprintf(szOutPath, _T("%s/image_mask_page%d_%d%s"), szOutputDir, iPageNo, iImgMaskCount, szExtension);
71
72            pOutStream = _tfopen(szOutPath, _T("wb+"));
73            GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
74
75            TPtxSys_StreamDescriptor outDescriptor;
76            PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
77            if (PtxPdfContent_ImageMask_Extract(pImageMask, &outDescriptor, NULL) == FALSE)
78            {
79                if (Ptx_GetLastError() == ePtx_Error_Generic)
80                {
81                    nBufSize = Ptx_GetLastErrorMessage(NULL, 0);
82                    Ptx_GetLastErrorMessage(szErrorBuff, MIN(ARRAY_SIZE(szErrorBuff), nBufSize));
83                    _tprintf(szErrorBuff);
84                }
85                else
86                    return FALSE;
87            }
88
89            if (pImageMask != NULL)
90            {
91                Ptx_Release(pImageMask);
92                pImageMask = NULL;
93            }
94            if (pOutStream != NULL)
95            {
96                fclose(pOutStream);
97                pOutStream = NULL;
98            }
99        }
100        if (pContentElement != NULL)
101        {
102            Ptx_Release(pContentElement);
103            pContentElement = NULL;
104        }
105        PtxPdfContent_ContentExtractorIterator_MoveNext(pIterator);
106    }
107
108cleanup:
109    if (pImage != NULL)
110        Ptx_Release(pImage);
111    if (pImageMask != NULL)
112        Ptx_Release(pImageMask);
113    if (pContentElement != NULL)
114        Ptx_Release(pContentElement);
115    if (pIterator != NULL)
116        Ptx_Release(pIterator);
117    if (pOutStream != NULL)
118        fclose(pOutStream);
119
120    return iReturnValue == 1 ? FALSE : TRUE;
121}
Download code sample
1// Open input document
2using (Stream stream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document doc = Document.Open(stream, null))
4{
5    // Loop over all pages and extract images
6    for (int i = 0; i < doc.Pages.Count; i++)
7    {
8        ContentExtractor extractor = new ContentExtractor(doc.Pages[i].Content);
9        ExtractImages(extractor, i + 1, outputDir);
10    }
11}
1private static void ExtractImages(ContentExtractor extractor, int pageNo, string outputDir)
2{
3    int imgCount = 0;
4    int imgMaskCount = 0;
5    foreach (ContentElement contentElement in extractor)
6    {
7        if (contentElement is ImageElement element)
8        {
9            imgCount++;
10            string extension = ".tiff";
11            switch (element.Image.DefaultImageType)
12            {
13                case ImageType.Jpeg:
14                    extension = ".jpg";
15                    break;
16                case ImageType.Tiff:
17                    extension = ".tiff";
18                    break;
19                default:
20                    break;
21            }
22            string outputPath = System.IO.Path.Combine(outputDir, $"image_page{pageNo}_{imgCount}{extension}");
23
24            try
25            {
26                using (Stream imageStream = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite))
27                {
28                    element.Image.Extract(imageStream);
29                }
30            }
31            catch (GenericException ex)
32            {
33                Console.WriteLine(ex.ToString());
34            }
35        }
36        else if (contentElement is ImageMaskElement maskElement)
37        {
38            imgMaskCount++;
39            string extension = ".tiff";
40            string outputPath = System.IO.Path.Combine(outputDir, $"image_mask_page{pageNo}_{imgMaskCount}{extension}");
41            try
42            {
43                using (Stream imageStream = new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite))
44                {
45                    maskElement.ImageMask.Extract(imageStream);
46                }
47            }
48            catch (GenericException ex)
49            {
50                Console.WriteLine(ex.ToString());
51            }
52        }
53    }
54}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null)) {
4
5    // Loop over all pages and extract images
6    for (int i = 0; i < inDoc.getPages().size(); i++) {
7        ContentExtractor extractor = new ContentExtractor(inDoc.getPages().get(i).getContent());
8        extractImages(extractor, i + 1, outputDir);
9    }
10}
1private static void extractImages(ContentExtractor extractor, int pageNo, String outputDir) throws IOException {
2    int imgCount = 0;
3    int imgMaskCount = 0;
4    for (Object elementObj : extractor) {
5        if (elementObj instanceof ImageElement) {
6            ImageElement element = (ImageElement) elementObj;
7            imgCount++;
8            String extension = ".tiff";
9            switch (element.getImage().getDefaultImageType()) {
10                case JPEG:
11                    extension = ".jpg";
12                    break;
13                case TIFF:
14                    extension = ".tiff";
15                    break;
16                default:
17                    break;
18            }
19            String outputPath = Paths.get(outputDir, "image_page" + pageNo + "_" + imgCount + extension).toString();
20            try (FileStream imageStream = new FileStream(outputPath, FileStream.Mode.READ_WRITE_NEW)) {
21                element.getImage().extract(imageStream);
22            } catch (GenericException ex) {
23                System.out.println(ex.toString());
24            }
25        }
26        else if (elementObj instanceof ImageMaskElement) {
27            ImageMaskElement element = (ImageMaskElement) elementObj;
28            imgMaskCount++;
29            String extension = ".tiff";
30            String outputPath = Paths.get(outputDir, "image_mask_page" + pageNo + "_" + imgMaskCount + extension).toString();
31            try (FileStream imageStream = new FileStream(outputPath, FileStream.Mode.READ_WRITE_NEW)) {
32                element.getImageMask().extract(imageStream);
33            } catch (GenericException ex) {
34                System.out.println(ex.toString());
35            }
36        }
37    }
38}
Download code sample
1def extract_image(image_element: ImageElement, output_path: str):
2    with open(output_path, "wb+") as out_stream:
3        image_element.image.extract(out_stream)
1def extract_image_mask(image_mask_element: ImageMaskElement, output_path: str):
2    with open(output_path, "wb+") as out_stream:
3        image_mask_element.image_mask.extract(out_stream)
1def process_page_content(page: Page, page_number: int, output_dir: str):
2    extractor = ContentExtractor(page.content)
3    img_count = 0
4    mask_count = 0
5
6    for content_element in extractor:
7        # Extract image elements
8        if isinstance(content_element, ImageElement):
9            img_count += 1
10            image_type = content_element.image.default_image_type
11
12            extension = ".jpg" if image_type == ImageType.JPEG else ".tiff"
13
14            output_path = os.path.join(output_dir, f"image_page{page_number}_{img_count}{extension}")
15
16            extract_image(content_element, output_path)
17
18            print(f"Extracted image: {output_path}")
19
20        # Extract image masks
21        elif isinstance(content_element, ImageMaskElement):
22            mask_count += 1
23            output_path = os.path.join(output_dir, f"image_mask_page{page_number}_{mask_count}.tiff")
24            extract_image_mask(content_element, output_path)
25            print(f"Extracted image mask: {output_path}")

List bounds of page content

Download code sample
1// Open input document
2using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
3using (Document doc = Document.Open(stream, null))
4{
5    // Iterate over all pages
6    int pageNumber = 1;
7    foreach (Page page in doc.Pages)
8    {
9        // Print page size
10        Console.WriteLine("Page {0}", pageNumber++);
11        Size size = page.Size;
12        Console.WriteLine("  Size:");
13        Console.WriteLine("    Width: {0}", size.Width);
14        Console.WriteLine("    Height: {0}", size.Height);
15
16        // Compute rectangular bounding box of all content on page
17        Rectangle contentBox = new Rectangle()
18        {
19            Left = double.MaxValue,
20            Bottom = double.MaxValue,
21            Right = double.MinValue,
22            Top = double.MinValue,
23        };
24        ContentExtractor extractor = new ContentExtractor(page.Content);
25        foreach (ContentElement element in extractor)
26        {
27            // Enlarge the content box for each content element
28            AffineTransform tr = element.Transform;
29            Rectangle box = element.BoundingBox;
30
31            // The location on the page is given by the transformed points
32            Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Left, Y = box.Bottom, }));
33            Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Right, Y = box.Bottom, }));
34            Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Right, Y = box.Top, }));
35            Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Left, Y = box.Top, }));
36        }
37        Console.WriteLine("  Content bounding box:");
38        Console.WriteLine("    Left: {0}", contentBox.Left);
39        Console.WriteLine("    Bottom: {0}", contentBox.Bottom);
40        Console.WriteLine("    Right: {0}", contentBox.Right);
41        Console.WriteLine("    Top: {0}", contentBox.Top);
42    }
43}
1static void Enlarge(ref Rectangle box, Point point)
2{
3    // Enlarge box if point lies outside of box
4    if (point.X < box.Left)
5        box.Left = point.X;
6    else if (point.X > box.Right)
7        box.Right = point.X;
8    if (point.Y < box.Bottom)
9        box.Bottom = point.Y;
10    else if (point.Y > box.Top)
11        box.Top = point.Y;
12}
Download code sample
1try (// Open input document
2    FileStream stream = new FileStream(path, FileStream.Mode.READ_ONLY);
3    Document doc = Document.open(stream, null)) {
4    // Iterate over all pages
5    int pageNumber = 1;
6    for (Page page : doc.getPages()) {
7        // Print page size
8        System.out.format("Page %d\n", pageNumber++);
9        Size size = page.getSize();
10        System.out.println("  Size:");
11        System.out.format("    Width: %f\n", size.getWidth());
12        System.out.format("    Height: %f\n", size.getHeight());
13
14        // Compute rectangular bounding box of all content on page
15        Rectangle contentBox = new Rectangle(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
16        ContentExtractor extractor = new ContentExtractor(page.getContent());
17        for (ContentElement element : extractor) {
18            // Enlarge the content box for each content element
19            AffineTransform tr = element.getTransform();
20            Rectangle box = element.getBoundingBox();
21
22            // The location on the page is given by the transformed points
23            contentBox = enlarge(contentBox, tr.transformPoint(new Point(box.getLeft(), box.getBottom())));
24            contentBox = enlarge(contentBox, tr.transformPoint(new Point(box.getRight(), box.getBottom())));
25            contentBox = enlarge(contentBox, tr.transformPoint(new Point(box.getRight(), box.getTop())));
26            contentBox = enlarge(contentBox, tr.transformPoint(new Point(box.getLeft(), box.getTop())));
27        }
28        System.out.println("  Content bounding box:");
29        System.out.format("    Left: %f\n", contentBox.getLeft());
30        System.out.format("    Bottom: %f\n", contentBox.getBottom());
31        System.out.format("    Right: %f\n", contentBox.getRight());
32        System.out.format("    Top: %f\n", contentBox.getTop());
33    }
34}
1static Rectangle enlarge(Rectangle box, Point point) {
2    // Enlarge box if point lies outside of box
3    if (point.getX() < box.getLeft())
4        box.setLeft(point.getX());
5    else if (point.getX() > box.getRight())
6        box.setRight(point.getX());
7    if (point.getY() < box.getBottom())
8        box.setBottom(point.getY());
9    else if (point.getY() > box.getTop())
10        box.setTop(point.getY());
11    return box;
12}
Download code sample
1def enlarge(content_box: Rectangle, point: Point):
2    """
3    Enlarge the bounding box to include the given point.
4    """
5    content_box.left = min(content_box.left, point.x)
6    content_box.right = max(content_box.right, point.x)
7    content_box.bottom = min(content_box.bottom, point.y)
8    content_box.top = max(content_box.top, point.y)
1def list_content_bounds(input_doc: Document):
2    """
3    Process the input PDF file to list page size and bounding boxes.
4    """
5    # Iterate over all pages
6    for page_number, page in enumerate(input_doc.pages, start=1):
7        print(f"Page {page_number}")
8
9        # Print page size
10        size = page.size
11        print("  Size:")
12        print(f"    Width: {size.width}")
13        print(f"    Height: {size.height}")
14
15        # Compute rectangular bounding box of all content on page
16        content_box = Rectangle(
17            left=float("inf"),
18            bottom=float("inf"),
19            right=float("-inf"),
20            top=float("-inf"),
21        )
22
23        # Extract content and compute bounding box
24        extractor = ContentExtractor(page.content)
25        for element in extractor:
26            # Enlarge the content box for each content element
27            tr = element.transform
28            box = element.bounding_box
29
30            # The location on the page is given by the transformed points
31            enlarge(content_box, tr.transform_point(Point(x=box.left, y=box.bottom)))
32            enlarge(content_box, tr.transform_point(Point(x=box.right, y=box.bottom)))
33            enlarge(content_box, tr.transform_point(Point(x=box.right, y=box.top)))
34            enlarge(content_box, tr.transform_point(Point(x=box.left, y=box.top)))
35
36        print("  Content bounding box:")
37        print(f"    Left: {content_box.left}")
38        print(f"    Bottom: {content_box.bottom}")
39        print(f"    Right: {content_box.right}")
40        print(f"    Top: {content_box.top}")

List document information of PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, szPassword);
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Conformance
10TPtxPdf_Conformance conformance = PtxPdf_Document_GetConformance(pInDoc);
11if (conformance == 0)
12{
13    GOTO_CLEANUP(szErrorBuff, Ptx_GetLastError());
14}
15_tprintf(_T("Conformance: "));
16switch (conformance)
17{
18case ePtxPdf_Conformance_Pdf10:
19    _tprintf(_T("PDF 1.0\n"));
20    break;
21case ePtxPdf_Conformance_Pdf11:
22    _tprintf(_T("PDF 1.1\n"));
23    break;
24case ePtxPdf_Conformance_Pdf12:
25    _tprintf(_T("PDF 1.2\n"));
26    break;
27case ePtxPdf_Conformance_Pdf13:
28    _tprintf(_T("PDF 1.3\n"));
29    break;
30case ePtxPdf_Conformance_Pdf14:
31    _tprintf(_T("PDF 1.4\n"));
32    break;
33case ePtxPdf_Conformance_Pdf15:
34    _tprintf(_T("PDF 1.5\n"));
35    break;
36case ePtxPdf_Conformance_Pdf16:
37    _tprintf(_T("PDF 1.6\n"));
38    break;
39case ePtxPdf_Conformance_Pdf17:
40    _tprintf(_T("PDF 1.7\n"));
41    break;
42case ePtxPdf_Conformance_Pdf20:
43    _tprintf(_T("PDF 2.0\n"));
44    break;
45case ePtxPdf_Conformance_PdfA1B:
46    _tprintf(_T("PDF/A1-b\n"));
47    break;
48case ePtxPdf_Conformance_PdfA1A:
49    _tprintf(_T("PDF/A1-a\n"));
50    break;
51case ePtxPdf_Conformance_PdfA2B:
52    _tprintf(_T("PDF/A2-b\n"));
53    break;
54case ePtxPdf_Conformance_PdfA2U:
55    _tprintf(_T("PDF/A2-u\n"));
56    break;
57case ePtxPdf_Conformance_PdfA2A:
58    _tprintf(_T("PDF/A2-a\n"));
59    break;
60case ePtxPdf_Conformance_PdfA3B:
61    _tprintf(_T("PDF/A3-b\n"));
62    break;
63case ePtxPdf_Conformance_PdfA3U:
64    _tprintf(_T("PDF/A3-u\n"));
65    break;
66case ePtxPdf_Conformance_PdfA3A:
67    _tprintf(_T("PDF/A3-a\n"));
68    break;
69}
70
71// Encryption information
72TPtxPdf_Permission permissions;
73BOOL               iRet = PtxPdf_Document_GetPermissions(pInDoc, &permissions);
74if (iRet == FALSE)
75{
76    if (Ptx_GetLastError() != ePtx_Error_Success)
77        GOTO_CLEANUP(szErrorBuff, Ptx_GetLastError());
78    _tprintf(_T("Not encrypted\n"));
79}
80else
81{
82    _tprintf(_T("Encryption:\n"));
83    _tprintf(_T("  - Permissions: "));
84    if (permissions & ePtxPdf_Permission_Print)
85        _tprintf(_T("Print, "));
86    if (permissions & ePtxPdf_Permission_Modify)
87        _tprintf(_T("Modify, "));
88    if (permissions & ePtxPdf_Permission_Copy)
89        _tprintf(_T("Copy, "));
90    if (permissions & ePtxPdf_Permission_Annotate)
91        _tprintf(_T("Annotate, "));
92    if (permissions & ePtxPdf_Permission_FillForms)
93        _tprintf(_T("FillForms, "));
94    if (permissions & ePtxPdf_Permission_SupportDisabilities)
95        _tprintf(_T("SupportDisabilities, "));
96    if (permissions & ePtxPdf_Permission_Assemble)
97        _tprintf(_T("Assemble, "));
98    if (permissions & ePtxPdf_Permission_DigitalPrint)
99        _tprintf(_T("DigitalPrint, "));
100    _tprintf(_T("\n"));
101}
102
103// Get metadata of input PDF
104pMetadata = PtxPdf_Document_GetMetadata(pInDoc);
105GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetadata, _T("Failed to get metadata. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
106                                 Ptx_GetLastError());
107_tprintf(_T("Document information:\n"));
108
109// Get title
110size_t nTitle = PtxPdf_Metadata_GetTitle(pMetadata, NULL, 0);
111if (nTitle != 0)
112{
113    TCHAR* szTitle = (TCHAR*)malloc(nTitle * sizeof(TCHAR));
114    if (szTitle != NULL)
115    {
116        PtxPdf_Metadata_GetTitle(pMetadata, szTitle, nTitle);
117        _tprintf(_T("  - Title: %s\n"), szTitle);
118        free(szTitle);
119    }
120}
121
122// Get author
123size_t nAuthor = PtxPdf_Metadata_GetAuthor(pMetadata, NULL, 0);
124if (nAuthor != 0)
125{
126    TCHAR* szAuthor = (TCHAR*)malloc(nAuthor * sizeof(TCHAR));
127    if (szAuthor != NULL)
128    {
129        PtxPdf_Metadata_GetAuthor(pMetadata, szAuthor, nAuthor);
130        _tprintf(_T("  - Author: %s\n"), szAuthor);
131        free(szAuthor);
132    }
133}
134
135// Get creator
136size_t nCreator = PtxPdf_Metadata_GetCreator(pMetadata, NULL, 0);
137if (nCreator != 0)
138{
139    TCHAR* szCreator = (TCHAR*)malloc(nCreator * sizeof(TCHAR));
140    if (szCreator != NULL)
141    {
142        PtxPdf_Metadata_GetCreator(pMetadata, szCreator, nCreator);
143        _tprintf(_T("  - Creator: %s\n"), szCreator);
144        free(szCreator);
145    }
146}
147
148// Get producer
149size_t nProducer = PtxPdf_Metadata_GetProducer(pMetadata, NULL, 0);
150if (nProducer != 0)
151{
152    TCHAR* szProducer = (TCHAR*)malloc(nProducer * sizeof(TCHAR));
153    if (szProducer != NULL)
154    {
155        PtxPdf_Metadata_GetProducer(pMetadata, szProducer, nProducer);
156        _tprintf(_T("  - Producer: %s\n"), szProducer);
157        free(szProducer);
158    }
159}
160
161// Get subject
162size_t nSubject = PtxPdf_Metadata_GetSubject(pMetadata, NULL, 0);
163if (nSubject != 0)
164{
165    TCHAR* szSubject = (TCHAR*)malloc(nSubject * sizeof(TCHAR));
166    if (szSubject != NULL)
167    {
168        PtxPdf_Metadata_GetSubject(pMetadata, szSubject, nSubject);
169        _tprintf(_T("  - Subject: %s\n"), szSubject);
170        free(szSubject);
171    }
172}
173
174// Get keywords
175size_t nKeywords = PtxPdf_Metadata_GetKeywords(pMetadata, NULL, 0);
176if (nKeywords != 0)
177{
178    TCHAR* szKeywords = (TCHAR*)malloc(nKeywords * sizeof(TCHAR));
179    if (szKeywords != NULL)
180    {
181        PtxPdf_Metadata_GetKeywords(pMetadata, szKeywords, nKeywords);
182        _tprintf(_T("  - Keywords: %s\n"), szKeywords);
183        free(szKeywords);
184    }
185}
186
187// Get creation date
188if (PtxPdf_Metadata_GetCreationDate(pMetadata, &date) == TRUE)
189{
190    _tprintf(_T("  - Creation Date: %02d-%02d-%d %02d:%02d:%02d%c%02d:%02d\n"), date.iYear, date.iMonth, date.iDay,
191             date.iHour, date.iMinute, date.iSecond, date.iTZSign >= 0 ? '+' : '-', date.iTZHour, date.iTZMinute);
192}
193
194// Get modification date
195if (PtxPdf_Metadata_GetModificationDate(pMetadata, &date) == TRUE)
196{
197    _tprintf(_T("  - Modification Date: %02d-%02d-%d %02d:%02d:%02d%c%02d:%02d\n"), date.iYear, date.iMonth,
198             date.iDay, date.iHour, date.iMinute, date.iSecond, date.iTZSign >= 0 ? '+' : '-', date.iTZHour,
199             date.iTZMinute);
200}
201
202// Get custom entries
203_tprintf(_T("Custom entries:\n"));
204TPtx_StringMap* pCustomEntries = PtxPdf_Metadata_GetCustomEntries(pMetadata);
205GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCustomEntries, _T("Failed to get custom entries. %s (ErrorCode: 0x%08x).\n"),
206                                 szErrorBuff, Ptx_GetLastError());
207for (int i = Ptx_StringMap_GetBegin(pCustomEntries), iEnd = Ptx_StringMap_GetEnd(pCustomEntries); i != iEnd;
208     i = Ptx_StringMap_GetNext(pCustomEntries, i))
209{
210    size_t nKeySize = Ptx_StringMap_GetKey(pCustomEntries, i, NULL, 0);
211    TCHAR* szKey    = (TCHAR*)malloc(nKeySize * sizeof(TCHAR));
212    nKeySize        = Ptx_StringMap_GetKey(pCustomEntries, i, szKey, nKeySize);
213
214    size_t nValueSize = Ptx_StringMap_GetValue(pCustomEntries, i, NULL, 0);
215    TCHAR* szValue    = (TCHAR*)malloc(nValueSize * sizeof(TCHAR));
216    nValueSize        = Ptx_StringMap_GetValue(pCustomEntries, i, szValue, nValueSize);
217
218    if (szKey && nKeySize && szValue && nValueSize)
219        _tprintf(_T("  - %s: %s\n"), szKey, szValue);
220
221    free(szKey);
222    free(szValue);
223}
224
225
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, password))
4{
5    // Conformance
6    Console.WriteLine("Conformance: {0}", inDoc.Conformance.ToString());
7
8    // Encryption information
9    Permission? permissions = inDoc.Permissions;
10    if (!permissions.HasValue)
11    {
12        Console.WriteLine("Not encrypted");
13    }
14    else
15    {
16        Console.WriteLine("Encryption:");
17        Console.Write("  - Permissions: ");
18        foreach (Enum flag in Enum.GetValues(typeof(Permission)))
19            if (permissions.Value.HasFlag(flag))
20                Console.Write("{0}, ", flag.ToString());
21        Console.WriteLine();
22    }
23
24    // Get metadata
25    Metadata metadata = inDoc.Metadata;
26    Console.WriteLine("Document information:");
27
28    // Get title
29    string title = metadata.Title;
30    if (title != null)
31        Console.WriteLine("  - Title: {0}", title);
32
33    // Get author
34    string author = metadata.Author;
35    if (author != null)
36        Console.WriteLine("  - Author: {0}", author);
37
38    // Get subject
39    string subject = metadata.Subject;
40    if (subject != null)
41        Console.WriteLine("  - Subject: {0}", subject);
42
43    // Get keywords
44    string keywords = metadata.Keywords;
45    if (keywords != null)
46        Console.WriteLine("  - Keywords: {0}", keywords);
47
48    // Get creation date
49    DateTimeOffset? creationDate = metadata.CreationDate;
50    if (creationDate != null)
51        Console.WriteLine("  - Creation Date: {0}", creationDate);
52
53    // Get modification date
54    DateTimeOffset? modificationDate = metadata.ModificationDate;
55    if (modificationDate != null)
56        Console.WriteLine("  - Modification Date: {0}", modificationDate);
57
58    // Get creator
59    string creator = metadata.Creator;
60    if (creator != null)
61        Console.WriteLine("  - Creator: {0}", creator);
62
63    // Get producer
64    string producer = metadata.Producer;
65    if (producer != null)
66        Console.WriteLine("  - Producer: {0}", producer);
67
68    // Custom entries
69    Console.WriteLine("Custom entries:");
70    foreach (var entry in metadata.CustomEntries)
71        Console.WriteLine("  - {0}: {1}", entry.Key, entry.Value);
72}
73
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null)) {
4    // Conformance
5    System.out.format("Conformance: %s\n", inDoc.getConformance().toString());
6
7    // Encryption information
8    EnumSet<Permission> permissions = inDoc.getPermissions();
9    if (permissions == null) {
10        System.out.println("Not encrypted");
11    } else {
12        System.out.println("Encryption:");
13        System.out.print("  - Permissions: ");
14        for (Permission permission : permissions) {
15            System.out.format("%s, ", permission.toString());
16        }
17        System.out.println();
18    }
19
20    // Get metadata of input PDF
21    Metadata metadata = inDoc.getMetadata();
22    System.out.format("Document information:\n");
23
24    // Get title
25    String title = metadata.getTitle();
26    if (title != null)
27        System.out.format("  - Title: %s\n", title);
28
29    // Get author
30    String author = metadata.getAuthor();
31    if (author != null)
32        System.out.format("  - Author: %s\n", author);
33
34    // Get subject
35    String subject = metadata.getSubject();
36    if (subject != null)
37        System.out.format("  - Subject: %s\n", subject);
38
39    // Get keywords
40    String keywords = metadata.getKeywords();
41    if (keywords != null)
42        System.out.format("  - Keywords: %s\n", keywords);
43
44    // Get creation date
45    OffsetDateTime creationDate = metadata.getCreationDate();
46    if (creationDate != null)
47        System.out.format("  - Creation Date: %s\n", creationDate.toString());
48
49    // Get modification date
50    OffsetDateTime modificationDate = metadata.getModificationDate();
51    if (modificationDate != null)
52        System.out.format("  - Modification Date: %s\n", modificationDate.toString());
53
54    // Get creator
55    String creator = metadata.getCreator();
56    if (creator != null)
57        System.out.format("  - Creator: %s\n", creator);
58
59    // Get producer
60    String producer = metadata.getProducer();
61    if (producer != null)
62        System.out.format("  - Producer: %s\n", producer);
63
64    // Custom entries
65    System.out.format("Custom entries:\n");
66    for (Map.Entry<String, String> entry : metadata.getCustomEntries().entrySet())
67        System.out.format("  - %s: %s\n", entry.getKey(), entry.getValue());
68}
69
Download code sample
1def display_permissions(permissions: int):
2    """Display encryption permissions in a readable format."""
3    # Display active permission names
4    active_permissions = [perm.name for perm in Permission if permissions & perm]
5    for perm in active_permissions:
6        print(f"  - {perm}")
1def list_pdf_info(input_doc: Document):
2    """
3    List document information and metadata of the given PDF.
4    """
5    # Conformance
6    print(f"Conformance: {input_doc.conformance.name}")
7
8    # Encryption information
9    permissions = input_doc.permissions
10    if permissions is None:
11        print("Not encrypted")
12    else:
13        display_permissions(permissions)
14
15    # Get metadata
16    metadata = input_doc.metadata
17    print("Document information:")
18
19    # Display standard metadata
20    if metadata.title:
21        print(f"  - Title: {metadata.title}")
22    if metadata.author:
23        print(f"  - Author: {metadata.author}")
24    if metadata.subject:
25        print(f"  - Subject: {metadata.subject}")
26    if metadata.keywords:
27        print(f"  - Keywords: {metadata.keywords}")
28    if metadata.creation_date:
29        print(f"  - Creation Date: {metadata.creation_date}")
30    if metadata.modification_date:
31        print(f"  - Modification Date: {metadata.modification_date}")
32    if metadata.creator:
33        print(f"  - Creator: {metadata.creator}")
34    if metadata.producer:
35        print(f"  - Producer: {metadata.producer}")
36
37    # Display custom entries
38    print("Custom entries:")
39    for key, value in metadata.custom_entries.items():
40        print(f"  - {key}: {value}")

List Signatures in PDF

Download code sample
1// Open input document
2pInStream = _tfopen(szInPath, _T("rb"));
3GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
4PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
5pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
6GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"),
7                                 szInPath, szErrorBuff, Ptx_GetLastError());
8
9// Get signatures of input PDF
10pSignatureFields = PtxPdf_Document_GetSignatureFields(pInDoc);
11GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pSignatureFields,
12                                 _T("Failed to get signatures of input PDF. %s (ErrorCode: 0x%08x).\n"),
13                                 szErrorBuff, Ptx_GetLastError());
14_tprintf(_T("Number of signature fields: %d\n"), PtxPdfForms_SignatureFieldList_GetCount(pSignatureFields));
15
16for (int i = 0; i < PtxPdfForms_SignatureFieldList_GetCount(pSignatureFields); i++)
17{
18    pSig = PtxPdfForms_SignatureFieldList_Get(pSignatureFields, i);
19    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pSig, _T("Failed to get signature. %s (ErrorCode: 0x%08x).\n"), szErrorBuff,
20                                     Ptx_GetLastError());
21
22    TPtxPdfForms_SignatureFieldType iFieldType = PtxPdfForms_SignatureField_GetType(pSig);
23    if (iFieldType == ePtxPdfForms_SignatureFieldType_Signature ||
24        iFieldType == ePtxPdfForms_SignatureFieldType_DocMdpSignature ||
25        iFieldType == ePtxPdfForms_SignatureFieldType_DocumentSignature)
26    {
27        // List name
28        size_t nName = PtxPdfForms_SignedSignatureField_GetName(pSig, NULL, 0);
29        _tprintf(_T("- %s fields"), PtxPdfForms_SignatureField_IsVisible(pSig) ? _T("Visible") : _T("Invisible"));
30        if (nName != 0)
31        {
32            TCHAR* szName = (TCHAR*)malloc(nName * sizeof(TCHAR));
33            if (szName != NULL)
34            {
35                PtxPdfForms_SignedSignatureField_GetName(pSig, szName, nName);
36                _tprintf(_T(", signed by: %s"), szName);
37                free(szName);
38            }
39        }
40        _tprintf(_T("\n"));
41
42        // List location
43        size_t nLocation = PtxPdfForms_Signature_GetLocation(pSig, NULL, 0);
44        if (nLocation != 0)
45        {
46            TCHAR* szLocation = (TCHAR*)malloc(nLocation * sizeof(TCHAR));
47            if (szLocation != NULL)
48            {
49                PtxPdfForms_Signature_GetLocation(pSig, szLocation, nLocation);
50                _tprintf(_T("  - Location: %s\n"), szLocation);
51                free(szLocation);
52            }
53        }
54
55        // List reason
56        size_t nReason = PtxPdfForms_Signature_GetReason(pSig, NULL, 0);
57        if (nReason != 0)
58        {
59            TCHAR* szReason = (TCHAR*)malloc(nReason * sizeof(TCHAR));
60            if (szReason != NULL)
61            {
62                PtxPdfForms_Signature_GetReason(pSig, szReason, nReason);
63                _tprintf(_T("  - Reason: %s\n"), szReason);
64                free(szReason);
65            }
66        }
67
68        // List contact info
69        size_t nContactInfo = PtxPdfForms_Signature_GetContactInfo(pSig, NULL, 0);
70        if (nContactInfo != 0)
71        {
72            TCHAR* szContactInfo = (TCHAR*)malloc(nContactInfo * sizeof(TCHAR));
73            if (szContactInfo != NULL)
74            {
75                PtxPdfForms_Signature_GetContactInfo(pSig, szContactInfo, nContactInfo);
76                _tprintf(_T("  - Contact info: %s\n"), szContactInfo);
77                free(szContactInfo);
78            }
79        }
80
81        // List date
82        if (PtxPdfForms_SignedSignatureField_GetDate(pSig, &date) == TRUE)
83        {
84            _tprintf(_T("  - Date: %02d-%02d-%d %02d:%02d:%02d%c%02d:%02d\n"), date.iYear, date.iMonth, date.iDay,
85                     date.iHour, date.iMinute, date.iSecond, date.iTZSign >= 0 ? '+' : '-', date.iTZHour,
86                     date.iTZMinute);
87        }
88    }
89    else
90    {
91        _tprintf(_T("- %s field, not signed\n"),
92                 PtxPdfForms_SignatureField_IsVisible(pSig) ? _T("Visible") : _T("Invisible"));
93    }
94}
95
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    SignatureFieldList signatureFields = inDoc.SignatureFields;
6    Console.WriteLine("Number of signature fields: {0}", signatureFields.Count);
7    foreach (SignatureField field in signatureFields)
8    {
9        if (field is Signature sig)
10        {
11            // List name
12            string name = sig.Name;
13            Console.WriteLine("- {0} fields, signed by: {1}",
14                sig.IsVisible ? "Visible" : "Invisible", name ?? "(Unknown name)");
15
16            // List location
17            string location = sig.Location;
18            if (location != null)
19                Console.WriteLine("  - Location: {0}", location);
20
21            // List reason 
22            string reason = sig.Reason;
23            if (reason != null)
24                Console.WriteLine("  - Reason: {0}", reason);
25
26            // List contact info
27            string contactInfo = sig.ContactInfo;
28            if (contactInfo != null)
29                Console.WriteLine("  - Contact info: {0}", contactInfo);
30
31            // List date
32            DateTimeOffset? date = sig.Date;
33            if (date != null)
34                Console.WriteLine("  - Date: {0}", date.Value);
35        }
36        else
37            Console.WriteLine("- {0} field, not signed", field.IsVisible ? "Visible" : "Invisible");
38    }
39}
40
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null)) {
4    SignatureFieldList signatureFields = inDoc.getSignatureFields();
5    System.out.format("Number of signature fields: %d\n", signatureFields.size());
6
7    for (SignatureField field : signatureFields) {
8        if (field instanceof Signature) {
9            Signature sig = (Signature)field;
10            // List name
11            String name = sig.getName();
12            System.out.format("- %s field, signed by: %s\n", sig.getIsVisible() ? "Visible" : "Invisible",
13                    name != null ? name : "(Unknown name)");
14
15            // List location
16            String location = sig.getLocation();
17            if (location != null)
18                System.out.format("  - Location: %s\n", location);
19
20            // List reason
21            String reason = sig.getReason();
22            if (reason != null)
23                System.out.format("  - Reason: %s\n", reason);
24
25            // List contact info
26            String contactInfo = sig.getContactInfo();
27            if (contactInfo != null)
28                System.out.format("  - Contact info: %s\n", contactInfo);
29
30            // List date
31            OffsetDateTime date = sig.getDate();
32            if (date != null)
33                System.out.format("  - Date: %s\n", date.toString());
34        } else {
35            System.out.format("- %s field, not signed\n", field.getIsVisible() ? "Visible" : "Invisible");
36        }
37    }
38}
39
Download code sample
1
2
3# Open input document
4with io.FileIO(input_file_path, "rb") as in_stream:
5    with Document.open(in_stream, None) as in_doc:
6        # List all signatures of the PDF document
7        list_signatures(in_doc)
8
1def list_signatures(in_doc: Document):
2    # Retrieve the list of signature fields
3    signature_fields = in_doc.signature_fields
4    print(f"Number of signature fields: {len(signature_fields)}")
5
6    for field in signature_fields:
7        if isinstance(field, Signature):
8            # List name
9            name = field.name or "(Unknown name)"
10            print(f"- {'Visible' if field.is_visible else 'Invisible'} field, signed by: {name}")
11
12            # List location
13            if field.location:
14                print(f"  - Location: {field.location}")
15
16            # List reason
17            if field.reason:
18                print(f"  - Reason: {field.reason}")
19
20            # List contact info
21            if field.contact_info:
22                print(f"  - Contact info: {field.contact_info}")
23
24            # List date
25            if field.date:
26                print(f"  - Date: {field.date}")
27        else:
28            print(f"- {'Visible' if field.is_visible else 'Invisible'} field, not signed")
Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    PrintOutlineItems(inDoc.Outline, "", inDoc);
6}
1static void PrintOutlineItem(OutlineItem item, string indentation, Document document)
2{
3    string title = item.Title;
4    Console.Out.Write("{0}{1}", indentation, title);
5    Destination dest = item.Destination;
6    if (dest != null)
7    {
8        int pageNumber = document.Pages.IndexOf(dest.Target.Page) + 1;
9        string dots = new string('.', 78 - indentation.Length - title.Length - pageNumber.ToString().Length);
10        Console.Out.Write(" {0} {1}", dots, pageNumber);
11    }
12    Console.Out.WriteLine();
13    PrintOutlineItems(item.Children, indentation + "  ", document);
14}
1static void PrintOutlineItems(OutlineItemList outlineItems, string indentation, Document document)
2{
3    foreach (var item in outlineItems)
4        PrintOutlineItem(item, indentation, document);
5}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null)) {
4    printOutlineItems(inDoc.getOutline(), "", inDoc);
5}
1static void printOutlineItem(OutlineItem item, String indentation, Document document) throws ToolboxException {
2    String title = item.getTitle();
3    System.out.format("%s%s", indentation, title);
4    Destination dest = item.getDestination();
5    if (dest != null) {
6        int pageNumber = document.getPages().indexOf(dest.getTarget().getPage()) + 1;
7        char[] dots = new char[78 - indentation.length() - title.length() - Integer.toString(pageNumber).length()];
8        Arrays.fill(dots, '.');
9        System.out.format(" %s %d", new String(dots), pageNumber);
10    }
11    System.out.println();
12    printOutlineItems(item.getChildren(), indentation + "  ", document);
13}
14
1static void printOutlineItems(OutlineItemList outlineItems, String indentation, Document document)
2        throws ToolboxException {
3    for (OutlineItem item : outlineItems)
4        printOutlineItem(item, indentation, document);
5}
Download code sample
1def print_outline_item(item: OutlineItem, indentation: str, in_doc: Document):
2    title = item.title
3    print(f"{indentation}{title}", end="")
4
5    dest = item.destination
6    if dest and dest.target:
7        page_number = in_doc.pages.index(dest.target.page) + 1
8        dots_length = max(0, 78 - len(indentation) - len(title) - len(str(page_number)))
9        dots = "." * dots_length
10        print(f" {dots} {page_number}", end="")
11
12    print()  # End the current line
13    print_outline_items(item.children, indentation + "  ", in_doc)
1def print_outline_items(items: OutlineItemList, indentation: str, in_doc: Document):
2    for outline_item in items:
3        print_outline_item(outline_item, indentation, in_doc);

Extract all text from PDF

Download code sample
1// Open input document
2using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
3using (Document inDoc = Document.Open(inStream, null))
4{
5    int pageNumber = 1;
6
7    // Process each page
8    foreach (var inPage in inDoc.Pages)
9    {
10        Console.WriteLine("==========");
11        Console.WriteLine($"Page: {pageNumber++}");
12        Console.WriteLine("==========");
13
14        ContentExtractor extractor = new ContentExtractor(inPage.Content);
15        extractor.Ungrouping = UngroupingSelection.All;
16
17        // Iterate over all content elements and only process text elements
18        foreach (ContentElement element in extractor)
19            if (element is TextElement textElement)
20                WriteText(textElement.Text);
21    }
22}
1private static void WriteText(Text text)
2{
3    string textPart = "";
4
5    // Write all text fragments
6    // Determine heuristically if there is a space between two text fragments
7    for (int iFragment = 0; iFragment < text.Count; iFragment++)
8    {
9
10        TextFragment currFragment = text[iFragment];
11        if (iFragment == 0)
12            textPart += currFragment.Text;
13        else
14        {
15            TextFragment lastFragment = text[iFragment - 1];
16            if (currFragment.CharacterSpacing != lastFragment.CharacterSpacing ||
17                currFragment.FontSize != lastFragment.FontSize ||
18                currFragment.HorizontalScaling != lastFragment.HorizontalScaling ||
19                currFragment.Rise != lastFragment.Rise ||
20                currFragment.WordSpacing != lastFragment.WordSpacing)
21                textPart += $" {currFragment.Text}";
22            else
23            {
24                Point currentBotLeft = currFragment.Transform.TransformRectangle(currFragment.BoundingBox).BottomLeft;
25                Point beforeBotRight = lastFragment.Transform.TransformRectangle(lastFragment.BoundingBox).BottomRight;
26
27                if (beforeBotRight.X < currentBotLeft.X - 0.7 * currFragment.FontSize ||
28                    beforeBotRight.Y < currentBotLeft.Y - 0.1 * currFragment.FontSize ||
29                    currentBotLeft.Y < beforeBotRight.Y - 0.1 * currFragment.FontSize)
30                    textPart += $" {currFragment.Text}";
31                else
32                    textPart += currFragment.Text;
33            }
34        }
35    }
36    Console.WriteLine(textPart);
37}
Download code sample
1try (// Open input document
2    FileStream inStream = new FileStream(inPath, FileStream.Mode.READ_ONLY);
3    Document inDoc = Document.open(inStream, null)) {
4    int pageNumber = 1;
5
6    // Process each page
7    for (Page inPage : inDoc.getPages()) {
8        System.out.println("==========");
9        System.out.println("Page: " + pageNumber++);
10        System.out.println("==========");
11
12        ContentExtractor extractor = new ContentExtractor(inPage.getContent());
13        extractor.setUngrouping(UngroupingSelection.ALL);
14
15        // Iterate over all content elements and only process text elements
16        for (ContentElement element : extractor) {
17            if (element instanceof TextElement)
18                writeText(((TextElement) element).getText());
19        }
20    }
21}
1private static void writeText(Text text) {
2    String textPart = "";
3
4    // Write all text fragments
5    // Determine heuristically if there is a space between two text fragments
6    for (int iFragment = 0; iFragment < text.size(); iFragment++) {
7        TextFragment currFragment = text.get(iFragment);
8        if (iFragment == 0)
9            textPart += currFragment.getText();
10        else {
11            TextFragment lastFragment = text.get(iFragment - 1);
12            if (currFragment.getCharacterSpacing() != lastFragment.getCharacterSpacing() ||
13                currFragment.getFontSize() != lastFragment.getFontSize() ||
14                currFragment.getHorizontalScaling() != lastFragment.getHorizontalScaling() ||
15                currFragment.getRise() != lastFragment.getRise() ||
16                currFragment.getWordSpacing() != lastFragment.getWordSpacing()) {
17                textPart += " ";
18                textPart += currFragment.getText();
19            }
20            else {
21                Point currentBotLeft = currFragment.getTransform().transformRectangle(currFragment.getBoundingBox()).getBottomLeft();
22                Point beforeBotRight = lastFragment.getTransform().transformRectangle(lastFragment.getBoundingBox()).getBottomRight();
23
24                if (beforeBotRight.getX() < currentBotLeft.getX() - 0.7 * currFragment.getFontSize() ||
25                    beforeBotRight.getY() < currentBotLeft.getY() - 0.1 * currFragment.getFontSize() ||
26                    currentBotLeft.getY() < beforeBotRight.getY() - 0.1 * currFragment.getFontSize()) {
27                    textPart += " ";
28                    textPart += currFragment.getText();
29                }
30                else
31                    textPart += currFragment.getText();
32            }
33        }
34    }
35    System.out.println(textPart);
36}
Download code sample
1
2
3# Open input document
4with open(input_path, "rb") as in_stream:
5    with Document.open(in_stream, None) as in_doc:
6        page_number = 1
7
8        # Process each page
9        for in_page in in_doc.pages:
10            print(f"==========\nPage: {page_number}\n==========")
11
12            extractor = ContentExtractor(in_page.content)
13            extractor.ungrouping = UngroupingSelection.ALL
14
15            # Iterate over all content elements and only process text elements
16            for element in extractor:
17                if isinstance(element, TextElement):
18                    write_text(element.text)
19
20            page_number += 1
21
1def write_text(text: Text):
2    """Reconstruct text heuristically from text fragments."""
3    text_part = []
4
5    # Write all text fragments
6    # Determine heuristically if there is a space between two text fragments
7    for i_fragment, curr_fragment in enumerate(text):
8        if i_fragment == 0:
9            text_part.append(curr_fragment.text)
10        else:
11            last_fragment = text[i_fragment - 1]
12
13            # Determine if there's a space between fragments
14            if (curr_fragment.character_spacing != last_fragment.character_spacing or
15                curr_fragment.font_size != last_fragment.font_size or
16                curr_fragment.horizontal_scaling != last_fragment.horizontal_scaling or
17                curr_fragment.rise != last_fragment.rise or
18                curr_fragment.word_spacing != last_fragment.word_spacing):
19                text_part.append(f" {curr_fragment.text}")
20            else:
21                current_bot_left = curr_fragment.transform.transform_rectangle(curr_fragment.bounding_box).bottom_left
22                before_bot_right = last_fragment.transform.transform_rectangle(last_fragment.bounding_box).bottom_right
23
24                if (before_bot_right.x < current_bot_left.x - 0.7 * curr_fragment.font_size or
25                    before_bot_right.y < current_bot_left.y - 0.1 * curr_fragment.font_size or
26                    current_bot_left.y < before_bot_right.y - 0.1 * curr_fragment.font_size):
27                    text_part.append(f" {curr_fragment.text}")
28                else:
29                    text_part.append(curr_fragment.text)
30
31    print("".join(text_part))