Search in sources :

Example 6 with PDAnnotation

use of com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation in project PdfBox-Android by TomRoush.

the class COSArrayListTest method removeFromListByIndex.

/**
 * Test removing a PDModel element by index is in sync with underlying COSArray
 */
@Test
public void removeFromListByIndex() throws Exception {
    COSArrayList<PDAnnotation> cosArrayList = new COSArrayList<PDAnnotation>(annotationsList, annotationsArray);
    int positionToRemove = 1;
    cosArrayList.remove(positionToRemove);
    assertTrue("List size shall be 2", cosArrayList.size() == 2);
    assertTrue("COSArray size shall be 2", annotationsArray.size() == 2);
    PDAnnotation annot = (PDAnnotation) cosArrayList.get(1);
    assertTrue("Object at original position 2 shall now be at position 1 in underlying COSArray", annotationsArray.indexOf(annot.getCOSObject()) == 1);
    // compare with Java List/Array to ensure correct object at position
    assertTrue("List object at 2 is at position 1 in COSArrayList now", cosArrayList.indexOf(tbcAnnotationsList.get(2)) == 1);
    assertTrue("COSObject of List object at 2 is at position 1 in COSArray now", annotationsArray.indexOf(tbcAnnotationsList.get(2).getCOSObject()) == 1);
    assertTrue("Array object at 2 is at position 1 in underlying COSArray now", annotationsArray.indexOf(tbcAnnotationsArray[2]) == 1);
    assertTrue("PDAnnotation shall no longer exist in List", cosArrayList.indexOf(tbcAnnotationsList.get(positionToRemove)) == -1);
    assertTrue("COSObject shall no longer exist in COSArray", annotationsArray.indexOf(tbcAnnotationsArray[positionToRemove]) == -1);
}
Also used : PDAnnotation(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation) Test(org.junit.Test)

Example 7 with PDAnnotation

use of com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation in project PdfBox-Android by TomRoush.

the class COSArrayListTest method addToList.

/**
 * Test adding a PDModel element is in sync with underlying COSArray
 */
@Test
public void addToList() throws Exception {
    COSArrayList<PDAnnotation> cosArrayList = new COSArrayList<PDAnnotation>(annotationsList, annotationsArray);
    // add new annotation
    PDAnnotationSquareCircle aSquare = new PDAnnotationSquareCircle(PDAnnotationSquareCircle.SUB_TYPE_SQUARE);
    cosArrayList.add(aSquare);
    assertTrue("List size shall be 4", annotationsList.size() == 4);
    assertTrue("COSArray size shall be 4", annotationsArray.size() == 4);
    PDAnnotation annot = (PDAnnotation) annotationsList.get(3);
    assertTrue("Added annotation shall be 4th entry in COSArray", annotationsArray.indexOf(annot.getCOSObject()) == 3);
    assertEquals("Provided COSArray and underlying COSArray shall be equal", annotationsArray, cosArrayList.toList());
}
Also used : PDAnnotation(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation) PDAnnotationSquareCircle(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle) Test(org.junit.Test)

Example 8 with PDAnnotation

use of com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation in project PdfBox-Android by TomRoush.

the class PDFMergerUtilityTest method checkWithNumberTree.

/**
 * PDFBOX-4408: Check that /StructParents values from pages and /StructParent values from
 * annotations are found in the /ParentTree.
 *
 * @param document
 */
void checkWithNumberTree(PDDocument document) throws IOException {
    PDDocumentCatalog documentCatalog = document.getDocumentCatalog();
    PDNumberTreeNode parentTree = documentCatalog.getStructureTreeRoot().getParentTree();
    Map<Integer, COSObjectable> numberTreeAsMap = PDFMergerUtility.getNumberTreeAsMap(parentTree);
    Set<Integer> keySet = numberTreeAsMap.keySet();
    PDAcroForm acroForm = documentCatalog.getAcroForm();
    if (acroForm != null) {
        for (PDField field : acroForm.getFieldTree()) {
            for (PDAnnotationWidget widget : field.getWidgets()) {
                if (widget.getStructParent() >= 0) {
                    assertTrue("field '" + field.getFullyQualifiedName() + "' /StructParent " + widget.getStructParent() + " missing in /ParentTree", keySet.contains(widget.getStructParent()));
                }
            }
        }
    }
    for (PDPage page : document.getPages()) {
        if (page.getStructParents() >= 0) {
            assertTrue(keySet.contains(page.getStructParents()));
        }
        for (PDAnnotation ann : page.getAnnotations()) {
            if (ann.getStructParent() >= 0) {
                assertTrue("/StructParent " + ann.getStructParent() + " missing in /ParentTree", keySet.contains(ann.getStructParent()));
            }
        }
    }
// might also test image and form dictionaries...
}
Also used : PDNumberTreeNode(com.tom_roush.pdfbox.pdmodel.common.PDNumberTreeNode) COSObjectable(com.tom_roush.pdfbox.pdmodel.common.COSObjectable) PDField(com.tom_roush.pdfbox.pdmodel.interactive.form.PDField) PDPage(com.tom_roush.pdfbox.pdmodel.PDPage) PDAnnotation(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation) PDAnnotationWidget(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget) PDAcroForm(com.tom_roush.pdfbox.pdmodel.interactive.form.PDAcroForm) PDDocumentCatalog(com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog)

