Skip to main content
Version: Version 1.7

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

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

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

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

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

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 do 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

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

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 horizontel 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

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 textinput 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

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
1# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_descriptor, "")
5    if not input_document:
6        print(f"Input file {input_file_path} cannot be opened.")
7        exit(1)
8
9    # Create output document
10    with io.FileIO(output_file_path, 'wb+') as output_file:
11        output_descriptor = StreamDescriptor(output_file)
12        conformance = pdf_document_getconformance(input_document)
13        output_document = pdf_document_create(output_descriptor, conformance, None)
14        if not output_document:
15            print(f"Output file {output_file_path} cannot be created.")
16            exit(1)
17
18        # Create embedded font in output document
19        font = pdfcontent_font_createfromsystem(output_document, "Arial", "Italic", True)
20        if not font:
21            print("Failed to create font.")
22            exit(1)
23
24        # Copy document-wide data
25        if not copy_document_data(input_document, output_document):
26            print("Failed to copy document-wide data.")
27            exit(1)
28
29        # Configure copy options
30        copy_options = pdf_pagecopyoptions_new()
31
32        # Get page lists of input and output document
33        input_page_list = pdf_document_getpages(input_document)
34        if not input_page_list:
35            print("Failed to get the pages of the input document.")
36            exit(1)
37        output_page_list = pdf_document_getpages(output_document)
38        if not output_page_list:
39            print("Failed to get the pages of the output document.")
40            exit(1)
41
42        # Copy first page
43        input_page = pdf_pagelist_get(input_page_list, 0)
44        if not input_page:
45            print("Failed to get the first page.")
46            exit(1)
47        output_page = pdf_page_copy(output_document, input_page, copy_options)
48        if not output_page:
49            print("Failed to copy page.")
50            exit(1)
51
52        # Add text to copied page
53        if add_text(output_document, output_page, text_string, font, 15) != 0:
54            exit(1)
55
56        # Add page to output document
57        if not pdf_pagelist_add(output_page_list, output_page):
58            print("Failed to add page to output document.")
59            exit(1)
60
61        # Get remaining pages from input
62        input_page_range = pdf_pagelist_getrange(input_page_list, 1, pdf_pagelist_getcount(input_page_list) - 1)
63        if not input_page_range:
64            print("Failed to get page range from input document.")
65            exit(1)
66
67        # Copy remaining pages to output
68        output_page_range = pdf_pagelist_copy(output_document, input_page_range, copy_options)
69        if not output_page_range:
70            print("Failed to copy page range to output document.")
71            exit(1)
72
73        # Add the copied pages to the output document
74        if not pdf_pagelist_addrange(output_page_list, output_page_range):
75            print("Failed to add page range to output page list.")
76            exit(1)
77
78        pdf_document_close(output_document)
79    pdf_document_close(input_document)
80
1def copy_document_data(in_doc, out_doc):
2    # Copy document-wide data (excluding metadata)
3
4    # Output intent
5    if pdf_document_getoutputintent(in_doc) is not None:
6        if not pdf_document_setoutputintent(out_doc, pdfcontent_iccbasedcolorspace_copy(out_doc, pdf_document_getoutputintent(in_doc))):
7            return False
8
9    # Metadata
10    if not pdf_document_setmetadata(out_doc, pdf_metadata_copy(out_doc, pdf_document_getmetadata(in_doc))):
11        return False
12
13    # Viewer settings
14    if not pdf_document_setviewersettings(out_doc, pdfnav_viewersettings_copy(out_doc, pdf_document_getviewersettings(in_doc))):
15        return False
16
17    # Associated files (for PDF/A-3 and PDF 2.0 only)
18    in_file_ref_list = pdf_document_getassociatedfiles(in_doc)
19    out_file_ref_list = pdf_document_getassociatedfiles(out_doc)
20    if in_file_ref_list is None or out_file_ref_list is None:
21        return False
22    for i in range(pdf_filereferencelist_getcount(in_file_ref_list)):
23        file_ref = pdf_filereference_copy(out_doc, pdf_filereferencelist_get(in_file_ref_list, i))
24        if not pdf_filereferencelist_add(out_file_ref_list, file_ref):
25            return False
26
27    # Plain embedded files
28    in_file_ref_list = pdf_document_getplainembeddedfiles(in_doc)
29    out_file_ref_list = pdf_document_getplainembeddedfiles(out_doc)
30    if in_file_ref_list is None or out_file_ref_list is None:
31        return False
32    for i in range(pdf_filereferencelist_getcount(in_file_ref_list)):
33        file_ref = pdf_filereference_copy(out_doc, pdf_filereferencelist_get(in_file_ref_list, i))
34        if not pdf_filereferencelist_add(out_file_ref_list, file_ref):
35            return False
36
37    return True
38
1def add_text(out_doc, out_page, text_string, font, font_size):
2    border = 40.0
3    try:
4        content = pdf_page_getcontent(out_page)
5        if not content:
6            print("Failed to get content of output file.")
7            return 1
8
9        # Create content generator
10        generator = pdfcontent_contentgenerator_new(content, False)
11        if not generator:
12            print("Failed to create a content generator.")
13            return 1
14
15        # Create text object
16        text = pdfcontent_text_create(out_doc)
17        if not text:
18            print("Failed to create text object.")
19            return 1
20
21        # Create a text generator
22        text_generator = pdfcontent_textgenerator_new(text, font, font_size, None)
23        if not text_generator:
24            print("Failed to create a text generator.")
25            return 1
26
27        # Get output page size
28        size = GeomRealSize()
29        if not pdf_page_getsize(out_page, size):
30            print("Failed to read page size.")
31            return 1
32
33        font_ascent = pdfcontent_font_getascent(font)
34        if font_ascent == 0.0:
35            print("Failed to get font ascent.")
36            return 1
37
38        # Calculate position
39        position = GeomRealPoint()
40        position.x = border
41        position.y = size.height - border - font_size * font_ascent
42
43        # Move to position
44        if not pdfcontent_textgenerator_moveto(text_generator, position):
45            print("Failed to move to position.")
46            return 1
47
48        # Add given text string
49        if not pdfcontent_textgenerator_showline(text_generator, text_string):
50            print("Failed to add text string.")
51            return 1
52
53        # Close text generator
54        pdfcontent_textgenerator_close(text_generator)
55        text_generator = None
56
57        # Paint the positioned text
58        if not pdfcontent_contentgenerator_painttext(generator, text):
59            print("Failed to paint the positioned text.")
60            return 1
61
62    except Exception as e:
63        print(f"An error occurred: {e}")
64        return 1
65    finally:
66        if text_generator:
67            pdfcontent_textgenerator_close(text_generator)
68        if text:
69            release(text)
70        if generator:
71            pdfcontent_contentgenerator_close(generator)
72        if content:
73            release(content)
74
75    return 0
76
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

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 throw 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 throw 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

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

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

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

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

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(_inputPath);
36
37        try
38        {
39            using var inpath = File.OpenRead(_inputPath);
40            using var inDocumentToolbox = Document.Open(inpath, _pdfPassword);
41
42            isValid &= ValidateConformance(inDocumentToolbox.Conformance);
43            isValid &= ValidateEncryption(inDocumentToolbox.Permissions);
44            isValid &= ValidatePagesSize(inDocumentToolbox);
45            isValid &= ValidateFonts(inDocumentToolbox);
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(string inputPath)
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 inDocToolbox)
134    {
135        var isValid = true;
136
137        if (_iniMaxPageSize != null)
138        {
139            var pageNumber = 0;
140            foreach (var page in inDocToolbox.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 inDocumentToolbox)
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 inDocumentToolbox.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 inDocToolbox = Document.open(inStream, pdfPassword)) {
36
37                isValid &= validateConformance(inDocToolbox.getConformance());
38                isValid &= validateEncryption(inDocToolbox.getPermissions());
39                isValid &= validatePagesSize(inDocToolbox);
40                isValid &= validateFonts(inDocToolbox);
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 inDocToolbox) {
104            boolean isValid = true;
105
106            if (iniMaxPageSize != null) {
107                int pageNumber = 0;
108                for (Page page : inDocToolbox.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 inDocumentToolbox) 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 : inDocumentToolbox.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

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            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
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        if (args.length == 3) {
19            Metadata mdata;
20
21            // Add metadata from a input file
22            FileStream metaStream = new FileStream(mdatafile, FileStream.Mode.READ_ONLY);
23
24            if (mdatafile.toLowerCase().endsWith(".pdf")) {
25                // Use the metadata of another PDF file
26                Document metaDoc = Document.open(metaStream, null);
27                mdata = Metadata.copy(outDoc, metaDoc.getMetadata());
28            } else {
29                // Use the content of an XMP metadata file
30                mdata = Metadata.create(outDoc, metaStream);
31            }
32            outDoc.setMetadata(mdata);
33        } else {
34            // Set some metadata properties
35            Metadata metadata = outDoc.getMetadata();
36            metadata.setAuthor("Your Author");
37            metadata.setTitle("Your Title");
38            metadata.setSubject("Your Subject");
39            metadata.setCreator("Your Creator");
40        }
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# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_descriptor, "")
5    if not input_document:
6        print(f"Input file {input_file_path} cannot be opened.")
7        exit(1)
8
9    # Create output document
10    with io.FileIO(output_file_path, 'wb+') as output_file:
11        output_descriptor = StreamDescriptor(output_file)
12        conformance = pdf_document_getconformance(input_document)
13        output_document = pdf_document_create(output_descriptor, conformance, None)
14        if not output_document:
15            print(f"Output file {output_file_path} cannot be created.")
16            exit(1)
17
18        # Copy document-wide data
19        if not copy_document_data(input_document, output_document):
20            print("Failed to copy document-wide data.")
21            exit(1)
22
23        # Configure copy options
24        copy_options = pdf_pagecopyoptions_new()
25
26        # Copy all pages
27        input_page_list = pdf_document_getpages(input_document)
28        if not input_page_list:
29            print("Failed to get pages of the input document.")
30            exit(1)
31
32        copied_pages = pdf_pagelist_copy(output_document, input_page_list, copy_options)
33        if not copied_pages:
34            print("Failed to copy pages.")
35            exit(1)
36
37        # Add copied pages to output
38        output_page_list = pdf_document_getpages(output_document)
39        if not output_page_list:
40            print("Failed to get pages of the output document.")
41            exit(1)
42
43        if not pdf_pagelist_addrange(output_page_list, copied_pages):
44            print("Failed to add copied pages to output.")
45            exit(1)
46
47        if metadata_file_path:
48            # Add metadata from a input file
49            with io.FileIO(metadata_file_path, 'rb') as metadata_file:
50                metadata_descriptor = StreamDescriptor(metadata_file)
51
52                # Get file extension
53                ext = metadata_file_path.split('.')[-1]
54
55                if ext == 'pdf':
56                    # Use the metadata of another PDF file
57                    meta_doc = pdf_document_open(metadata_descriptor, "")
58                    if not meta_doc:
59                        print("Failed to open metadata file.")
60                        exit(1)
61
62                    metadata = pdf_metadata_copy(output_document, pdf_document_getmetadata(meta_doc))
63                    if not metadata or not pdf_document_setmetadata(output_document, metadata):
64                        print("Failed to copy metadata.")
65                        exit(1)
66                else:
67                    # Use the content of an XMP metadata file
68                    if not pdf_document_setmetadata(output_document, pdf_metadata_create(output_document, metadata_descriptor)):
69                        print("Failed to set metadata.")
70                        exit(1)
71        else:
72            # Set some metadata properties
73            metadata = pdf_document_getmetadata(output_document)
74            if not metadata:
75                print("Failed to get metadata.")
76                exit(1)
77
78            if not pdf_metadata_setauthor(metadata, "Your Author") or \
79               not pdf_metadata_settitle(metadata, "Your Title") or \
80               not pdf_metadata_setsubject(metadata, "Your Subject") or \
81               not pdf_metadata_setcreator(metadata, "Your Creator"):
82                print("Failed to set metadata properties.")
83                exit(1)
84
85        pdf_document_close(output_document)
86    pdf_document_close(input_document)
87
1def copy_document_data(in_doc, out_doc):
2    # Copy document-wide data (excluding metadata)
3    in_file_ref_list = pdf_document_getassociatedfiles(in_doc)
4    out_file_ref_list = pdf_document_getassociatedfiles(out_doc)
5
6    if not in_file_ref_list or not out_file_ref_list:
7        return False
8
9    for i in range(pdf_filereferencelist_getcount(in_file_ref_list)):
10        file_ref = pdf_filereference_copy(out_doc, pdf_filereferencelist_get(in_file_ref_list, i))
11        if not pdf_filereferencelist_add(out_file_ref_list, file_ref):
12            return False
13
14    in_file_ref_list = pdf_document_getplainembeddedfiles(in_doc)
15    out_file_ref_list = pdf_document_getplainembeddedfiles(out_doc)
16
17    if not in_file_ref_list or not out_file_ref_list:
18        return False
19
20    for i in range(pdf_filereferencelist_getcount(in_file_ref_list)):
21        file_ref = pdf_filereference_copy(out_doc, pdf_filereferencelist_get(in_file_ref_list, i))
22        if not pdf_filereferencelist_add(out_file_ref_list, file_ref):
23            return False
24
25    return True
26
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

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

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    // Creat 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

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

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

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        Size size = inPage.Size;
36        Page outPage = Page.Copy(outDoc, inPage, copyOptions);
37
38        // Create a content generator
39        using (ContentGenerator generator = new ContentGenerator(outPage.Content, false))
40        {
41            // Compute Rectangle
42            Rectangle rect = new Rectangle
43            {
44                Left = 0,
45                Bottom = 0,
46                Right = size.Width,
47                Top = size.Height
48            };
49
50            // Make a rectangular path the same size as the page
51            PdfTools.Toolbox.Pdf.Content.Path path = new PdfTools.Toolbox.Pdf.Content.Path();
52            using (PathGenerator pathGenerator = new PathGenerator(path))
53            {
54                Rectangle pathRect = new Rectangle
55                {
56                    Left = 0,
57                    Bottom = 0,
58                    Right = size.Width,
59                    Top = size.Height
60                };
61                pathGenerator.AddRectangle(pathRect);
62            }
63            // Paint the path with the transparent paint
64            generator.PaintPath(path, fill, null);
65        }
66        // Add pages to output document
67        outPages.Add(outPage);
68    }
69}
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

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

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

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

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

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

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

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# Open input document
2with io.FileIO(input_file_path, 'rb') as input_file:
3    input_descriptor = StreamDescriptor(input_file)
4    input_document = pdf_document_open(input_descriptor, "")
5    if not input_document:
6        print(f"Input file {input_file_path} cannot be opened.")
7        exit(1)
8
9    # Create output document
10    with io.FileIO(output_file_path, 'wb+') as output_file:
11        output_descriptor = StreamDescriptor(output_file)
12        conformance = pdf_document_getconformance(input_document)
13        output_document = pdf_document_create(output_descriptor, conformance, None)
14        if not output_document:
15            print(f"Output file {output_file_path} cannot be created.")
16            exit(1)
17
18        # Copy document-wide data
19        if not copy_document_data(input_document, output_document):
20            print("Failed to copy document-wide data.")
21            exit(1)
22
23        # Configure copy options
24        copy_options = pdf_pagecopyoptions_new()
25
26        # Get page lists of input and output document
27        input_page_list = pdf_document_getpages(input_document)
28        if not input_page_list:
29            print("Failed to get the pages of the input document.")
30            exit(1)
31        output_page_list = pdf_document_getpages(output_document)
32        if not output_page_list:
33            print("Failed to get the pages of the output document.")
34            exit(1)
35
36        page_count = 0
37        generator = None
38        output_page = None
39        for page in range(pdf_pagelist_getcount(input_page_list)):
40            input_page = pdf_pagelist_get(input_page_list, page)
41
42            if page_count == nx * ny:
43                # Add to output document
44                pdfcontent_contentgenerator_close(generator)
45                if not pdf_pagelist_add(output_page_list, output_page):
46                    print("Failed to add page to output document.")
47                    exit(1)
48                release(output_page)
49                output_page = None
50                page_count = 0
51
52            if output_page is None:
53                # Create a new output page
54                output_page = pdf_page_create(output_document, page_size)
55                if not output_page:
56                    print("Failed to create a new output page.")
57                    exit(1)
58                content = pdf_page_getcontent(output_page)
59                generator = pdfcontent_contentgenerator_new(content, False)
60                if not generator:
61                    print("Failed to create content generator.")
62                    exit(1)
63
64            # Get area where group has to be
65            x = page_count % nx
66            y = ny - (page_count // nx) - 1
67
68            # Calculate cell size
69            cell_width = (page_size.width - ((nx + 1) * border)) / nx
70            cell_height = (page_size.height - ((ny + 1) * border)) / ny
71
72            # Calculate cell position
73            cell_x = border + x * (cell_width + border)
74            cell_y = border + y * (cell_height + border)
75
76            # Copy page group from input to output
77            group = pdfcontent_group_copyfrompage(output_document, input_page, copy_options)
78            if not group:
79                print("Failed to copy page group from input to output.")
80                exit(1)
81
82            # Calculate group position
83            group_size = GeomRealSize()
84            if not pdfcontent_group_getsize(group, group_size):
85                print("Failed to get group size.")
86                exit(1)
87            scale = min(cell_width / group_size.width, cell_height / group_size.height)
88
89            # Calculate target size
90            target_width = group_size.width * scale
91            target_height = group_size.height * scale
92
93            # Calculate position
94            target_x = cell_x + ((cell_width - target_width) / 2)
95            target_y = cell_y + ((cell_height - target_height) / 2)
96
97            # Calculate rectangle
98            target_rect = GeomRealRectangle()
99            target_rect.left = target_x
100            target_rect.bottom = target_y
101            target_rect.right = target_x + target_width
102            target_rect.top = target_y + target_height
103
104            # Add group to page
105            if not pdfcontent_contentgenerator_paintgroup(generator, group, target_rect, None):
106                print("Failed to paint the group.")
107                exit(1)
108
109            if group:
110                release(group)
111                group = None
112            if input_page:
113                release(input_page)
114                input_page = None
115
116            page_count += 1
117
118        # Add partially filled page
119        if output_page:
120            pdfcontent_contentgenerator_close(generator)
121            if not pdf_pagelist_add(output_page_list, output_page):
122                print("Failed to add page to output document.")
123                exit(1)
124            release(output_page)
125
126        pdf_document_close(output_document)
127    pdf_document_close(input_document)
128
1def copy_document_data(in_doc, out_doc):
2    # Copy document-wide data (excluding metadata)
3
4    # Output intent
5    if pdf_document_getoutputintent(in_doc) is not None:
6        if not pdf_document_setoutputintent(out_doc, pdfcontent_iccbasedcolorspace_copy(out_doc, pdf_document_getoutputintent(in_doc))):
7            return False
8
9    # Metadata
10    if not pdf_document_setmetadata(out_doc, pdf_metadata_copy(out_doc, pdf_document_getmetadata(in_doc))):
11        return False
12
13    # Viewer settings
14    if not pdf_document_setviewersettings(out_doc, pdfnav_viewersettings_copy(out_doc, pdf_document_getviewersettings(in_doc))):
15        return False
16
17    # Associated files (for PDF/A-3 and PDF 2.0 only)
18    in_file_ref_list = pdf_document_getassociatedfiles(in_doc)
19    out_file_ref_list = pdf_document_getassociatedfiles(out_doc)
20    if in_file_ref_list is None or out_file_ref_list is None:
21        return False
22    for i in range(pdf_filereferencelist_getcount(in_file_ref_list)):
23        file_ref = pdf_filereference_copy(out_doc, pdf_filereferencelist_get(in_file_ref_list, i))
24        if not pdf_filereferencelist_add(out_file_ref_list, file_ref):
25            return False
26
27    # Plain embedded files
28    in_file_ref_list = pdf_document_getplainembeddedfiles(in_doc)
29    out_file_ref_list = pdf_document_getplainembeddedfiles(out_doc)
30    if in_file_ref_list is None or out_file_ref_list is None:
31        return False
32    for i in range(pdf_filereferencelist_getcount(in_file_ref_list)):
33        file_ref = pdf_filereference_copy(out_doc, pdf_filereferencelist_get(in_file_ref_list, i))
34        if not pdf_filereferencelist_add(out_file_ref_list, file_ref):
35            return False
36
37    return True
38
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

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

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

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

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

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, _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// 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, null))
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

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// 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

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