Skip to main content
Version: Version 1.8

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

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
Download code sample

Update annotations to PDF

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)
Download code sample

Annotations and Form Fields

Add Form Field

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))
Download code sample

Fill Form Fields

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
Download code sample

Content Addition

Add barcode to PDF

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)
Download code sample

Add Data Matrix to PDF

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(x=border, y=page.size.height - (data_matrix_size + border), width=data_matrix_size + border, height=page.size.height - border)
16
17        # Paint the positioned barcode text
18        generator.paint_image(data_matrix, rect)
Download code sample

Add image to PDF

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)
Download code sample

Add image mask to PDF

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)
Download code sample

Add line numbers to PDF

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)
Download code sample

Add stamp to PDF

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)
Download code sample

Add text to PDF

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)
Download code sample

Add vector graphic to PDF

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)
Download code sample

Layout text on PDF page

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)
Download code sample

Stamp page number to PDF

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)
Download code sample

Content Modification

Remove glyphs

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)
Download code sample

Remove White Text from PDF

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)
Download code sample

Replace Text Fragment in PDF

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)
Download code sample

Custom Validation

Validate custom properties of a PDF file

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}")
Download code sample

Document Setup

Add metadata to PDF

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))
Download code sample

Encrypt PDF

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))
Download code sample

Flatten form fields in PDF

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))
Download code sample

Merge multiple PDFs and create a table of contents page

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
Download code sample

Merge multiple PDFs

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
Download code sample

Merge multiple PDFs with outlines

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
Download code sample

Overlay color of PDF

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)
Download code sample

Add info entries to PDF

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))
Download code sample

Set the open-destination of a PDF

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))
Download code sample

Remove pages from PDF

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))
Download code sample

Split at Outlines

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
Download code sample

Imposition

Create a booklet from PDF

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)
Download code sample

Fit pages to specific page format

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)
Download code sample

Place multiple pages on one page

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))
Download code sample

Set page orientation

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))
Download code sample

Information Extraction

Embed files into a PDF

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)
Download code sample

Extract files embedded from a PDF

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)
Download code sample

Extract all images and image masks from a PDF

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}")
Download code sample

List bounds of page content

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}")
Download code sample

List document information of PDF

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}")
Download code sample

List Signatures in PDF

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);
Download code sample

Extract all text from PDF

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
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))
Download code sample