Example 9 with PDAnnotation

use of com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation in project PdfBox-Android by TomRoush.

the class MergeAnnotationsTest method testAnnotationsMatch.

/*
     * Source and target annotations are lĂ­nked by name with the target annotation's name
     * being the source annotation's name prepended with 'annoRef_'
     */
private boolean testAnnotationsMatch(List<PDAnnotation> sourceAnnots, List<PDAnnotation> targetAnnots) {
    Map<String, PDAnnotation> targetAnnotsByName = new HashMap<String, PDAnnotation>();
    COSName destinationName;
    // fill the map with the annotations destination name
    for (PDAnnotation targetAnnot : targetAnnots) {
        destinationName = (COSName) targetAnnot.getCOSObject().getDictionaryObject(COSName.DEST);
        targetAnnotsByName.put(destinationName.getName(), targetAnnot);
    }
    // try to lookup the target annotation for the source annotation by destination name
    for (PDAnnotation sourceAnnot : sourceAnnots) {
        destinationName = (COSName) sourceAnnot.getCOSObject().getDictionaryObject(COSName.DEST);
        if (targetAnnotsByName.get("annoRef_" + destinationName.getName()) == null) {
            return false;
        }
    }
    return true;
}
Also used : COSName(com.tom_roush.pdfbox.cos.COSName) HashMap(java.util.HashMap) PDAnnotation(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation)

Example 10 with PDAnnotation

use of com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation in project PdfBox-Android by TomRoush.

the class PDAcroForm method flatten.

/**
 * This will flatten the specified form fields.
 *
 * <p>Flattening a form field will take the current appearance and make that part
 * of the pages content stream. All form fields and annotations associated are removed.</p>
 *
 * <p>Invisible and hidden fields will be skipped and will not become part of the
 * page content stream</p>
 *
 * @param fields
 * @param refreshAppearances if set to true the appearances for the form field widgets will be updated
 * @throws IOException
 */
