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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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
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}
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}
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}
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}
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}
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}
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}
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}
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
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
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
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
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
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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}
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
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
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
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
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
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
Print a table of content
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}
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}
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}
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}