Example usage for org.apache.pdfbox.util Matrix Matrix

List of usage examples for org.apache.pdfbox.util Matrix Matrix

Introduction

In this page you can find the example usage for org.apache.pdfbox.util Matrix Matrix.

Prototype

public Matrix() 

Source Link

Document

Constructor.

Usage

From source file:edu.umass.cs.iesl.pdf2meta.cli.extract.pdfbox.pagedrawer.BeginInlineImage.java

License:Apache License

/**
 * process : BI : begin inline image.//from   www  .j ava 2s . c  o  m
 * @param operator The operator that is being executed.
 * @param arguments List
 * @throws java.io.IOException If there is an error displaying the inline image.
 */
public void process(PDFOperator operator, List<COSBase> arguments) throws IOException {
    GraphicsAwarePDFStreamEngine drawer = (GraphicsAwarePDFStreamEngine) context;

    PDPage page = drawer.getPage();
    //begin inline image object
    ImageParameters params = operator.getImageParameters();
    PDInlinedImage image = new PDInlinedImage();
    image.setImageParameters(params);
    image.setImageData(operator.getImageData());
    BufferedImage awtImage = image.createImage(context.getColorSpaces());

    if (awtImage == null) {
        log.warn("BeginInlineImage.process(): createImage returned NULL");
        return;
    }
    int imageWidth = awtImage.getWidth();
    int imageHeight = awtImage.getHeight();
    double pageHeight = drawer.getPageSize().getHeight();

    Matrix ctm = drawer.getGraphicsState().getCurrentTransformationMatrix();
    int pageRotation = page.findRotation();

    AffineTransform ctmAT = ctm.createAffineTransform();
    ctmAT.scale(1f / imageWidth, 1f / imageHeight);
    Matrix rotationMatrix = new Matrix();
    rotationMatrix.setFromAffineTransform(ctmAT);
    // calculate the inverse rotation angle
    // scaleX = m00 = cos
    // shearX = m01 = -sin
    // tan = sin/cos
    double angle = Math.atan(ctmAT.getShearX() / ctmAT.getScaleX());
    Matrix translationMatrix = null;
    if (pageRotation == 0 || pageRotation == 180) {
        translationMatrix = Matrix.getTranslatingInstance((float) (Math.sin(angle) * ctm.getXScale()),
                (float) (pageHeight - 2 * ctm.getYPosition() - Math.cos(angle) * ctm.getYScale()));
    } else if (pageRotation == 90 || pageRotation == 270) {
        translationMatrix = Matrix.getTranslatingInstance((float) (Math.sin(angle) * ctm.getYScale()),
                (float) (pageHeight - 2 * ctm.getYPosition()));
    }
    rotationMatrix = rotationMatrix.multiply(translationMatrix);
    rotationMatrix.setValue(0, 1, (-1) * rotationMatrix.getValue(0, 1));
    rotationMatrix.setValue(1, 0, (-1) * rotationMatrix.getValue(1, 0));
    AffineTransform at = new AffineTransform(rotationMatrix.getValue(0, 0), rotationMatrix.getValue(0, 1),
            rotationMatrix.getValue(1, 0), rotationMatrix.getValue(1, 1), rotationMatrix.getValue(2, 0),
            rotationMatrix.getValue(2, 1));
    drawer.drawImage(awtImage, at);
}

From source file:org.elacin.pdfextract.datasource.pdfbox.PDFBoxIntegration.java

License:Apache License

/**
 * Old version/*  ww  w  .  j  av a2s.co m*/
 */
