Search in sources :

Example 1 with PDAppearanceStream

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

the class PDAbstractAppearanceHandler method getAppearanceEntryAsContentStream.

private PDAppearanceContentStream getAppearanceEntryAsContentStream(PDAppearanceEntry appearanceEntry, boolean compress) throws IOException {
    PDAppearanceStream appearanceStream = appearanceEntry.getAppearanceStream();
    setTransformationMatrix(appearanceStream);
    // ensure there are resources
    PDResources resources = appearanceStream.getResources();
    if (resources == null) {
        resources = new PDResources();
        appearanceStream.setResources(resources);
    }
    return new PDAppearanceContentStream(appearanceStream, compress);
}
Also used : PDAppearanceStream(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream) PDAppearanceContentStream(com.tom_roush.pdfbox.pdmodel.PDAppearanceContentStream) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources)

Example 2 with PDAppearanceStream

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

the class PDPolygonAppearanceHandler method generateNormalAppearance.

@Override
public void generateNormalAppearance() {
    PDAnnotationMarkup annotation = (PDAnnotationMarkup) getAnnotation();
    float lineWidth = getLineWidth();
    PDRectangle rect = annotation.getRectangle();
    // Adjust rectangle even if not empty
    // CTAN-example-Annotations.pdf p2
    float minX = Float.MAX_VALUE;
    float minY = Float.MAX_VALUE;
    float maxX = Float.MIN_VALUE;
    float maxY = Float.MIN_VALUE;
    float[][] pathArray = getPathArray(annotation);
    if (pathArray == null) {
        return;
    }
    for (int i = 0; i < pathArray.length; ++i) {
        for (int j = 0; j < pathArray[i].length / 2; ++j) {
            float x = pathArray[i][j * 2];
            float y = pathArray[i][j * 2 + 1];
            minX = Math.min(minX, x);
            minY = Math.min(minY, y);
            maxX = Math.max(maxX, x);
            maxY = Math.max(maxY, y);
        }
    }
    rect.setLowerLeftX(Math.min(minX - lineWidth, rect.getLowerLeftX()));
    rect.setLowerLeftY(Math.min(minY - lineWidth, rect.getLowerLeftY()));
    rect.setUpperRightX(Math.max(maxX + lineWidth, rect.getUpperRightX()));
    rect.setUpperRightY(Math.max(maxY + lineWidth, rect.getUpperRightY()));
    annotation.setRectangle(rect);
    PDAppearanceContentStream contentStream = null;
    try {
        contentStream = getNormalAppearanceAsContentStream();
        boolean hasStroke = contentStream.setStrokingColorOnDemand(getColor());
        boolean hasBackground = contentStream.setNonStrokingColorOnDemand(annotation.getInteriorColor());
        setOpacity(contentStream, annotation.getConstantOpacity());
        contentStream.setBorderLine(lineWidth, annotation.getBorderStyle(), annotation.getBorder());
        PDBorderEffectDictionary borderEffect = annotation.getBorderEffect();
        if (borderEffect != null && borderEffect.getStyle().equals(PDBorderEffectDictionary.STYLE_CLOUDY)) {
            CloudyBorder cloudyBorder = new CloudyBorder(contentStream, borderEffect.getIntensity(), lineWidth, getRectangle());
            cloudyBorder.createCloudyPolygon(pathArray);
            annotation.setRectangle(cloudyBorder.getRectangle());
            PDAppearanceStream appearanceStream = annotation.getNormalAppearanceStream();
            appearanceStream.setBBox(cloudyBorder.getBBox());
            appearanceStream.setMatrix(cloudyBorder.getMatrix());
        } else {
            for (int i = 0; i < pathArray.length; i++) {
                float[] pointsArray = pathArray[i];
                // first array shall be of size 2 and specify the moveto operator
                if (i == 0 && pointsArray.length == 2) {
                    contentStream.moveTo(pointsArray[0], pointsArray[1]);
                } else {
                    // entries of length 2 shall be treated as lineto operator
                    if (pointsArray.length == 2) {
                        contentStream.lineTo(pointsArray[0], pointsArray[1]);
                    } else if (pointsArray.length == 6) {
                        contentStream.curveTo(pointsArray[0], pointsArray[1], pointsArray[2], pointsArray[3], pointsArray[4], pointsArray[5]);
                    }
                }
            }
            contentStream.closePath();
        }
        contentStream.drawShape(lineWidth, hasStroke, hasBackground);
    } catch (IOException e) {
        Log.e("PdfBox-Android", e.getMessage(), e);
    } finally {
        IOUtils.closeQuietly(contentStream);
    }
}
Also used : PDAppearanceContentStream(com.tom_roush.pdfbox.pdmodel.PDAppearanceContentStream) PDAppearanceStream(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream) PDBorderEffectDictionary(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDBorderEffectDictionary) PDAnnotationMarkup(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) IOException(java.io.IOException)

