Search in sources :

Example 26 with Matrix

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

the class Concatenate method process.

@Override
public void process(Operator operator, List<COSBase> arguments) throws IOException {
    if (arguments.size() < 6) {
        throw new MissingOperandException(operator, arguments);
    }
    if (!checkArrayTypesClass(arguments, COSNumber.class)) {
        return;
    }
    // concatenate matrix to current transformation matrix
    COSNumber a = (COSNumber) arguments.get(0);
    COSNumber b = (COSNumber) arguments.get(1);
    COSNumber c = (COSNumber) arguments.get(2);
    COSNumber d = (COSNumber) arguments.get(3);
    COSNumber e = (COSNumber) arguments.get(4);
    COSNumber f = (COSNumber) arguments.get(5);
    Matrix matrix = new Matrix(a.floatValue(), b.floatValue(), c.floatValue(), d.floatValue(), e.floatValue(), f.floatValue());
    context.getGraphicsState().getCurrentTransformationMatrix().concatenate(matrix);
}
Also used : Matrix(com.tom_roush.pdfbox.util.Matrix) MissingOperandException(com.tom_roush.pdfbox.contentstream.operator.MissingOperandException) COSNumber(com.tom_roush.pdfbox.cos.COSNumber)

Example 27 with Matrix

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

the class LayerUtility method importPageAsForm.

/**
 * Imports a page from some PDF file as a Form XObject so it can be placed on another page
 * in the target document.
 * <p>
 * You may want to call {@link #wrapInSaveRestore(PDPage) wrapInSaveRestore(PDPage)} before invoking the Form XObject to
 * make sure that the graphics state is reset.
 *
 * @param sourceDoc the source PDF document that contains the page to be copied
 * @param page the page in the source PDF document to be copied
 * @return a Form XObject containing the original page's content
 * @throws IOException if an I/O error occurs
 */
public PDFormXObject importPageAsForm(PDDocument sourceDoc, PDPage page) throws IOException {
    importOcProperties(sourceDoc);
    PDStream newStream = new PDStream(targetDoc, page.getContents(), COSName.FLATE_DECODE);
    PDFormXObject form = new PDFormXObject(newStream);
    // Copy resources
    PDResources pageRes = page.getResources();
    PDResources formRes = new PDResources();
    cloner.cloneMerge(pageRes, formRes);
    form.setResources(formRes);
    // Transfer some values from page to form
    transferDict(page.getCOSObject(), form.getCOSObject(), PAGE_TO_FORM_FILTER, true);
    Matrix matrix = form.getMatrix();
    AffineTransform at = matrix.createAffineTransform();
    PDRectangle mediaBox = page.getMediaBox();
    PDRectangle cropBox = page.getCropBox();
    PDRectangle viewBox = (cropBox != null ? cropBox : mediaBox);
    // Handle the /Rotation entry on the page dict
    int rotation = page.getRotation();
    // Transform to FOP's user space
    // at.scale(1 / viewBox.getWidth(), 1 / viewBox.getHeight());
    at.translate(mediaBox.getLowerLeftX() - viewBox.getLowerLeftX(), mediaBox.getLowerLeftY() - viewBox.getLowerLeftY());
    switch(rotation) {
        case 90:
            at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
            at.translate(0, viewBox.getWidth());
            at.rotate(-Math.PI / 2.0);
            break;
        case 180:
            at.translate(viewBox.getWidth(), viewBox.getHeight());
            at.rotate(-Math.PI);
            break;
        case 270:
            at.scale(viewBox.getWidth() / viewBox.getHeight(), viewBox.getHeight() / viewBox.getWidth());
            at.translate(viewBox.getHeight(), 0);
            at.rotate(-Math.PI * 1.5);
            break;
        default:
    }
    // Compensate for Crop Boxes not starting at 0,0
    at.translate(-viewBox.getLowerLeftX(), -viewBox.getLowerLeftY());
    if (!at.isIdentity()) {
        form.setMatrix(at);
    }
    BoundingBox bbox = new BoundingBox();
    bbox.setLowerLeftX(viewBox.getLowerLeftX());
    bbox.setLowerLeftY(viewBox.getLowerLeftY());
    bbox.setUpperRightX(viewBox.getUpperRightX());
    bbox.setUpperRightY(viewBox.getUpperRightY());
    form.setBBox(new PDRectangle(bbox));
    return form;
}
Also used : Matrix(com.tom_roush.pdfbox.util.Matrix) BoundingBox(com.tom_roush.fontbox.util.BoundingBox) PDFormXObject(com.tom_roush.pdfbox.pdmodel.graphics.form.PDFormXObject) PDResources(com.tom_roush.pdfbox.pdmodel.PDResources) AffineTransform(com.tom_roush.harmony.awt.geom.AffineTransform) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) PDStream(com.tom_roush.pdfbox.pdmodel.common.PDStream)

Example 28 with Matrix

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

the class PDCaretAppearanceHandler method generateNormalAppearance.

