Samples Overview

Annotations | Content Addition | Annotations and Form Fields | Document Setup | Imposition | Information Extraction | Content Modification

Annotations

Add annotations to PDF

Generate and add various types of annotations at specified positions on the first page of a PDF document.

C# sample: Download
// 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;
}
Java sample: Download
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;
}

Content Addition

Add barcode to PDF

Generate and add a barcode at a specified position on the first page of a PDF document.

C# sample: Download
// 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);
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Add Data Matrix to PDF

Add a two-dimensional barcode from an existing image on the first page of a PDF document.

C# sample: Download
// 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);
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Add image to PDF

Place an image with a specified size at a specific location of a page.

C# sample: Download
// 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);
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Add image mask to PDF

Place a rectangular image mask at a specified location of a page. The image mask is a stencil mask to fill or mask out the image per pixel.

C# sample: Download
// 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);
    }
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Add stamp to PDF

Add a semi-transparent stamp text onto each page of a PDF document. Optionally specify the color and the opacity of the stamp.

C# sample: Download
// 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);
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Add text to PDF

Add text at a specified position on the first page of a PDF document.

C# sample: Download
// 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);
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Add vector graphic to PDF

Draw a line on an existing PDF page.

C# sample: Download
// 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);
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Layout text on PDF page

Create a new PDF document with one page. On this page, within a given rectangular area, add a text block with a full justification layout.

C# sample: Download
// 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);
}
Java sample: Download
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<String> 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);
    }
}

Stamp page number to PDF

Stamp the page number to the footer of each page of a PDF document.

C# sample: Download
// 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);
}
Java sample: Download
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);
    }
}
C sample: Download
// 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;
}

Annotations and Form Fields

Add Form Field

Add form fields to a PDF.

C# sample: Download
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<string, FieldNode> inPair in inFormFields)
    {
        FieldNode outFormFieldNode = FieldNode.Copy(outDoc, inPair.Value);
        outFormFields.Add(new KeyValuePair<string, FieldNode>(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(new KeyValuePair<string, FieldNode>(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(new KeyValuePair<string, FieldNode>(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(new KeyValuePair<string, FieldNode>(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(new KeyValuePair<string, FieldNode>(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(new KeyValuePair<string, FieldNode>(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));
}
Java sample: Download
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<String, FieldNode> 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<String> 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));
}

Fill Form Fields

Change values of AcroForm form fields.

C# sample: Download
// 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;
            }
        }
    }
}
Java sample: Download
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<String, FieldNode> 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;
            }
        }
    }
}

Document Setup

Add metadata to PDF

Set metadata such as author, title, and creator of a PDF document. Optionally use the metadata of another PDF document or the content of an XMP file.

C# sample: Download
// 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));
}
Java sample: Download
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));
}
C sample: Download
// 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;
}

Encrypt PDF

Encrypt a PDF document with a user password and an owner password. When opening the document, either of the passwords must be provided. If providing the user password, the document can be viewed and printed only. Providing the owner password grants full access to the document.

C# sample: Download
// 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));
}
Java sample: Download
// 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));
}
C sample: Download
// 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;
}

Flatten form fields in PDF

Flatten the visual appearance of form fields and discard all interactive elements.

C# sample: Download
// 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));
}
Java sample: Download
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));
}
C sample: Download
// 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;
}

Merge multiple PDFs

Merge several PDF documents to one.

C# sample: Download
// 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);
    }
}
Java sample: Download
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);
            }
        }
    }
}
C sample: Download
// 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;
}

Merge multiple PDFs with outlines

Merge several PDF documents to one, while creating an outline item for each input document.

C# sample: Download
// 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));
    }
}
Java sample: Download
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));
            }
        }
    }
}

Overlay color of PDF

Overlay all pages of a PDF document with a configurable color.

C# sample: Download
// 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));
}
Java sample: Download
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));
}

Add info entries to PDF

Set metadata such as author, title, and creator of a PDF document or add a custom entry.

C# sample: Download
// 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));
}
Java sample: Download
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));
}

Set the open-destination of a PDF

Set the page that is displayed when opening the document.

C# sample: Download
// 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));
}
Java sample: Download
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));
}

Remove pages from PDF

Selectively remove pages from a PDF document.

C# sample: Download
// 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));
}
Java sample: Download
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));
}
C sample: Download
// 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;
}

Imposition

Create a booklet from PDF

Place up to two A4 pages in the right order on an A3 page, so that duplex printing and folding the A3 pages results in a booklet.

