Search in sources :

Example 11 with Matrix

use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.

the class PDFStreamEngine method processStream.

/**
 * Process a content stream.
 *
 * @param contentStream the content stream
 * @throws IOException if there is an exception while processing the stream
 */
private void processStream(PDContentStream contentStream) throws IOException {
    PDResources parent = pushResources(contentStream);
    Deque<PDGraphicsState> savedStack = saveGraphicsStack();
    Matrix parentMatrix = initialMatrix;
    // transform the CTM using the stream's matrix
    getGraphicsState().getCurrentTransformationMatrix().concatenate(contentStream.getMatrix());
    // the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form
    initialMatrix = getGraphicsState().getCurrentTransformationMatrix().clone();
    // clip to bounding box
    PDRectangle bbox = contentStream.getBBox();
    clipToRect(bbox);
    processStreamOperators(contentStream);
    initialMatrix = parentMatrix;
    restoreGraphicsStack(savedStack);
    popResources(parent);
}
Also used : Matrix(com.tom_roush.pdfbox.util.Matrix) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) PDGraphicsState(com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState)

Example 12 with Matrix

use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.

the class PDFStreamEngine method processTransparencyGroup.

/**
 * Processes a transparency group stream.
 *
 * @param group the transparency group.
 *
 * @throws IOException
 */
protected void processTransparencyGroup(PDTransparencyGroup group) throws IOException {
    if (currentPage == null) {
        throw new IllegalStateException("No current page, call " + "#processChildStream(PDContentStream, PDPage) instead");
    }
    PDResources parent = pushResources(group);
    Deque<PDGraphicsState> savedStack = saveGraphicsStack();
    Matrix parentMatrix = initialMatrix;
    // the stream's initial matrix includes the parent CTM, e.g. this allows a scaled form
    initialMatrix = getGraphicsState().getCurrentTransformationMatrix().clone();
    // transform the CTM using the stream's matrix
    getGraphicsState().getCurrentTransformationMatrix().concatenate(group.getMatrix());
    // Before execution of the transparency group XObject’s content stream,
    // the current blend mode in the graphics state shall be initialized to Normal,
    // the current stroking and nonstroking alpha constants to 1.0, and the current soft mask to None.
    getGraphicsState().setBlendMode(BlendMode.NORMAL);
    getGraphicsState().setAlphaConstant(1);
    getGraphicsState().setNonStrokeAlphaConstant(1);
    getGraphicsState().setSoftMask(null);
    // clip to bounding box
    clipToRect(group.getBBox());
    processStreamOperators(group);
    initialMatrix = parentMatrix;
    restoreGraphicsStack(savedStack);
    popResources(parent);
}
Also used : Matrix(com.tom_roush.pdfbox.util.Matrix) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources) PDGraphicsState(com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState)

Example 13 with Matrix

use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.

the class PDFStreamEngine method processTilingPattern.

/**
 * Process the given tiling pattern. Allows the pattern matrix to be overridden for custom
 * rendering.
 *
 * @param tilingPattern the tiling pattern
 * @param color color to use, if this is an uncoloured pattern, otherwise null.
 * @param colorSpace color space to use, if this is an uncoloured pattern, otherwise null.
 * @param patternMatrix the pattern matrix, may be overridden for custom rendering.
 * @throws IOException if there is an error reading or parsing the tiling pattern content stream.
 */