public void processEncodedText(@NotNull byte[] string) throws IOException {

    /*
     *  Note on variable names.  There are three different units being used
     *     in this code.  Character sizes are given in glyph units, text locations
     *     are initially given in text units, and we want to save the data in
     *     display units. The variable names should end with Text or Disp to
     *     represent if the values are in text or disp units (no glyph units are saved).
     */
    final float fontSizeText = getGraphicsState().getTextState().getFontSize();
    final float horizontalScalingText = getGraphicsState().getTextState().getHorizontalScalingPercent() / 100f;

    // float verticalScalingText = horizontalScaling;//not sure if this is right but what else to
    // do???
    final float riseText = getGraphicsState().getTextState().getRise();
    final float wordSpacingText = getGraphicsState().getTextState().getWordSpacing();
    final float characterSpacingText = getGraphicsState().getTextState().getCharacterSpacing();

    /*
     *  We won't know the actual number of characters until
     * we process the byte data(could be two bytes each) but
     * it won't ever be more than string.length*2(there are some cases
     * were a single byte will result in two output characters "fi"
     */
    final PDFont font = getGraphicsState().getTextState().getFont();

    /*
     *  This will typically be 1000 but in the case of a type3 font this might be a different
     * number
     */
    final float glyphSpaceToTextSpaceFactor;

    if (font instanceof PDType3Font) {
        PDMatrix fontMatrix = font.getFontMatrix();
        float fontMatrixXScaling = fontMatrix.getValue(0, 0);

        glyphSpaceToTextSpaceFactor = 1.0f / fontMatrixXScaling;
    } else {
        glyphSpaceToTextSpaceFactor = /* 1.0f / */ 1000f;
    }

    float spaceWidthText = 0.0F;

    try {
        spaceWidthText = (font.getFontWidth(SPACE_BYTES, 0, 1) / glyphSpaceToTextSpaceFactor);
    } catch (Throwable exception) {
        log.warn(exception, exception);
    }

    if (spaceWidthText == 0.0F) {
        spaceWidthText = (font.getAverageFontWidth() / glyphSpaceToTextSpaceFactor);
        spaceWidthText *= .80f;
    }

    /* Convert textMatrix to display units */
    final Matrix initialMatrix = new Matrix();

    initialMatrix.setValue(0, 0, 1.0F);
    initialMatrix.setValue(0, 1, 0.0F);
    initialMatrix.setValue(0, 2, 0.0F);
    initialMatrix.setValue(1, 0, 0.0F);
    initialMatrix.setValue(1, 1, 1.0F);
    initialMatrix.setValue(1, 2, 0.0F);
    initialMatrix.setValue(2, 0, 0.0F);
    initialMatrix.setValue(2, 1, riseText);
    initialMatrix.setValue(2, 2, 1.0F);

    final Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
    final Matrix dispMatrix = initialMatrix.multiply(ctm);
    Matrix textMatrixStDisp = getTextMatrix().multiply(dispMatrix);
    final float xScaleDisp = textMatrixStDisp.getXScale();
    final float yScaleDisp = textMatrixStDisp.getYScale();
    final float spaceWidthDisp = spaceWidthText * xScaleDisp * fontSizeText;
    final float wordSpacingDisp = wordSpacingText * xScaleDisp * fontSizeText;
    float maxVerticalDisplacementText = 0.0F;
    StringBuilder characterBuffer = new StringBuilder(string.length);
    int codeLength = 1;

    for (int i = 0; i < string.length; i += codeLength) {

        // Decode the value to a Unicode character
        codeLength = 1;

        String c = font.encode(string, i, codeLength);

        if ((c == null) && (i + 1 < string.length)) {

            // maybe a multibyte encoding
            codeLength++;
            c = font.encode(string, i, codeLength);
        }

        c = inspectFontEncoding(c);

        // todo, handle horizontal displacement
        // get the width and height of this character in text units
        float fontWidth = font.getFontWidth(string, i, codeLength) * 0.95f;

        if (fontWidth == 0.0f) {
            fontWidth = spaceWidthDisp;
        }

        float characterHorizontalDisplacementText = (fontWidth / glyphSpaceToTextSpaceFactor);

        maxVerticalDisplacementText = Math.max(maxVerticalDisplacementText,
                font.getFontHeight(string, i, codeLength) / glyphSpaceToTextSpaceFactor);

        if (maxVerticalDisplacementText <= 0.0f) {
            maxVerticalDisplacementText = font.getFontBoundingBox().getHeight() / glyphSpaceToTextSpaceFactor;
        }

        /**
         * PDF Spec - 5.5.2 Word Spacing
         *
         * Word spacing works the same was as character spacing, but applies
         * only to the space character, code 32.
         *
         * Note: Word spacing is applied to every occurrence of the single-byte
         * character code 32 in a string.  This can occur when using a simple
         * font or a composite font that defines code 32 as a single-byte code.
         * It does not apply to occurrences of the byte value 32 in multiple-byte
         * codes.
         *
         * RDD - My interpretation of this is that only character code 32's that
         * encode to spaces should have word spacing applied.  Cases have been
         * observed where a font has a space character with a character code
         * other than 32, and where word spacing (Tw) was used.  In these cases,
         * applying word spacing to either the non-32 space or to the character
         * code 32 non-space resulted in errors consistent with this interpretation.
         */
        float spacingText = characterSpacingText;

        if ((string[i] == (byte) 0x20) && (codeLength == 1)) {
            spacingText += wordSpacingText;
        }

        /*
         *  The text matrix gets updated after each glyph is placed.  The updated
         *          version will have the X and Y coordinates for the next glyph.
         */
        Matrix glyphMatrixStDisp = getTextMatrix().multiply(dispMatrix);

        // The adjustment will always be zero.  The adjustment as shown in the
        // TJ operator will be handled separately.
        float adjustment = 0.0F;

        // TODO : tx should be set for horizontal text and ty for vertical text
        // which seems to be specified in the font (not the direction in the matrix).
        float tx = ((characterHorizontalDisplacementText - adjustment / glyphSpaceToTextSpaceFactor)
                * fontSizeText) * horizontalScalingText;
        Matrix td = new Matrix();

        td.setValue(2, 0, tx);

        float ty = 0.0F;

        td.setValue(2, 1, ty);
        setTextMatrix(td.multiply(getTextMatrix()));

        Matrix glyphMatrixEndDisp = getTextMatrix().multiply(dispMatrix);
        float sx = spacingText * horizontalScalingText;
        Matrix sd = new Matrix();

        sd.setValue(2, 0, sx);

        float sy = 0.0F;

        sd.setValue(2, 1, sy);
        setTextMatrix(sd.multiply(getTextMatrix()));

        float widthText = glyphMatrixEndDisp.getXPosition() - glyphMatrixStDisp.getXPosition();

        characterBuffer.append(c);

        Matrix textMatrixEndDisp = glyphMatrixEndDisp;
        float totalVerticalDisplacementDisp = maxVerticalDisplacementText * fontSizeText * yScaleDisp;

        try {
            final ETextPosition text = new ETextPosition(page, textMatrixStDisp, textMatrixEndDisp,
                    totalVerticalDisplacementDisp, new float[] { widthText }, spaceWidthDisp,
                    characterBuffer.toString(), font, fontSizeText,
                    (int) (fontSizeText * getTextMatrix().getXScale()), wordSpacingDisp);

            correctPosition(font, string, i, c, fontSizeText, glyphSpaceToTextSpaceFactor,
                    horizontalScalingText, codeLength, text);
            processTextPosition(text);
        } catch (Exception e) {
            log.warn("LOG00570:Error adding '" + characterBuffer + "': " + e.getMessage());
        }

        textMatrixStDisp = getTextMatrix().multiply(dispMatrix);
        characterBuffer.setLength(0);
    }
}

