Aperçu d'exemples
Annotations
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
// Create output document
using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page and add annotations
Page outPage = CopyAndAddAnnotations(outDoc, inDoc.Pages[0], copyOptions);
// Add the page to the output document's page list
outDoc.Pages.Add(outPage);
// Copy the remaining pages and add to the output document's page list
PageList inPages = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList outPages = PageList.Copy(outDoc, inPages, copyOptions);
outDoc.Pages.AddRange(outPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static Page CopyAndAddAnnotations(Document outDoc, Page inPage, PageCopyOptions copyOptions)
{
// Copy page to output document
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// Make a RGB color space
ColorSpace rgb = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
// Get the page size for positioning annotations
Size pageSize = outPage.Size;
// Get the output page's list of annotations for adding annotations
AnnotationList annotations = outPage.Annotations;
// Create a sticky note and add to output page's annotations
Paint green = Paint.Create(outDoc, rgb, new double[] { 0, 1, 0 }, null);
Point stickyNoteTopLeft = new Point() { X = 10, Y = pageSize.Height - 10 };
StickyNote stickyNote = StickyNote.Create(outDoc, stickyNoteTopLeft, "Hello world!", green);
annotations.Add(stickyNote);
// Create an ellipse and add to output page's annotations
Paint blue = Paint.Create(outDoc, rgb, new double[] { 0, 0, 1 }, null);
Paint yellow = Paint.Create(outDoc, rgb, new double[] { 1, 1, 0 }, null);
Rectangle ellipseBox = new Rectangle() { Left = 10, Bottom = pageSize.Height - 60, Right = 70, Top = pageSize.Height - 20 };
EllipseAnnotation ellipse = EllipseAnnotation.Create(outDoc, ellipseBox, new Stroke(blue, 1.5), yellow);
annotations.Add(ellipse);
// Create a free text and add to output page's annotations
Paint yellowTransp = Paint.Create(outDoc, rgb, new double[] { 1, 1, 0 }, new Transparency(0.5));
Rectangle freeTextBox = new Rectangle() { Left = 10, Bottom = pageSize.Height - 170, Right = 120, Top = pageSize.Height - 70 };
FreeText freeText = FreeText.Create(outDoc, freeTextBox, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", yellowTransp);
annotations.Add(freeText);
// A highlight and a web-link to be fitted on existing page content elements
Highlight highlight = null;
WebLink webLink = null;
// Extract content elements from the input page
ContentExtractor extractor = new ContentExtractor(inPage.Content);
foreach (ContentElement element in extractor)
{
// Take the first text element
if (highlight == null && element is TextElement textElement)
{
// Get the quadrilaterals of this text element
QuadrilateralList quadrilaterals = new QuadrilateralList();
foreach (TextFragment fragment in textElement.Text)
quadrilaterals.Add(fragment.Transform.TransformRectangle(fragment.BoundingBox));
// Create a highlight and add to output page's annotations
highlight = Highlight.CreateFromQuadrilaterals(outDoc, quadrilaterals, yellow);
annotations.Add(highlight);
}
// Take the first image element
if (webLink == null && element is ImageElement)
{
// Get the quadrilateral of this image
QuadrilateralList quadrilaterals = new QuadrilateralList();
quadrilaterals.Add(element.Transform.TransformRectangle(element.BoundingBox));
// Create a web-link and add to the output page's links
webLink = WebLink.CreateFromQuadrilaterals(outDoc, quadrilaterals, "https://www.pdf-tools.com");
Paint red = Paint.Create(outDoc, rgb, new double[] { 1, 0, 0 }, null);
webLink.BorderStyle = new Stroke(red, 1.5);
outPage.Links.Add(webLink);
}
// Exit loop if highlight and webLink have been created
if (highlight != null && webLink != null)
break;
}
// return the finished page
return outPage;
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
// Create file stream
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page and add annotations
Page outPage = copyAndAddAnnotations(outDoc, inDoc.getPages().get(0), copyOptions);
// Add the page to the output document's page list
outDoc.getPages().add(outPage);
// Copy the remaining pages and add to the output document's page list
PageList inPages = inDoc.getPages().subList(1, inDoc.getPages().size());
PageList outPages = PageList.copy(outDoc, inPages, copyOptions);
outDoc.getPages().addAll(outPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static Page copyAndAddAnnotations(Document outDoc, Page inPage, PageCopyOptions copyOptions) throws ConformanceException, CorruptException, IOException, UnsupportedFeatureException {
// Copy page to output document
Page outPage = Page.copy(outDoc, inPage, copyOptions);
// Make a RGB color space
ColorSpace rgb = ColorSpace.createProcessColorSpace(outDoc, ProcessColorSpaceType.RGB);
// Get the page size for positioning annotations
Size pageSize = outPage.getSize();
// Get the output page's list of annotations for adding annotations
AnnotationList annotations = outPage.getAnnotations();
// Create a sticky note and add to output page's annotations
Paint green = Paint.create(outDoc, rgb, new double[] { 0, 1, 0 }, null);
Point stickyNoteTopLeft = new Point(10, pageSize.height - 10 );
StickyNote stickyNote = StickyNote.create(outDoc, stickyNoteTopLeft, "Hello world!", green);
annotations.add(stickyNote);
// Create an ellipse and add to output page's annotations
Paint blue = Paint.create(outDoc, rgb, new double[] { 0, 0, 1 }, null);
Paint yellow = Paint.create(outDoc, rgb, new double[] { 1, 1, 0 }, null);
Rectangle ellipseBox = new Rectangle(10, pageSize.height - 60, 70, pageSize.height - 20);
EllipseAnnotation ellipse = EllipseAnnotation.create(outDoc, ellipseBox, new Stroke(blue, 1.5), yellow);
annotations.add(ellipse);
// Create a free text and add to output page's annotations
Paint yellowTransp = Paint.create(outDoc, rgb, new double[] { 1, 1, 0 }, new Transparency(0.5));
Rectangle freeTextBox = new Rectangle(10, pageSize.height - 170, 120, pageSize.height - 70);
FreeText freeText = FreeText.create(outDoc, freeTextBox, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", yellowTransp);
annotations.add(freeText);
// A highlight and a web-link to be fitted on existing page content elements
Highlight highlight = null;
WebLink webLink = null;
// Extract content elements from the input page
ContentExtractor extractor = new ContentExtractor(inPage.getContent());
for (ContentElement element : extractor) {
// Take the first text element
if (highlight == null && element instanceof TextElement) {
TextElement textElement = (TextElement)element;
// Get the quadrilaterals of this text element
QuadrilateralList quadrilaterals = new QuadrilateralList();
for (TextFragment fragment : textElement.getText())
quadrilaterals.add(fragment.getTransform().transformRectangle(fragment.getBoundingBox()));
// Create a highlight and add to output page's annotations
highlight = Highlight.createFromQuadrilaterals(outDoc, quadrilaterals, yellow);
annotations.add(highlight);
}
// Take the first image element
if (webLink == null && element instanceof ImageElement) {
// Get the quadrilateral of this image
QuadrilateralList quadrilaterals = new QuadrilateralList();
quadrilaterals.add(element.getTransform().transformRectangle(element.getBoundingBox()));
// Create a web-link and add to the output page's links
webLink = WebLink.createFromQuadrilaterals(outDoc, quadrilaterals, "https://www.pdf-tools.com");
Paint red = Paint.create(outDoc, rgb, new double[] { 1, 0, 0 }, null);
webLink.setBorderStyle(new Stroke(red, 1.5));
outPage.getLinks().add(webLink);
}
// Exit loop if highlight and webLink have been created
if (highlight != null && webLink != null)
break;
}
// return the finished page
return outPage;
}
Java sample:
Content Addition
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create file stream
using (Stream fontStream = new FileStream(fontPath, FileMode.Open, FileAccess.Read))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Create embedded font in output document
Font font = Font.Create(outDoc, fontStream, true);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page, add barcode, and append to output document
Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
AddBarcode(outDoc, outPage, barcode, font, 50);
outDoc.Pages.Add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddBarcode(Document outputDoc, Page outPage, string barcode,
Font font, double fontSize)
{
// Create content generator
using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
// Create text object
Text barcodeText = Text.Create(outputDoc);
// Create text generator
using (TextGenerator textGenerator = new TextGenerator(barcodeText, font, fontSize, null))
{
// Calculate position
Point position = new Point
{
X = outPage.Size.Width - (textGenerator.GetWidth(barcode) + Border),
Y = outPage.Size.Height - (fontSize * (font.Ascent + font.Descent) + Border)
};
// Move to position
textGenerator.MoveTo(position);
// Add given barcode string
textGenerator.ShowLine(barcode);
}
// Paint the positioned barcode text
gen.PaintText(barcodeText);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
// Create file stream
FileStream fontStream = new FileStream(fontPath, "r");
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Create embedded font in output document
Font font = Font.create(outDoc, fontStream, true);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page, add barcode, and append to output document
Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
addBarcode(outDoc, outPage, barcode, font, 50);
outDoc.getPages().add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addBarcode(Document outputDoc, Page outPage, String barcode, Font font, double fontSize) throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Create text object
Text barcodeText = Text.create(outputDoc);
// Create a text generator
TextGenerator textgenerator = new TextGenerator(barcodeText, font, fontSize, null);
// Calculate position
Point position = new Point(outPage.getSize().width - (textgenerator.getWidth(barcode) + Border),
outPage.getSize().height - (fontSize * (font.getAscent() + font.getDescent()) + Border));
// Move to position
textgenerator.moveTo(position);
// Add given barcode string
textgenerator.showLine(barcode);
// Close text generator
textgenerator.close();
// Paint the positioned barcode text
generator.paintText(barcodeText);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create file stream
pFontStream = _tfopen(szFontPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pFontStream, _T("Failed to open font file."));
PtxSysCreateFILEStreamDescriptor(&fontDescriptor, pFontStream, 0);
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
pFont = PtxPdfContent_Font_Create(pOutDoc, &fontDescriptor, TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Get page lists of input and output document
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy first page
pInPage = PtxPdf_PageList_Get(pInPageList, 0);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add barcode image to copied page
if (addBarcode(pOutDoc, pOutPage, szBarcode, pFont, 50) != 0)
goto cleanup;
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Get remaining pages from input
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy remaining pages to output
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add the copied pages to the output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange), _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addBarcode(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szBarcode, TPtxPdfContent_Font* pFont, double dFontSize)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Text* pBarcodeText = NULL;
TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create text object
pBarcodeText = PtxPdfContent_Text_Create(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pBarcodeText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create text generator
pTextGenerator = PtxPdfContent_TextGenerator_New(pBarcodeText, pFont, dFontSize, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate position
TPtxGeomReal_Size size;
PtxPdf_Page_GetSize(pOutPage, &size);
TPtxGeomReal_Point position;
double dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szBarcode);
GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dTextWidth, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
double dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dFontAscent, _T("%s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
double dFontDescent = PtxPdfContent_Font_GetDescent(pFont);
GOTO_CLEANUP_IF_NEGATIVE_PRINT_ERROR(dFontDescent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
position.dX = size.dWidth - (dTextWidth + dBorder);
position.dY = size.dHeight - (dFontSize * (dFontAscent + dFontDescent) + dBorder);
// Move to position
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position), _T("Failed to move to position %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add given barcode string
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szBarcode), _T("Failed to add barcode string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Close text generator
if (pTextGenerator != NULL)
PtxPdfContent_TextGenerator_Close(pTextGenerator);
// Paint the positioned barcode text
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pBarcodeText), _T("Failed to paint the positioned barcode text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
return iReturnValue;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page, add datamatrix image, and append to output document
Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
AddDataMatrix(outDoc, outPage, datamatrixPath);
outDoc.Pages.Add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddDataMatrix(Document document, Page page, string datamatrixPath)
{
// Create content generator
using ContentGenerator generator = new ContentGenerator(page.Content, false);
// Import data matrix
using Stream inMatrix = new FileStream(datamatrixPath, FileMode.Open, FileAccess.Read);
// Create image object for data matrix
Image datamatrix = Image.Create(document, inMatrix);
// Data matrix size
double datamatrixSize = 85;
// Calculate Rectangle for data matrix
Rectangle rect = new Rectangle
{
Left = Border,
Bottom = page.Size.Height - (datamatrixSize + Border),
Right = datamatrixSize + Border,
Top = page.Size.Height - Border
};
// Paint image of data matrix into the specified rectangle
generator.PaintImage(datamatrix, rect);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page, add data matrix image, and append to output document
Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
addDatamatrix(outDoc, outPage, datamatrixPath);
outDoc.getPages().add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addDatamatrix(Document document, Page page, String datamatrixPath)
throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(page.getContent(), false);
// Import data matrix
FileStream inMatrix = new FileStream(datamatrixPath, "r")) {
// Create image object for data matrix
Image datamatrix = Image.create(document, inMatrix);
// Data matrix size
double datamatrixSize = 85;
// Calculate Rectangle for data matrix
Rectangle rect = new Rectangle(Border, page.getSize().height - (datamatrixSize + Border),
datamatrixSize + Border, page.getSize().height - Border);
// Paint image of data matrix into the specified rectangle
generator.paintImage(datamatrix, rect);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Create embedded font in output document
pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Get page lists of input and output document
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy first page
pInPage = PtxPdf_PageList_Get(pInPageList, 0);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add datamatrix image to copied page
if (addDataMatrix(pOutDoc, pOutPage, szDatamatrixPath) != 0)
goto cleanup;
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Get remaining pages from input
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy remaining pages to output
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add the copied pages to the output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange), _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addDataMatrix(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szDataMatrixPath)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxSys_StreamDescriptor datamatrixDescriptor;
FILE* pDatamatrixStream = NULL;
TPtxPdfContent_Image* pDatamatrix = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Import data matrix
pDatamatrixStream = _tfopen(szDataMatrixPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pDatamatrixStream, _T("Failed to open data matrix file \"%s\".\n"), szDataMatrixPath);
PtxSysCreateFILEStreamDescriptor(&datamatrixDescriptor, pDatamatrixStream, 0);
// Create image object for data matrix
pDatamatrix = PtxPdfContent_Image_Create(pOutDoc, &datamatrixDescriptor);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pDatamatrix, _T("Failed to create image object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Data matrix size
double dDatamatrixSize = 85.0;
// Calculate Rectangle for data matrix
TPtxGeomReal_Size size;
PtxPdf_Page_GetSize(pOutPage, &size);
TPtxGeomReal_Rectangle rect;
rect.dLeft = dBorder;
rect.dBottom = size.dHeight - (dDatamatrixSize + dBorder);
rect.dRight = dDatamatrixSize + dBorder;
rect.dTop = size.dHeight - dBorder;
// Paint image of data matrix into the specified rectangle
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintImage(pGenerator, pDatamatrix, &rect), _T("Failed to paint data matrix into the specified rectangle. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy pages preceding selected page and append do output document
PageList inPageRange = inDoc.Pages.GetRange(0, pageNumber - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
// Copy selected page, add image, and append to output document
Page outPage = Page.Copy(outDoc, inDoc.Pages[pageNumber - 1], copyOptions);
AddImage(outDoc, outPage, imagePath, 150, 150);
outDoc.Pages.Add(outPage);
// Copy remaining pages and append to output document
inPageRange = inDoc.Pages.GetRange(pageNumber, inDoc.Pages.Count - pageNumber);
copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddImage(Document document, Page page, string imagePath, double x, double y)
{
// Create content generator
using ContentGenerator generator = new ContentGenerator(page.Content, false);
// Load image from input path
using Stream inImage = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
// Create image object
Image image = Image.Create(document, inImage);
double resolution = 150;
// Calculate rectangle for image
PdfTools.FourHeights.PdfToolbox.Geometry.Integer.Size size = image.Size;
Rectangle rect = new Rectangle
{
Left = x,
Bottom = y,
Right = x + size.Width * 72 / resolution,
Top = y + size.Height * 72 / resolution
};
// Paint image into the specified rectangle
generator.PaintImage(image, rect);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy pages preceding selected page and append to output document
PageList inPageRange = inDoc.getPages().subList(0, pageNumber - 1);
PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(copiedPages);
// Copy selected page, add image, and append to output document
Page outPage = Page.copy(outDoc, inDoc.getPages().get(pageNumber - 1), copyOptions);
addImage(outDoc, outPage, imagePath, 150, 150);
outDoc.getPages().add(outPage);
// Copy remaining pages and append to output document
inPageRange = inDoc.getPages().subList(pageNumber, inDoc.getPages().size());
copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addImage(Document document, Page outPage, String imagePath, double x, double y)
throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false);
// Load image from input path
FileStream inImage = new FileStream(imagePath, "r")) {
// Create image object
Image image = Image.create(document, inImage);
double resolution = 150;
// Calculate rectangle for image
Size size = image.getSize();
Rectangle rect = new Rectangle(x, y, x + size.getWidth() * 72 / resolution,
y + size.getHeight() * 72 / resolution);
// Paint image into the specified rectangle
generator.paintImage(image, rect);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Get input and output page lists
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy pages preceding selected page
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 0, iPageNumber - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange), _T("Failed to add page range. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
Ptx_Release(pInPageRange);
pInPageRange = NULL;
Ptx_Release(pOutPageRange);
pOutPageRange = NULL;
// Copy selected page an add image
pInPage = PtxPdf_PageList_Get(pInPageList, iPageNumber - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (addImage(pOutDoc, pOutPage, szImagePath, 150.0, 150.0) != 0)
goto cleanup;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy remaining pages
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange), _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addImage(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szImagePath, double x, double y)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxSys_StreamDescriptor imageDescriptor;
FILE* pImageStream = NULL;
TPtxPdfContent_Image* pImage = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
// Load image from input path
pImageStream = _tfopen(szImagePath, _T("rb"));
PtxSysCreateFILEStreamDescriptor(&imageDescriptor, pImageStream, 0);
// Create image object
pImage = PtxPdfContent_Image_Create(pOutDoc, &imageDescriptor);
double dResolution = 150.0;
TPtxGeomInt_Size size;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Image_GetSize(pImage, &size), _T("Failed to get image size. %s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate Rectangle for data matrix
TPtxGeomReal_Rectangle rect;
rect.dLeft = x;
rect.dBottom = y;
rect.dRight = x + (double)size.iWidth * 72.0 / dResolution;
rect.dTop = y + (double)size.iHeight * 72.0 / dResolution;
// Paint image into the specified rectangle
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintImage(pGenerator, pImage, &rect), _T("Failed to paint image. %s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Get the device color space
ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
// Create paint object
paint = Paint.Create(outDoc, colorSpace, new double[] { 1.0, 0.0, 0.0 }, null);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page, add image mask, and append to output document
Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
AddImageMask(outDoc, outPage, imageMaskPath, 250, 150);
outDoc.Pages.Add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddImageMask(Document document, Page outPage, string imagePath,
double x, double y)
{
// Create content generator
using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
// Load image from input path
using Stream inImage = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
// Create image mask object
ImageMask imageMask = ImageMask.Create(document, inImage);
double resolution = 150;
// Calculate rectangle for image
PdfTools.FourHeights.PdfToolbox.Geometry.Integer.Size size = imageMask.Size;
Rectangle rect = new Rectangle
{
Left = x,
Bottom = y,
Right = x + size.Width * 72 / resolution,
Top = y + size.Height * 72 / resolution
};
// Paint image mask into the specified rectangle
generator.PaintImageMask(imageMask, rect, paint);
}
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Get the device color space
ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outDoc, ProcessColorSpaceType.RGB);
// Create paint object
paint = Paint.create(outDoc, colorSpace, new double[] { 1.0, 0.0, 0.0 }, null);
// Copy first page, add image mask, and append to output document
Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
addImageMask(outDoc, outPage, imageMaskPath, 250, 150);
outDoc.getPages().add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addImageMask(Document document, Page outPage, String imagePath, double x, double y)
throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false);
// Load image from input path
FileStream inImage = new FileStream(imagePath, "r")) {
// Create image mask object
ImageMask imageMask = ImageMask.create(document, inImage);
double resolution = 150;
// Calculate rectangle for image
Size size = imageMask.getSize();
Rectangle rect = new Rectangle(x, y, x + size.getWidth() * 72 / resolution,
y + size.getHeight() * 72 / resolution);
// Paint image mask into the specified rectangle
generator.paintImageMask(imageMask, rect, paint);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(_T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(_T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Get the device color space
TPtxPdfContent_ColorSpace* pColorSpace = PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pColorSpace, _T("Failed to get the device color space. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Chose the RGB color value
double color[] = { 1.0, 0.0, 0.0 };
size_t nColor = sizeof(color) / sizeof(double);
// Create paint object
pPaint = PtxPdfContent_Paint_Create(pOutDoc, pColorSpace, color, nColor, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pPaint, _T("Failed to create a transparent paint. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Get input and output page lists
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy first page an add image mask
pInPage = PtxPdf_PageList_Get(pInPageList, 0);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (addImageMask(pOutDoc, pOutPage, szImageMaskPath, 250, 150) != 0)
goto cleanup;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy remaining pages
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange), _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addImageMask(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szImageMaskPath, double x, double y)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
FILE* pImageStream = NULL;
TPtxSys_StreamDescriptor imageDescriptor;
TPtxPdfContent_ImageMask* pImageMask = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Load image from input path
pImageStream = _tfopen(szImageMaskPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pImageStream, _T("Failed to open image mask file \"%s\".\n"), szImageMaskPath);
PtxSysCreateFILEStreamDescriptor(&imageDescriptor, pImageStream, 0);
// Create image mask object
pImageMask = PtxPdfContent_ImageMask_Create(pOutDoc, &imageDescriptor);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pImageMask, _T("Failed to create image mask obejct. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
double dResolution = 150.0;
TPtxGeomInt_Size size;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ImageMask_GetSize(pImageMask, &size), _T("Failed to get image mask size. %s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate Rectangle for data matrix
TPtxGeomReal_Rectangle rect;
rect.dLeft = x;
rect.dBottom = y;
rect.dRight = x + (double)size.iWidth * 72.0 / dResolution;
rect.dTop = y + (double)size.iHeight * 72.0 / dResolution;
// Paint image mask into the specified rectangle
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintImageMask(pGenerator, pImageMask, &rect, pPaint), _T("Failed to paint image mask. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
// Get the color space
ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);
// Choose the RGB color value
double[] color = { 1.0, 0.0, 0.0 };
Transparency transparency = new Transparency(alpha);
// Create paint object with the choosen RGB color
paint = Paint.Create(outDoc, colorSpace, color, transparency);
// Define copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages from input document
foreach (Page inPage in inDoc.Pages)
{
// Copy page from input to output
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// Add text to page
AddStamp(outDoc, outPage, stampString);
// Add page to document
outDoc.Pages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddStamp(Document outputDoc, Page outPage, string stampString)
{
// Create content generator and text object
using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
Text text = Text.Create(outputDoc);
// Create text generator
using (TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null))
{
// Calculate point and angle of rotation
Point rotationCenter = new Point
{
X = outPage.Size.Width / 2.0,
Y = outPage.Size.Height / 2.0
};
double rotationAngle = Math.Atan2(outPage.Size.Height,
outPage.Size.Width) / Math.PI * 180.0;
// Rotate textinput around the calculated position
AffineTransform trans = AffineTransform.Identity;
trans.Rotate(rotationAngle, rotationCenter);
gen.Transform(trans);
// Calculate position
Point position = new Point
{
X = (outPage.Size.Width - textgenerator.GetWidth(stampString)) / 2.0,
Y = (outPage.Size.Height - font.Ascent * fontSize) / 2.0
};
// Move to position
textgenerator.MoveTo(position);
// Set text paint
textgenerator.Fill = paint;
// Add given stamp string
textgenerator.ShowLine(stampString);
}
// Paint the positioned text
gen.PaintText(text);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Create embedded font in output document
font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
// Get the color space
ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outDoc, ProcessColorSpaceType.RGB);
// Choose the RGB color value
double[] color = { 1.0, 0.0, 0.0 };
Transparency transparency = new Transparency(alpha);
// Create paint object
paint = Paint.create(outDoc, colorSpace, color, transparency);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Loop throw all pages of input
for (Page inPage : inDoc.getPages()) {
// Copy page from input to output
Page outPage = Page.copy(outDoc, inPage, copyOptions);
// Add text to page
addStamp(outDoc, outPage, stampString);
// Add page to document
outDoc.getPages().add(outPage);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addStamp(Document outputDoc, Page outPage, String stampString)
throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Create text object
Text text = Text.create(outputDoc);
try (// Create text generator
TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null)) {
// Calculate point and angle of rotation
Point rotationCenter = new Point(outPage.getSize().width / 2.0, outPage.getSize().height / 2.0);
// Calculate rotation angle
double rotationAngle = Math.atan2(outPage.getSize().height, outPage.getSize().width) / Math.PI * 180.0;
// Rotate text input around the calculated position
AffineTransform trans = AffineTransform.getIdentity();
trans.rotate(rotationAngle, rotationCenter);
generator.transform(trans);
// Calculate position
Point position = new Point((outPage.getSize().width - textgenerator.getWidth(stampString)) / 2.0,
(outPage.getSize().height - font.getAscent() * fontSize) / 2.0);
// Move to position
textgenerator.moveTo(position);
// Set text paint
textgenerator.setFill(paint);
// Add given stamp string
textgenerator.showLine(stampString);
}
// Paint the positioned text
generator.paintText(text);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&inDescriptor, pInStream, FALSE);
pInDoc = PtxPdf_Document_Open(&inDescriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file %s.\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file %s cannot be closed. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Create embedded font in output document
pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Embedded font cannot be created. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Get the color space
TPtxPdfContent_ColorSpace* pColorSpace = PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pColorSpace, _T("Failed to get the color space. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Chose the RGB color values
double color[] = { 1.0, 0.0, 0.0 };
size_t nColor = sizeof(color) / sizeof(double);
pTransparency = PtxPdfContent_Transparency_New(dAlpha);
// Create paint object
pPaint = PtxPdfContent_Paint_Create(pOutDoc, pColorSpace, color, nColor, pTransparency);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pPaint, _T("Failed to create a transparent paint. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Loop through all pages of input
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
for (int i = 0; i < PtxPdf_PageList_GetCount(pInPageList); i++)
{
// Get a list of pages
pInPage = PtxPdf_PageList_Get(pInPageList, i);
// Copy page from input to output
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add stamp to page
if (addStamp(pOutDoc, pOutPage, szStampString, pFont, 50) == 1)
{
goto cleanup;
}
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (pOutPage != NULL)
{
Ptx_Release(pOutPage);
pOutPage = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
}
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addStamp(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szStampString, TPtxPdfContent_Font* pFont, double dFontSize)
{
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Text* pText = NULL;
TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
TPtxGeomReal_AffineTransform trans;
TPtxGeomReal_Point rotationCenter;
double dTextWidth;
double dFontAscent;
TPtxPdfContent_Content* pContent = PtxPdf_Page_GetContent(pOutPage);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create text object
pText = PtxPdfContent_Text_Create(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create a text generator
pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, dFontSize, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Get output page size
TPtxGeomReal_Size size;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size), _T("Failed to read page size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate point and angle of rotation
rotationCenter.dX = size.dWidth / 2.0;
rotationCenter.dY = size.dHeight / 2.0;
double dRotationAngle = atan2(size.dHeight, size.dWidth) / M_PI * 180.0;
// Rotate textinput around the calculated position
PtxGeomReal_AffineTransform_GetIdentity(&trans);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Rotate(&trans, dRotationAngle, &rotationCenter), _T("Failed to rotate textinput around the calculated position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_Transform(pGenerator, &trans), _T("Failed to modify the current transformation. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate position
TPtxGeomReal_Point position;
dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampString);
GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dTextWidth, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dFontAscent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
position.dX = (size.dWidth - dTextWidth) / 2.0;
position.dY = (size.dHeight - dFontAscent * dFontSize) / 2.0;
// Move to position
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position), _T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Set text rendering
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_SetFill(pTextGenerator, pPaint), _T("Failed to set fill paint. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add given stamp string
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szStampString), _T("Failed to add stamp. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Close text generator
if (pTextGenerator != NULL)
{
PtxPdfContent_TextGenerator_Close(pTextGenerator);
pTextGenerator = NULL;
}
// Paint the positioned text
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText), _T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pTextGenerator != NULL)
PtxPdfContent_TextGenerator_Close(pTextGenerator);
if (pText != NULL)
Ptx_Release(pText);
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Create a font
font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page, add text, and append to output document
Page outPage = Page.Copy(outDoc, inDoc.Pages[0], copyOptions);
AddText(outDoc, outPage, textString);
outDoc.Pages.Add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddText(Document outputDoc, Page outPage, string textString)
{
// Create content generator and text object
using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
Text text = Text.Create(outputDoc);
// Create text generator
using (TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null))
{
// Calculate position
Point position = new Point
{
X = border,
Y = outPage.Size.Height - border - fontSize * font.Ascent
};
// Move to position
textGenerator.MoveTo(position);
// Add given text string
textGenerator.ShowLine(textString);
}
// Paint the positioned text
gen.PaintText(text);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Create embedded font in output document
font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy first page, add text, and append to output document
Page outPage = Page.copy(outDoc, inDoc.getPages().get(0), copyOptions);
addText(outDoc, outPage, textString);
outDoc.getPages().add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data (excluding metadata)
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addText(Document outputDoc, Page outPage, String textString)
throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Create text object
Text text = Text.create(outputDoc);
try (// Create a text generator
TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null)) {
// Calculate position
Point position = new Point(border, outPage.getSize().height - border - fontSize * font.getAscent());
// Move to position
textgenerator.moveTo(position);
// Add given text string
textgenerator.showLine(textString);
}
// Paint the positioned text
generator.paintText(text);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Create embedded font in output document
pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Get page lists of input and output document
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy first page
pInPage = PtxPdf_PageList_Get(pInPageList, 0);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get the first page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add text to copied page
if (addText(pOutDoc, pOutPage, szTextString, pFont, 15) != 0)
goto cleanup;
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Get remaining pages from input
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, 1, PtxPdf_PageList_GetCount(pInPageList) - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy remaining pages to output
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageRange, _T("Failed to copy page range to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add the copied pages to the output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange), _T("Failed to add page range to output page list. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addText(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szTextString, TPtxPdfContent_Font* pFont, double dFontSize)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Text* pText = NULL;
TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
TPtxGeomReal_Size size;
TPtxGeomReal_Point position;
double dFontAscent;
pContent = PtxPdf_Page_GetContent(pOutPage);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pContent, _T("Failed to get content of output file. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create text object
pText = PtxPdfContent_Text_Create(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create text object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create a text generator
pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, dFontSize, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Get output page size
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size), _T("Failed to read page size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dFontAscent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate position
position.dX = dBorder;
position.dY = size.dHeight - dBorder - dFontSize * dFontAscent;
// Move to position
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position), _T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add given text string
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szTextString), _T("Failed to add text string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Close text generator
PtxPdfContent_TextGenerator_Close(pTextGenerator);
pTextGenerator = NULL;
// Paint the positioned text
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText), _T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pTextGenerator != NULL)
PtxPdfContent_TextGenerator_Close(pTextGenerator);
if (pText != NULL)
Ptx_Release(pText);
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
C sample:
C# sample:
// Open input document
using (System.IO.Stream inStream = new System.IO.FileStream(inPath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (System.IO.Stream outStream = new System.IO.FileStream(outPath, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages from input document
foreach (Page inPage in inDoc.Pages)
{
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// Add a line
AddLine(outDoc, outPage);
// Add page to output document
outDoc.Pages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddLine(Document document, Page page)
{
// Create content generator
using ContentGenerator generator = new ContentGenerator(page.Content, false);
// Create a path
Path path = new Path();
using (PathGenerator pathGenerator = new PathGenerator(path))
{
// Draw a line diagonally across the page
Size pageSize = page.Size;
pathGenerator.MoveTo(new Point() { X = 10.0, Y = 10.0 });
pathGenerator.LineTo(new Point() { X = pageSize.Width - 10.0, Y = pageSize.Height - 10.0 });
}
// Create a RGB color space
ColorSpace deviceRgbColorSpace = ColorSpace.CreateProcessColorSpace(document, ProcessColorSpaceType.Rgb);
// Create a red color
double[] color = new double[] { 1.0, 0.0, 0.0 };
// Create a paint
Paint paint = Paint.Create(document, deviceRgbColorSpace, color, null);
// Create stroking parameters with given paint and line width
Stroke stroke = new Stroke(paint, 10.0);
// Draw the path onto the page
generator.PaintPath(path, null, stroke);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages
for (Page inPage : inDoc.getPages()) {
// Copy page from input to output
Page outPage = Page.copy(outDoc, inPage, copyOptions);
// Add a line
addLine(outDoc, outPage);
// Add page to output document
outDoc.getPages().add(outPage);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addLine(Document document, Page outPage)
throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Create a path
Path path = new Path();
try (// Create a path generator
PathGenerator pathGenerator = new PathGenerator(path)) {
// Draw a line diagonally across the page
Size pageSize = outPage.getSize();
pathGenerator.moveTo(new Point(10.0, 10.0));
pathGenerator.lineTo(new Point(pageSize.width - 10.0, pageSize.height - 10.0));
}
// Create a RGB color space
ColorSpace deviceRgbColorSpace = ColorSpace.createProcessColorSpace(document, ProcessColorSpaceType.RGB);
// Create a red color
double[] color = new double[] { 1.0, 0.0, 0.0 };
// Create a paint
Paint paint = Paint.create(document, deviceRgbColorSpace, color, null);
// Create stroking parameters with given paint and line width
Stroke stroke = new Stroke(paint, 10.0);
// Draw the path onto the page
generator.paintPath(path, null, stroke);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Loop through all pages of input
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
for (int iPage = 1; iPage <= PtxPdf_PageList_GetCount(pInPageList); iPage++)
{
pInPage = PtxPdf_PageList_Get(pInPageList, iPage - 1);
// Copy page from input to output
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
PtxPdf_Page_GetSize(pOutPage, &size);
//Add text on first page
if (addLine(pOutDoc, pOutPage) == 1)
{
goto cleanup;
}
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (pOutPage != NULL)
{
Ptx_Release(pOutPage);
pOutPage = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
}
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addLine(TPtxPdf_Document * pOutDoc, TPtxPdf_Page * pOutPage)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Path* pPath = NULL;
TPtxPdfContent_PathGenerator* pPathGenerator = NULL;
TPtxPdfContent_ColorSpace* pDeviceRgbColorSpace = NULL;
double aColor[3];
TPtxPdfContent_Paint* pPaint = NULL;
TPtxPdfContent_Stroke* pStroke;
TPtxGeomReal_Size pageSize;
TPtxGeomReal_Point point;
pContent = PtxPdf_Page_GetContent(pOutPage);
PtxPdf_Page_GetSize(pOutPage, &pageSize);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL(pGenerator, szErrorBuff, Ptx_GetLastError());
// Create a path
pPath = PtxPdfContent_Path_New();
GOTO_CLEANUP_IF_NULL(pPath, szErrorBuff, Ptx_GetLastError());
// Create a path generator
pPathGenerator = PtxPdfContent_PathGenerator_New(pPath);
GOTO_CLEANUP_IF_NULL(pPathGenerator, szErrorBuff, Ptx_GetLastError());
// Draw a line diagonally across the page
point.dX = 10.0;
point.dY = 10.0;
GOTO_CLEANUP_IF_FALSE(PtxPdfContent_PathGenerator_MoveTo(pPathGenerator, &point), szErrorBuff, Ptx_GetLastError());
point.dX = pageSize.dWidth - 10.0;
point.dY = pageSize.dHeight - 10.0;
GOTO_CLEANUP_IF_FALSE(PtxPdfContent_PathGenerator_LineTo(pPathGenerator, &point), szErrorBuff, Ptx_GetLastError());
// Close the path generator in order to finish the path
PtxPdfContent_PathGenerator_Close(pPathGenerator);
pPathGenerator = NULL;
// Create a RGB color space
pDeviceRgbColorSpace = PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
GOTO_CLEANUP_IF_NULL(pDeviceRgbColorSpace, szErrorBuff, Ptx_GetLastError());
// Initialize a red color
aColor[0] = 1.0;
aColor[1] = 0.0;
aColor[2] = 0.0;
// Create a paint
pPaint = PtxPdfContent_Paint_Create(pOutDoc, pDeviceRgbColorSpace, aColor, sizeof(aColor) / sizeof(aColor[0]), NULL);
GOTO_CLEANUP_IF_NULL(pPaint, szErrorBuff, Ptx_GetLastError());
// Setup stroking parameters with given paint and line width
pStroke = PtxPdfContent_Stroke_New(pPaint, 10.0);
GOTO_CLEANUP_IF_NULL(pStroke, szErrorBuff, Ptx_GetLastError());
// Draw the path onto the page
GOTO_CLEANUP_IF_FALSE(PtxPdfContent_ContentGenerator_PaintPath(pGenerator, pPath, NULL, pStroke), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pPathGenerator != NULL)
PtxPdfContent_PathGenerator_Close(pPathGenerator);
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
C sample:
C# sample:
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.CreateNew, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, null, null))
{
Font font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
// Create page
Page outPage = Page.Create(outDoc, PageSize);
// Add text as justified text
LayoutText(outDoc, outPage, textPath, font, 20);
// Add page to document
outDoc.Pages.Add(outPage);
}
private static void LayoutText(Document outputDoc, Page outPage, string textPath, Font font,
double fontSize)
{
// Create content generator
using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
// Create text object
Text text = Text.Create(outputDoc);
// Create text generator
using TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null);
// Calculate position
Point position = new Point
{
X = Border,
Y = outPage.Size.Height - Border
};
// Move to position
textGenerator.MoveTo(position);
// Loop throw all lines of the textinput
string[] lines = File.ReadAllLines(textPath, Encoding.Default);
foreach (string line in lines)
{
// Split string in substrings
string[] substrings = line.Split(new char[] { ' ' }, StringSplitOptions.None);
string currentLine = null;
double maxWidth = outPage.Size.Width - Border * 2;
int wordcount = 0;
// Loop throw all words of input strings
foreach (string word in substrings)
{
string tempLine;
// Concatenate substrings to line
if (currentLine != null)
tempLine = currentLine + " " + word;
else
tempLine = word;
// Calculate the current width of line
double width = textGenerator.GetWidth(currentLine);
if (textGenerator.GetWidth(tempLine) > maxWidth)
{
// Calculate the word spacing
textGenerator.WordSpacing = (maxWidth - width) / (wordcount - 1);
// Paint on new line
textGenerator.ShowLine(currentLine);
textGenerator.WordSpacing = 0;
currentLine = word;
wordcount = 1;
}
else
{
currentLine = tempLine;
wordcount++;
}
}
textGenerator.WordSpacing = 0;
// Add given stamp string
textGenerator.ShowLine(currentLine);
}
// Paint the positioned text
gen.PaintText(text);
}
C# sample:
Java sample:
try (
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, null, null)) {
// Create embedded font in output document
Font font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
// Create page
Page outPage = Page.create(outDoc, new Size(595, 842));
// Add text to document
layoutText(outDoc, outPage, textPath, font, 20);
// Add page to output document
outDoc.getPages().add(outPage);
}
}
private static void layoutText(Document outputDoc, Page outPage, String textPath, Font font, double fontSize)
throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Create text object
Text text = Text.create(outputDoc);
try (// Create a text generator
TextGenerator textGenerator = new TextGenerator(text, font, fontSize, null)) {
// Calculate position
Point position = new Point(Border, outPage.getSize().height - Border);
// Move to position
textGenerator.moveTo(position);
// Loop throw all lines of the textinput
List lines = Files.readAllLines(Paths.get(textPath), Charset.defaultCharset());
for (String line : lines) {
// Split string in substrings
String[] substrings = line.split(" ");
String currentLine = null;
double maxWidth = outPage.getSize().width - (Border * 2);
int wordCount = 0;
// Loop throw all words of input strings
for (String word : substrings) {
String tempLine;
// Concatenate substrings to line
if (currentLine != null) {
tempLine = currentLine + " " + word;
} else {
tempLine = word;
}
// Calculate the current width of line
double width = textGenerator.getWidth(currentLine);
if ((textGenerator.getWidth(tempLine) > maxWidth)) {
// Calculate the word spacing
textGenerator.setWordSpacing((maxWidth - width) / (double) (wordCount - 1));
// Paint on new line
textGenerator.showLine(currentLine);
textGenerator.setWordSpacing(0);
currentLine = word;
wordCount = 1;
} else {
currentLine = tempLine;
wordCount++;
}
}
textGenerator.setWordSpacing(0);
// Add given stamp string
textGenerator.showLine(currentLine);
}
}
// Paint the positioned text
generator.paintText(text);
}
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Create embedded font in output document
Font font = Font.CreateFromSystem(outDoc, "Arial", string.Empty, true);
// Copy all pages from input document
int currentPageNumber = 1;
foreach (Page inPage in inDoc.Pages)
{
// Copy page from input to output
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// Stamp page number on current page of output document
AddPageNumber(outDoc, outPage, font, currentPageNumber++);
// Add page to output document
outDoc.Pages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddPageNumber(Document outDoc, Page outPage, Font font, int pageNumber)
{
// Create content generator
using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
// Create text object
Text text = Text.Create(outDoc);
// Create a text generator with the given font, size and position
using (TextGenerator textgenerator = new TextGenerator(text, font, 8, null))
{
// Generate string to be stamped as page number
string stampText = string.Format("Page {0}", pageNumber);
// Calculate position for centering text at bottom of page
Point position = new Point
{
X = (outPage.Size.Width / 2) - (textgenerator.GetWidth(stampText) / 2),
Y = 10
};
// Position the text
textgenerator.MoveTo(position);
// Add page number
textgenerator.Show(stampText);
}
// Paint the positioned text
generator.PaintText(text);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy pages from input to output
int pageNo = 1;
// Create embedded font in output document
Font font = Font.createFromSystem(outDoc, "Arial", "", true);
// Loop through all pages of input
for (Page inPage : inDoc.getPages()) {
// Copy page from input to output
Page outPage = Page.copy(outDoc, inPage, copyOptions);
// Stamp page number on current page of output document
applyStamps(outDoc, outPage, font, pageNo++);
// Add page to output document
outDoc.getPages().add(outPage);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void applyStamps(Document doc, Page page, Font font, int pageNo) throws PdfToolboxException, IOException {
try (// Create content generator
ContentGenerator generator = new ContentGenerator(page.getContent(), false)) {
// Create text object
Text text = Text.create(doc);
try (// Create a text generator with the given font, size and position
TextGenerator textgenerator = new TextGenerator(text, font, 8, null)) {
// Generate string to be stamped as page number
String stampText = String.format("Page %d", pageNo);
// Calculate position for centering text at bottom of page
Point position = new Point((page.getSize().width / 2) - (textgenerator.getWidth(stampText) / 2), 10);
// Position the text
textgenerator.moveTo(position);
// Add page number
textgenerator.show(stampText);
}
// Paint the positioned text
generator.paintText(text);
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Create embedded font in output document
pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T(""), TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Failed to create font. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
{
pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
// Copy page from input to output
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size), _T("Failed to get size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Stamp page number on current page of output document
if (addPageNumber(pOutDoc, pOutPage, pFont, iPage + 1) == 1)
{
goto cleanup;
}
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (pOutPage != NULL)
{
Ptx_Release(pOutPage);
pOutPage = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
}
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
int addPageNumber(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TPtxPdfContent_Font* pFont, int nPageNumber)
{
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdfContent_Text* pText = NULL;
TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
pContent = PtxPdf_Page_GetContent(pOutPage);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create text object
pText = PtxPdfContent_Text_Create(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Create a text generator with the given font, size and position
pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, 8, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Generate string to be stamped as page number
char szStampBuffer[50];
sprintf(szStampBuffer, _T("Page %d"), nPageNumber);
TCHAR* szStampText = szStampBuffer;
double dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampText);
GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dTextWidth, _T("Failed to get text width. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate position
TPtxGeomReal_Point position;
position.dX = (size.dWidth / 2) - (dTextWidth / 2);
position.dY = 10;
// Move to position
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position), _T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add given text string
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szStampText), _T("Failed to add given text string. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Close text generator
PtxPdfContent_TextGenerator_Close(pTextGenerator);
pTextGenerator = NULL;
// Paint the positioned text
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText), _T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pTextGenerator != NULL)
PtxPdfContent_TextGenerator_Close(pTextGenerator);
if (pGenerator != NULL)
PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pText != NULL)
Ptx_Release(pText);
if (pContent != NULL)
Ptx_Release(pContent);
return iReturnValue;
}
C sample:
Annotations and Form Fields
C# sample:
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Copy all form fields
FieldNodeMap inFormFields = inDoc.FormFields;
FieldNodeMap outFormFields = outDoc.FormFields;
foreach (KeyValuePair inPair in inFormFields)
{
FieldNode outFormFieldNode = FieldNode.Copy(outDoc, inPair.Value);
outFormFields.Add(inPair.Key, outFormFieldNode);
}
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions
{
FormFields = FormFieldCopyStrategy.CopyAndUpdateWidgets,
UnsignedSignatures = CopyStrategy.Remove,
};
// Copy first page
Page inPage = inDoc.Pages[0];
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// Add different types of form fields to the output page
AddCheckBox(outDoc, "Check Box ID", true, outPage, new Rectangle { Left = 50, Bottom = 300, Right = 70, Top = 320 });
AddComboBox(outDoc, "Combo Box ID", new string[] { "item 1", "item 2" }, "item 1", outPage, new Rectangle { Left = 50, Bottom = 260, Right = 210, Top = 280 });
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 });
AddRadioButtonGroup(outDoc, "Radio Button ID", new string[] { "A", "B", "C" }, 0, outPage, new Rectangle { Left = 50, Bottom = 120, Right = 210, Top = 140 });
AddGeneralTextField(outDoc, "Text ID", "Text", outPage, new Rectangle { Left = 50, Bottom = 80, Right = 210, Top = 100 });
// Add page to output document
outDoc.Pages.Add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.Pages.GetRange(1, inDoc.Pages.Count - 1);
PageList copiedPages = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddCheckBox(Document doc, string id, bool isChecked, Page page, Rectangle rectangle)
{
// Create a check box
CheckBox checkBox = CheckBox.Create(doc);
// Add the check box to the document
doc.FormFields.Add(id, checkBox);
// Set the check box's state
checkBox.Checked = isChecked;
// Create a widget and add it to the page's widgets
page.Widgets.Add(checkBox.AddNewWidget(rectangle));
}
private static void AddComboBox(Document doc, string id, string[] itemNames, string value, Page page, Rectangle rectangle)
{
// Create a combo box
ComboBox comboBox = ComboBox.Create(doc);
// Add the combo box to the document
doc.FormFields.Add(id, comboBox);
// Loop over all given item names
foreach (string itemName in itemNames)
{
// Create a new choice item
ChoiceItem item = comboBox.AddNewItem(itemName);
// Check whether this is the chosen item name
if (value.Equals(itemName))
comboBox.ChosenItem = item;
}
if (comboBox.ChosenItem == null && !string.IsNullOrEmpty(value))
{
// If no item has been chosen then assume we want to set the editable item
comboBox.CanEdit = true;
comboBox.EditableItemName = value;
}
// Create a widget and add it to the page's widgets
page.Widgets.Add(comboBox.AddNewWidget(rectangle));
}
private static void AddListBox(Document doc, string id, string[] itemNames, string[] chosenNames, Page page, Rectangle rectangle)
{
// Create a list box
ListBox listBox = ListBox.Create(doc);
// Add the list box to the document
doc.FormFields.Add(id, listBox);
// Allow multiple selections
listBox.AllowMultiSelect = true;
ChoiceItemList chosenItems = listBox.ChosenItems;
// Loop over all given item names
foreach (string itemName in itemNames)
{
// Create a new choice item
ChoiceItem item = listBox.AddNewItem(itemName);
// Check whether to add to the chosen items
if (chosenNames.Contains(itemName))
chosenItems.Add(item);
}
// Create a widget and add it to the page's widgets
page.Widgets.Add(listBox.AddNewWidget(rectangle));
}
private static void AddRadioButtonGroup(Document doc, string id, string[] buttonNames, int chosen, Page page, Rectangle rectangle)
{
// Create a radio button group
RadioButtonGroup group = RadioButtonGroup.Create(doc);
// Get the page's widgets
WidgetList widgets = page.Widgets;
// Add the radio button group to the document
doc.FormFields.Add(id, group);
// We partition the given rectangle horizontally into sub-rectangles, one for each button
// Compute the width of the sub-rectangles
double buttonWidth = (rectangle.Right - rectangle.Left) / buttonNames.Length;
// Loop over all button names
for (int i = 0; i < buttonNames.Length; i++)
{
// Compute the sub-rectangle for this button
Rectangle buttonRectangle = new Rectangle()
{
Left = rectangle.Left + i * buttonWidth,
Bottom = rectangle.Bottom,
Right = rectangle.Left + (i + 1) * buttonWidth,
Top = rectangle.Top
};
// Create the button and an associated widget
RadioButton button = group.AddNewButton(buttonNames[i]);
Widget widget = button.AddNewWidget(buttonRectangle);
// Check if this is the chosen button
if (i == chosen)
group.ChosenButton = button;
// Add the widget to the page's widgets
widgets.Add(widget);
}
}
private static void AddGeneralTextField(Document doc, string id, string value, Page page, Rectangle rectangle)
{
// Create a general text field
GeneralTextField field = GeneralTextField.Create(doc);
// Add the field to the document
doc.FormFields.Add(id, field);
// Set the text value
field.Text = value;
// Create a widget and add it to the page's widgets
page.Widgets.Add(field.AddNewWidget(rectangle));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Copy all form fields
FieldNodeMap inFormFields = inDoc.getFormFields();
FieldNodeMap outFormFields = outDoc.getFormFields();
for (Entry entry : inFormFields.entrySet())
outFormFields.put(entry.getKey(), FieldNode.copy(outDoc, entry.getValue()));
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
copyOptions.setFormFields(FormFieldCopyStrategy.COPY_AND_UPDATE_WIDGETS);
copyOptions.setUnsignedSignatures(CopyStrategy.REMOVE);
// Copy first page
Page inPage = inDoc.getPages().get(0);
Page outPage = Page.copy(outDoc, inPage, copyOptions);
// Add different types of form fields to the output page
addCheckBox(outDoc, "Check Box ID", true, outPage, new Rectangle(50, 300, 70, 320));
addComboBox(outDoc, "Combo Box ID", new String[] { "item 1", "item 2" }, "item 1", outPage,
new Rectangle(50, 260, 210, 280));
addListBox(outDoc, "List Box ID", new String[] { "item 1", "item 2", "item 3" },
new String[] { "item 1", "item 3" }, outPage, new Rectangle(50, 160, 210, 240));
addRadioButtonGroup(outDoc, "Radio Button ID", new String[] { "A", "B", "C" }, 0, outPage,
new Rectangle(50, 120, 210, 140));
addGeneralTextField(outDoc, "Text ID", "Text", outPage, new Rectangle(50, 80, 210, 100));
// Add page to output document
outDoc.getPages().add(outPage);
// Copy remaining pages and append to output document
PageList inPageRange = inDoc.getPages().subList(1, inDoc.getPages().size());
PageList copiedPages = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addCheckBox(Document doc, String id, boolean isChecked, Page page, Rectangle rectangle)
throws PdfToolboxException {
// Create a check box
CheckBox checkBox = CheckBox.create(doc);
// Add the check box to the document
doc.getFormFields().put(id, checkBox);
// Set the check box's state
checkBox.setChecked(isChecked);
// Create a widget and add it to the page's widgets
page.getWidgets().add(checkBox.addNewWidget(rectangle));
}
private static void addListBox(Document doc, String id, String[] itemNames, String[] chosenNames, Page page,
Rectangle rectangle) throws PdfToolboxException {
List chosenNamesList = Arrays.asList(chosenNames);
// Create a list box
ListBox listBox = ListBox.create(doc);
// Add the list box to the document
doc.getFormFields().put(id, listBox);
// Allow multiple selections
listBox.setAllowMultiSelect(true);
// Get the list of chosen items
ChoiceItemList chosenItems = listBox.getChosenItems();
// Loop over all given item names
for (String itemName : itemNames) {
ChoiceItem item = listBox.addNewItem(itemName);
// Check whether to add to the chosen items
if (chosenNamesList.contains(itemName))
chosenItems.add(item);
}
// Create a widget and add it to the page's widgets
page.getWidgets().add(listBox.addNewWidget(rectangle));
}
private static void addComboBox(Document doc, String id, String[] itemNames, String value, Page page,
Rectangle rectangle) throws PdfToolboxException {
// Create a combo box
ComboBox comboBox = ComboBox.create(doc);
// Add the combo box to the document
doc.getFormFields().put(id, comboBox);
// Loop over all given item names
for (String itemName : itemNames) {
ChoiceItem item = comboBox.addNewItem(itemName);
// Check whether to add to the chosen items
if (value.equals(itemName))
comboBox.setChosenItem(item);
}
if (comboBox.getChosenItem() == null && !(value == null || value.isEmpty())) {
// If no item has been chosen then assume we want to set the editable item
comboBox.setCanEdit(true);
comboBox.setEditableItemName(value);
}
// Create a widget and add it to the page's widgets
page.getWidgets().add(comboBox.addNewWidget(rectangle));
}
private static void addRadioButtonGroup(Document doc, String id, String[] buttonNames, int chosen, Page page,
Rectangle rectangle) throws PdfToolboxException {
// Create a radio button group
RadioButtonGroup group = RadioButtonGroup.create(doc);
// Add the radio button group to the document
doc.getFormFields().put(id, group);
// We partition the given rectangle horizontally into sub-rectangles, one for
// each button
// Compute the width of the sub-rectangles
double buttonWidth = (rectangle.right - rectangle.left) / buttonNames.length;
// Get the page's widgets
WidgetList widgets = page.getWidgets();
// Loop over all button names
for (int i = 0; i < buttonNames.length; i++) {
// Compute the sub-rectangle for this button
Rectangle buttonRectangle = new Rectangle(rectangle.left + i * buttonWidth, rectangle.bottom,
rectangle.left + (i + 1) * buttonWidth, rectangle.top);
// Create the button and an associated widget
RadioButton button = group.addNewButton(buttonNames[i]);
Widget widget = button.addNewWidget(buttonRectangle);
// Check if this is the chosen button
if (i == chosen)
group.setChosenButton(button);
// Add the widget to the page's widgets
widgets.add(widget);
}
}
private static void addGeneralTextField(Document doc, String id, String value, Page page, Rectangle rectangle)
throws PdfToolboxException {
// Create a general text field
GeneralTextField field = GeneralTextField.create(doc);
// Add the field to the document
doc.getFormFields().put(id, field);
// Set the check box's state
field.setText(value);
// Create a widget and add it to the page's widgets
page.getWidgets().add(field.addNewWidget(rectangle));
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
FieldNodeMap outFields = outDoc.FormFields;
// Copy all form fields
FieldNodeMap inFields = inDoc.FormFields;
foreach (var inPair in inFields)
{
FieldNode inFieldNode = inPair.Value;
FieldNode outFormFieldNode = FieldNode.Copy(outDoc, inFieldNode);
outFields.Add(inPair.Key, outFormFieldNode);
}
// Find the given field, exception thrown if not found
var selectedNode = outFields.Lookup(fieldIdentifier);
if (selectedNode is Field selectedField)
FillFormField(selectedField, fieldValue);
// Configure copying options for updating existing widgets and removing signature fields
PageCopyOptions copyOptions = new PageCopyOptions
{
FormFields = FormFieldCopyStrategy.CopyAndUpdateWidgets,
UnsignedSignatures = CopyStrategy.Remove,
};
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
static void FillFormField(Field formField, string value)
{
// Apply the value, depending on the field type
if (formField is TextField textField)
{
// Set the text
textField.Text = value;
}
else if (formField is CheckBox checkBox)
{
// Check or un-check
checkBox.Checked = "on".Equals(value, StringComparison.CurrentCultureIgnoreCase);
}
else if (formField is RadioButtonGroup group)
{
// Search the buttons for given name
foreach (var button in group.Buttons)
{
if (value.Equals(button.ExportName))
{
// Found: Select this button
group.ChosenButton = button;
break;
}
}
}
else if (formField is ComboBox comboBox)
{
// Search for the given item
foreach (var item in comboBox.Items)
{
if (value.Equals(item.DisplayName))
{
// Found: Select this item.
comboBox.ChosenItem = item;
break;
}
}
}
else if (formField is ListBox listBox)
{
// Search for the given item
foreach (var item in listBox.Items)
{
if (value.Equals(item.DisplayName))
{
// Found: Set this item as the only selected item
var itemList = listBox.ChosenItems;
itemList.Clear();
itemList.Add(item);
break;
}
}
}
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Copy all form fields
FieldNodeMap inFormFields = inDoc.getFormFields();
FieldNodeMap outFormFields = outDoc.getFormFields();
for (Entry entry : inFormFields.entrySet())
outFormFields.put(entry.getKey(), FieldNode.copy(outDoc, entry.getValue()));
// Find the given field, exception thrown if not found
Field selectedField = (Field) outFormFields.lookup(fieldIdentifier);
fillFormField(selectedField, fieldValue);
// Configure copying options for updating existing widgets and removing signature fields
PageCopyOptions copyOptions = new PageCopyOptions();
copyOptions.setFormFields(FormFieldCopyStrategy.COPY_AND_UPDATE_WIDGETS);
copyOptions.setUnsignedSignatures(CopyStrategy.REMOVE);
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void fillFormField(Field formField, String value) throws PdfToolboxException {
// Apply the value, depending on the field type
if (formField instanceof TextField) {
// Set the text
TextField textField = (TextField) formField;
textField.setText(value);
} else if (formField instanceof CheckBox) {
// Check or un-check
CheckBox checkBox = (CheckBox) formField;
checkBox.setChecked(value.equalsIgnoreCase("on"));
} else if (formField instanceof RadioButtonGroup) {
// Search the buttons for given name
RadioButtonGroup group = (RadioButtonGroup) formField;
for (RadioButton button : group.getButtons()) {
if (value.equals(button.getExportName())) {
// Found: Select this button
group.setChosenButton(button);
break;
}
}
} else if (formField instanceof ComboBox) {
// Search for the given item
ComboBox comboBox = (ComboBox) formField;
for (ChoiceItem item : comboBox.getItems()) {
if (value.equals(item.getDisplayName())) {
// Found: Select this item
comboBox.setChosenItem(item);
break;
}
}
} else if (formField instanceof ListBox) {
// Search for the given item
ListBox listBox = (ListBox) formField;
for (ChoiceItem item : listBox.getItems()) {
if (value.equals(item.getDisplayName())) {
// Found: Set this item as the only selected item
ChoiceItemList itemList = listBox.getChosenItems();
itemList.clear();
itemList.add(item);
break;
}
}
}
}
Java sample:
Document Setup
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Set Metadata
if (args.Length == 3)
{
Metadata mdata;
// Add metadata from a input file
using FileStream metaStream = File.OpenRead(mdatafile);
if (mdatafile.EndsWith(".pdf"))
{
// Use the metadata of another PDF file
Document metaDoc = Document.Open(metaStream, "");
mdata = Metadata.Copy(outDoc, metaDoc.Metadata);
}
else
{
// Use the content of an XMP metadata file
mdata = Metadata.Create(outDoc, metaStream);
}
outDoc.Metadata = mdata;
}
else
{
// Set some metadata properties
Metadata metadata = outDoc.Metadata;
metadata.Author = "Your Author";
metadata.Title = "Your Title";
metadata.Subject = "Your Subject";
metadata.Creator = "Your Creator";
}
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data (except metadata)
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
outDoc.getPages().addAll(copiedPages);
if (args.length == 3) {
Metadata mdata;
// Add metadata from a input file
FileStream metaStream = new FileStream(mdatafile, "r");
if (mdatafile.toLowerCase().endsWith(".pdf")) {
// Use the metadata of another PDF file
Document metaDoc = Document.open(metaStream, null);
mdata = Metadata.copy(outDoc, metaDoc.getMetadata());
} else {
// Use the content of an XMP metadata file
mdata = Metadata.create(outDoc, metaStream);
}
outDoc.setMetadata(mdata);
} else {
// Set some metadata properties
Metadata metadata = outDoc.getMetadata();
metadata.setAuthor("Your Author");
metadata.setTitle("Your Title");
metadata.setSubject("Your Subject");
metadata.setCreator("Your Creator");
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data (excluding metadata)
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add copied pages to output
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages), _T("Failed to add copied pages to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (argc == 4)
{
// Add metadata from a input file
pMdataStream = _tfopen(szMdatafile, _T("rb"));
GOTO_CLEANUP_IF_NULL(pMdataStream, _T("Failed to open metadata file \"%s\".\n"), szMdatafile);
PtxSysCreateFILEStreamDescriptor(&mdataDescriptor, pMdataStream, 0);
// Get file extension
TCHAR* szExt = _tcsrchr(szMdatafile, '.');
_tcscpy(szExtension, szExt);
if (_tcscmp(szExtension, _T(".pdf")) == 0)
{
// Use the metadata of another PDF file
TPtxPdf_Document* pMetaDoc = PtxPdf_Document_Open(&mdataDescriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetaDoc, _T("Failed to open metadata file. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
TPtxPdf_Metadata* pMetadata = PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pMetaDoc));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetadata, _T("Failed to copy metadata. %s (ErrorCode: 0x%08x)."), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetMetadata(pOutDoc, pMetadata), _T("Failed to set metadata. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
else
{
// Use the content of an XMP metadata file
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Create(pOutDoc, &mdataDescriptor)), _T("Failed to set metadata. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
}
else
{
// Set some metadata properties
TPtxPdf_Metadata* pMetadata = PtxPdf_Document_GetMetadata(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetadata, _T("Failed to get metadata. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetAuthor(pMetadata, _T("Your Author")), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetTitle(pMetadata, _T("Your Title")), _T("%s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetSubject(pMetadata, _T("Your Subject")), _T("%s(ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Metadata_SetCreator(pMetadata, _T("Your Creator")), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
// Copy document-wide data (excluding metadata)
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
C sample:
C# sample:
// Create encryption parameters
Encryption encryptionParams = new Encryption(UserPwd, OwnerPwd, Permission.Print |
Permission.DigitalPrint);
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document and set a user and owner password
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, encryptionParams))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
// Create encryption parameters
Encryption encryptionParams = new Encryption(userPwd, ownerPwd,
EnumSet.of(Permission.PRINT, Permission.DIGITAL_PRINT));
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document and set a user and owner password
Document outDoc = Document.create(outStream, inDoc.getConformance(), encryptionParams)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
pEncryption = PtxPdf_Encryption_New(szUserPwd, szOwnerPwd, ePtxPdf_Permission_Print | ePtxPdf_Permission_DigitalPrint);
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, pEncryption);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add copied pages to output
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages), _T("Failed to add copied pages to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define copy options including form field flattening
PageCopyOptions copyOptions = new PageCopyOptions();
copyOptions.FormFields = FormFieldCopyStrategy.Flatten;
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define copy options including form field flattening
PageCopyOptions copyOptions = new PageCopyOptions();
copyOptions.setFormFields(FormFieldCopyStrategy.FLATTEN);
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options: enable form field flattening
pCopyOptions = PtxPdf_PageCopyOptions_New();
PtxPdf_PageCopyOptions_SetFormFields(pCopyOptions, ePtxPdfForms_FormFieldCopyStrategy_Flatten);
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Add copied pages to output
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages), _T("Failed to add copied pages to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
C sample:
C# sample:
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, null, null))
{
// Create embedded font in output document
Font font = Font.CreateFromSystem(outDoc, "Arial", string.Empty, true);
// Define page copy options
PageCopyOptions pageCopyOptions = new PageCopyOptions();
var copiedPageLists = new List>(inPaths.Length);
// A page number counter
int pageNumber = 2;
// Copy all input documents pages
foreach (string inPath in inPaths)
{
// Open input document
using Stream inFs = new FileStream(inPath, FileMode.Open, FileAccess.Read);
using Document inDoc = Document.Open(inFs, null);
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, pageCopyOptions);
// Add page numbers to copied pages
foreach (var copiedPage in copiedPages)
{
AddPageNumber(outDoc, copiedPage, font, pageNumber++);
}
// Create outline item
string title = inDoc.Metadata.Title ?? System.IO.Path.GetFileNameWithoutExtension(inPath);
copiedPageLists.Add(new Tuple(title, copiedPages));
}
// Create table of contents page
var contentsPage = CreateTableOfContents(outDoc, copiedPageLists);
AddPageNumber(outDoc, contentsPage, font, 1);
// Add pages to the output document
PageList outPages = outDoc.Pages;
outPages.Add(contentsPage);
foreach (var tuple in copiedPageLists)
{
outPages.AddRange(tuple.Item2);
}
private static void AddPageNumber(Document outDoc, Page copiedPage, Font font, int pageNumber)
{
// Create content generator
using ContentGenerator generator = new ContentGenerator(copiedPage.Content, false);
// Create text object
Text text = Text.Create(outDoc);
// Create a text generator with the given font, size and position
using (TextGenerator textgenerator = new TextGenerator(text, font, 8, null))
{
// Generate string to be stamped as page number
string stampText = string.Format("Page {0}", pageNumber);
// Calculate position for centering text at bottom of page
Point position = new Point
{
X = (copiedPage.Size.Width / 2) - (textgenerator.GetWidth(stampText) / 2),
Y = 10
};
// Position the text
textgenerator.MoveTo(position);
// Add page number
textgenerator.Show(stampText);
}
// Paint the positioned text
generator.PaintText(text);
}
private static Page CreateTableOfContents(Document outDoc, List> copiedPageLists)
{
// Create a new page with size equal to the first page copied
var page = Page.Create(outDoc, copiedPageLists[0].Item2[0].Size);
// Create a font
var font = Font.CreateFromSystem(outDoc, "Arial", null, true);
// Parameters for layout computation
double border = 30;
double textWidth = page.Size.Width - 2 * border;
double chapterTitleSize = 24;
double titleSize = 12;
// The current text location
var location = new Point() { X = border, Y = page.Size.Height - border - chapterTitleSize };
// The page number of the current item in the table of content
int pageNumber = 2;
// Creat a content generator for the table of contents page
using (var contentGenerator = new ContentGenerator(page.Content, false))
{
// Create a text object
var text = Text.Create(outDoc);
// Create a text generator to generate the table of contents. Initially, use the chapter title font size
using (var textGenerator = new TextGenerator(text, font, chapterTitleSize, location))
{
// Show a chapter title
textGenerator.ShowLine("Table of Contents");
// Advance the vertical position
location.Y -= 1.7 * chapterTitleSize;
// Select the font size for an entry in the table of contents
textGenerator.FontSize = titleSize;
// Iterate over all copied page ranges
foreach (var tuple in copiedPageLists)
{
// The title string for the current entry
string title = tuple.Item1;
// The page number string of the target page for this entry
string pageNumberString = string.Format("{0}", pageNumber);
// The width of the page number string
double pageNumberWidth = textGenerator.GetWidth(pageNumberString);
// Compute the number of filler dots to be displayed between the entry title and the page number
int numberOfDots = (int)Math.Floor((textWidth - textGenerator.GetWidth(title) - pageNumberWidth) / textGenerator.GetWidth("."));
// Move to the current location and show the entry's title and the filler dots
textGenerator.MoveTo(location);
textGenerator.Show(title + new string('.', numberOfDots));
// Show the page number
textGenerator.MoveTo(new Point() { X = page.Size.Width - border - pageNumberWidth, Y = location.Y });
textGenerator.Show(pageNumberString);
// Compute the rectangle for the link
var linkRectangle = new Rectangle()
{
Left = border,
Bottom = location.Y + font.Descent * titleSize,
Right = border + textWidth,
Top = location.Y + font.Ascent * titleSize
};
// Create a destination to the first page of the current page range and create a link for this destination
var pageList = tuple.Item2;
var targetPage = pageList[0];
var destination = LocationZoomDestination.Create(outDoc, targetPage, 0, targetPage.Size.Height, null);
var link = InternalLink.Create(outDoc, linkRectangle, destination);
// Add the link to the table of contents page
page.Links.Add(link);
// Advance the location for the next entry
location.Y -= 1.8 * titleSize;
pageNumber += pageList.Count;
}
}
// Paint the generated text
contentGenerator.PaintText(text);
}
// Return the finished table-of-contents page
return page;
}
C# sample:
Java sample:
try (
// Open input document
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, null, null)) {
// Create embedded font in output document
Font font = Font.createFromSystem(outDoc, "Arial", "", true);
// Configure page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
Set> copiedPageLists = new HashSet<>(inPaths.length);
// A page number counter
int pageNumber = 2;
// Copy all input documents pages
for (String inPath : inPaths) {
try (// Open input document
Stream inFs = new FileStream(inPath, "r");
Document inDoc = Document.open(inFs, null)) {
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
// Add page numbers to copied pages
for ( Page copiedPage : copiedPages)
{
AddPageNumber(outDoc, copiedPage, font, pageNumber++);
}
// Hold the file name without extension
if (inPath == null)
continue;
// Get position of last '.'.
int pos = inPath.lastIndexOf(".");
// If there was a '.', hold the file name only
if (pos != -1)
inPath = inPath.substring(0, pos);
// Create outline item
String title = (inDoc.getMetadata().getTitle() == null ? inPath : inDoc.getMetadata().getTitle());
copiedPageLists.add(new AbstractMap.SimpleEntry(title, copiedPages));
}
}
// Create table of contents page
Page contentsPage = CreateTableOfContents(outDoc, copiedPageLists);
AddPageNumber(outDoc, contentsPage, font, 1);
// Add pages to the output document
PageList outPages = outDoc.getPages();
outPages.add(contentsPage);
for (Map.Entry entry : copiedPageLists)
{
outPages.addAll(entry.getValue());
}
private static void AddPageNumber(Document outDoc, Page copiedPage, Font font, int pageNumber) throws PdfToolboxException, IOException
{
// Create content generator
try (ContentGenerator generator = new ContentGenerator(copiedPage.getContent(), false)) {
// Create text object
Text text = Text.create(outDoc);
// Create a text generator with the given font, size and position
try (TextGenerator textgenerator = new TextGenerator(text, font, 8, null)) {
// Generate string to be stamped as page number
String stampText = String.format("Page %d", pageNumber);
// Calculate position for centering text at bottom of page
Point position = new Point();
position.x = (copiedPage.getSize().getWidth() / 2) - (textgenerator.getWidth(stampText) / 2);
position.y = 10;
// Position the text
textgenerator.moveTo(position);
// Add page number
textgenerator.show(stampText);
}
// Paint the positioned text
generator.paintText(text);
}
}
private static Page CreateTableOfContents(Document outDoc, Set> copiedPageLists) throws IOException, PdfToolboxException
{
// Create a new page with size equal to the first page copied
Page page = Page.create(outDoc, copiedPageLists.iterator().next().getValue().get(0).getSize());
// Create a font
Font font = Font.createFromSystem(outDoc, "Arial", null, true);
// Parameters for layout computation
double border = 30;
double textWidth = page.getSize().getWidth() - 2 * border;
double chapterTitleSize = 24;
double titleSize = 12;
// The current text location
Point location = new Point();
location.x = border;
location.y = page.getSize().getHeight() - border - chapterTitleSize;
// The page number of the current item in the table of content
int pageNumber = 2;
// Creat a content generator for the table of contents page
try (ContentGenerator contentGenerator = new ContentGenerator(page.getContent(), false)) {
// Create a text object
Text text = Text.create(outDoc);
// Create a text generator to generate the table of contents. Initially, use the chapter title font size
try (TextGenerator textGenerator = new TextGenerator(text, font, chapterTitleSize, location)) {
// Show a chapter title
textGenerator.showLine("Table of Contents");
// Advance the vertical position
location.y -= 1.7 * chapterTitleSize;
// Select the font size for an entry in the table of contents
textGenerator.setFontSize(titleSize);
// Iterate over all copied page ranges
for (Map.Entry entry : copiedPageLists)
{
// The title string for the current entry
String title = entry.getKey();
// The page number string of the target page for this entry
String pageNumberString = String.format("%d", pageNumber);
// The width of the page number string
double pageNumberWidth = textGenerator.getWidth(pageNumberString);
// Compute the number of filler dots to be displayed between the entry title and the page number
int numberOfDots = (int)Math.floor((textWidth - textGenerator.getWidth(title) - pageNumberWidth) / textGenerator.getWidth("."));
// Move to the current location and show the entry's title and the filler dots
textGenerator.moveTo(location);
String dots = new String();
for (int i = 0; i < numberOfDots; i++)
{
dots += '.';
}
textGenerator.show(title + dots);
// Show the page number
Point point = new Point();
point.x = page.getSize().getWidth() - border - pageNumberWidth;
point.y = location.y;
textGenerator.moveTo(point);
textGenerator.show(pageNumberString);
// Compute the rectangle for the link
Rectangle linkRectangle = new Rectangle();
linkRectangle.setLeft(border);
linkRectangle.setBottom(location.y + font.getDescent() * titleSize);
linkRectangle.setRight(border + textWidth);
linkRectangle.setTop(location.y + font.getAscent() * titleSize);
// Create a destination to the first page of the current page range and create a link for this destination
PageList pageList = entry.getValue();
Page targetPage = pageList.get(0);
LocationZoomDestination destination = LocationZoomDestination.create(outDoc, targetPage, (double) 0, targetPage.getSize().getHeight(), null);
InternalLink link = InternalLink.create(outDoc, linkRectangle, destination);
// Add the link to the table of contents page
page.getLinks().add(link);
// Advance the location for the next entry
location.y -= 1.8 * titleSize;
pageNumber += pageList.size();
}
}
// Paint the generated text
contentGenerator.paintText(text);
}
// Return the finished table-of-contents page
return page;
}
Java sample:
C# sample:
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, null, null))
{
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Get output pages
PageList outPages = outDoc.Pages;
// Merge input documents
for (int i = 0; i < args.Length - 1; i++)
{
// Open input document
using Stream inFs = new FileStream(inPath[i], FileMode.Open, FileAccess.Read);
using Document inDoc = Document.Open(inFs, null);
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outPages.AddRange(copiedPages);
}
}
C# sample:
Java sample:
try (
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, null, null)) {
// Configure page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Get output pages
PageList outPages = outDoc.getPages();
// Merge input document
for (int i = 0; i < args.length - 1; i++) {
try (// Open input document
FileStream inStream = new FileStream(inPath[i], "r");
Document inDoc = Document.open(inStream, null)) {
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
outPages.addAll(copiedPages);
}
}
}
}
Java sample:
C sample:
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, NULL, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Get output page list
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Merge input documents
for (int i = 1; i < argc - 1; i++)
{
// Open input document
pInStream = _tfopen(szInPath[i], _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath[i]);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath[i], szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Append copied pages
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages), _T("Failed to add page range. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
Ptx_Release(pInPageList);
pInPageList = NULL;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_Close(pInDoc), _T("Failed to close input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pInDoc = NULL;
fclose(pInStream);
pInStream = NULL;
Ptx_Release(pCopiedPages);
pCopiedPages = NULL;
}
C sample:
C# sample:
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, null, null))
{
// Define page copy options, skip outline
PageCopyOptions pageCopyOptions = new PageCopyOptions
{
CopyOutlineItems = false
};
// Define outline copy options
OutlineCopyOptions outlineCopyOptions = new OutlineCopyOptions();
// Get output pages
PageList outPages = outDoc.Pages;
// Merge input documents
foreach (string inPath in inPaths)
{
// Open input document
using Stream inFs = new FileStream(inPath, FileMode.Open, FileAccess.Read);
using Document inDoc = Document.Open(inFs, null);
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, pageCopyOptions);
outPages.AddRange(copiedPages);
// Create outline item
string title = inDoc.Metadata.Title ?? Path.GetFileName(inPath);
Page firstCopiedPage = copiedPages[0];
Destination destination = LocationZoomDestination.Create(outDoc, firstCopiedPage, 0, firstCopiedPage.Size.Height, null);
OutlineItem outlineItem = OutlineItem.Create(outDoc, title, destination);
outDoc.Outline.Add(outlineItem);
// Add outline items from input document as children
OutlineItemList children = outlineItem.Children;
foreach (OutlineItem inputOutline in inDoc.Outline)
children.Add(OutlineItem.Copy(outDoc, inputOutline, outlineCopyOptions));
}
}
C# sample:
Java sample:
try (
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, null, null)) {
// Define page copy options, skip outline
PageCopyOptions pageCopyOptions = new PageCopyOptions();
pageCopyOptions.setCopyOutlineItems(false);
// Define outline copy options
OutlineCopyOptions outlineCopyOptions = new OutlineCopyOptions();
// Get output pages
PageList outPages = outDoc.getPages();
// Merge input document
for (String inPath : inPaths) {
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null)) {
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), pageCopyOptions);
outPages.addAll(copiedPages);
// Create outline item
String title = inDoc.getMetadata().getTitle();
if (title == null)
title = Paths.get(inPath).getFileName().toString();
Page firstCopiedPage = copiedPages.get(0);
Destination destination = LocationZoomDestination.create(outDoc, firstCopiedPage, 0.0,
firstCopiedPage.getSize().getHeight(), null);
OutlineItem outlineItem = OutlineItem.create(outDoc, title, destination);
outDoc.getOutline().add(outlineItem);
// Add outline items from input document as children
OutlineItemList children = outlineItem.getChildren();
for (OutlineItem inputOutline : inDoc.getOutline())
children.add(OutlineItem.copy(outDoc, inputOutline, outlineCopyOptions));
}
}
}
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Create transparency and set blend mode
Transparency transparency = new Transparency(colorAlpha)
{
BlendMode = BlendMode.Multiply
};
// Create colorspace
ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, colorType);
// Create a transparent paint for the given color
Paint paint = Paint.Create(outDoc, colorSpace, color, transparency);
Fill fill = new Fill(paint);
// Get output pages
PageList outPages = outDoc.Pages;
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Loop through all pages
foreach (Page inPage in inDoc.Pages)
{
// Create a new page
Size size = inPage.Size;
Page outPage = Page.Copy(outDoc, inPage, copyOptions);
// Create a content generator
using (ContentGenerator generator = new ContentGenerator(outPage.Content, false))
{
// Compute Rectangle
Rectangle rect = new Rectangle
{
Left = 0,
Bottom = 0,
Right = size.Width,
Top = size.Height
};
// Make a rectangular path the same size as the page
PdfTools.FourHeights.PdfToolbox.Pdf.Content.Path path = new PdfTools.FourHeights.PdfToolbox.Pdf.Content.Path();
using (PathGenerator pathGenerator = new PathGenerator(path))
{
Rectangle pathRect = new Rectangle
{
Left = 0,
Bottom = 0,
Right = size.Width,
Top = size.Height
};
pathGenerator.AddRectangle(pathRect);
}
// Paint the path with the transparent paint
generator.PaintPath(path, fill, null);
}
// Add pages to output document
outPages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Create transparency and set blend mode
Transparency transparency = new Transparency(colorAlpha);
transparency.setBlendMode(BlendMode.MULTIPLY);
// Create colorspace
ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outDoc, colorType);
// Create a transparent paint for the given color
Paint paint = Paint.create(outDoc, colorSpace, color, transparency);
Fill fill = new Fill(paint);
// Set copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Loop through all pages
for (Page inPage : inDoc.getPages()) {
// Create a new page
Size size = inPage.getSize();
Page outPage = Page.copy(outDoc, inPage, copyOptions);
try (// Create a content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Calculate rectangle
Rectangle rect = new Rectangle(0, 0, size.width, size.height);
// Make a rectangular path the same size as the page
Path path = new Path();
try (
PathGenerator pathGenerator = new PathGenerator(path)) {
pathGenerator.addRectangle(rect);
}
// Paint the path with the transparent paint
generator.paintPath(path, fill, null);
}
// Add pages to output document
outDoc.getPages().add(outPage);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outDoc.Pages.AddRange(copiedPages);
// Set info entry
Metadata metadata = Metadata.Copy(outDoc, inDoc.Metadata);
if (key == "Title")
metadata.Title = value;
else if (key == "Author")
metadata.Author = value;
else if (key == "Subject")
metadata.Subject = value;
else if (key == "Keywords")
metadata.Keywords = value;
else if (key == "CreationDate")
metadata.CreationDate = DateTimeOffset.Parse(value);
else if (key == "ModDate")
throw new Exception("ModDate cannot be set.");
else if (key == "Creator")
metadata.Creator = value;
else if (key == "Producer")
throw new Exception("Producer is set by means of the license key.");
else
metadata.CustomEntries[key] = value;
outDoc.Metadata = metadata;
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data (except metadata)
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
outDoc.getPages().addAll(copiedPages);
// Set info entry
Metadata metadata = Metadata.copy(outDoc, inDoc.getMetadata());
if (key.equals("Title"))
metadata.setTitle(value);
else if (key.equals("Author"))
metadata.setAuthor(value);
else if (key.equals("Subject"))
metadata.setSubject(value);
else if (key.equals("Keywords"))
metadata.setKeywords(value);
else if (key.equals("CreationDate")) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd' 'HH:mm:ssZ");
OffsetDateTime creationDate = OffsetDateTime.parse(value, formatter);
metadata.setCreationDate(creationDate);
} else if (key.equals("ModDate"))
throw new Exception("ModDate cannot be set.");
else if (key.equals("Creator"))
metadata.setCreator(value);
else if (key.equals("Producer"))
throw new Exception("Producer is set by means of the license key.");
else
metadata.getCustomEntries().put(key, value);
outDoc.setMetadata(metadata);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data (excluding metadata)
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
if (destinationPageNumber < 1 || destinationPageNumber > inDoc.Pages.Count)
throw new ArgumentOutOfRangeException("Given page number is invalid");
// Create output document
using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
outDoc.Pages.AddRange(copiedPages);
// Add open destination
Page outPage = copiedPages[destinationPageNumber - 1];
outDoc.OpenDestination = LocationZoomDestination.Create(outDoc, outPage, 0, outPage.Size.Height, null);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Check given page number
if (destinationPageNumber < 1 || destinationPageNumber > inDoc.getPages().size()) {
System.out.println("Given pageNumber is invalid.");
return;
}
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages and append to output document
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
outDoc.getPages().addAll(copiedPages);
// Add open destination
Page outPage = outDoc.getPages().get(destinationPageNumber - 1);
LocationZoomDestination destination = LocationZoomDestination.create(outDoc, outPage, 0.0, outPage.getSize().getHeight(), null);
outDoc.setOpenDestination(destination);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
startIndex = Math.Max(Math.Min(inDoc.Pages.Count - 1, startIndex), 0);
count = Math.Min(inDoc.Pages.Count - startIndex, count);
if (count <= 0)
{
Console.WriteLine("lastPage must be greater or equal to firstPage");
return;
}
// Create output document
using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Get page range from input pages
PageList inPageRange = inDoc.Pages.GetRange(startIndex, count);
// Copy page range and append to output document
PageList outPageRange = PageList.Copy(outDoc, inPageRange, copyOptions);
outDoc.Pages.AddRange(outPageRange);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null)) {
// Get pages from input document
PageList inPages = inDoc.getPages();
// Correct and check page indices
startIndex = Math.max(Math.min(inPages.size() - 1, startIndex), 0);
endIndex = Math.max(Math.min(inPages.size(), endIndex), 0);
if (startIndex >= endIndex) {
System.out.println("lastPage must be greater or equal to firstPage");
return;
}
try (
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Get page range from input pages
PageList inPageRange = inPages.subList(startIndex, endIndex);
// Copy page range and append to output document
PageList outPageRange = PageList.copy(outDoc, inPageRange, copyOptions);
outDoc.getPages().addAll(outPageRange);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain mbedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int nInPages = PtxPdf_PageList_GetCount(pInPageList);
iStartIndex = MAX(MIN(nInPages - 1, iStartIndex), 0);
nCount = MIN(nInPages - iStartIndex, nCount);
GOTO_CLEANUP_IF_FALSE(nCount > 0, _T("lastPage must be greater or equal to firstPage.\n"));
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Get page range from input pages
pInPageRange = PtxPdf_PageList_GetRange(pInPageList, iStartIndex, nCount);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to get page range from input document. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Copy page range to toutput document
pOutPageRange = PtxPdf_PageList_Copy(pOutDoc, pInPageRange, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageRange, _T("Failed to copy page range. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Get output pages
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Appende page range to output pages
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pOutPageRange), _T("Failed to append page range. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
// Collect all outline items at the given level
List outlines = GetOutlines(inDoc.Outline, level);
// Collect all page ranges corresponding to the given outline items
List> parts = GetParts(inDoc.Pages, outlines);
// Iterate over all collected parts
foreach (var part in parts)
{
// Turn the outline item's title into a valid file name
string fileName = part.Item2.Title;
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(c, '_');
}
fileName += ".pdf";
fileName = System.IO.Path.Combine(outDir, fileName);
// Create output document
using Stream outStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions pageCopyOptions = new PageCopyOptions();
pageCopyOptions.CopyOutlineItems = false;
// Copy the pages and add to the output document's page list
PageList outPages = PageList.Copy(outDoc, part.Item1, pageCopyOptions);
outDoc.Pages.AddRange(outPages);
// Copy child outline items
OutlineCopyOptions outlineCopyOptions = new OutlineCopyOptions();
foreach (var child in part.Item2.Children)
{
outDoc.Outline.Add(OutlineItem.Copy(outDoc, child, outlineCopyOptions));
}
}
}
private static List GetOutlines(OutlineItemList currentOutlines, int level, int currentLevel = 1)
{
List matchingOutlines = new List();
// If the current level matches the specified level add the given outline items
if (level == currentLevel)
{
matchingOutlines.AddRange(currentOutlines);
}
else
{
// Otherwise recurse to next level
foreach (var outline in currentOutlines)
{
matchingOutlines.AddRange(GetOutlines(outline.Children, level, currentLevel + 1));
}
}
return matchingOutlines;
}
private static List> GetParts(PageList inPages, List outlines)
{
// Construct parts according to the given outlines
List> parts = new List>();
// No parts to be constructed if no outlines are found
if (outlines.Count == 0)
return parts;
// Keep both the last and the next outline items while iterating
OutlineItem lastOutline = null;
var outlineEnumerator = outlines.GetEnumerator();
outlineEnumerator.MoveNext();
OutlineItem nextOutline = outlineEnumerator.Current;
// Keep both, the last and the current page index while iterating
int lastPageIndex = 0;
for (int pageIndex = 0; pageIndex < inPages.Count; pageIndex++)
{
// Check if this page is the destination's page of the next outline
if (inPages[pageIndex].Equals(nextOutline.Destination.Target.Page))
{
// Create a new part if the last outline item is defined and if the page index has increased at least by 1
if (lastOutline != null && pageIndex - lastPageIndex > 0)
parts.Add(new Tuple(inPages.GetRange(lastPageIndex, pageIndex - lastPageIndex), lastOutline));
// Keep the current page index as the last page index used
lastPageIndex = pageIndex;
// Keep the current outline as the last outline used
lastOutline = nextOutline;
// Iterate to the next outline item and stop if none left
if (outlineEnumerator.MoveNext())
nextOutline = outlineEnumerator.Current;
else
break;
}
}
// Add the last part which is assumed to contain all the pages until the end of the document
parts.Add(new Tuple(inPages.GetRange(lastPageIndex, inPages.Count - lastPageIndex), lastOutline));
return parts;
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Imposition
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Create a font
Font font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);
// Copy pages
PageList inPages = inDoc.Pages;
PageList outPages = outDoc.Pages;
int numberOfSheets = (inPages.Count + 3) / 4;
for (int sheetNumber = 0; sheetNumber < numberOfSheets; ++sheetNumber)
{
// Add on front side
CreateBooklet(inPages, outDoc, outPages, 4 * numberOfSheets - 2 * sheetNumber - 1,
2 * sheetNumber, font);
// Add on back side
CreateBooklet(inPages, outDoc, outPages, 2 * sheetNumber + 1,
4 * numberOfSheets - 2 * sheetNumber - 2, font);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void CreateBooklet(PageList inPages, Document outDoc, PageList outPages, int leftPageIndex,
int rightPageIndex, Font font)
{
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Create page object
Page outpage = Page.Create(outDoc, PageSize);
// Create content generator
using (ContentGenerator generator = new ContentGenerator(outpage.Content, false))
{
// Left page
if (leftPageIndex < inPages.Count)
{
// Copy page from input to output
Page leftPage = inPages[leftPageIndex];
Group leftGroup = Group.CopyFromPage(outDoc, leftPage, copyOptions);
// Paint group on the calculated rectangle
generator.PaintGroup(leftGroup, ComputTargetRect(leftGroup.Size, true), null);
// Add page number to page
StampPageNumber(outDoc, font, generator, leftPageIndex + 1, true);
}
// Right page
if (rightPageIndex < inPages.Count)
{
// Copy page from input to output
Page rigthPage = inPages[rightPageIndex];
Group rightGroup = Group.CopyFromPage(outDoc, rigthPage, copyOptions);
// Paint group on the calculated rectangle
generator.PaintGroup(rightGroup, ComputTargetRect(rightGroup.Size, false), null);
// Add page number to page
StampPageNumber(outDoc, font, generator, rightPageIndex + 1, false);
}
}
// Add page to output document
outPages.Add(outpage);
}
private static Rectangle ComputTargetRect(Size bbox, bool isLeftPage)
{
// Calculate factor for fitting page into rectangle
double scale = Math.Min(CellWidth / bbox.Width, CellHeight / bbox.Height);
double groupWidth = bbox.Width * scale;
double groupHeight = bbox.Height * scale;
// Calculate x-value
double groupXPos = isLeftPage ? CellLeft + (CellWidth - groupWidth) / 2 :
CellRight + (CellWidth - groupWidth) / 2;
// Calculate y-value
double groupYPos = CellYPos + (CellHeight - groupHeight) / 2;
// Calculate rectangle
return new Rectangle
{
Left = groupXPos,
Bottom = groupYPos,
Right = groupXPos + groupWidth,
Top = groupYPos + groupHeight
};
}
private static void StampPageNumber(Document document, Font font, ContentGenerator generator,
int PageNo, bool isLeftPage)
{
// Create text object
Text text = Text.Create(document);
// Create text generator
using (TextGenerator textgenerator = new TextGenerator(text, font, 8, null))
{
string stampText = string.Format("Page {0}", PageNo);
// Get width of stamp text
double width = textgenerator.GetWidth(stampText);
// Calculate position
double x = isLeftPage ? Border + 0.5 * CellWidth - width / 2 :
2 * Border + 1.5 * CellWidth - width / 2;
double y = Border;
// Move to position
textgenerator.MoveTo(new Point { X = x, Y = y});
// Add page number
textgenerator.Show(stampText);
}
// Paint the positioned text
generator.PaintText(text);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
Font font = Font.createFromSystem(outDoc, "Arial", "Italic", true);
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Copy pages
PageList inPages = inDoc.getPages();
PageList outPages = outDoc.getPages();
int numberOfSheets = (inPages.size() + 3) / 4;
for (int sheetNumber = 0; sheetNumber < numberOfSheets; ++sheetNumber) {
// Add on front side
createBooklet(inPages, outDoc, outPages, 4 * numberOfSheets - 2 * sheetNumber - 1,
2 * sheetNumber, font);
// Add on back side
createBooklet(inPages, outDoc, outPages, 2 * sheetNumber + 1,
4 * numberOfSheets - 2 * sheetNumber - 2, font);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void createBooklet(PageList inPages, Document outDoc, PageList outPages, int leftPageIndex,
int rightPageIndex, Font font) throws PdfToolboxException, IOException {
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Create page object
Page outPage = Page.create(outDoc, new Size(PageWidth, PageHeight));
try (// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Left page
if (leftPageIndex < inPages.size()) {
Page leftPage = inPages.get(leftPageIndex);
// Copy page from input to output
Group leftGroup = Group.copyFromPage(outDoc, leftPage, copyOptions);
// Paint group on the calculated rectangle
generator.paintGroup(leftGroup, computeTargetRect(leftGroup.getSize(), true), null);
// Add page number to page
StampPageNumber(outDoc, font, generator, leftPageIndex + 1, true);
}
// Right page
if (rightPageIndex < inPages.size()) {
Page rightPage = inPages.get(rightPageIndex);
// Copy page from input to output
Group rightGroup = Group.copyFromPage(outDoc, rightPage, copyOptions);
// Paint group on the calculated rectangle
generator.paintGroup(rightGroup, computeTargetRect(rightGroup.getSize(), false), null);
// Add page number to page
StampPageNumber(outDoc, font, generator, rightPageIndex + 1, false);
}
}
// Add page to output document
outPages.add(outPage);
}
private static Rectangle computeTargetRect(Size bbox, Boolean isLeftPage) {
// Calculate factor for fitting page into rectangle
double scale = Math.min(CellWidth / bbox.width, CellHeight / bbox.height);
double groupWidth = bbox.width * scale;
double groupHeight = bbox.height * scale;
// Calculate x-value
double groupXPos = isLeftPage ? CellLeft + (CellWidth - groupWidth) / 2 :
CellRight + (CellWidth - groupWidth) / 2;
// Calculate y-value
double groupYPos = CellYPos + (CellHeight - groupHeight) / 2;
// Calculate rectangle
return new Rectangle(groupXPos, groupYPos, groupXPos + groupWidth, groupYPos + groupHeight);
}
private static void StampPageNumber(Document document, Font font, ContentGenerator generator, int pageNo,
boolean isLeftPage) throws PdfToolboxException, IOException {
// Create text object
Text text = Text.create(document);
try (// Create text generator
TextGenerator textgenerator = new TextGenerator(text, font, 8, null)) {
String stampText = String.format("Page %d", pageNo);
// Get width of stamp text
double width = textgenerator.getWidth(stampText);
// Calculate position
double x = isLeftPage ? Border + 0.5 * CellWidth - width / 2 :
2 * Border + 1.5 * CellWidth - width / 2;
double y = Border;
// Move to position
textgenerator.moveTo(new Point(x, y));
// Add page number
textgenerator.show(stampText);
}
// Paint the positioned text
generator.paintText(text);
}
Java sample:
C sample:
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
// Objects that need releasing or closing
TPtxPdfContent_IccBasedColorSpace* pInOutputIntent = NULL;
TPtxPdfContent_IccBasedColorSpace* pOutOutputIntent = NULL;
TPtxPdf_Metadata* pInMetadata = NULL;
TPtxPdf_Metadata* pOutMetadata = NULL;
TPtxPdfNav_ViewerSettings* pInViewerSettings = NULL;
TPtxPdfNav_ViewerSettings* pOutViewerSettings = NULL;
TPtxPdf_FileReferenceList* pInFileRefList = NULL;
TPtxPdf_FileReferenceList* pOutFileRefList = NULL;
TPtxPdf_FileReference* pInFileRef = NULL;
TPtxPdf_FileReference* pOutFileRef = NULL;
iReturnValue = 0;
// Output intent
pInOutputIntent = PtxPdf_Document_GetOutputIntent(pInDoc);
if (pInOutputIntent != NULL)
{
pOutOutputIntent = PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, pInOutputIntent);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutOutputIntent, _T("Failed to copy ICC-based color space. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetOutputIntent(pOutDoc, pOutOutputIntent), _T("Failed to set output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
}
else
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get output intent. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Metadata
pInMetadata = PtxPdf_Document_GetMetadata(pInDoc);
if (pInMetadata != NULL)
{
pOutMetadata = PtxPdf_Metadata_Copy(pOutDoc, pInMetadata);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutMetadata, _T("Failed to copy metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetMetadata(pOutDoc, pOutMetadata), _T("Failed to set metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
}
else
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get metadata. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Viewer settings
pInViewerSettings = PtxPdf_Document_GetViewerSettings(pInDoc);
if (pInViewerSettings != NULL)
{
pOutViewerSettings = PtxPdfNav_ViewerSettings_Copy(pOutDoc, pInViewerSettings);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutViewerSettings, _T("Failed to copy viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Document_SetViewerSettings(pOutDoc, pOutViewerSettings), _T("Failed to set viewer settings. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
}
else
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get viewer settings. %s (ErrorCode: 0x%08x)"), szErrorBuff, Ptx_GetLastError());
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of input document. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get associated files of output document. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
int nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of associated files. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
{
pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef), _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
Ptx_Release(pInFileRef);
pInFileRef = NULL;
Ptx_Release(pOutFileRef);
pOutFileRef = NULL;
}
Ptx_Release(pInFileRefList);
pInFileRefList = NULL;
Ptx_Release(pOutFileRefList);
pOutFileRefList = NULL;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRefList, _T("Failed to get plain embedded files of input document %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRefList, _T("Failed to get plain embedded files of output document %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
nFileRefs = PtxPdf_FileReferenceList_GetCount(pInFileRefList);
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get count of plain embedded files. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
for (int iFileRef = 0; iFileRef < nFileRefs; iFileRef++)
{
pInFileRef = PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInFileRef, _T("Failed to get file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
pOutFileRef = PtxPdf_FileReference_Copy(pOutDoc, pInFileRef);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutFileRef, _T("Failed to copy file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_FileReferenceList_Add(pOutFileRefList, pOutFileRef), _T("Failed to add file reference. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
Ptx_Release(pInFileRef);
pInFileRef = NULL;
Ptx_Release(pOutFileRef);
pOutFileRef = NULL;
}
cleanup:
if (pInOutputIntent != NULL) Ptx_Release(pInOutputIntent);
if (pOutOutputIntent != NULL) Ptx_Release(pOutOutputIntent);
if (pInMetadata != NULL) Ptx_Release(pInMetadata);
if (pOutMetadata != NULL) Ptx_Release(pOutMetadata);
if (pInViewerSettings != NULL) Ptx_Release(pInViewerSettings);
if (pOutViewerSettings != NULL) Ptx_Release(pOutViewerSettings);
if (pInFileRefList != NULL) Ptx_Release(pInFileRefList);
if (pOutFileRefList != NULL) Ptx_Release(pOutFileRefList);
if (pInFileRef != NULL) Ptx_Release(pInFileRef);
if (pOutFileRef != NULL) Ptx_Release(pOutFileRef);
return iReturnValue;
}
int StampPageNumber(TPtxPdf_Document* pDocument, TPtxPdfContent_Font* pFont, TPtxPdfContent_ContentGenerator* pGenerator, int nPageNo, BOOL bIsLeftPage)
{
// Objects that need releasing or closing
TPtxPdfContent_Text* pText = NULL;
TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
// Create text object
pText = PtxPdfContent_Text_Create(pDocument);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create text object. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Create text generator
pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, 8.0, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create text generator. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
TCHAR szStampText[50];
_stprintf(szStampText, _T("Page %d"), nPageNo);
// Get width of stamp text
double dStampWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampText);
if (dStampWidth == 0.0)
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get text width. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Compute position
TPtxGeomReal_Point point =
{
.dX = bIsLeftPage ? dBorder + 0.5 * dCellWidth - dStampWidth / 2 :
2 * dBorder + 1.5 * dCellWidth - dStampWidth / 2,
.dY = dBorder,
};
// Move to position
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &point), _T("Failed to move to position. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Add page number
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_Show(pTextGenerator, szStampText), _T("Failed to show text. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
BOOL bClose = PtxPdfContent_TextGenerator_Close(pTextGenerator);
pTextGenerator = NULL;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(bClose, _T("Failed to close text generator. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Paint the positioned text
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText), _T("Failed to paint text. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pText != NULL) Ptx_Release(pText);
if (pTextGenerator != NULL) PtxPdfContent_TextGenerator_Close(pTextGenerator);
return iReturnValue;
}
void ComputeTargetRect(TPtxGeomReal_Rectangle* pRectangle, const TPtxGeomReal_Size* pBBox, BOOL bIsLeftPage)
{
// Compute factor for fitting page into rectangle
double dScale = MIN(dCellWidth / pBBox->dWidth, dCellHeight / pBBox->dHeight);
double dGroupWidth = pBBox->dWidth * dScale;
double dGroupHeight = pBBox->dHeight * dScale;
// Compute x-value
double dGroupXPos = bIsLeftPage ? dCellLeft + (dCellWidth - dGroupWidth) / 2 :
dCellRight + (dCellWidth - dGroupWidth) / 2;
// Compute y-value
double dGroupYPos = dCellYPos + (dCellHeight - dGroupHeight) / 2;
// Set rectangle
pRectangle->dLeft = dGroupXPos;
pRectangle->dBottom = dGroupYPos;
pRectangle->dRight = dGroupXPos + dGroupWidth;
pRectangle->dTop = dGroupYPos + dGroupHeight;
}
int CreateBooklet(TPtxPdf_PageList* pInDocList, TPtxPdf_Document* pOutDoc, TPtxPdf_PageList* pOutDocList, int nLeftPageIndex, int nRightPageIndex, TPtxPdfContent_Font* pFont)
{
// Objects that need releasing or closing
TPtxPdf_PageCopyOptions* pCopyOptions = NULL;
TPtxPdf_Page* pOutPage = NULL;
TPtxPdfContent_Content* pContent = NULL;
TPtxPdfContent_ContentGenerator* pGenerator = NULL;
TPtxPdf_Page* pInPage = NULL;
TPtxPdfContent_Group* pGroup = NULL;
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Create page object
pOutPage = PtxPdf_Page_Create(pOutDoc, &pageSize);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to create page object. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Create content generator
pContent = PtxPdf_Page_GetContent(pOutPage);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pContent, _T("Failed to get content. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create content generator. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
int nPageCount = PtxPdf_PageList_GetCount(pInDocList);
GOTO_CLEANUP_IF_ERROR_PRINT_ERROR(_T("Failed to get page list count. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Left page
if (nLeftPageIndex < nPageCount)
{
// Get the input page
pInPage = PtxPdf_PageList_Get(pInDocList, nLeftPageIndex);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Copy page from input to output
pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Compute group location
TPtxGeomReal_Size groupSize;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize), _T("Failed to get group size. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
TPtxGeomReal_Rectangle targetRect;
ComputeTargetRect(&targetRect, &groupSize, TRUE);
// Paint group at location
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL), _T("Failed to paint group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Add page number to page
if (StampPageNumber(pOutDoc, pFont, pGenerator, nLeftPageIndex + 1, TRUE) != 0)
goto cleanup;
Ptx_Release(pInPage);
pInPage = NULL;
Ptx_Release(pGroup);
pGroup = NULL;
}
// Right page
if (nRightPageIndex < nPageCount)
{
// Get the input Page
pInPage = PtxPdf_PageList_Get(pInDocList, nRightPageIndex);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("Failed to get page. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Copy page from input to output
pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Compute group location
TPtxGeomReal_Size groupSize;
PtxPdfContent_Group_GetSize(pGroup, &groupSize);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize), _T("Failed to get group size. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
TPtxGeomReal_Rectangle targetRect;
ComputeTargetRect(&targetRect, &groupSize, FALSE);
// Paint group on the Computed rectangle
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL), _T("Failed to paint group. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Add page number to page
if (StampPageNumber(pOutDoc, pFont, pGenerator, nRightPageIndex + 1, FALSE) != 0)
goto cleanup;
}
BOOL bClose = PtxPdfContent_ContentGenerator_Close(pGenerator);
pGenerator = NULL;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(bClose, _T("Failed to close content generator. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutDocList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x)\n"), szErrorBuff, Ptx_GetLastError());
cleanup:
if (pGenerator != NULL) PtxPdfContent_ContentGenerator_Close(pGenerator);
if (pCopyOptions != NULL) Ptx_Release(pCopyOptions);
if (pOutPage != NULL) Ptx_Release(pOutPage);
if (pContent != NULL) Ptx_Release(pContent);
if (pInPage != NULL) Ptx_Release(pInPage);
if (pGroup != NULL) Ptx_Release(pGroup);
return iReturnValue;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy pages
foreach (Page inPage in inDoc.Pages)
{
Page outPage = null;
Size pageSize = inPage.Size;
bool rotate = AllowRotate &&
(pageSize.Height >= pageSize.Width) != (TargetSize.Height >= TargetSize.Width);
Size rotatedSize = pageSize;
if (rotate)
rotatedSize = new Size { Width = pageSize.Height, Height = pageSize.Width };
if (rotatedSize.Width == TargetSize.Width && rotatedSize.Height == TargetSize.Width)
{
// If size is correct, copy page only
outPage = Page.Copy(outDoc, inPage, copyOptions);
if (rotate)
outPage.Rotate(Rotation.Clockwise);
}
else
{
// Create new page of correct size and fit existing page onto it
outPage = Page.Create(outDoc, TargetSize);
// Copy page as group
Group group = Group.CopyFromPage(outDoc, inPage, copyOptions);
// Calculate scaling and position of group
double scale = Math.Min(TargetSize.Width / rotatedSize.Width,
TargetSize.Height / rotatedSize.Height);
// Calculate position
Point position = new Point
{
X = (TargetSize.Width - pageSize.Width * scale) / 2,
Y = (TargetSize.Height - pageSize.Height * scale) / 2
};
// Create content generator
using ContentGenerator generator = new ContentGenerator(outPage.Content, false);
// Calculate and apply transformation
AffineTransform transform = AffineTransform.Identity;
transform.Translate(position.X, position.Y);
transform.Scale(scale, scale);
Point point = new Point()
{
X = pageSize.Width / 2.0,
Y = pageSize.Height / 2.0
};
// Rotate input file
if (rotate)
transform.Rotate(90, point);
generator.Transform(transform);
// Paint group
generator.PaintGroup(group, null, null);
}
// Add page to output document
outDoc.Pages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy pages
for (Page inPage : inDoc.getPages()) {
Page outPage = null;
Size pageSize = inPage.getSize();
boolean rotate = AllowRotate &&
(pageSize.height >= pageSize.width) != (TargetHeight >= TargetWidth);
Size rotatedSize = pageSize;
if (rotate)
rotatedSize = new Size(pageSize.height, pageSize.width);
if (rotatedSize.width == TargetWidth && rotatedSize.height == TargetWidth) {
// If size is correct, copy page only
outPage = Page.copy(outDoc, inPage, copyOptions);
if (rotate)
outPage.rotate(Rotation.CLOCKWISE);
} else {
// Create new page of correct size and fit existing page onto it
outPage = Page.create(outDoc, new Size(TargetWidth, TargetHeight));
// Copy page as group
Group group = Group.copyFromPage(outDoc, inPage, copyOptions);
// Calculate scaling and position of group
double scale = Math.min(TargetWidth / rotatedSize.width,
TargetHeight / rotatedSize.height);
// Calculate position
Point position = new Point(
(TargetWidth - pageSize.width * scale) / 2,
(TargetHeight - pageSize.height * scale) / 2);
try(// Create content generator
ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
// Calculate and apply transformation
AffineTransform transform = AffineTransform.getIdentity();
transform.translate(position.x, position.y);
transform.scale(scale, scale);
Point point = new Point(pageSize.width / 2.0, pageSize.height / 2.0);
// Rotate input file
if (rotate)
transform.rotate(90, point);
generator.transform(transform);
// Paint group
generator.paintGroup(group, null, null);
}
}
// Add page to output document
outDoc.getPages().add(outPage);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
{
TPtxGeomReal_Size pageSize;
TPtxGeomReal_Size rotatedSize;
BOOL bRotate;
pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPage, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPage = NULL;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pInPage, &pageSize), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
bRotate = bAllowRotate && (pageSize.dHeight >= pageSize.dWidth) != (targetSize.dHeight >= targetSize.dWidth);
if (bRotate)
{
rotatedSize.dWidth = pageSize.dHeight;
rotatedSize.dHeight = pageSize.dHeight;
}
else
{
rotatedSize = pageSize;
}
if (rotatedSize.dWidth == targetSize.dWidth && rotatedSize.dHeight == targetSize.dWidth)
{
// If size is correct, copy page only
pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (bRotate)
{
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_Rotate(pOutPage, ePtxGeom_Rotation_Clockwise), _T("Failed to rotate page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
}
else
{
TPtxPdfContent_Group* pGroup = NULL;
TPtxPdfContent_Content* pContent = NULL;
TPtxGeomReal_AffineTransform transform;
TPtxGeomReal_Point position;
TPtxGeomReal_Point point;
// Create a new page of correct size and fit existing page onto it
pOutPage = PtxPdf_Page_Create(pOutDoc, &targetSize);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to create a new page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Copy page as group
pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page as group. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate scaling and position of group
double scale = MIN(targetSize.dWidth / rotatedSize.dWidth, targetSize.dHeight / rotatedSize.dHeight);
// Calculate position
position.dX = (targetSize.dWidth - pageSize.dWidth * scale) / 2;
position.dY = (targetSize.dHeight - pageSize.dHeight * scale) / 2;
pContent = PtxPdf_Page_GetContent(pOutPage);
// Create content generator
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate and apply transformation
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_GetIdentity(&transform), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Translate(&transform, position.dX, position.dY), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Scale(&transform, scale, scale), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
point.dX = pageSize.dWidth / 2.0;
point.dY = pageSize.dHeight / 2.0;
// Rotate input file
if (bRotate)
{
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Rotate(&transform, 90, &point), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_Transform(pGenerator, &transform), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Paint form
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, NULL, NULL), _T("Failed to paint the group. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
PtxPdfContent_ContentGenerator_Close(pGenerator);
pGenerator = NULL;
if (pGenerator != NULL)
Ptx_Release(pGenerator);
if (pGroup != NULL)
Ptx_Release(pGroup);
}
// Add page to output document
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (pOutPage != NULL)
{
Ptx_Release(pOutPage);
pOutPage = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
}
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
// Create output document
using Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite);
using Document outDoc = Document.Create(outStream, inDoc.Conformance, null);
PageList outPages = outDoc.Pages;
int pageCount = 0;
ContentGenerator generator = null;
Page outPage = null;
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Copy all pages from input document
foreach (Page inPage in inDoc.Pages)
{
if (pageCount == Nx * Ny)
{
// Add to output document
generator.Dispose();
outPages.Add(outPage);
outPage = null;
pageCount = 0;
}
if (outPage == null)
{
// Create a new output page
outPage = Page.Create(outDoc, PageSize);
generator = new ContentGenerator(outPage.Content, false);
}
// Get area where group has to be
int x = pageCount % Nx;
int y = Ny - (pageCount / Nx) - 1;
// Compute cell size
Size cellSize = new Size
{
Width = (PageSize.Width - ((Nx + 1) * Border)) / Nx,
Height = (PageSize.Height - ((Ny + 1) * Border)) / Ny
};
// Compute cell position
Point cellPosition = new Point
{
X = Border + x * (cellSize.Width + Border),
Y = Border + y * (cellSize.Height + Border)
};
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy page as group from input to output
Group group = Group.CopyFromPage(outDoc, inPage, copyOptions);
// Compute group position
Size groupSize = group.Size;
double scale = Math.Min(cellSize.Width / groupSize.Width,
cellSize.Height / groupSize.Height);
// Compute target size
Size targetSize = new Size
{
Width = groupSize.Width * scale,
Height = groupSize.Height * scale
};
// Compute position
Point targetPos = new Point
{
X = cellPosition.X + ((cellSize.Width - targetSize.Width) / 2),
Y = cellPosition.Y + ((cellSize.Height - targetSize.Height) / 2)
};
// Compute rectangle
Rectangle targetRect = new Rectangle
{
Left = targetPos.X,
Bottom = targetPos.Y,
Right = targetPos.X + targetSize.Width,
Top = targetPos.Y + targetSize.Height
};
// Add group to page
generator.PaintGroup(group, targetRect, null);
pageCount++;
}
// Add page
if (outPage != null)
{
generator.Dispose();
outPages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null)) {
try (
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
PageList outPages = outDoc.getPages();
int pageCount = 0;
ContentGenerator generator = null;
Page outPage = null;
// A4 portrait
Size pageSize = new Size(595, 842);
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Copy pages
for (Page inPage : inDoc.getPages()) {
if (pageCount == Nx * Ny) {
// Add to output document
generator.close();
outPages.add(outPage);
outPage = null;
pageCount = 0;
}
if (outPage == null) {
// Create a new output page
outPage = Page.create(outDoc, pageSize);
generator = new ContentGenerator(outPage.getContent(), false);
}
// Get area where group has to be
int x = pageCount % Nx;
int y = Ny - (pageCount / Nx) - 1;
// Calculate cell size
Size cellSize = new Size((pageSize.width - ((Nx + 1) * Border)) / Nx,
(pageSize.height - ((Ny + 1) * Border)) / Ny);
// Calculate cell position
Point cellPosition = new Point(Border + x * (cellSize.width + Border),
Border + y * (cellSize.height + Border));
// Set copy option
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy page group from input to output
Group group = Group.copyFromPage(outDoc, inPage, copyOptions);
// Calculate group position
Size groupSize = group.getSize();
double scale = Math.min(cellSize.width / groupSize.width,
cellSize.height / groupSize.height);
// Calculate target size
Size targetSize = new Size(groupSize.width * scale, groupSize.height * scale);
// Calculate position
Point targetPos = new Point(cellPosition.x + ((cellSize.width - targetSize.width) / 2),
cellPosition.y + ((cellSize.height - targetSize.height) / 2));
// Calculate rectangle
Rectangle targetRect = new Rectangle(targetPos.x, targetPos.y,
targetPos.x + targetSize.width, targetPos.y + targetSize.height);
// Add group to page
generator.paintGroup(group, targetRect, null);
pageCount++;
}
// Add page
if (outPage != null) {
generator.close();
outPages.add(outPage);
}
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int nPageCount = 0;
for (int iPage = 0; iPage < PtxPdf_PageList_GetCount(pInPageList); iPage++)
{
pInPage = PtxPdf_PageList_Get(pInPageList, iPage);
if (nPageCount == nNx * nNy)
{
// Add to output document
PtxPdfContent_ContentGenerator_Close(pGenerator);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
Ptx_Release(pOutPage);
pOutPage = NULL;
nPageCount = 0;
}
if (pOutPage == NULL)
{
// Create a new output page
pOutPage = PtxPdf_Page_Create(pOutDoc, &PageSize);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to create a new output page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
TPtxPdfContent_Content* pContent = PtxPdf_Page_GetContent(pOutPage);
pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
// Get area where group has to be
int x = nPageCount % nNx;
int y = nNy - (nPageCount / nNx) - 1;
// Calculate cell size
TPtxGeomReal_Size cellSize;
cellSize.dWidth = (PageSize.dWidth - ((nNx + 1) * dBorder)) / nNx;
cellSize.dHeight = (PageSize.dHeight - ((nNy + 1) * dBorder)) / nNy;
// Calculate cell position
TPtxGeomReal_Point cellPosition;
cellPosition.dX = dBorder + x * (cellSize.dWidth + dBorder);
cellPosition.dY = dBorder + y * (cellSize.dHeight + dBorder);
// Copy page group from input to output
pGroup = PtxPdfContent_Group_CopyFromPage(pOutDoc, pInPage, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGroup, _T("Failed to copy page group from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Calculate group position
TPtxGeomReal_Size groupSize;
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_Group_GetSize(pGroup, &groupSize), _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
double dScale = MIN(cellSize.dWidth / groupSize.dWidth, cellSize.dHeight / groupSize.dHeight);
// Calculate target size
TPtxGeomReal_Size targetSize;
targetSize.dWidth = groupSize.dWidth * dScale;
targetSize.dHeight = groupSize.dHeight * dScale;
// Calculate position
TPtxGeomReal_Point targetPos;
targetPos.dX = cellPosition.dX + ((cellSize.dWidth - targetSize.dWidth) / 2);
targetPos.dY = cellPosition.dY + ((cellSize.dHeight - targetSize.dHeight) / 2);
// Calculate rectangle
TPtxGeomReal_Rectangle targetRect;
targetRect.dLeft = targetPos.dX;
targetRect.dBottom = targetPos.dY;
targetRect.dRight = targetPos.dX + targetSize.dWidth;
targetRect.dTop = targetPos.dY + targetSize.dHeight;
// Add group to page
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintGroup(pGenerator, pGroup, &targetRect, NULL), _T("Failed to paint the group. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
if (pGroup != NULL)
{
Ptx_Release(pGroup);
pGroup = NULL;
}
if (pInPage != NULL)
{
Ptx_Release(pInPage);
pInPage = NULL;
}
nPageCount++;
}
// Add partially filled page
if (pOutPage != NULL)
{
PtxPdfContent_ContentGenerator_Close(pGenerator);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
Ptx_Release(pOutPage);
pOutPage = NULL;
}
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outFs = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outFs, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Define page copy options
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages
PageList copiedPages = PageList.Copy(outDoc, inDoc.Pages, copyOptions);
// Rotate selected pages by 90 degrees
foreach (var pageNumber in pageNumbers)
{
copiedPages[pageNumber - 1].Rotate(Rotation.Clockwise);
}
// Add pages to output document
outDoc.Pages.AddRange(copiedPages);
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Set copy options and flatten annotations, form fields and signatures
PageCopyOptions copyOptions = new PageCopyOptions();
// Copy all pages
PageList copiedPages = PageList.copy(outDoc, inDoc.getPages(), copyOptions);
// Rotate selected pages by 90 degrees
for (int pageNumber : pageNumbers) {
copiedPages.get(pageNumber - 1).rotate(Rotation.CLOCKWISE);
}
// Add pages to output document
outDoc.getPages().addAll(copiedPages);
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file \"%s\".\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file \"%s\" cannot be created. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());
// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();
// Copy all pages
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pCopiedPages = PtxPdf_PageList_Copy(pOutDoc, pInPageList, pCopyOptions);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCopiedPages, _T("Failed to copy pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
// Rotate given pages by 90 degrees
for (int i = 0; i < ARRAY_SIZE(aPageNumbers); i++)
{
pOutPage = PtxPdf_PageList_Get(pCopiedPages, aPageNumbers[i] - 1);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to get copied page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_Rotate(pOutPage, ePtxGeom_Rotation_Clockwise), _T("Failed to rotate page. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
}
// Add pages to output document
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_AddRange(pOutPageList, pCopiedPages), _T("Failed to add copied pages. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
TPtxPdf_FileReferenceList* pInFileRefList;
TPtxPdf_FileReferenceList* pOutFileRefList;
// Output intent
if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
return FALSE;
// Metadata
if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
return FALSE;
// Viewer settings
if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
return FALSE;
// Associated files (for PDF/A-3 and PDF 2.0 only)
pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
// Plain embedded files
pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
if (pInFileRefList == NULL || pOutFileRefList == NULL)
return FALSE;
for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
return FALSE;
return TRUE;
}
C sample:
Information Extraction
C# sample:
// Open input document
using (Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
using (Document doc = Document.Open(stream, null))
{
// Iterate over all pages
int pageNumber = 1;
foreach (Page page in doc.Pages)
{
// Print page size
Console.WriteLine("Page {0}", pageNumber++);
Size size = page.Size;
Console.WriteLine(" Size:");
Console.WriteLine(" Width: {0}", size.Width);
Console.WriteLine(" Height: {0}", size.Height);
// Compute rectangular bounding box of all content on page
Rectangle contentBox = new Rectangle()
{
Left = double.MaxValue,
Bottom = double.MaxValue,
Right = double.MinValue,
Top = double.MinValue,
};
ContentExtractor extractor = new ContentExtractor(page.Content);
foreach (ContentElement element in extractor)
{
// Enlarge the content box for each content element
AffineTransform tr = element.Transform;
Rectangle box = element.BoundingBox;
// The location on the page is given by the transformed points
Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Left, Y = box.Bottom, }));
Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Right, Y = box.Bottom, }));
Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Right, Y = box.Top, }));
Enlarge(ref contentBox, tr.TransformPoint(new Point { X = box.Left, Y = box.Top, }));
}
Console.WriteLine(" Content bounding box:");
Console.WriteLine(" Left: {0}", contentBox.Left);
Console.WriteLine(" Bottom: {0}", contentBox.Bottom);
Console.WriteLine(" Right: {0}", contentBox.Right);
Console.WriteLine(" Top: {0}", contentBox.Top);
}
}
static void Enlarge(ref Rectangle box, Point point)
{
// Enlarge box if point lies outside of box
if (point.X < box.Left)
box.Left = point.X;
else if (point.X > box.Right)
box.Right = point.X;
if (point.Y < box.Bottom)
box.Bottom = point.Y;
else if (point.Y > box.Top)
box.Top = point.Y;
}
C# sample:
Java sample:
try (// Open input document
FileStream stream = new FileStream(path, "r");
Document doc = Document.open(stream, null)) {
// Iterate over all pages
int pageNumber = 1;
for (Page page : doc.getPages()) {
// Print page size
System.out.format("Page %d\n", pageNumber++);
Size size = page.getSize();
System.out.println(" Size:");
System.out.format(" Width: %f\n", size.getWidth());
System.out.format(" Height: %f\n", size.getHeight());
// Compute rectangular bounding box of all content on page
Rectangle contentBox = new Rectangle(Double.MAX_VALUE, Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_VALUE);
ContentExtractor extractor = new ContentExtractor(page.getContent());
for (ContentElement element : extractor) {
// Enlarge the content box for each content element
AffineTransform tr = element.getTransform();
Rectangle box = element.getBoundingBox();
// The location on the page is given by the transformed points
contentBox = Enlarge(contentBox, tr.transformPoint(new Point(box.getLeft(), box.getBottom())));
contentBox = Enlarge(contentBox, tr.transformPoint(new Point(box.getRight(), box.getBottom())));
contentBox = Enlarge(contentBox, tr.transformPoint(new Point(box.getRight(), box.getTop())));
contentBox = Enlarge(contentBox, tr.transformPoint(new Point(box.getLeft(), box.getTop())));
}
System.out.println(" Content bounding box:");
System.out.format(" Left: %f\n", contentBox.getLeft());
System.out.format(" Bottom: %f\n", contentBox.getBottom());
System.out.format(" Right: %f\n", contentBox.getRight());
System.out.format(" Top: %f\n", contentBox.getTop());
}
}
static Rectangle Enlarge(Rectangle box, Point point) {
// Enlarge box if point lies outside of box
if (point.getX() < box.getLeft())
box.setLeft(point.getX());
else if (point.getX() > box.getRight())
box.setRight(point.getX());
if (point.getY() < box.getBottom())
box.setBottom(point.getY());
else if (point.getY() > box.getTop())
box.setTop(point.getY());
return box;
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
// Conformance
Console.WriteLine("Conformance: {0}", inDoc.Conformance.ToString());
// Encryption information
Permission? permissions = inDoc.Permissions;
if (!permissions.HasValue)
{
Console.WriteLine("Not encrypted");
}
else
{
Console.WriteLine("Encryption:");
Console.Write(" - Permissions: ");
foreach (Enum flag in Enum.GetValues(typeof(Permission)))
if (permissions.Value.HasFlag(flag))
Console.Write("{0}, ", flag.ToString());
Console.WriteLine();
}
// Get metadata
Metadata metadata = inDoc.Metadata;
Console.WriteLine("Document information:");
// Get title
string title = metadata.Title;
if (title != null)
Console.WriteLine(" - Title: {0}", title);
// Get author
string author = metadata.Author;
if (author != null)
Console.WriteLine(" - Author: {0}", author);
// Get subject
string subject = metadata.Subject;
if (subject != null)
Console.WriteLine(" - Subject: {0}", subject);
// Get keywords
string keywords = metadata.Keywords;
if (keywords != null)
Console.WriteLine(" - Keywords: {0}", keywords);
// Get creation date
DateTimeOffset? creationDate = metadata.CreationDate;
if (creationDate != null)
Console.WriteLine(" - Creation Date: {0}", creationDate);
// Get modification date
DateTimeOffset? modificationDate = metadata.ModificationDate;
if (modificationDate != null)
Console.WriteLine(" - Modification Date: {0}", modificationDate);
// Get creator
string creator = metadata.Creator;
if (creator != null)
Console.WriteLine(" - Creator: {0}", creator);
// Get producer
string producer = metadata.Producer;
if (producer != null)
Console.WriteLine(" - Producer: {0}", producer);
// Custom entries
Console.WriteLine("Custom entries:");
foreach (var entry in metadata.CustomEntries)
Console.WriteLine(" - {0}: {1}", entry.Key, entry.Value);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null)) {
// Conformance
System.out.format("Conformance: %s\n", inDoc.getConformance().toString());
// Encryption information
EnumSet permissions = inDoc.getPermissions();
if (permissions == null) {
System.out.println("Not encrypted");
} else {
System.out.println("Encryption:");
System.out.print(" - Permissions: ");
for (Permission permission : permissions) {
System.out.format("%s, ", permission.toString());
}
System.out.println();
}
// Get metadata of input PDF
Metadata metadata = inDoc.getMetadata();
System.out.format("Document information:\n");
// Get title
String title = metadata.getTitle();
if (title != null)
System.out.format(" - Title: %s\n", title);
// Get author
String author = metadata.getAuthor();
if (author != null)
System.out.format(" - Author: %s\n", author);
// Get subject
String subject = metadata.getSubject();
if (subject != null)
System.out.format(" - Subject: %s\n", subject);
// Get keywords
String keywords = metadata.getKeywords();
if (keywords != null)
System.out.format(" - Keywords: %s\n", keywords);
// Get creation date
OffsetDateTime creationDate = metadata.getCreationDate();
if (creationDate != null)
System.out.format(" - Creation Date: %s\n", creationDate.toString());
// Get modification date
OffsetDateTime modificationDate = metadata.getModificationDate();
if (modificationDate != null)
System.out.format(" - Modification Date: %s\n", modificationDate.toString());
// Get creator
String creator = metadata.getCreator();
if (creator != null)
System.out.format(" - Creator: %s\n", creator);
// Get producer
String producer = metadata.getProducer();
if (producer != null)
System.out.format(" - Producer: %s\n", producer);
// Custom entries
System.out.format("Custom entries:\n");
for (Map.Entry entry : metadata.getCustomEntries().entrySet())
System.out.format(" - %s: %s\n", entry.getKey(), entry.getValue());
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Conformance
TPtxPdf_Conformance conformance = PtxPdf_Document_GetConformance(pInDoc);
if (conformance == 0)
{
GOTO_CLEANUP(szErrorBuff, Ptx_GetLastError());
}
_tprintf(_T("Conformance: "));
switch (conformance)
{
case ePtxPdf_Conformance_Pdf10: _tprintf(_T("PDF 1.0\n")); break;
case ePtxPdf_Conformance_Pdf11: _tprintf(_T("PDF 1.1\n")); break;
case ePtxPdf_Conformance_Pdf12: _tprintf(_T("PDF 1.2\n")); break;
case ePtxPdf_Conformance_Pdf13: _tprintf(_T("PDF 1.3\n")); break;
case ePtxPdf_Conformance_Pdf14: _tprintf(_T("PDF 1.4\n")); break;
case ePtxPdf_Conformance_Pdf15: _tprintf(_T("PDF 1.5\n")); break;
case ePtxPdf_Conformance_Pdf16: _tprintf(_T("PDF 1.6\n")); break;
case ePtxPdf_Conformance_Pdf17: _tprintf(_T("PDF 1.7\n")); break;
case ePtxPdf_Conformance_Pdf20: _tprintf(_T("PDF 2.0\n")); break;
case ePtxPdf_Conformance_PdfA1B: _tprintf(_T("PDF/A1-b\n")); break;
case ePtxPdf_Conformance_PdfA1A: _tprintf(_T("PDF/A1-a\n")); break;
case ePtxPdf_Conformance_PdfA2B: _tprintf(_T("PDF/A2-b\n")); break;
case ePtxPdf_Conformance_PdfA2U: _tprintf(_T("PDF/A2-u\n")); break;
case ePtxPdf_Conformance_PdfA2A: _tprintf(_T("PDF/A2-a\n")); break;
case ePtxPdf_Conformance_PdfA3B: _tprintf(_T("PDF/A3-b\n")); break;
case ePtxPdf_Conformance_PdfA3U: _tprintf(_T("PDF/A3-u\n")); break;
case ePtxPdf_Conformance_PdfA3A: _tprintf(_T("PDF/A3-a\n")); break;
}
// Encryption information
TPtxPdf_Permission permissions;
BOOL iRet = PtxPdf_Document_GetPermissions(pInDoc, &permissions);
if (iRet == FALSE)
{
if (Ptx_GetLastError() != ePtx_Error_Success)
GOTO_CLEANUP(szErrorBuff, Ptx_GetLastError());
_tprintf(_T("Not encrypted\n"));
}
else
{
_tprintf(_T("Encryption:\n"));
_tprintf(_T(" - Permissions: "));
if (permissions & ePtxPdf_Permission_Print) _tprintf(_T("Print, "));
if (permissions & ePtxPdf_Permission_Modify) _tprintf(_T("Modify, "));
if (permissions & ePtxPdf_Permission_Copy) _tprintf(_T("Copy, "));
if (permissions & ePtxPdf_Permission_Annotate) _tprintf(_T("Annotate, "));
if (permissions & ePtxPdf_Permission_FillForms) _tprintf(_T("FillForms, "));
if (permissions & ePtxPdf_Permission_SupportDisabilities) _tprintf(_T("SupportDisabilities, "));
if (permissions & ePtxPdf_Permission_Assemble) _tprintf(_T("Assemble, "));
if (permissions & ePtxPdf_Permission_DigitalPrint) _tprintf(_T("DigitalPrint, "));
_tprintf(_T("\n"));
}
// Get metadata of input PDF
pMetadata = PtxPdf_Document_GetMetadata(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pMetadata, _T("Failed to get metadata. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
_tprintf(_T("Document information:\n"));
// Get title
size_t nTitle = PtxPdf_Metadata_GetTitle(pMetadata, NULL, 0);
if (nTitle != 0)
{
TCHAR* szTitle = (TCHAR*)malloc(nTitle * sizeof(TCHAR));
if (szTitle != NULL)
{
PtxPdf_Metadata_GetTitle(pMetadata, szTitle, nTitle);
_tprintf(_T(" - Title: %s\n"), szTitle);
free(szTitle);
}
}
// Get author
size_t nAuthor = PtxPdf_Metadata_GetAuthor(pMetadata, NULL, 0);
if (nAuthor != 0)
{
TCHAR* szAuthor = (TCHAR*)malloc(nAuthor * sizeof(TCHAR));
if (szAuthor != NULL)
{
PtxPdf_Metadata_GetAuthor(pMetadata, szAuthor, nAuthor);
_tprintf(_T(" - Author: %s\n"), szAuthor);
free(szAuthor);
}
}
// Get creator
size_t nCreator = PtxPdf_Metadata_GetCreator(pMetadata, NULL, 0);
if (nCreator != 0)
{
TCHAR* szCreator = (TCHAR*)malloc(nCreator * sizeof(TCHAR));
if (szCreator != NULL)
{
PtxPdf_Metadata_GetCreator(pMetadata, szCreator, nCreator);
_tprintf(_T(" - Creator: %s\n"), szCreator);
free(szCreator);
}
}
// Get producer
size_t nProducer = PtxPdf_Metadata_GetProducer(pMetadata, NULL, 0);
if (nProducer != 0)
{
TCHAR* szProducer = (TCHAR*)malloc(nProducer * sizeof(TCHAR));
if (szProducer != NULL)
{
PtxPdf_Metadata_GetProducer(pMetadata, szProducer, nProducer);
_tprintf(_T(" - Producer: %s\n"), szProducer);
free(szProducer);
}
}
// Get subject
size_t nSubject = PtxPdf_Metadata_GetSubject(pMetadata, NULL, 0);
if (nSubject != 0)
{
TCHAR* szSubject = (TCHAR*)malloc(nSubject * sizeof(TCHAR));
if (szSubject != NULL)
{
PtxPdf_Metadata_GetSubject(pMetadata, szSubject, nSubject);
_tprintf(_T(" - Subject: %s\n"), szSubject);
free(szSubject);
}
}
// Get keywords
size_t nKeywords = PtxPdf_Metadata_GetKeywords(pMetadata, NULL, 0);
if (nKeywords != 0)
{
TCHAR* szKeywords = (TCHAR*)malloc(nKeywords * sizeof(TCHAR));
if (szKeywords != NULL)
{
PtxPdf_Metadata_GetKeywords(pMetadata, szKeywords, nKeywords);
_tprintf(_T(" - Keywords: %s\n"), szKeywords);
free(szKeywords);
}
}
// Get creation date
if (PtxPdf_Metadata_GetCreationDate(pMetadata, &date) == TRUE)
{
_tprintf(_T(" - Creation Date: %02d-%02d-%d %02d:%02d:%02d%c%02d:%02d\n"), date.iYear, date.iMonth, date.iDay,
date.iHour, date.iMinute, date.iSecond,
date.iTZSign >= 0 ? '+' : '-', date.iTZHour, date.iTZMinute);
}
// Get modification date
if (PtxPdf_Metadata_GetModificationDate(pMetadata, &date) == TRUE)
{
_tprintf(_T(" - Modification Date: %02d-%02d-%d %02d:%02d:%02d%c%02d:%02d\n"), date.iYear, date.iMonth, date.iDay,
date.iHour, date.iMinute, date.iSecond,
date.iTZSign >= 0 ? '+' : '-', date.iTZHour, date.iTZMinute);
}
// Get custom entries
_tprintf(_T("Custom entries:\n"));
TPtx_StringMap* pCustomEntries = PtxPdf_Metadata_GetCustomEntries(pMetadata);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pCustomEntries, _T("Failed to get custom entries. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
for (int i = Ptx_StringMap_GetBegin(pCustomEntries), iEnd = Ptx_StringMap_GetEnd(pCustomEntries); i != iEnd; i = Ptx_StringMap_GetNext(pCustomEntries, i))
{
size_t nKeySize = Ptx_StringMap_GetKey(pCustomEntries, i, NULL, 0);
TCHAR* szKey = (TCHAR*)malloc(nKeySize * sizeof(TCHAR));
nKeySize = Ptx_StringMap_GetKey(pCustomEntries, i, szKey, nKeySize);
size_t nValueSize = Ptx_StringMap_GetValue(pCustomEntries, i, NULL, 0);
TCHAR* szValue = (TCHAR*)malloc(nValueSize * sizeof(TCHAR));
nValueSize = Ptx_StringMap_GetValue(pCustomEntries, i, szValue, nValueSize);
if (szKey && nKeySize && szValue && nValueSize)
_tprintf(_T(" - %s: %s\n"), szKey, szValue);
free (szKey);
free (szValue);
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
SignatureFieldList signatureFields = inDoc.SignatureFields;
Console.WriteLine("Number of signature fields: {0}", signatureFields.Count);
foreach (SignatureField field in signatureFields)
{
if (field is Signature sig)
{
// List name
string name = sig.Name;
Console.WriteLine("- {0} fields, signed by: {1}",
sig.IsVisible ? "Visible" : "Invisible", name ?? "(Unknown name)");
// List location
string location = sig.Location;
if (location != null)
Console.WriteLine(" - Location: {0}", location);
// List reason
string reason = sig.Reason;
if (reason != null)
Console.WriteLine(" - Reason: {0}", reason);
// List contact info
string contactInfo = sig.ContactInfo;
if (contactInfo != null)
Console.WriteLine(" - Contact info: {0}", contactInfo);
// List date
DateTimeOffset? date = sig.Date;
if (date != null)
Console.WriteLine(" - Date: {0}", date.Value);
}
else
Console.WriteLine("- {0} field, not signed", field.IsVisible ? "Visible" : "Invisible");
}
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null)) {
SignatureFieldList signatureFields = inDoc.getSignatureFields();
System.out.format("Number of signature fields: %d\n", signatureFields.size());
for (SignatureField field : signatureFields) {
if (field instanceof Signature) {
Signature sig = (Signature)field;
// List name
String name = sig.getName();
System.out.format("- %s field, signed by: %s\n", sig.getIsVisible() ? "Visible" : "Invisible",
name != null ? name : "(Unknown name)");
// List location
String location = sig.getLocation();
if (location != null)
System.out.format(" - Location: %s\n", location);
// List reason
String reason = sig.getReason();
if (reason != null)
System.out.format(" - Reason: %s\n", reason);
// List contact info
String contactInfo = sig.getContactInfo();
if (contactInfo != null)
System.out.format(" - Contact info: %s\n", contactInfo);
// List date
OffsetDateTime date = sig.getDate();
if (date != null)
System.out.format(" - Date: %s\n", date.toString());
} else {
System.out.format("- %s field, not signed\n", field.getIsVisible() ? "Visible" : "Invisible");
}
}
}
Java sample:
C sample:
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&descriptor, pInStream, 0);
pInDoc = PtxPdf_Document_Open(&descriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());
// Get signatures of input PDF
pSignatureFields = PtxPdf_Document_GetSignatureFields(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pSignatureFields, _T("Failed to get signatures of input PDF. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
_tprintf(_T("Number of signature fields: %d\n"), PtxPdfForms_SignatureFieldList_GetCount(pSignatureFields));
for (int i = 0; i < PtxPdfForms_SignatureFieldList_GetCount(pSignatureFields); i++)
{
pSig = PtxPdfForms_SignatureFieldList_Get(pSignatureFields, i);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pSig, _T("Failed to get signature. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
TPtxPdfForms_SignatureFieldType iFieldType = PtxPdfForms_SignatureField_GetType(pSig);
if (iFieldType == ePtxPdfForms_SignatureFieldType_Signature
|| iFieldType == ePtxPdfForms_SignatureFieldType_DocMdpSignature
|| iFieldType == ePtxPdfForms_SignatureFieldType_DocumentSignature
|| iFieldType == ePtxPdfForms_SignatureFieldType_DocUrSignature)
{
// List name
size_t nName = PtxPdfForms_SignedSignatureField_GetName(pSig, NULL, 0);
_tprintf(_T("- %s fields"), PtxPdfForms_SignatureField_IsVisible(pSig) ? _T("Visible") : _T("Invisible"));
if (nName != 0)
{
TCHAR* szName = (TCHAR*)malloc(nName * sizeof(TCHAR));
if (szName != NULL)
{
PtxPdfForms_SignedSignatureField_GetName(pSig, szName, nName);
_tprintf(_T(", signed by: %s"), szName);
free(szName);
}
}
_tprintf(_T("\n"));
// List location
size_t nLocation = PtxPdfForms_Signature_GetLocation(pSig, NULL, 0);
if (nLocation != 0)
{
TCHAR* szLocation = (TCHAR*)malloc(nLocation * sizeof(TCHAR));
if (szLocation != NULL)
{
PtxPdfForms_Signature_GetLocation(pSig, szLocation, nLocation);
_tprintf(_T(" - Location: %s\n"), szLocation);
free(szLocation);
}
}
// List reason
size_t nReason = PtxPdfForms_Signature_GetReason(pSig, NULL, 0);
if (nReason != 0)
{
TCHAR* szReason = (TCHAR*)malloc(nReason * sizeof(TCHAR));
if (szReason != NULL)
{
PtxPdfForms_Signature_GetReason(pSig, szReason, nReason);
_tprintf(_T(" - Reason: %s\n"), szReason);
free(szReason);
}
}
// List contact info
size_t nContactInfo = PtxPdfForms_Signature_GetContactInfo(pSig, NULL, 0);
if (nContactInfo != 0)
{
TCHAR* szContactInfo = (TCHAR*)malloc(nContactInfo * sizeof(TCHAR));
if (szContactInfo != NULL)
{
PtxPdfForms_Signature_GetContactInfo(pSig, szContactInfo, nContactInfo);
_tprintf(_T(" - Contact info: %s\n"), szContactInfo);
free(szContactInfo);
}
}
// List date
if (PtxPdfForms_SignedSignatureField_GetDate(pSig, &date) == TRUE)
{
_tprintf(_T(" - Date: %02d-%02d-%d %02d:%02d:%02d%c%02d:%02d\n"), date.iYear, date.iMonth, date.iDay,
date.iHour, date.iMinute, date.iSecond,
date.iTZSign >= 0 ? '+' : '-', date.iTZHour, date.iTZMinute);
}
}
else
{
_tprintf(_T("- %s field, not signed\n"), PtxPdfForms_SignatureField_IsVisible(pSig) ? _T("Visible") : _T("Invisible"));
}
}
C sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
PrintOutlineItems(inDoc.Outline, "", inDoc);
}
static void PrintOutlineItem(OutlineItem item, string indentation, Document document)
{
string title = item.Title;
Console.Out.Write("{0}{1}", indentation, title);
Destination dest = item.Destination;
if (dest != null)
{
int pageNumber = document.Pages.IndexOf(dest.Target.Page) + 1;
string dots = new string('.', 78 - indentation.Length - title.Length - pageNumber.ToString().Length);
Console.Out.Write(" {0} {1}", dots, pageNumber);
}
Console.Out.WriteLine();
PrintOutlineItems(item.Children, indentation + " ", document);
}
static void PrintOutlineItems(OutlineItemList outlineItems, string indentation, Document document)
{
foreach (var item in outlineItems)
PrintOutlineItem(item, indentation, document);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null)) {
printOutlineItems(inDoc.getOutline(), "", inDoc);
}
static void printOutlineItem(OutlineItem item, String indentation, Document document) throws PdfToolboxException {
String title = item.getTitle();
System.out.format("%s%s", indentation, title);
Destination dest = item.getDestination();
if (dest != null) {
int pageNumber = document.getPages().indexOf(dest.getTarget().getPage()) + 1;
char[] dots = new char[78 - indentation.length() - title.length() - Integer.toString(pageNumber).length()];
Arrays.fill(dots, '.');
System.out.format(" %s %d", new String(dots), pageNumber);
}
System.out.println();
printOutlineItems(item.getChildren(), indentation + " ", document);
}
static void printOutlineItems(OutlineItemList outlineItems, String indentation, Document document)
throws PdfToolboxException {
for (OutlineItem item : outlineItems)
printOutlineItem(item, indentation, document);
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
{
int pageNumber = 1;
// Process each page
foreach (var inPage in inDoc.Pages)
{
Console.WriteLine("==========");
Console.WriteLine($"Page: {pageNumber++}");
Console.WriteLine("==========");
ContentExtractor extractor = new ContentExtractor(inPage.Content);
extractor.Ungrouping = UngroupingSelection.All;
// Iterate over all content elements and only process text elements
foreach (ContentElement element in extractor)
if (element is TextElement textElement)
WriteText(textElement.Text);
}
}
private static void WriteText(Text text)
{
string textPart = "";
// Write all text fragments
// Determine heuristically if there is a space between two text fragments
for (int iFragment = 0; iFragment < text.Count; iFragment++)
{
TextFragment currFragment = text[iFragment];
if (iFragment == 0)
textPart += currFragment.Text;
else
{
TextFragment lastFragment = text[iFragment - 1];
if (currFragment.CharacterSpacing != lastFragment.CharacterSpacing ||
currFragment.FontSize != lastFragment.FontSize ||
currFragment.HorizontalScaling != lastFragment.HorizontalScaling ||
currFragment.Rise != lastFragment.Rise ||
currFragment.WordSpacing != lastFragment.WordSpacing)
textPart += $" {currFragment.Text}";
else
{
Point currentBotLeft = currFragment.Transform.TransformRectangle(currFragment.BoundingBox).BottomLeft;
Point beforeBotRight = lastFragment.Transform.TransformRectangle(lastFragment.BoundingBox).BottomRight;
if (beforeBotRight.X < currentBotLeft.X - 0.7 * currFragment.FontSize ||
beforeBotRight.Y < currentBotLeft.Y - 0.1 * currFragment.FontSize ||
currentBotLeft.Y < beforeBotRight.Y - 0.1 * currFragment.FontSize)
textPart += $" {currFragment.Text}";
else
textPart += currFragment.Text;
}
}
}
Console.WriteLine(textPart);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null)) {
int pageNumber = 1;
// Process each page
for (Page inPage : inDoc.getPages()) {
System.out.println("==========");
System.out.println("Page: " + pageNumber++);
System.out.println("==========");
ContentExtractor extractor = new ContentExtractor(inPage.getContent());
extractor.setUngrouping(UngroupingSelection.ALL);
// Iterate over all content elements and only process text elements
for (ContentElement element : extractor) {
if (element instanceof TextElement)
writeText(((TextElement) element).getText());
}
}
}
private static void writeText(Text text) {
String textPart = "";
// Write all text fragments
// Determine heuristically if there is a space between two text fragments
for (int iFragment = 0; iFragment < text.size(); iFragment++) {
TextFragment currFragment = text.get(iFragment);
if (iFragment == 0)
textPart += currFragment.getText();
else {
TextFragment lastFragment = text.get(iFragment - 1);
if (currFragment.getCharacterSpacing() != lastFragment.getCharacterSpacing() ||
currFragment.getFontSize() != lastFragment.getFontSize() ||
currFragment.getHorizontalScaling() != lastFragment.getHorizontalScaling() ||
currFragment.getRise() != lastFragment.getRise() ||
currFragment.getWordSpacing() != lastFragment.getWordSpacing()) {
textPart += " ";
textPart += currFragment.getText();
}
else {
Point currentBotLeft = currFragment.getTransform().transformRectangle(currFragment.getBoundingBox()).getBottomLeft();
Point beforeBotRight = lastFragment.getTransform().transformRectangle(lastFragment.getBoundingBox()).getBottomRight();
if (beforeBotRight.getX() < currentBotLeft.getX() - 0.7 * currFragment.getFontSize() ||
beforeBotRight.getY() < currentBotLeft.getY() - 0.1 * currFragment.getFontSize() ||
currentBotLeft.getY() < beforeBotRight.getY() - 0.1 * currFragment.getFontSize()) {
textPart += " ";
textPart += currFragment.getText();
}
else
textPart += currFragment.getText();
}
}
}
System.out.println(textPart);
}
Java sample:
Content Modification
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Process each page
foreach (var inPage in inDoc.Pages)
{
// Create empty output page
Page outPage = Page.Create(outDoc, inPage.Size);
// Copy page content from input to output
CopyContent(inPage.Content, outPage.Content, outDoc);
// Add the new page to the output document's page list
outDoc.Pages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void CopyContent(Content inContent, Content outContent, Document outDoc)
{
// Use a content extractor and a content generator to copy content
ContentExtractor extractor = new ContentExtractor(inContent);
using ContentGenerator generator = new ContentGenerator(outContent, false);
// Iterate over all content elements
foreach (ContentElement inElement in extractor)
{
ContentElement outElement;
// Special treatment for group elements
if (inElement is GroupElement inGroupElement)
{
// Create empty output group element
GroupElement outGroupElement = GroupElement.CopyWithoutContent(outDoc, inGroupElement);
outElement = outGroupElement;
// Call CopyContent() recursively for the group element's content
CopyContent(inGroupElement.Group.Content, outGroupElement.Group.Content, outDoc);
}
else
{
// Copy the content element to the output document
outElement = ContentElement.Copy(outDoc, inElement);
if (outElement is TextElement outTextElement)
{
// Special treatment for text element
Text text = outTextElement.Text;
// Remove all those text fragments whose fill and stroke paint is white
for (int iFragment = text.Count - 1; iFragment >= 0; iFragment--)
{
TextFragment fragment = text[iFragment];
if ((fragment.Fill == null || IsWhite(fragment.Fill.Paint)) &&
(fragment.Stroke == null || IsWhite(fragment.Stroke.Paint)))
text.RemoveAt(iFragment);
}
// Prevent appending an empty text element
if (text.Count == 0)
outElement = null;
}
}
// Append the finished output element to the content generator
if (outElement != null)
generator.AppendContentElement(outElement);
}
}
private static bool IsWhite(Paint paint)
{
ColorSpace colorSpace = paint.ColorSpace;
if (colorSpace is DeviceGrayColorSpace || colorSpace is CalibratedGrayColorSpace ||
colorSpace is DeviceRgbColorSpace || colorSpace is CalibratedRgbColorSpace)
{
// These color spaces are additive: white is 1.0
return paint.Color.Min() == 1.0;
}
if (colorSpace is DeviceCmykColorSpace)
{
// This color space is subtractive: white is 0.0
return paint.Color.Max() == 0.0;
}
return false;
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Process each page
for (Page inPage : inDoc.getPages()) {
// Create empty output page
Page outPage = Page.create(outDoc, inPage.getSize());
// Copy page content from input to output
CopyContent(inPage.getContent(), outPage.getContent(), outDoc);
// Add page to output document
outDoc.getPages().add(outPage);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void CopyContent(Content inContent, Content outContent, Document outDoc) throws PdfToolboxException, IOException {
// Use a content extractor and a content generator to copy content
ContentExtractor extractor = new ContentExtractor(inContent);
try (ContentGenerator generator = new ContentGenerator(outContent, false)) {
// Iterate over all content elements
for (ContentElement inElement : extractor) {
ContentElement outElement = null;
// Special treatment for group elements
if (inElement instanceof GroupElement) {
GroupElement inGroupElement = (GroupElement)inElement;
// Create empty output group element
GroupElement outGroupElement = GroupElement.copyWithoutContent(outDoc, inGroupElement);
outElement = outGroupElement;
// Call CopyContent() recursively for the group element's content
CopyContent(inGroupElement.getGroup().getContent(), outGroupElement.getGroup().getContent(), outDoc);
} else {
// Copy the content element to the output document
outElement = ContentElement.copy(outDoc, inElement);
if (outElement instanceof TextElement) {
// Special treatment for text element
TextElement outTextElement = (TextElement)outElement;
Text text = outTextElement.getText();
// Remove all those text fragments whose fill and stroke paint is white
for (int iFragment = text.size() - 1; iFragment >= 0; iFragment--) {
TextFragment fragment = text.get(iFragment);
if ((fragment.getFill() == null || IsWhite(fragment.getFill().getPaint())) &&
(fragment.getStroke() == null || IsWhite(fragment.getStroke().getPaint())))
text.remove(iFragment);
}
// Prevent appending an empty text element
if (text.size() == 0)
outElement = null;
}
}
// Append the finished output element to the content generator
if (outElement != null)
generator.appendContentElement(outElement);
}
}
}
private static boolean IsWhite(Paint paint) {
double[] color = paint.getColor();
ColorSpace colorSpace = paint.getColorSpace();
if (colorSpace instanceof DeviceGrayColorSpace || colorSpace instanceof CalibratedGrayColorSpace ||
colorSpace instanceof DeviceRgbColorSpace || colorSpace instanceof CalibratedRgbColorSpace) {
// These color spaces are additive: white is 1.0
for (double value : color)
if (value != 1.0)
return false;
return true;
}
if (colorSpace instanceof DeviceCmykColorSpace) {
// This color space is subtractive: white is 0.0
for (double value : color)
if (value != 0.0)
return false;
return true;
}
return false;
}
Java sample:
C# sample:
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))
// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
// Copy document-wide data
CopyDocumentData(inDoc, outDoc);
// Process each page
foreach (var inPage in inDoc.Pages)
{
// Create empty output page
Page outPage = Page.Create(outDoc, inPage.Size);
// Copy page content from input to output and search for string
CopyContent(inPage.Content, outPage.Content, outDoc, searchString);
// If the text was found and deleted, add the replacement text
if (fragment != null)
AddText(outDoc, outPage, replString);
// Add the new page to the output document's page list
outDoc.Pages.Add(outPage);
}
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
// Copy document-wide data
// Output intent
if (inDoc.OutputIntent != null)
outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);
// Metadata
outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);
// Viewer settings
outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
foreach (FileReference inFileRef in inDoc.AssociatedFiles)
outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void CopyContent(Content inContent, Content outContent, Document outDoc, string searchString)
{
// Use a content extractor and a content generator to copy content
ContentExtractor extractor = new ContentExtractor(inContent);
using ContentGenerator generator = new ContentGenerator(outContent, false);
// Iterate over all content elements
foreach (ContentElement inElement in extractor)
{
ContentElement outElement;
// Special treatment for group elements
if (inElement is GroupElement inGroupElement)
{
// Create empty output group element
GroupElement outGroupElement = GroupElement.CopyWithoutContent(outDoc, inGroupElement);
outElement = outGroupElement;
// Save transform for later restore
AffineTransform currentTransform = overallTransform;
// Update the transform
overallTransform.Concatenate(inGroupElement.Transform);
// Call CopyContent() recursively for the group element's content
CopyContent(inGroupElement.Group.Content, outGroupElement.Group.Content, outDoc, searchString);
// Restore the transform
overallTransform = currentTransform;
}
else
{
// Copy the content element to the output document
outElement = ContentElement.Copy(outDoc, inElement);
if (fragment == null && outElement is TextElement outTextElement)
{
// Special treatment for text element
Text text = outTextElement.Text;
// Find text fragment with string to replace
for (int iFragment = text.Count - 1; iFragment >= 0; iFragment--)
{
// In this sample, the fragment text must match in its entirety
if (text[iFragment].Text == searchString)
{
// Keep the found fragment for later use
fragment = text[iFragment];
// Update the transform
overallTransform.Concatenate(fragment.Transform);
// Remove the found text fragment from the output
text.RemoveAt(iFragment);
break;
}
}
// Prevent appending an empty text element
if (text.Count == 0)
outElement = null;
}
}
// Append the finished output element to the content generator
if (outElement != null)
generator.AppendContentElement(outElement);
}
}
private static void AddText(Document doc, Page page, string replString)
{
// Create a new text object
Text text = Text.Create(doc);
// Heuristic to map the extracted font base name to a font name and font family
string[] parts = fragment.Font.BaseFont.Split('-');
string family = parts[0];
string style = parts.Length > 1 ? parts[1] : null;
// Create a new font object
Font font = Font.CreateFromSystem(doc, family, style, true);
// Create a text generator and set the original fragment's properties
using (TextGenerator textGenerator = new TextGenerator(text, font, fragment.FontSize, null))
{
textGenerator.CharacterSpacing = fragment.CharacterSpacing;
textGenerator.WordSpacing = fragment.WordSpacing;
textGenerator.HorizontalScaling = fragment.HorizontalScaling;
textGenerator.Rise = fragment.Rise;
textGenerator.Show(replString);
}
// Create a content generator
using ContentGenerator contentGenerator = new ContentGenerator(page.Content, false);
// Apply the computed transform
contentGenerator.Transform(overallTransform);
// Paint the new text
contentGenerator.PaintText(text);
}
C# sample:
Java sample:
try (// Open input document
FileStream inStream = new FileStream(inPath, "r");
Document inDoc = Document.open(inStream, null);
FileStream outStream = new FileStream(outPath, "rw")) {
outStream.setLength(0);
try (// Create output document
Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
// Copy document-wide data
copyDocumentData(inDoc, outDoc);
// Process each page
for (Page inPage : inDoc.getPages()) {
// Create empty output page
Page outPage = Page.create(outDoc, inPage.getSize());
// Copy page content from input to output and search for string
CopyContent(inPage.getContent(), outPage.getContent(), outDoc, searchString);
// If the text was found and deleted, add the replacement text
if (fragment != null)
AddText(outDoc, outPage, replString);
// Add page to output document
outDoc.getPages().add(outPage);
}
}
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
// Copy document-wide data
// Output intent
if (inDoc.getOutputIntent() != null)
outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));
// Metadata
outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));
// Viewer settings
outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));
// Associated files (for PDF/A-3 and PDF 2.0 only)
FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
for (FileReference inFileRef : inDoc.getAssociatedFiles())
outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));
// Plain embedded files
FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void CopyContent(Content inContent, Content outContent, Document outDoc, String searchString) throws PdfToolboxException, IOException {
// Use a content extractor and a content generator to copy content
ContentExtractor extractor = new ContentExtractor(inContent);
try (ContentGenerator generator = new ContentGenerator(outContent, false)) {
// Iterate over all content elements
for (ContentElement inElement : extractor) {
ContentElement outElement = null;
// Special treatment for group elements
if (inElement instanceof GroupElement) {
GroupElement inGroupElement = (GroupElement)inElement;
// Create empty output group element
GroupElement outGroupElement = GroupElement.copyWithoutContent(outDoc, inGroupElement);
outElement = outGroupElement;
// Save transform for later restor
AffineTransform currentTransform = overallTransform;
// Update the transform
overallTransform.concatenate(inGroupElement.getTransform());
// Call CopyContent() recursively for the group element's content
CopyContent(inGroupElement.getGroup().getContent(), outGroupElement.getGroup().getContent(), outDoc, searchString);
// Restor the transform
overallTransform = currentTransform;
} else {
// Copy the content element to the output document
outElement = ContentElement.copy(outDoc, inElement);
if (fragment == null && outElement instanceof TextElement) {
// Special treatment for text element
TextElement outTextElement = (TextElement)outElement;
Text text = outTextElement.getText();
// Find text fragment with string to replace
for (int iFragment = text.size() - 1; iFragment >= 0; iFragment--) {
// In this sample, the fragment text must match in its entirety
if (text.get(iFragment).getText().equals(searchString)) {
// Keep the found fragment for later use
fragment = text.get(iFragment);
// Update the transform
overallTransform.concatenate(fragment.getTransform());
// Remove the found text fragment from the output
text.remove(iFragment);
break;
}
}
// Prevent appending an empty text element
if (text.size() == 0)
outElement = null;
}
}
// Append the finished output element to the content generator
if (outElement != null)
generator.appendContentElement(outElement);
}
}
}
private static void AddText(Document doc, Page page, String replString) throws CorruptException, PdfToolboxException, IOException {
// Create a new text object
Text text = Text.create(doc);
// Heuristic to map the extracted fon base name to a font family and font style
String[] parts = fragment.getFont().getBaseFont().split("-");
String family = parts[0];
String style = parts.length > 1 ? parts[1] : null;
// Create a new font object
Font font = Font.createFromSystem(doc, family, style, true);
// Create a text generator and set the original fragment's properties
try (TextGenerator textGenerator = new TextGenerator(text, font, fragment.getFontSize(), null)) {
textGenerator.setCharacterSpacing(fragment.getCharacterSpacing());
textGenerator.setWordSpacing(fragment.getWordSpacing());
textGenerator.setHorizontalScaling(fragment.getHorizontalScaling());
textGenerator.setRise(fragment.getRise());
textGenerator.show(replString);
}
// Create a content generator
try (ContentGenerator contentGenerator = new ContentGenerator(page.getContent(), false)) {
// Apply the computed transform
contentGenerator.transform(overallTransform);
// Paint the new text
contentGenerator.paintText(text);
}
}
Java sample: