Search in sources :

Example 1 with PDActionGoTo

use of org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo in project pdfbox by apache.

the class PDFMergerUtility method appendDocument.

/**
 * append all pages from source to destination.
 *
 * @param destination the document to receive the pages
 * @param source the document originating the new pages
 *
 * @throws IOException If there is an error accessing data from either
 * document.
 */
public void appendDocument(PDDocument destination, PDDocument source) throws IOException {
    if (source.getDocument().isClosed()) {
        throw new IOException("Error: source PDF is closed.");
    }
    if (destination.getDocument().isClosed()) {
        throw new IOException("Error: destination PDF is closed.");
    }
    PDDocumentCatalog destCatalog = destination.getDocumentCatalog();
    PDDocumentCatalog srcCatalog = source.getDocumentCatalog();
    if (isDynamicXfa(srcCatalog.getAcroForm())) {
        throw new IOException("Error: can't merge source document containing dynamic XFA form content.");
    }
    PDDocumentInformation destInfo = destination.getDocumentInformation();
    PDDocumentInformation srcInfo = source.getDocumentInformation();
    mergeInto(srcInfo.getCOSObject(), destInfo.getCOSObject(), Collections.<COSName>emptySet());
    // use the highest version number for the resulting pdf
    float destVersion = destination.getVersion();
    float srcVersion = source.getVersion();
    if (destVersion < srcVersion) {
        destination.setVersion(srcVersion);
    }
    int pageIndexOpenActionDest = -1;
    if (destCatalog.getOpenAction() == null) {
        // PDFBOX-3972: get local dest page index, it must be reassigned after the page cloning
        PDDestinationOrAction openAction = srcCatalog.getOpenAction();
        PDDestination openActionDestination = null;
        if (openAction instanceof PDActionGoTo) {
            openActionDestination = ((PDActionGoTo) openAction).getDestination();
        } else if (openAction instanceof PDDestination) {
            openActionDestination = (PDDestination) openAction;
        }
        if (openActionDestination instanceof PDPageDestination) {
            PDPage page = ((PDPageDestination) openActionDestination).getPage();
            if (page != null) {
                pageIndexOpenActionDest = srcCatalog.getPages().indexOf(page);
            }
        }
        destCatalog.setOpenAction(srcCatalog.getOpenAction());
    }
    PDFCloneUtility cloner = new PDFCloneUtility(destination);
    mergeAcroForm(cloner, destCatalog, srcCatalog);
    COSArray destThreads = (COSArray) destCatalog.getCOSObject().getDictionaryObject(COSName.THREADS);
    COSArray srcThreads = (COSArray) cloner.cloneForNewDocument(destCatalog.getCOSObject().getDictionaryObject(COSName.THREADS));
    if (destThreads == null) {
        destCatalog.getCOSObject().setItem(COSName.THREADS, srcThreads);
    } else {
        destThreads.addAll(srcThreads);
    }
    PDDocumentNameDictionary destNames = destCatalog.getNames();
    PDDocumentNameDictionary srcNames = srcCatalog.getNames();
    if (srcNames != null) {
        if (destNames == null) {
            destCatalog.getCOSObject().setItem(COSName.NAMES, cloner.cloneForNewDocument(srcNames));
        } else {
            cloner.cloneMerge(srcNames, destNames);
        }
    }
    PDDocumentNameDestinationDictionary destDests = destCatalog.getDests();
    PDDocumentNameDestinationDictionary srcDests = srcCatalog.getDests();
    if (srcDests != null) {
        if (destDests == null) {
            destCatalog.getCOSObject().setItem(COSName.DESTS, cloner.cloneForNewDocument(srcDests));
        } else {
            cloner.cloneMerge(srcDests, destDests);
        }
    }
    PDDocumentOutline destOutline = destCatalog.getDocumentOutline();
    PDDocumentOutline srcOutline = srcCatalog.getDocumentOutline();
    if (srcOutline != null) {
        if (destOutline == null || destOutline.getFirstChild() == null) {
            PDDocumentOutline cloned = new PDDocumentOutline((COSDictionary) cloner.cloneForNewDocument(srcOutline));
            destCatalog.setDocumentOutline(cloned);
        } else {
            // search last sibling for dest, because /Last entry is sometimes wrong
            PDOutlineItem destLastOutlineItem = destOutline.getFirstChild();
            while (destLastOutlineItem.getNextSibling() != null) {
                destLastOutlineItem = destLastOutlineItem.getNextSibling();
            }
            for (PDOutlineItem item : srcOutline.children()) {
                // get each child, clone its dictionary, remove siblings info,
                // append outline item created from there
                COSDictionary clonedDict = (COSDictionary) cloner.cloneForNewDocument(item);
                clonedDict.removeItem(COSName.PREV);
                clonedDict.removeItem(COSName.NEXT);
                PDOutlineItem clonedItem = new PDOutlineItem(clonedDict);
                destLastOutlineItem.insertSiblingAfter(clonedItem);
                destLastOutlineItem = destLastOutlineItem.getNextSibling();
            }
        }
    }
    PageMode destPageMode = destCatalog.getPageMode();
    PageMode srcPageMode = srcCatalog.getPageMode();
    if (destPageMode == null) {
        destCatalog.setPageMode(srcPageMode);
    }
    COSDictionary destLabels = (COSDictionary) destCatalog.getCOSObject().getDictionaryObject(COSName.PAGE_LABELS);
    COSDictionary srcLabels = (COSDictionary) srcCatalog.getCOSObject().getDictionaryObject(COSName.PAGE_LABELS);
    if (srcLabels != null) {
        int destPageCount = destination.getNumberOfPages();
        COSArray destNums;
        if (destLabels == null) {
            destLabels = new COSDictionary();
            destNums = new COSArray();
            destLabels.setItem(COSName.NUMS, destNums);
            destCatalog.getCOSObject().setItem(COSName.PAGE_LABELS, destLabels);
        } else {
            destNums = (COSArray) destLabels.getDictionaryObject(COSName.NUMS);
        }
        COSArray srcNums = (COSArray) srcLabels.getDictionaryObject(COSName.NUMS);
        if (srcNums != null) {
            for (int i = 0; i < srcNums.size(); i += 2) {
                COSNumber labelIndex = (COSNumber) srcNums.getObject(i);
                long labelIndexValue = labelIndex.intValue();
                destNums.add(COSInteger.get(labelIndexValue + destPageCount));
                destNums.add(cloner.cloneForNewDocument(srcNums.getObject(i + 1)));
            }
        }
    }
    COSStream destMetadata = (COSStream) destCatalog.getCOSObject().getDictionaryObject(COSName.METADATA);
    COSStream srcMetadata = (COSStream) srcCatalog.getCOSObject().getDictionaryObject(COSName.METADATA);
    if (destMetadata == null && srcMetadata != null) {
        PDStream newStream = new PDStream(destination, srcMetadata.createInputStream(), (COSName) null);
        mergeInto(srcMetadata, newStream.getCOSObject(), new HashSet<>(Arrays.asList(COSName.FILTER, COSName.LENGTH)));
        destCatalog.getCOSObject().setItem(COSName.METADATA, newStream);
    }
    COSDictionary destOCP = (COSDictionary) destCatalog.getCOSObject().getDictionaryObject(COSName.OCPROPERTIES);
    COSDictionary srcOCP = (COSDictionary) srcCatalog.getCOSObject().getDictionaryObject(COSName.OCPROPERTIES);
    if (destOCP == null && srcOCP != null) {
        destCatalog.getCOSObject().setItem(COSName.OCPROPERTIES, cloner.cloneForNewDocument(srcOCP));
    }
    mergeOutputIntents(cloner, srcCatalog, destCatalog);
    // merge logical structure hierarchy if logical structure information is available in both source pdf and
    // destination pdf
    boolean mergeStructTree = false;
    int destParentTreeNextKey = -1;
    COSDictionary destParentTreeDict = null;
    COSDictionary srcParentTreeDict;
    COSArray destNumbersArray = null;
    COSArray srcNumbersArray = null;
    PDMarkInfo destMark = destCatalog.getMarkInfo();
    PDStructureTreeRoot destStructTree = destCatalog.getStructureTreeRoot();
    PDMarkInfo srcMark = srcCatalog.getMarkInfo();
    PDStructureTreeRoot srcStructTree = srcCatalog.getStructureTreeRoot();
    if (destStructTree != null) {
        PDNumberTreeNode destParentTree = destStructTree.getParentTree();
        destParentTreeNextKey = destStructTree.getParentTreeNextKey();
        if (destParentTree != null) {
            destParentTreeDict = destParentTree.getCOSObject();
            destNumbersArray = (COSArray) destParentTreeDict.getDictionaryObject(COSName.NUMS);
            if (destNumbersArray != null) {
                if (destParentTreeNextKey < 0) {
                    destParentTreeNextKey = destNumbersArray.size() / 2;
                }
                if (destParentTreeNextKey > 0 && srcStructTree != null) {
                    PDNumberTreeNode srcParentTree = srcStructTree.getParentTree();
                    if (srcParentTree != null) {
                        srcParentTreeDict = srcParentTree.getCOSObject();
                        srcNumbersArray = (COSArray) srcParentTreeDict.getDictionaryObject(COSName.NUMS);
                        if (srcNumbersArray != null) {
                            mergeStructTree = true;
                        }
                    }
                }
            }
        }
        if (destMark != null && destMark.isMarked() && !mergeStructTree) {
            destMark.setMarked(false);
        }
        if (!mergeStructTree) {
            destCatalog.setStructureTreeRoot(null);
        }
    }
    Map<COSDictionary, COSDictionary> objMapping = new HashMap<>();
    int pageIndex = 0;
    for (PDPage page : srcCatalog.getPages()) {
        PDPage newPage = new PDPage((COSDictionary) cloner.cloneForNewDocument(page.getCOSObject()));
        newPage.setCropBox(page.getCropBox());
        newPage.setMediaBox(page.getMediaBox());
        newPage.setRotation(page.getRotation());
        PDResources resources = page.getResources();
        if (resources != null) {
            // this is smart enough to just create references for resources that are used on multiple pages
            newPage.setResources(new PDResources((COSDictionary) cloner.cloneForNewDocument(resources)));
        } else {
            newPage.setResources(new PDResources());
        }
        if (mergeStructTree) {
            updateStructParentEntries(newPage, destParentTreeNextKey);
            objMapping.put(page.getCOSObject(), newPage.getCOSObject());
            List<PDAnnotation> oldAnnots = page.getAnnotations();
            List<PDAnnotation> newAnnots = newPage.getAnnotations();
            for (int i = 0; i < oldAnnots.size(); i++) {
                objMapping.put(oldAnnots.get(i).getCOSObject(), newAnnots.get(i).getCOSObject());
            }
        // TODO update mapping for XObjects
        }
        destination.addPage(newPage);
        if (pageIndex == pageIndexOpenActionDest) {
            // PDFBOX-3972: reassign the page.
            // The openAction is either a PDActionGoTo or a PDPageDestination
            PDDestinationOrAction openAction = destCatalog.getOpenAction();
            PDPageDestination pageDestination;
            if (openAction instanceof PDActionGoTo) {
                pageDestination = (PDPageDestination) ((PDActionGoTo) openAction).getDestination();
            } else {
                pageDestination = (PDPageDestination) openAction;
            }
            pageDestination.setPage(newPage);
        }
        ++pageIndex;
    }
    if (mergeStructTree) {
        updatePageReferences(srcNumbersArray, objMapping);
        for (int i = 0; i < srcNumbersArray.size() / 2; i++) {
            destNumbersArray.add(COSInteger.get(destParentTreeNextKey + i));
            destNumbersArray.add(srcNumbersArray.getObject(i * 2 + 1));
        }
        destParentTreeNextKey += srcNumbersArray.size() / 2;
        destParentTreeDict.setItem(COSName.NUMS, destNumbersArray);
        PDNumberTreeNode newParentTreeNode = new PDNumberTreeNode(destParentTreeDict, COSBase.class);
        destStructTree.setParentTree(newParentTreeNode);
        destStructTree.setParentTreeNextKey(destParentTreeNextKey);
        COSDictionary kDictLevel0 = new COSDictionary();
        COSArray newKArray = new COSArray();
        COSArray destKArray = destStructTree.getKArray();
        COSArray srcKArray = srcStructTree.getKArray();
        if (destKArray != null && srcKArray != null) {
            updateParentEntry(destKArray, kDictLevel0);
            newKArray.addAll(destKArray);
            updateParentEntry(srcKArray, kDictLevel0);
            newKArray.addAll(srcKArray);
        }
        kDictLevel0.setItem(COSName.K, newKArray);
        kDictLevel0.setItem(COSName.P, destStructTree);
        kDictLevel0.setItem(COSName.S, COSName.DOCUMENT);
        destStructTree.setK(kDictLevel0);
    }
}
Also used : COSStream(org.apache.pdfbox.cos.COSStream) PDPage(org.apache.pdfbox.pdmodel.PDPage) HashMap(java.util.HashMap) PDDestinationOrAction(org.apache.pdfbox.pdmodel.common.PDDestinationOrAction) PDStructureTreeRoot(org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot) PDPageDestination(org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination) PDMarkInfo(org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDMarkInfo) PDNumberTreeNode(org.apache.pdfbox.pdmodel.common.PDNumberTreeNode) COSArray(org.apache.pdfbox.cos.COSArray) COSNumber(org.apache.pdfbox.cos.COSNumber) PDDocumentInformation(org.apache.pdfbox.pdmodel.PDDocumentInformation) PDActionGoTo(org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo) PDDocumentNameDestinationDictionary(org.apache.pdfbox.pdmodel.PDDocumentNameDestinationDictionary) PageMode(org.apache.pdfbox.pdmodel.PageMode) COSDictionary(org.apache.pdfbox.cos.COSDictionary) PDDocumentOutline(org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline) PDAnnotation(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation) PDResources(org.apache.pdfbox.pdmodel.PDResources) IOException(java.io.IOException) PDDestination(org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination) PDStream(org.apache.pdfbox.pdmodel.common.PDStream) PDDocumentCatalog(org.apache.pdfbox.pdmodel.PDDocumentCatalog) PDDocumentNameDictionary(org.apache.pdfbox.pdmodel.PDDocumentNameDictionary) PDOutlineItem(org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem)