Example 3 with PDAppearanceStream

use of com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream 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)

Example 4 with PDAppearanceStream

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

the class PDVisibleSigBuilder method createAppearanceDictionary.

@Override
public void createAppearanceDictionary(PDFormXObject holderForml, PDSignatureField signatureField) throws IOException {
    PDAppearanceDictionary appearance = new PDAppearanceDictionary();
    appearance.getCOSObject().setDirect(true);
    PDAppearanceStream appearanceStream = new PDAppearanceStream(holderForml.getCOSObject());
    appearance.setNormalAppearance(appearanceStream);
    signatureField.getWidgets().get(0).setAppearance(appearance);
    pdfStructure.setAppearanceDictionary(appearance);
    Log.i("PdfBox-Android", "PDF appearance dictionary has been created");
}
Also used : PDAppearanceDictionary(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary) PDAppearanceStream(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream)

Example 5 with PDAppearanceStream

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

the class PDAcroForm method resolveNeedsScaling.

/**
 * Check if there needs to be a scaling transformation applied.
 *
 * @param annotation
 * @param rotation
 * @return the need for a scaling transformation.
 */
private boolean resolveNeedsScaling(PDAnnotation annotation, int rotation) {
    PDAppearanceStream appearanceStream = annotation.getNormalAppearanceStream();
    // Check if there is a transformation within the XObjects content
    PDResources resources = appearanceStream.getResources();
    if (resources != null && resources.getXObjectNames().iterator().hasNext()) {
        return true;
    }
    PDRectangle bbox = appearanceStream.getBBox();
    PDRectangle fieldRect = annotation.getRectangle();
    if (rotation == 90 || rotation == 270) {
        return Float.compare(bbox.getWidth(), fieldRect.getHeight()) != 0 || Float.compare(bbox.getHeight(), fieldRect.getWidth()) != 0;
    } else {
        return Float.compare(bbox.getWidth(), fieldRect.getWidth()) != 0 || Float.compare(bbox.getHeight(), fieldRect.getHeight()) != 0;
    }
}
Also used : PDAppearanceStream(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle)

Aggregations

PDAppearanceStream (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream)11 PDRectangle (com.tom_roush.pdfbox.pdmodel.common.PDRectangle)9 PDAppearanceContentStream (com.tom_roush.pdfbox.pdmodel.PDAppearanceContentStream)5 PDResources (com.tom_roush.pdfbox.pdmodel.PDResources)4 PDBorderEffectDictionary (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDBorderEffectDictionary)4 IOException (java.io.IOException)4 PDAppearanceDictionary (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary)3 PDAnnotationMarkup (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup)2 PDAnnotationSquareCircle (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle)2 Matrix (com.tom_roush.pdfbox.util.Matrix)2 PointF (android.graphics.PointF)1 AffineTransform (com.tom_roush.harmony.awt.geom.AffineTransform)1 COSDictionary (com.tom_roush.pdfbox.cos.COSDictionary)1 PDPage (com.tom_roush.pdfbox.pdmodel.PDPage)1 PDPageContentStream (com.tom_roush.pdfbox.pdmodel.PDPageContentStream)1 COSArrayList (com.tom_roush.pdfbox.pdmodel.common.COSArrayList)1 PDFont (com.tom_roush.pdfbox.pdmodel.font.PDFont)1 PDColor (com.tom_roush.pdfbox.pdmodel.graphics.color.PDColor)1 PDFormXObject (com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject)1 PDFormFieldAdditionalActions (com.tom_roush.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions)1