List of usage examples for org.apache.pdfbox.util Matrix multiply
public Matrix multiply(Matrix b)
From source file:net.timendum.pdf.Images2HTML.java
License:Open Source License
@Override protected void processOperator(PDFOperator operator, List arguments) throws IOException { String operation = operator.getOperation(); if (INVOKE_OPERATOR.equals(operation)) { COSName objectName = (COSName) arguments.get(0); Map<String, PDXObject> xobjects = getResources().getXObjects(); PDXObject xobject = xobjects.get(objectName.getName()); if (xobject instanceof PDXObjectImage) { PDXObjectImage image = (PDXObjectImage) xobject; PDPage page = getCurrentPage(); int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); double pageHeight = page.getMediaBox().getHeight(); Matrix ctmNew = getGraphicsState().getCurrentTransformationMatrix(); float yScaling = ctmNew.getYScale(); float angle = (float) Math.acos(ctmNew.getValue(0, 0) / ctmNew.getXScale()); if (ctmNew.getValue(0, 1) < 0 && ctmNew.getValue(1, 0) > 0) { angle = (-1) * angle;/*from w ww . ja v a 2 s . com*/ } ctmNew.setValue(2, 1, (float) (pageHeight - ctmNew.getYPosition() - Math.cos(angle) * yScaling)); ctmNew.setValue(2, 0, (float) (ctmNew.getXPosition() - Math.sin(angle) * yScaling)); // because of the moved 0,0-reference, we have to shear in the opposite direction ctmNew.setValue(0, 1, (-1) * ctmNew.getValue(0, 1)); ctmNew.setValue(1, 0, (-1) * ctmNew.getValue(1, 0)); AffineTransform ctmAT = ctmNew.createAffineTransform(); ctmAT.scale(1f / imageWidth, 1f / imageHeight); Image entry = new Image(); entry.x = ctmNew.getXPosition(); entry.image = image; entry.name = objectName.getName(); images.put(page, ctmNew.getYPosition(), entry); } else if (xobject instanceof PDXObjectForm) { // save the graphics state getGraphicsStack().push((PDGraphicsState) getGraphicsState().clone()); PDPage page = getCurrentPage(); PDXObjectForm form = (PDXObjectForm) xobject; COSStream invoke = (COSStream) form.getCOSObject(); PDResources pdResources = form.getResources(); if (pdResources == null) { pdResources = page.findResources(); } // if there is an optional form matrix, we have to // map the form space to the user space Matrix matrix = form.getMatrix(); if (matrix != null) { Matrix xobjectCTM = matrix.multiply(getGraphicsState().getCurrentTransformationMatrix()); getGraphicsState().setCurrentTransformationMatrix(xobjectCTM); } processSubStream(page, pdResources, invoke); // restore the graphics state setGraphicsState(getGraphicsStack().pop()); } } else { super.processOperator(operator, arguments); } }
From source file:org.elacin.pdfextract.datasource.pdfbox.PDFBoxIntegration.java
License:Apache License
/** * Old version//from ww w . ja v a 2 s. 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 w w.j ava 2 s . c o m*/ 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.pauldeschacht.pdfgrid.operator.Invoke.java
License:Apache License
/** * process : Do : Paint the specified XObject (section 4.7). * @param operator The operator that is being executed. * @param arguments List//w w w . jav a 2 s . com * @throws IOException If there is an error invoking the sub object. */ public void process(PDFOperator operator, List<COSBase> arguments) throws IOException { PageGridDrawer drawer = (PageGridDrawer) context; PDPage page = drawer.getPage(); COSName objectName = (COSName) arguments.get(0); Map<String, PDXObject> xobjects = context.getResources().getXObjects(); PDXObject xobject = (PDXObject) xobjects.get(objectName.getName()); if (xobject == null) { LOG.warn("Can't find the XObject for '" + objectName.getName() + "'"); } else if (xobject instanceof PDXObjectImage) { /* PDXObjectImage image = (PDXObjectImage)xobject; try { if (image.getImageMask()) { // set the current non stroking colorstate, so that it can // be used to create a stencil masked image image.setStencilColor(drawer.getGraphicsState().getNonStrokingColor()); } BufferedImage awtImage = image.getRGBImage(); if (awtImage == null) { LOG.warn("getRGBImage returned NULL"); return;//TODO PKOCH } int imageWidth = awtImage.getWidth(); int imageHeight = awtImage.getHeight(); double pageHeight = drawer.getPageSize().getHeight(); LOG.debug("imageWidth: " + imageWidth + "\t\timageHeight: " + imageHeight); Matrix ctm = context.getGraphicsState().getCurrentTransformationMatrix(); float yScaling = ctm.getYScale(); float angle = (float)Math.acos(ctm.getValue(0, 0)/ctm.getXScale()); if (ctm.getValue(0, 1) < 0 && ctm.getValue(1, 0) > 0) { angle = (-1)*angle; } ctm.setValue(2, 1, (float)(pageHeight - ctm.getYPosition() - Math.cos(angle)*yScaling)); ctm.setValue(2, 0, (float)(ctm.getXPosition() - Math.sin(angle)*yScaling)); // because of the moved 0,0-reference, we have to shear in the opposite direction ctm.setValue(0, 1, (-1)*ctm.getValue(0, 1)); ctm.setValue(1, 0, (-1)*ctm.getValue(1, 0)); AffineTransform ctmAT = ctm.createAffineTransform(); ctmAT.scale(1f/imageWidth, 1f/imageHeight); drawer.drawImage( awtImage, ctmAT ); } catch( Exception e ) { e.printStackTrace(); LOG.error(e, e); } */ } else if (xobject instanceof PDXObjectForm) { System.out.println("Invoke::PDXObjectForm"); // save the graphics state context.getGraphicsStack().push((PDGraphicsState) context.getGraphicsState().clone()); PDXObjectForm form = (PDXObjectForm) xobject; COSStream formContentstream = form.getCOSStream(); // find some optional resources, instead of using the current resources PDResources pdResources = form.getResources(); // if there is an optional form matrix, we have to map the form space to the user space Matrix matrix = form.getMatrix(); if (matrix != null) { Matrix xobjectCTM = matrix.multiply(context.getGraphicsState().getCurrentTransformationMatrix()); context.getGraphicsState().setCurrentTransformationMatrix(xobjectCTM); } context.processSubStream(page, pdResources, formContentstream); // restore the graphics state context.setGraphicsState((PDGraphicsState) context.getGraphicsStack().pop()); } }
From source file:pdfimport.pdfbox.operators.Invoke.java
License:Apache License
/** * process : Do : Paint the specified XObject (section 4.7). * @param operator The operator that is being executed. * @param arguments List/* w w w. j av a2s . c o m*/ * @throws IOException If there is an error invoking the sub object. */ @Override public void process(PDFOperator operator, List<COSBase> arguments) throws IOException { PageDrawer drawer = (PageDrawer) context; PDPage page = drawer.getPage(); COSName objectName = (COSName) arguments.get(0); Map xobjects = drawer.getResources().getXObjects(); PDXObject xobject = (PDXObject) xobjects.get(objectName.getName()); if (xobject instanceof PDXObjectImage) { drawer.drawImage(); } else if (xobject instanceof PDXObjectForm) { PDXObjectForm form = (PDXObjectForm) xobject; COSStream invoke = (COSStream) form.getCOSObject(); PDResources pdResources = form.getResources(); if (pdResources == null) { pdResources = page.findResources(); } // if there is an optional form matrix, we have to // map the form space to the user space Matrix matrix = form.getMatrix(); if (matrix != null) { Matrix xobjectCTM = matrix.multiply(context.getGraphicsState().getCurrentTransformationMatrix()); context.getGraphicsState().setCurrentTransformationMatrix(xobjectCTM); } getContext().processSubStream(page, pdResources, invoke); } else { //unknown xobject type } //invoke named object. }
From source file:pdfpicmangler.ResolutionAnalyzer.java
License:Open Source License
protected void processOperator(PDFOperator operator, List<COSBase> arguments) throws IOException { String operation = operator.getOperation(); if (INVOKE_OPERATOR.equals(operation)) { COSName objectName = (COSName) arguments.get(0); Map<String, PDXObject> xobjects = getResources().getXObjects(); PDXObject xobject = (PDXObject) xobjects.get(objectName.getName()); if (xobject instanceof PDXObjectImage) { PDXObjectImage image = (PDXObjectImage) xobject; PDPage page = getCurrentPage(); int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); System.out.println("***************************************************************"); String imageName = currentPage + objectName.getName(); System.out.println("Found image [" + imageName + "]"); Matrix ctmNew = getGraphicsState().getCurrentTransformationMatrix(); float imageXScale = ctmNew.getXScale() / 72; float imageYScale = ctmNew.getYScale() / 72; // size in pixel System.out.println(" size: " + imageWidth + " x " + imageHeight + " px"); // size in page units System.out.print(" size_on_page: " + imageXScale + " x " + imageYScale + " in "); System.out.println("( = " + (imageXScale * 25.4) + " x " + (imageYScale * 25.4) + " mm)"); System.out.println(// w w w . java2 s .c o m " dpi: " + (imageWidth / imageXScale) + " x " + (imageHeight / imageYScale) + " dpi"); System.out.println(" filters: " + image.getPDStream().getFilters()); System.out.println(" compressed_size: " + image.getPDStream().getLength()); COSBase userUnit = page.getCOSDictionary().getDictionaryObject("UserUnit"); System.out.println(" userunit: " + userUnit); System.out.println("***************************************************************"); float dpiX = imageWidth / imageXScale; float dpiY = imageHeight / imageYScale; float dpi = 0.5f * (dpiX + dpiY); if (Math.abs((dpiX - dpiY) / dpi) > 0.05) { System.out.println("warning: resolution of image " + imageName + "is not square: dpiX=" + dpiX + " dpiY=" + dpiY); } if (resolutions.containsKey(imageName)) { float dpiOld = resolutions.get(imageName); System.out.println("re-used image name=" + imageName + " dpi=" + dpi + " dpiOld=" + dpiOld); if (dpiOld > dpi) { resolutions.put(imageName, dpi); } } else { resolutions.put(imageName, dpi); } } else if (xobject instanceof PDXObjectForm) { // save the graphics state getGraphicsStack().push((PDGraphicsState) getGraphicsState().clone()); PDPage page = getCurrentPage(); PDXObjectForm form = (PDXObjectForm) xobject; PDResources pdResources = form.getResources(); if (pdResources == null) { pdResources = page.findResources(); } // if there is an optional form matrix, we have to // map the form space to the user space Matrix matrix = form.getMatrix(); if (matrix != null) { Matrix xobjectCTM = matrix.multiply(getGraphicsState().getCurrentTransformationMatrix()); getGraphicsState().setCurrentTransformationMatrix(xobjectCTM); } processSubStream(page, pdResources, (COSStream) form.getCOSObject()); // restore the graphics state setGraphicsState((PDGraphicsState) getGraphicsStack().pop()); } } else { super.processOperator(operator, arguments); } }
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 ava 2s .co 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); } }