Example 2 with PDActionGoTo

use of org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo in project pdfbox by apache.

the class TestGotoAction method testGoto_OK.

@Test
public void testGoto_OK() throws Exception {
    PDActionGoTo gotoAction = new PDActionGoTo();
    gotoAction.setDestination(new PDDestination() {

        @Override
        public COSBase getCOSObject() {
            return COSName.getPDFName("ADest");
        }
    });
    valid(gotoAction, true);
}
Also used : COSBase(org.apache.pdfbox.cos.COSBase) PDDestination(org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination) PDActionGoTo(org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo) Test(org.junit.Test)

Example 3 with PDActionGoTo

use of org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo in project pdfbox by apache.

the class TestGotoAction method testGoto_KO_missingD.

@Test
public void testGoto_KO_missingD() throws Exception {
    PDActionGoTo gotoAction = new PDActionGoTo();
    valid(gotoAction, false, PreflightConstants.ERROR_ACTION_MISING_KEY);
}
Also used : PDActionGoTo(org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo) Test(org.junit.Test)

Example 4 with PDActionGoTo

use of org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo in project pdfbox by apache.

the class TestGotoAction method testGoto_KO_invalidContent.

@Test
public void testGoto_KO_invalidContent() throws Exception {
    PDActionGoTo gotoAction = new PDActionGoTo();
    gotoAction.setDestination(new PDDestination() {

        @Override
        public COSBase getCOSObject() {
            return new COSDictionary();
        }
    });
    valid(gotoAction, false, PreflightConstants.ERROR_SYNTAX_DICT_INVALID);
}
Also used : COSDictionary(org.apache.pdfbox.cos.COSDictionary) COSBase(org.apache.pdfbox.cos.COSBase) PDDestination(org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination) PDActionGoTo(org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo) Test(org.junit.Test)

Example 5 with PDActionGoTo

use of org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo in project pdfbox by apache.

the class AddAnnotations method main.

public static void main(String[] args) throws IOException {
    if (args.length != 1) {
        System.err.println("Usage: " + AddAnnotations.class.getName() + " <output-pdf>");
        System.exit(1);
    }
    try (PDDocument document = new PDDocument()) {
        PDPage page1 = new PDPage();
        PDPage page2 = new PDPage();
        PDPage page3 = new PDPage();
        document.addPage(page1);
        document.addPage(page2);
        document.addPage(page3);
        List<PDAnnotation> annotations = page1.getAnnotations();
        // Some basic reusable objects/constants
        // Annotations themselves can only be used once!
        PDColor red = new PDColor(new float[] { 1, 0, 0 }, PDDeviceRGB.INSTANCE);
        PDColor blue = new PDColor(new float[] { 0, 0, 1 }, PDDeviceRGB.INSTANCE);
        PDColor black = new PDColor(new float[] { 0, 0, 0 }, PDDeviceRGB.INSTANCE);
        PDBorderStyleDictionary borderThick = new PDBorderStyleDictionary();
        // 12th inch
        borderThick.setWidth(INCH / 12);
        PDBorderStyleDictionary borderThin = new PDBorderStyleDictionary();
        // 1 point
        borderThin.setWidth(INCH / 72);
        PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary();
        borderULine.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE);
        // 1 point
        borderULine.setWidth(INCH / 72);
        float pw = page1.getMediaBox().getUpperRightX();
        float ph = page1.getMediaBox().getUpperRightY();
        // First add some text, two lines we'll add some annotations to this later
        PDFont font = PDType1Font.HELVETICA_BOLD;
        try (PDPageContentStream contents = new PDPageContentStream(document, page1)) {
            contents.beginText();
            contents.setFont(font, 18);
            contents.newLineAtOffset(INCH, ph - INCH - 18);
            contents.showText("PDFBox");
            contents.newLineAtOffset(0, -(INCH / 2));
            contents.showText("External URL");
            contents.newLineAtOffset(0, -(INCH / 2));
            contents.showText("Jump to page three");
            contents.endText();
        }
        // Now add the markup annotation, a highlight to PDFBox text
        PDAnnotationHighlight txtHighlight = new PDAnnotationHighlight();
        txtHighlight.setColor(new PDColor(new float[] { 0, 1, 1 }, PDDeviceRGB.INSTANCE));
        // 20% transparent
        txtHighlight.setConstantOpacity((float) 0.2);
        // Set the rectangle containing the markup
        float textWidth = font.getStringWidth("PDFBox") / 1000 * 18;
        PDRectangle position = new PDRectangle();
        position.setLowerLeftX(INCH);
        position.setLowerLeftY(ph - INCH - 18);
        position.setUpperRightX(INCH + textWidth);
        position.setUpperRightY(ph - INCH);
        txtHighlight.setRectangle(position);
        // work out the points forming the four corners of the annotations
        // set out in anti clockwise form (Completely wraps the text)
        // OK, the below doesn't match that description.
        // It's what acrobat 7 does and displays properly!
        float[] quads = new float[8];
        // x1
        quads[0] = position.getLowerLeftX();
        // y1
        quads[1] = position.getUpperRightY() - 2;
        // x2
        quads[2] = position.getUpperRightX();
        // y2
        quads[3] = quads[1];
        // x3
        quads[4] = quads[0];
        // y3
        quads[5] = position.getLowerLeftY() - 2;
        // x4
        quads[6] = quads[2];
        // y5
        quads[7] = quads[5];
        txtHighlight.setQuadPoints(quads);
        txtHighlight.setContents("Highlighted since it's important");
        annotations.add(txtHighlight);
        // Now add the link annotation, so the click on "External URL" works
        PDAnnotationLink txtLink = new PDAnnotationLink();
        txtLink.setBorderStyle(borderULine);
        // Set the rectangle containing the link
        textWidth = font.getStringWidth("External URL") / 1000 * 18;
        position = new PDRectangle();
        position.setLowerLeftX(INCH);
        // down a couple of points
        position.setLowerLeftY(ph - 1.5f * INCH - 20);
        position.setUpperRightX(INCH + textWidth);
        position.setUpperRightY(ph - 1.5f * INCH);
        txtLink.setRectangle(position);
        // add an action
        PDActionURI action = new PDActionURI();
        action.setURI("http://pdfbox.apache.org");
        txtLink.setAction(action);
        annotations.add(txtLink);
        // Now draw a few more annotations
        PDAnnotationCircle aCircle = new PDAnnotationCircle();
        aCircle.setContents("Circle Annotation");
        // Fill in circle in red
        aCircle.setInteriorColor(red);
        // The border itself will be blue
        aCircle.setColor(blue);
        aCircle.setBorderStyle(borderThin);
        // Place the annotation on the page, we'll make this 1" round
        // 3" down, 1" in on the page
        position = new PDRectangle();
        position.setLowerLeftX(INCH);
        // 1" height, 3" down
        position.setLowerLeftY(ph - 3 * INCH - INCH);
        // 1" in, 1" width
        position.setUpperRightX(2 * INCH);
        // 3" down
        position.setUpperRightY(ph - 3 * INCH);
        aCircle.setRectangle(position);
        annotations.add(aCircle);
        // Now a square annotation
        PDAnnotationSquare aSquare = new PDAnnotationSquare();
        aSquare.setContents("Square Annotation");
        // Outline in red, not setting a fill
        aSquare.setColor(red);
        aSquare.setBorderStyle(borderThick);
        // Place the annotation on the page, we'll make this 1" (72 points) square
        // 3.5" down, 1" in from the right on the page
        // Reuse the variable, but note it's a new object!
        position = new PDRectangle();
        // 1" in from right, 1" wide
        position.setLowerLeftX(pw - 2 * INCH);
        // 1" height, 3.5" down
        position.setLowerLeftY(ph - 3.5f * INCH - INCH);
        // 1" in from right
        position.setUpperRightX(pw - INCH);
        // 3.5" down
        position.setUpperRightY(ph - 3.5f * INCH);
        aSquare.setRectangle(position);
        annotations.add(aSquare);
        // Now we want to draw a line between the two, one end with an open arrow
        PDAnnotationLine aLine = new PDAnnotationLine();
        aLine.setEndPointEndingStyle(PDAnnotationLine.LE_OPEN_ARROW);
        aLine.setContents("Circle->Square");
        // Make the contents a caption on the line
        aLine.setCaption(true);
        // Set the rectangle containing the line
        // Reuse the variable, but note it's a new object!
        position = new PDRectangle();
        // 1" in + width of circle
        position.setLowerLeftX(2 * INCH);
        // 1" height, 3.5" down
        position.setLowerLeftY(ph - 3.5f * INCH - INCH);
        // 1" in from right, and width of square
        position.setUpperRightX(pw - INCH - INCH);
        // 3" down (top of circle)
        position.setUpperRightY(ph - 3 * INCH);
        aLine.setRectangle(position);
        // Now set the line position itself
        float[] linepos = new float[4];
        // x1 = rhs of circle
        linepos[0] = 2 * INCH;
        // y1 halfway down circle
        linepos[1] = ph - 3.5f * INCH;
        // x2 = lhs of square
        linepos[2] = pw - 2 * INCH;
        // y2 halfway down square
        linepos[3] = ph - 4 * INCH;
        aLine.setLine(linepos);
        aLine.setBorderStyle(borderThick);
        aLine.setColor(black);
        annotations.add(aLine);
        // Now add the link annotation, so the click on "Jump to page three" works
        PDAnnotationLink pageLink = new PDAnnotationLink();
        pageLink.setBorderStyle(borderULine);
        // Set the rectangle containing the link
        textWidth = font.getStringWidth("Jump to page three") / 1000 * 18;
        position = new PDRectangle();
        position.setLowerLeftX(INCH);
        // down a couple of points
        position.setLowerLeftY(ph - 2 * INCH - 20);
        position.setUpperRightX(INCH + textWidth);
        position.setUpperRightY(ph - 2 * INCH);
        pageLink.setRectangle(position);
        // add the GoTo action
        PDActionGoTo actionGoto = new PDActionGoTo();
        // see javadoc for other types of PDPageDestination
        PDPageDestination dest = new PDPageFitWidthDestination();
        // do not use setPageNumber(), this is for external destinations only
        dest.setPage(page3);
        actionGoto.setDestination(dest);
        pageLink.setAction(actionGoto);
        annotations.add(pageLink);
        PDAnnotationFreeText freeTextAnnotation = new PDAnnotationFreeText();
        PDColor yellow = new PDColor(new float[] { 1, 1, 0 }, PDDeviceRGB.INSTANCE);
        // this sets background only (contradicts PDF specification)
        freeTextAnnotation.setColor(yellow);
        position = new PDRectangle();
        position.setLowerLeftX(1 * INCH);
        position.setLowerLeftY(ph - 5f * INCH - 3 * INCH);
        position.setUpperRightX(pw - INCH);
        position.setUpperRightY(ph - 5f * INCH);
        freeTextAnnotation.setRectangle(position);
        freeTextAnnotation.setTitlePopup("Sophia Lorem");
        freeTextAnnotation.setSubject("Lorem ipsum");
        freeTextAnnotation.setContents("Lorem ipsum dolor sit amet, consetetur sadipscing elitr," + " sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam " + "erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea " + "rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum " + "dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " + "sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam " + "erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea " + "rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum " + "dolor sit amet.");
        // Text and border in blue RGB color, "Helv" font, 20 point
        freeTextAnnotation.setDefaultAppearance("0 0 1 rg /Helv 20 Tf");
        // Quadding does not have any effect?!
        freeTextAnnotation.setQ(PDVariableText.QUADDING_RIGHT);
        annotations.add(freeTextAnnotation);
        // add the "Helv" font to the default resources
        PDAcroForm acroForm = document.getDocumentCatalog().getAcroForm();
        if (acroForm == null) {
            acroForm = new PDAcroForm(document);
            document.getDocumentCatalog().setAcroForm(acroForm);
        }
        PDResources dr = acroForm.getDefaultResources();
        if (dr == null) {
            dr = new PDResources();
            acroForm.setDefaultResources(dr);
        }
        dr.put(COSName.getPDFName("Helv"), PDType1Font.HELVETICA);
        // but other applications may not.
        for (PDAnnotation ann : annotations) {
            ann.constructAppearances();
        }
        showPageNo(document, page1, "Page 1");
        showPageNo(document, page2, "Page 2");
        showPageNo(document, page3, "Page 3");
        // save the PDF
        document.save(args[0]);
    }
}
Also used : PDFont(org.apache.pdfbox.pdmodel.font.PDFont) PDAnnotationSquare(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquare) PDPage(org.apache.pdfbox.pdmodel.PDPage) PDAnnotation(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation) PDPageDestination(org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination) PDAnnotationHighlight(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationHighlight) PDResources(org.apache.pdfbox.pdmodel.PDResources) PDAcroForm(org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm) PDBorderStyleDictionary(org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary) PDColor(org.apache.pdfbox.pdmodel.graphics.color.PDColor) PDPageFitWidthDestination(org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageFitWidthDestination) PDAnnotationLine(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLine) PDDocument(org.apache.pdfbox.pdmodel.PDDocument) PDAnnotationCircle(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationCircle) PDPageContentStream(org.apache.pdfbox.pdmodel.PDPageContentStream) PDRectangle(org.apache.pdfbox.pdmodel.common.PDRectangle) PDAnnotationFreeText(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationFreeText) PDAnnotationLink(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink) PDActionGoTo(org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo) PDActionURI(org.apache.pdfbox.pdmodel.interactive.action.PDActionURI)

Aggregations

PDActionGoTo (org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo)10 PDDestination (org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination)6 PDPageDestination (org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageDestination)5 PDPage (org.apache.pdfbox.pdmodel.PDPage)4 IOException (java.io.IOException)3 PDDocument (org.apache.pdfbox.pdmodel.PDDocument)3 PDAction (org.apache.pdfbox.pdmodel.interactive.action.PDAction)3 PDAnnotation (org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation)3 PDOutlineItem (org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem)3 Test (org.junit.Test)3 HashMap (java.util.HashMap)2 COSBase (org.apache.pdfbox.cos.COSBase)2 COSDictionary (org.apache.pdfbox.cos.COSDictionary)2 PDResources (org.apache.pdfbox.pdmodel.PDResources)2 PDAnnotationLink (org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink)2 PDDocumentOutline (org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline)2 File (java.io.File)1 Map (java.util.Map)1 COSArray (org.apache.pdfbox.cos.COSArray)1 COSNumber (org.apache.pdfbox.cos.COSNumber)1