public void flatten(List<PDField> fields, boolean refreshAppearances) throws IOException {
    // Nothing to flatten if there are no fields provided
    if (fields.isEmpty()) {
        return;
    }
    if (!refreshAppearances && getNeedAppearances()) {
        Log.w("PdfBox-Android", "acroForm.getNeedAppearances() returns true, " + "visual field appearances may not have been set");
        Log.w("PdfBox-Android", "call acroForm.refreshAppearances() or " + "use the flatten() method with refreshAppearances parameter");
    }
    // from the XFA content into a static PDF.
    if (xfaIsDynamic()) {
        Log.w("PdfBox-Android", "Flatten for a dynamix XFA form is not supported");
        return;
    }
    // refresh the appearances if set
    if (refreshAppearances) {
        refreshAppearances(fields);
    }
    // the content stream to write to
    PDPageContentStream contentStream;
    // get the widgets per page
    Map<COSDictionary, Set<COSDictionary>> pagesWidgetsMap = buildPagesWidgetsMap(fields);
    // preserve all non widget annotations
    for (PDPage page : document.getPages()) {
        Set<COSDictionary> widgetsForPageMap = pagesWidgetsMap.get(page.getCOSObject());
        // indicates if the original content stream
        // has been wrapped in a q...Q pair.
        boolean isContentStreamWrapped = false;
        List<PDAnnotation> annotations = new ArrayList<PDAnnotation>();
        for (PDAnnotation annotation : page.getAnnotations()) {
            if (widgetsForPageMap != null && !widgetsForPageMap.contains(annotation.getCOSObject())) {
                annotations.add(annotation);
            } else if (!annotation.isInvisible() && !annotation.isHidden() && annotation.getNormalAppearanceStream() != null && annotation.getNormalAppearanceStream().getBBox() != null) {
                contentStream = new PDPageContentStream(document, page, AppendMode.APPEND, true, !isContentStreamWrapped);
                isContentStreamWrapped = true;
                PDAppearanceStream appearanceStream = annotation.getNormalAppearanceStream();
                PDFormXObject fieldObject = new PDFormXObject(appearanceStream.getCOSObject());
                contentStream.saveGraphicsState();
                // translate the appearance stream to the widget location if there is
                // not already a transformation in place
                boolean needsTranslation = resolveNeedsTranslation(appearanceStream);
                // scale the appearance stream - mainly needed for images
                // in buttons and signatures
                boolean needsScaling = resolveNeedsScaling(annotation, page.getRotation());
                Matrix transformationMatrix = new Matrix();
                boolean transformed = false;
                if (needsTranslation) {
                    transformationMatrix.translate(annotation.getRectangle().getLowerLeftX(), annotation.getRectangle().getLowerLeftY());
                    transformed = true;
                }
                // PDFBOX-4693: field could have a rotation matrix
                Matrix m = appearanceStream.getMatrix();
                int angle = (int) Math.round(Math.toDegrees(Math.atan2(m.getShearY(), m.getScaleY())));
                int rotation = (angle + 360) % 360;
                if (needsScaling) {
                    PDRectangle bbox = appearanceStream.getBBox();
                    PDRectangle fieldRect = annotation.getRectangle();
                    float xScale;
                    float yScale;
                    if (rotation == 90 || rotation == 270) {
                        xScale = fieldRect.getWidth() / bbox.getHeight();
                        yScale = fieldRect.getHeight() / bbox.getWidth();
                    } else {
                        xScale = fieldRect.getWidth() / bbox.getWidth();
                        yScale = fieldRect.getHeight() / bbox.getHeight();
                    }
                    Matrix scalingMatrix = Matrix.getScaleInstance(xScale, yScale);
                    transformationMatrix.concatenate(scalingMatrix);
                    transformed = true;
                }
                if (transformed) {
                    contentStream.transform(transformationMatrix);
                }
                contentStream.drawForm(fieldObject);
                contentStream.restoreGraphicsState();
                contentStream.close();
            }
        }
        page.setAnnotations(annotations);
    }
    // remove the fields
    removeFields(fields);
    // remove XFA for hybrid forms
    dictionary.removeItem(COSName.XFA);
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) COSDictionary(com.tom_roush.pdfbox.cos.COSDictionary) PDPage(com.tom_roush.pdfbox.pdmodel.PDPage) PDAppearanceStream(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream) PDAnnotation(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation) ArrayList(java.util.ArrayList) COSArrayList(com.tom_roush.pdfbox.pdmodel.common.COSArrayList) Matrix(com.tom_roush.pdfbox.util.Matrix) PDFormXObject(com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject) PDPageContentStream(com.tom_roush.pdfbox.pdmodel.PDPageContentStream) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle)

Aggregations

PDAnnotation (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotation)21 Test (org.junit.Test)9 COSArray (com.tom_roush.pdfbox.cos.COSArray)6 PDPage (com.tom_roush.pdfbox.pdmodel.PDPage)5 PDAnnotationLink (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink)5 COSDictionary (com.tom_roush.pdfbox.cos.COSDictionary)4 AnnotationFilter (com.tom_roush.pdfbox.pdmodel.interactive.annotation.AnnotationFilter)4 COSBase (com.tom_roush.pdfbox.cos.COSBase)3 COSArrayList (com.tom_roush.pdfbox.pdmodel.common.COSArrayList)3 PDAnnotationSquareCircle (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle)3 PDAnnotationWidget (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget)3 ArrayList (java.util.ArrayList)3 COSName (com.tom_roush.pdfbox.cos.COSName)2 COSStream (com.tom_roush.pdfbox.cos.COSStream)2 PDDocumentCatalog (com.tom_roush.pdfbox.pdmodel.PDDocumentCatalog)2 PDDocumentNameDestinationDictionary (com.tom_roush.pdfbox.pdmodel.PDDocumentNameDestinationDictionary)2 COSObjectable (com.tom_roush.pdfbox.pdmodel.common.COSObjectable)2 PDNumberTreeNode (com.tom_roush.pdfbox.pdmodel.common.PDNumberTreeNode)2 PDActionGoTo (com.tom_roush.pdfbox.pdmodel.interactive.action.PDActionGoTo)2 PDDestination (com.tom_roush.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination)2