C# sample: Download
// 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);
}
Java sample: Download
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);
}
C sample: Download
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;
}

Fit pages to specific page format

Fit each page of a PDF document to a specific page format.

C# sample: Download
// 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));
}
Java sample: Download
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));
}
C sample: Download
// 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;
}

Place multiple pages on one page

Place four pages of a PDF document on a single page.

C# sample: Download
// 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));
}
Java sample: Download
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));
}
C sample: Download
// 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;
}

Set page orientation

Rotate a specified page of a PDF document by 90 degrees.

C# sample: Download
// 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));
}
Java sample: Download
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));
}
C sample: Download
// 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;
}

Information Extraction

List bounds of page content

For each page, list the page size and the rectangular bounding box of all content on the page in PDF points (1/72 inch).

C# sample: Download
// 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;
}
Java sample: Download
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;
}

List document information of PDF

List attributes of a PDF document (i.e. conformance and encryption information) and metadata (i.e. author, title, creation date etc.).

C# sample: Download
// 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);
}
Java sample: Download
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<Permission> 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<String, String> entry : metadata.getCustomEntries().entrySet())
        System.out.format("  - %s: %s\n", entry.getKey(), entry.getValue());
}
C sample: Download
// 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);
}


List Signatures in PDF

List all signature fields in a PDF document and their properties.

C# sample: Download
// 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 sig in signatureFields)
    {
        if (sig.IsSigned)
        {
            // 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", sig.IsVisible ? "Visible" : "Invisible");
    }
}
Java sample: Download
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 sig : signatureFields) {
        if (sig.getIsSigned()) {
            // 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", sig.getIsVisible() ? "Visible" : "Invisible");
        }
    }
}
C sample: Download
// 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());
    if (PtxPdfForms_SignatureField_IsSigned(pSig))
    {
        // List name
        size_t nName = PtxPdfForms_SignatureField_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_SignatureField_GetName(pSig, szName, nName);
                _tprintf(_T(", signed by: %s"), szName);
                free(szName);
            }
        }
        _tprintf(_T("\n"));

        // List location
        size_t nLocation = PtxPdfForms_SignatureField_GetLocation(pSig, NULL, 0);
        if (nLocation != 0)
        {
            TCHAR* szLocation = (TCHAR*)malloc(nLocation * sizeof(TCHAR));
            if (szLocation != NULL)
            {
                PtxPdfForms_SignatureField_GetLocation(pSig, szLocation, nLocation);
                _tprintf(_T("  - Location: %s\n"), szLocation);
                free(szLocation);
            }
        }

        // List reason
        size_t nReason = PtxPdfForms_SignatureField_GetReason(pSig, NULL, 0);
        if (nReason != 0)
        {
            TCHAR* szReason = (TCHAR*)malloc(nReason * sizeof(TCHAR));
            if (szReason != NULL)
            {
                PtxPdfForms_SignatureField_GetReason(pSig, szReason, nReason);
                _tprintf(_T("  - Reason: %s\n"), szReason);
                free(szReason);
            }
        }

        // List contact info
        size_t nContactInfo = PtxPdfForms_SignatureField_GetContactInfo(pSig, NULL, 0);
        if (nContactInfo != 0)
        {
            TCHAR* szContactInfo = (TCHAR*)malloc(nContactInfo * sizeof(TCHAR));
            if (szContactInfo != NULL)
            {
                PtxPdfForms_SignatureField_GetContactInfo(pSig, szContactInfo, nContactInfo);
                _tprintf(_T("  - Contact info: %s\n"), szContactInfo);
                free(szContactInfo);
            }
        }

        // List date
        if (PtxPdfForms_SignatureField_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"));
    }
}

Print a table of content

Print a formatted table of content from the document outline.

C# sample: Download
// 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);
}
Java sample: Download
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);
}

Content Modification

Remove White Text from PDF

Remove white text from all pages of a PDF. Links, annotations, form fields, outlines, logical structure, and embedded files are discarded.

C# sample: Download
// 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;
}
Java sample: Download
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;
}

Replace Text Fragment in PDF

For a given text, search through all text fragments on all pages and replace the first matching fragment found. Links, annotations, form fields, outlines, and logical structure are discarded.

C# sample: Download
// 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);
    // Create a new font object
    Font font = Font.CreateFromSystem(doc, "Arial", null, 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);
}
Java sample: Download
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);
    // Create a new font object
    Font font = Font.createFromSystem(doc, "Arial", null, 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);
    }
}