protected final void processTilingPattern(PDTilingPattern tilingPattern, PDColor color, PDColorSpace colorSpace, Matrix patternMatrix) throws IOException {
    PDResources parent = pushResources(tilingPattern);
    Matrix parentMatrix = initialMatrix;
    initialMatrix = Matrix.concatenate(initialMatrix, patternMatrix);
    // save the original graphics state
    Deque<PDGraphicsState> savedStack = saveGraphicsStack();
    // save a clean state (new clipping path, line path, etc.)
    RectF bbox = new RectF();
    tilingPattern.getBBox().transform(patternMatrix).computeBounds(bbox, true);
    PDRectangle rect = new PDRectangle((float) bbox.left, (float) bbox.top, (float) bbox.width(), (float) bbox.height());
    graphicsStack.push(new PDGraphicsState(rect));
    // non-colored patterns have to be given a color
    if (colorSpace != null) {
        color = new PDColor(color.getComponents(), colorSpace);
        getGraphicsState().setNonStrokingColorSpace(colorSpace);
        getGraphicsState().setNonStrokingColor(color);
        getGraphicsState().setStrokingColorSpace(colorSpace);
        getGraphicsState().setStrokingColor(color);
    }
    // transform the CTM using the stream's matrix
    getGraphicsState().getCurrentTransformationMatrix().concatenate(patternMatrix);
    // clip to bounding box
    clipToRect(tilingPattern.getBBox());
    processStreamOperators(tilingPattern);
    initialMatrix = parentMatrix;
    restoreGraphicsStack(savedStack);
    popResources(parent);
}
Also used : RectF(android.graphics.RectF) Matrix(com.tom_roush.pdfbox.util.Matrix) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) PDGraphicsState(com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState) PDColor(com.tom_roush.pdfbox.pdmodel.graphics.color.PDColor)

Example 14 with Matrix

use of com.tom_roush.pdfbox.util.Matrix 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 15 with Matrix

use of com.tom_roush.pdfbox.util.Matrix in project PdfBox-Android by TomRoush.

the class AppearanceGeneratorHelper method calculateMatrix.

private AffineTransform calculateMatrix(PDRectangle bbox, int rotation) {
    if (rotation == 0) {
        return new AffineTransform();
    }
    float tx = 0, ty = 0;
    switch(rotation) {
        case 90:
            tx = bbox.getUpperRightY();
            break;
        case 180:
            tx = bbox.getUpperRightY();
            ty = bbox.getUpperRightX();
            break;
        case 270:
            ty = bbox.getUpperRightX();
            break;
        default:
            break;
    }
    Matrix matrix = Matrix.getRotateInstance(Math.toRadians(rotation), tx, ty);
    return matrix.createAffineTransform();
}
Also used : Matrix(com.tom_roush.pdfbox.util.Matrix) AffineTransform(com.tom_roush.harmony.awt.geom.AffineTransform)

Aggregations

Matrix (com.tom_roush.pdfbox.util.Matrix)31 PDRectangle (com.tom_roush.pdfbox.pdmodel.common.PDRectangle)11 AffineTransform (com.tom_roush.harmony.awt.geom.AffineTransform)9 PDResources (com.tom_roush.pdfbox.pdmodel.PDResources)9 PDGraphicsState (com.tom_roush.pdfbox.pdmodel.graphics.state.PDGraphicsState)7 MissingOperandException (com.tom_roush.pdfbox.contentstream.operator.MissingOperandException)3 COSBase (com.tom_roush.pdfbox.cos.COSBase)3 COSNumber (com.tom_roush.pdfbox.cos.COSNumber)3 PDPageContentStream (com.tom_roush.pdfbox.pdmodel.PDPageContentStream)3 PDFormXObject (com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject)3 RectF (android.graphics.RectF)2 BoundingBox (com.tom_roush.fontbox.util.BoundingBox)2 COSName (com.tom_roush.pdfbox.cos.COSName)2 PDAppearanceContentStream (com.tom_roush.pdfbox.pdmodel.PDAppearanceContentStream)2 PDPage (com.tom_roush.pdfbox.pdmodel.PDPage)2 PDFont (com.tom_roush.pdfbox.pdmodel.font.PDFont)2 PDColor (com.tom_roush.pdfbox.pdmodel.graphics.color.PDColor)2 PDAppearanceStream (com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream)2 IOException (java.io.IOException)2 Paint (android.graphics.Paint)1