From source file:org.fit.pdfdom.PDFBoxTree.java

License:Open Source License

/**
 * Transforms a length according to the current transformation matrix.
 *///from   w ww.jav  a 2  s .  c  om
protected float transformLength(float w) {
    Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
    Matrix m = new Matrix();
    m.setValue(2, 0, w);
    return m.multiply(ctm).getTranslateX();
}

From source file:org.nmrfx.processor.gui.graphicsio.PDFWriter.java

License:Open Source License

public void showCenteredText(String message, double startX, double startY, String anchor, double rotate)
        throws GraphicsIOException, IllegalArgumentException {
    try {// w w w .j  a  va 2  s .  com
        int aLen = anchor.length();
        double xFrac = 0.0;
        double yFrac = 0.0;
        if (aLen > 0) {
            switch (anchor) {
            case "nw":
                xFrac = 0.0;
                yFrac = 1.0;
                break;
            case "n":
                xFrac = 0.5;
                yFrac = 1.0;
                break;
            case "ne":
                xFrac = 1.0;
                yFrac = 1.0;
                break;
            case "e":
                xFrac = 1.0;
                yFrac = 0.5;
                break;
            case "se":
                xFrac = 1.0;
                yFrac = 0.0;
                break;
            case "s":
                xFrac = 0.5;
                yFrac = 0.0;
                break;
            case "sw":
                xFrac = 0.0;
                yFrac = 0.0;
                break;
            case "w":
                xFrac = 0.0;
                yFrac = 0.5;
                break;
            default:
                throw new IllegalArgumentException("Invalid anchor \"" + anchor + "\"");
            }
        }
        font = PDType1Font.HELVETICA;
        float fontSize = 12;
        float stringWidth = font.getStringWidth(message) * fontSize / 1000f;
        PDFontDescriptor pdfFontDescriptor = font.getFontDescriptor();
        float stringHeight = pdfFontDescriptor.getCapHeight() * fontSize / 1000f;
        float xOffset = -stringWidth * (float) xFrac;
        float yOffset = -stringHeight * (float) yFrac;

        contentStream.newLineAtOffset(tX(startX + xOffset), tY(startY - yOffset));
        if (rotate != 0.0) {
            Matrix matrix = new Matrix();
            matrix.translate(tX(startX), tY(startY));
            matrix.rotate(rotate * Math.PI / 180.0);
            matrix.translate(xOffset, -yOffset);
            contentStream.setTextMatrix(matrix);
        }

        contentStream.showText(message);
    } catch (IOException ioE) {
        throw new GraphicsIOException(ioE.getMessage());
    }

}

