private BufferedImage adjustImage(BufferedImage gray) throws IOException { AffineTransform at = new AffineTransform(xform); Matrix m = new Matrix(at); at.scale(1.0 / Math.abs(m.getScalingFactorX()), 1.0 / Math.abs(m.getScalingFactorY())); Rectangle originalBounds = new Rectangle(gray.getWidth(), gray.getHeight()); Rectangle2D transformedBounds = at.createTransformedShape(originalBounds).getBounds2D(); at.preConcatenate(AffineTransform.getTranslateInstance(-transformedBounds.getMinX(), -transformedBounds.getMinY())); int width = (int) Math.ceil(transformedBounds.getWidth()); int height = (int) Math.ceil(transformedBounds.getHeight()); BufferedImage transformedGray = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY); Graphics2D g2 = (Graphics2D) transformedGray.getGraphics(); g2.drawImage(gray, at, null); g2.dispose(); return transformedGray; }
/** * Not called in TexturePaint subclasses, which is why we wrap TexturePaint. */ @Override public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) { AffineTransform xformPattern = (AffineTransform)xform.clone(); // applies the pattern matrix with scaling removed AffineTransform patternNoScale = patternMatrix.createAffineTransform(); patternNoScale.scale(1 / patternMatrix.getScalingFactorX(), 1 / patternMatrix.getScalingFactorY()); xformPattern.concatenate(patternNoScale); return paint.createContext(cm, deviceBounds, userBounds, xformPattern, hints); }
/** * Applies a text position adjustment from the TJ operator. May be overridden in subclasses. * * @param tx x-translation * @param ty y-translation */ protected void applyTextAdjustment(float tx, float ty) throws IOException { // update the text matrix textMatrix.concatenate(Matrix.getTranslateInstance(tx, ty)); }
/** * Rotares this matrix by the given factors. * * @param theta The angle of rotation measured in radians */ public void rotate(double theta) { Matrix m = Matrix.getRotateInstance(theta, 0, 0); concatenate(m); }
/** * Produces a copy of the first matrix, with the second matrix concatenated. * * @param a The matrix to copy. * @param b The matrix to concatenate. */ public static Matrix concatenate(Matrix a, Matrix b) { Matrix copy = a.clone(); copy.concatenate(b); return copy; }
@Override public void drawImage(PDImage pdImage) throws IOException Matrix ctm = getGraphicsState().getCurrentTransformationMatrix(); AffineTransform at = ctm.createAffineTransform(); boolean isScaledUp = pdImage.getWidth() < Math.round(at.getScaleX()) || pdImage.getHeight() < Math.round(at.getScaleY()); if (getGraphicsState().getNonStrokingColor().getColorSpace() instanceof PDPattern) Rectangle2D bounds = at.createTransformedShape(unitRect).getBounds2D(); BufferedImage renderedPaint = new BufferedImage((int) Math.ceil(bounds.getWidth()), graphics.setComposite(getGraphicsState().getNonStrokingJavaComposite()); if (isContentRendered())
this.flip = new AffineTransform(); flip.translate(0, cropBox.getHeight()); flip.scale(1, -1); GeneralPath p = r.transform(Matrix.getTranslateInstance(-cropBox.getLowerLeftX(), cropBox.getLowerLeftY())); Shape s = flip.createTransformedShape(p); graphics.setColor(Color.green);
private void adjustRectangle(Rectangle2D r) { Matrix m = new Matrix(xform); double scaleX = Math.abs(m.getScalingFactorX()); double scaleY = Math.abs(m.getScalingFactorY()); AffineTransform adjustedTransform = new AffineTransform(xform); adjustedTransform.scale(1.0 / scaleX, 1.0 / scaleY); r.setRect(adjustedTransform.createTransformedShape(r).getBounds2D()); }
AffineTransform at = (AffineTransform) flip.clone(); at.concatenate(text.getTextMatrix().createAffineTransform()); text.getWidthDirAdj() / text.getTextMatrix().getScalingFactorX(), text.getHeightDir() / text.getTextMatrix().getScalingFactorY()); graphics.setColor(Color.red); graphics.draw(at.createTransformedShape(rect)); BoundingBox bbox = font.getBoundingBox(); float xadvance = font.getWidth(text.getCharacterCodes()[0]); // todo: should iterate all chars Rectangle2D rect = new Rectangle2D.Float(0, bbox.getLowerLeftY(), xadvance, bbox.getHeight()); AffineTransform at = (AffineTransform) flip.clone(); at.concatenate(text.getTextMatrix().createAffineTransform()); at.concatenate(font.getFontMatrix().createAffineTransform());
= new TransparencyGroup(form, false, getGraphicsState().getCurrentTransformationMatrix(), null); BufferedImage image = group.getImage(); if (image == null) graphics.setComposite(getGraphicsState().getNonStrokingJavaComposite()); setClip(); AffineTransform prev = graphics.getTransform(); Matrix m = new Matrix(xform); float xScale = Math.abs(m.getScalingFactorX()); float yScale = Math.abs(m.getScalingFactorY()); AffineTransform transform = new AffineTransform(xform); transform.scale(1.0 / xScale, 1.0 / yScale); graphics.setTransform(transform); float x = bbox.getLowerLeftX() - pageSize.getLowerLeftX(); float y = pageSize.getUpperRightY() - bbox.getUpperRightY(); PDSoftMask softMask = getGraphicsState().getSoftMask(); if (softMask != null)
rat = shading.getMatrix().createAffineTransform().createInverse(); rat.concatenate(matrix.createAffineTransform().createInverse()); rat.concatenate(xform.createInverse());
private Shape calculateGlyphBounds(Matrix textRenderingMatrix, PDFont font, int code) throws IOException AffineTransform at = textRenderingMatrix.createAffineTransform(); at.concatenate(font.getFontMatrix().createAffineTransform()); if (font instanceof PDType3Font) glyphBBox.setLowerLeftX(Math.max(fontBBox.getLowerLeftX(), glyphBBox.getLowerLeftX())); glyphBBox.setLowerLeftY(Math.max(fontBBox.getLowerLeftY(), glyphBBox.getLowerLeftY())); glyphBBox.setUpperRightX(Math.min(fontBBox.getUpperRightX(), glyphBBox.getUpperRightX())); glyphBBox.setUpperRightY(Math.min(fontBBox.getUpperRightY(), glyphBBox.getUpperRightY())); at.scale(1000d / unitsPerEm, 1000d / unitsPerEm); at.scale(1000d / unitsPerEm, 1000d / unitsPerEm);
AffineTransform at = textRenderingMatrix.createAffineTransform(); at.concatenate(font.getFontMatrix().createAffineTransform()); if (!font.isEmbedded() && !font.isVertical() && !font.isStandard14() && font.hasExplicitWidth(code)) float fontWidth = font.getWidthFromFont(code); at.scale(pdfWidth / fontWidth, 1); Shape glyph = at.createTransformedShape(path); bbox = glyph.getBounds2D();
public Rectangle2D getBounds() { Point2D size = new Point2D.Double(pageSize.getWidth(), pageSize.getHeight()); // apply the underlying Graphics2D device's DPI transform and y-axis flip Matrix m = new Matrix(xform); AffineTransform dpiTransform = AffineTransform.getScaleInstance(Math.abs(m.getScalingFactorX()), Math.abs(m.getScalingFactorY())); size = dpiTransform.transform(size, size); // Flip y return new Rectangle2D.Double(minX - pageSize.getLowerLeftX() * Math.abs(m.getScalingFactorX()), size.getY() - minY - height + pageSize.getLowerLeftY() * Math.abs(m.getScalingFactorY()), width, height); } }
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(); }
/** * Draw an image at the x,y coordinates, with the given size. * * @param image The image to draw. * @param x The x-coordinate to draw the image. * @param y The y-coordinate to draw the image. * @param width The width to draw the image. * @param height The height to draw the image. * * @throws IOException If there is an error writing to the stream. * @throws IllegalStateException If the method was called within a text block. */ public void drawImage(PDImageXObject image, float x, float y, float width, float height) throws IOException { if (inTextMode) { throw new IllegalStateException("Error: drawImage is not allowed within a text block."); } saveGraphicsState(); AffineTransform transform = new AffineTransform(width, 0, 0, height, x, y); transform(new Matrix(transform)); writeOperand(resources.add(image)); writeOperator("Do"); restoreGraphicsState(); }
if (fontBBox.getWidth() < 72 || fontBBox.getHeight() < 72) scale = (int) (72 / Math.min(fontBBox.getWidth(), fontBBox.getHeight())); PDPage page = new PDPage(new PDRectangle(fontBBox.getWidth() * scale, fontBBox.getHeight() * scale)); try try (PDPageContentStream cs = new PDPageContentStream(doc, page)) cs.transform(Matrix.getTranslateInstance(-fontBBox.getLowerLeftX(), -fontBBox.getLowerLeftY())); try AffineTransform at = font.getFontMatrix().createAffineTransform(); if (!at.isIdentity()) at.invert(); cs.transform(new Matrix(at));
/** * Transforms a point using the CTM. */ public Point2D.Float transformedPoint(float x, float y) { float[] position = { x, y }; getGraphicsState().getCurrentTransformationMatrix().createAffineTransform() .transform(position, 0, position, 0, 1); return new Point2D.Float(position[0], position[1]); }
if (font instanceof PDType3Font) height = font.getFontMatrix().transformPoint(0, glyphHeight).y; Matrix td = Matrix.getTranslateInstance(tx, ty); Matrix nextTextRenderingMatrix = td.multiply(textMatrix).multiply(ctm); // text space -> device space float nextX = nextTextRenderingMatrix.getTranslateX(); float nextY = nextTextRenderingMatrix.getTranslateY(); float dxDisplay = nextX - textRenderingMatrix.getTranslateX(); float dyDisplay = height * textRenderingMatrix.getScalingFactorY(); if (font instanceof PDType3Font) glyphSpaceToTextSpaceFactor = font.getFontMatrix().getScaleX(); float spaceWidthDisplay = spaceWidthText * textRenderingMatrix.getScalingFactorX(); translatedTextRenderingMatrix = Matrix.concatenate(translateMatrix, textRenderingMatrix); nextX -= pageSize.getLowerLeftX(); nextY -= pageSize.getLowerLeftY(); processTextPosition(new TextPosition(pageRotation, pageSize.getWidth(), pageSize.getHeight(), translatedTextRenderingMatrix, nextX, nextY, Math.abs(dyDisplay), dxDisplay, Math.abs(spaceWidthDisplay), unicode, new int[] { code } , font, fontSize, (int)(fontSize * textMatrix.getScalingFactorX())));