@Override
public void generateNormalAppearance() {
    PDAnnotationMarkup annotation = (PDAnnotationMarkup) getAnnotation();
    PDAppearanceContentStream contentStream = null;
    try {
        contentStream = getNormalAppearanceAsContentStream();
        contentStream.setStrokingColor(getColor());
        contentStream.setNonStrokingColor(getColor());
        setOpacity(contentStream, annotation.getConstantOpacity());
        PDRectangle rect = getRectangle();
        PDRectangle bbox = new PDRectangle(rect.getWidth(), rect.getHeight());
        if (!annotation.getCOSObject().containsKey(COSName.RD)) {
            // Adobe creates the /RD entry with a number that is decided
            // by dividing the height by 10, with a maximum result of 5.
            // That number is then used to enlarge the bbox and the rectangle and added to the
            // translation values in the matrix and also used for the line width
            // (not here because it has no effect, see comment near fill() ).
            // The curves are based on the original rectangle.
            float rd = Math.min(rect.getHeight() / 10, 5);
            annotation.setRectDifferences(rd);
            bbox = new PDRectangle(-rd, -rd, rect.getWidth() + 2 * rd, rect.getHeight() + 2 * rd);
            Matrix matrix = annotation.getNormalAppearanceStream().getMatrix();
            matrix.transformPoint(rd, rd);
            annotation.getNormalAppearanceStream().setMatrix(matrix.createAffineTransform());
            PDRectangle rect2 = new PDRectangle(rect.getLowerLeftX() - rd, rect.getLowerLeftY() - rd, rect.getWidth() + 2 * rd, rect.getHeight() + 2 * rd);
            annotation.setRectangle(rect2);
        }
        annotation.getNormalAppearanceStream().setBBox(bbox);
        float halfX = rect.getWidth() / 2;
        float halfY = rect.getHeight() / 2;
        contentStream.moveTo(0, 0);
        contentStream.curveTo(halfX, 0, halfX, halfY, halfX, rect.getHeight());
        contentStream.curveTo(halfX, halfY, halfX, 0, rect.getWidth(), 0);
        contentStream.closePath();
        contentStream.fill();
    // Adobe has an additional stroke, but it has no effect
    // because fill "consumes" the path.
    } catch (IOException e) {
        Log.e("PdfBox-Android", e.getMessage(), e);
    } finally {
        IOUtils.closeQuietly(contentStream);
    }
}
Also used : Matrix(com.tom_roush.pdfbox.util.Matrix) PDAppearanceContentStream(com.tom_roush.pdfbox.pdmodel.PDAppearanceContentStream) PDAnnotationMarkup(com.tom_roush.pdfbox.pdmodel.interactive.annotation.PDAnnotationMarkup) PDRectangle(com.tom_roush.pdfbox.pdmodel.common.PDRectangle) IOException(java.io.IOException)

Example 29 with Matrix

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

the class PDFStreamEngine method processSoftMask.

/**
 * Processes a soft mask transparency group stream.
 *
 * @param group the transparency group.
 *
 * @throws IOException
 */
protected void processSoftMask(PDTransparencyGroup group) throws IOException {
    saveGraphicsState();
    Matrix softMaskCTM = getGraphicsState().getSoftMask().getInitialTransformationMatrix();
    getGraphicsState().setCurrentTransformationMatrix(softMaskCTM);
    processTransparencyGroup(group);
    restoreGraphicsState();
}
Also used : Matrix(com.tom_roush.pdfbox.util.Matrix)

Example 30 with Matrix

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

the class PDFStreamEngine method processAnnotation.

/**
 * Process the given annotation with the specified appearance stream.
 *
 * @param annotation The annotation containing the appearance stream to process.
 * @param appearance The appearance stream to process.
 * @throws IOException If there is an error reading or parsing the appearance content stream.
 */
protected void processAnnotation(PDAnnotation annotation, PDAppearanceStream appearance) throws IOException {
    PDResources parent = pushResources(appearance);
    Deque<PDGraphicsState> savedStack = saveGraphicsStack();
    PDRectangle bbox = appearance.getBBox();
    PDRectangle rect = annotation.getRectangle();
    Matrix matrix = appearance.getMatrix();
    // zero-sized rectangles are not valid
    if (rect != null && rect.getWidth() > 0 && rect.getHeight() > 0 && bbox != null) {
        // transformed appearance box  fixme: may be an arbitrary shape
        RectF transformedBox = new RectF();
        bbox.transform(matrix).computeBounds(transformedBox, true);
        // compute a matrix which scales and translates the transformed appearance box to align
        // with the edges of the annotation's rectangle
        Matrix a = Matrix.getTranslateInstance(rect.getLowerLeftX(), rect.getLowerLeftY());
        a.concatenate(Matrix.getScaleInstance((float) (rect.getWidth() / transformedBox.width()), (float) (rect.getHeight() / transformedBox.height())));
        a.concatenate(Matrix.getTranslateInstance((float) -transformedBox.left, (float) -transformedBox.top));
        // Matrix shall be concatenated with A to form a matrix AA that maps from the appearance's
        // coordinate system to the annotation's rectangle in default user space
        // 
        // HOWEVER only the opposite order works for rotated pages with
        // filled fields / annotations that have a matrix in the appearance stream, see PDFBOX-3083
        Matrix aa = Matrix.concatenate(a, matrix);
        // make matrix AA the CTM
        getGraphicsState().setCurrentTransformationMatrix(aa);
        // clip to bounding box
        clipToRect(bbox);
        // needed for patterns in appearance streams, e.g. PDFBOX-2182
        initialMatrix = aa.clone();
        processStreamOperators(appearance);
    }
    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)

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