From source file:Project.data.preparation.PrintImageLocation.java

public void processOperator(PDFOperator operator, List arguments) throws IOException {

    String operation = operator.getOperation();
    if (operation.equals("Do")) {
        COSName objectName = (COSName) arguments.get(0);
        Map xobjects = getResources().getXObjects();
        PDXObject xobject = (PDXObject) xobjects.get(objectName.getName());
        if (xobject instanceof PDXObjectImage) {
            try {
                PDXObjectImage image = (PDXObjectImage) xobject;
                PDPage page = getCurrentPage();
                Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
                double rotationInRadians = (page.findRotation() * Math.PI) / 180;

                AffineTransform rotation = new AffineTransform();
                rotation.setToRotation(rotationInRadians);
                AffineTransform rotationInverse = rotation.createInverse();
                Matrix rotationInverseMatrix = new Matrix();
                rotationInverseMatrix.setFromAffineTransform(rotationInverse);
                Matrix rotationMatrix = new Matrix();
                rotationMatrix.setFromAffineTransform(rotation);

                Matrix unrotatedCTM = ctm.multiply(rotationInverseMatrix);
                float xScale = unrotatedCTM.getXScale();
                float yScale = unrotatedCTM.getYScale();
                double[] location = { unrotatedCTM.getXPosition(), unrotatedCTM.getYPosition() };
                double[] size = { image.getWidth(), image.getHeight() };
                location_xy.add(location);
                size_xy.add(size);/* w  w  w  .j  a  v  a 2s.  c o m*/
                setLocation_xy(location_xy);
                setSize_xy(size_xy);
                //                    System.out.println("Found image[" + objectName.getName() + "] "
                //                            + "at " + unrotatedCTM.getXPosition() + "," + unrotatedCTM.getYPosition()
                //                           // + " \t\tsize=" + (xScale / 100f * image.getWidth()) + "," + (yScale / 100f * image.getHeight())
                //                            + " \t\tactual size=" + image.getWidth() + "," + image.getHeight());
            } catch (NoninvertibleTransformException e) {
                throw new WrappedIOException(e);
            }
        }
    } else {
        super.processOperator(operator, arguments);
    }
}