Search in sources :

Example 1 with PlaceableShape

use of org.apache.poi.sl.usermodel.PlaceableShape in project poi by apache.

the class DrawTextShape method drawContent.

@Override
public void drawContent(Graphics2D graphics) {
    DrawFactory.getInstance(graphics).fixFonts(graphics);
    TextShape<?, ?> s = getShape();
    Rectangle2D anchor = DrawShape.getAnchor(graphics, s);
    Insets2D insets = s.getInsets();
    double x = anchor.getX() + insets.left;
    double y = anchor.getY();
    // remember the initial transform
    AffineTransform tx = graphics.getTransform();
    // Transform of text in flipped shapes is special.
    // At this point the flip and rotation transform is already applied
    // (see DrawShape#applyTransform ), but we need to restore it to avoid painting "upside down".
    // See Bugzilla 54210.
    boolean vertFlip = s.getFlipVertical();
    boolean horzFlip = s.getFlipHorizontal();
    ShapeContainer<?, ?> sc = s.getParent();
    while (sc instanceof PlaceableShape) {
        PlaceableShape<?, ?> ps = (PlaceableShape<?, ?>) sc;
        vertFlip ^= ps.getFlipVertical();
        horzFlip ^= ps.getFlipHorizontal();
        sc = ps.getParent();
    }
    // Applying flip second time restores the original not-flipped transform
    if (horzFlip ^ vertFlip) {
        final double ax = anchor.getX();
        final double ay = anchor.getY();
        graphics.translate(ax + anchor.getWidth(), ay);
        graphics.scale(-1, 1);
        graphics.translate(-ax, -ay);
    }
    Double textRot = s.getTextRotation();
    if (textRot != null && textRot != 0) {
        final double cx = anchor.getCenterX();
        final double cy = anchor.getCenterY();
        graphics.translate(cx, cy);
        graphics.rotate(Math.toRadians(textRot));
        graphics.translate(-cx, -cy);
    }
    // first dry-run to calculate the total height of the text
    double textHeight;
    switch(s.getVerticalAlignment()) {
        default:
        case TOP:
            y += insets.top;
            break;
        case BOTTOM:
            textHeight = getTextHeight(graphics);
            y += anchor.getHeight() - textHeight - insets.bottom;
            break;
        case MIDDLE:
            textHeight = getTextHeight(graphics);
            double delta = anchor.getHeight() - textHeight - insets.top - insets.bottom;
            y += insets.top + delta / 2;
            break;
    }
    TextDirection textDir = s.getTextDirection();
    if (textDir == TextDirection.VERTICAL || textDir == TextDirection.VERTICAL_270) {
        final double deg = (textDir == TextDirection.VERTICAL) ? 90 : 270;
        final double cx = anchor.getCenterX();
        final double cy = anchor.getCenterY();
        graphics.translate(cx, cy);
        graphics.rotate(Math.toRadians(deg));
        graphics.translate(-cx, -cy);
        // old top/left edge is now bottom/left or top/right - as we operate on the already
        // rotated drawing context, both verticals can be moved in the same direction
        final double w = anchor.getWidth();
        final double h = anchor.getHeight();
        final double dx = (w - h) / 2d;
        graphics.translate(dx, -dx);
    }
    drawParagraphs(graphics, x, y);
    // restore the transform
    graphics.setTransform(tx);
}
Also used : TextDirection(org.apache.poi.sl.usermodel.TextShape.TextDirection) Rectangle2D(java.awt.geom.Rectangle2D) AffineTransform(java.awt.geom.AffineTransform) Insets2D(org.apache.poi.sl.usermodel.Insets2D) PlaceableShape(org.apache.poi.sl.usermodel.PlaceableShape)

Example 2 with PlaceableShape

use of org.apache.poi.sl.usermodel.PlaceableShape in project poi by apache.

the class DrawBackground method draw.

@SuppressWarnings("rawtypes")
public void draw(Graphics2D graphics) {
    Dimension pg = shape.getSheet().getSlideShow().getPageSize();
    final Rectangle2D anchor = new Rectangle2D.Double(0, 0, pg.getWidth(), pg.getHeight());
    PlaceableShape<?, ?> ps = new PlaceableShape() {

        public ShapeContainer<?, ?> getParent() {
            return null;
        }

        public Rectangle2D getAnchor() {
            return anchor;
        }

        public void setAnchor(Rectangle2D newAnchor) {
        }

        public double getRotation() {
            return 0;
        }

        public void setRotation(double theta) {
        }

        public void setFlipHorizontal(boolean flip) {
        }

        public void setFlipVertical(boolean flip) {
        }

        public boolean getFlipHorizontal() {
            return false;
        }

        public boolean getFlipVertical() {
            return false;
        }

        public Sheet<?, ?> getSheet() {
            return shape.getSheet();
        }
    };
    DrawFactory drawFact = DrawFactory.getInstance(graphics);
    DrawPaint dp = drawFact.getPaint(ps);
    Paint fill = dp.getPaint(graphics, getShape().getFillStyle().getPaint());
    Rectangle2D anchor2 = getAnchor(graphics, anchor);
    if (fill != null) {
        graphics.setRenderingHint(Drawable.GRADIENT_SHAPE, anchor);
        graphics.setPaint(fill);
        graphics.fill(anchor2);
    }
}
Also used : Rectangle2D(java.awt.geom.Rectangle2D) Dimension(java.awt.Dimension) Paint(java.awt.Paint) PlaceableShape(org.apache.poi.sl.usermodel.PlaceableShape)

Example 3 with PlaceableShape

use of org.apache.poi.sl.usermodel.PlaceableShape in project poi by apache.

the class DrawShape method applyTransform.

/**
     * Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
     *
     * @param graphics the graphics whos transform matrix will be modified
     */
@Override
public void applyTransform(Graphics2D graphics) {
    if (!(shape instanceof PlaceableShape)) {
        return;
    }
    PlaceableShape<?, ?> ps = (PlaceableShape<?, ?>) shape;
    final boolean isHSLF = isHSLF(shape);
    AffineTransform tx = (AffineTransform) graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
    if (tx == null) {
        tx = new AffineTransform();
    }
    final Rectangle2D anchor = tx.createTransformedShape(ps.getAnchor()).getBounds2D();
    char[] cmds = isHSLF ? new char[] { 'h', 'v', 'r' } : new char[] { 'r', 'h', 'v' };
    for (char ch : cmds) {
        switch(ch) {
            case 'h':
                //flip horizontal
                if (ps.getFlipHorizontal()) {
                    graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
                    graphics.scale(-1, 1);
                    graphics.translate(-anchor.getX(), -anchor.getY());
                }
                break;
            case 'v':
                //flip vertical
                if (ps.getFlipVertical()) {
                    graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
                    graphics.scale(1, -1);
                    graphics.translate(-anchor.getX(), -anchor.getY());
                }
                break;
            case 'r':
                // rotation
                double rotation = ps.getRotation();
                if (rotation != 0.) {
                    // PowerPoint rotates shapes relative to the geometric center
                    double centerX = anchor.getCenterX();
                    double centerY = anchor.getCenterY();
                    // normalize rotation
                    rotation %= 360.;
                    if (rotation < 0) {
                        rotation += 360.;
                    }
                    int quadrant = (((int) rotation + 45) / 90) % 4;
                    double scaleX = 1.0, scaleY = 1.0;
                    // scale to bounding box (bug #53176)
                    if (quadrant == 1 || quadrant == 3) {
                        // In quadrant 1 and 3, which is basically a shape in a more or less portrait orientation
                        // (45-135 degrees and 225-315 degrees), we need to first rotate the shape by a multiple
                        // of 90 degrees and then resize the bounding box to its original bbox. After that we can
                        // rotate the shape to the exact rotation amount.
                        // It's strange that you'll need to rotate the shape back and forth again, but you can
                        // think of it, as if you paint the shape on a canvas. First you rotate the canvas, which might
                        // be already (differently) scaled, so you can paint the shape in its default orientation
                        // and later on, turn it around again to compare it with its original size ...
                        AffineTransform txs;
                        if (isHSLF) {
                            txs = new AffineTransform(tx);
                        } else {
                            // this handling is only based on try and error ... not sure why xslf is handled differently.
                            txs = new AffineTransform();
                            txs.translate(centerX, centerY);
                            // actually doesn't matter if +/- 90 degrees
                            txs.rotate(Math.PI / 2.);
                            txs.translate(-centerX, -centerY);
                            txs.concatenate(tx);
                        }
                        txs.translate(centerX, centerY);
                        txs.rotate(Math.PI / 2.);
                        txs.translate(-centerX, -centerY);
                        Rectangle2D anchor2 = txs.createTransformedShape(ps.getAnchor()).getBounds2D();
                        scaleX = safeScale(anchor.getWidth(), anchor2.getWidth());
                        scaleY = safeScale(anchor.getHeight(), anchor2.getHeight());
                    } else {
                        quadrant = 0;
                    }
                    // transformation is applied reversed ...
                    graphics.translate(centerX, centerY);
                    double rot = Math.toRadians(rotation - quadrant * 90.);
                    if (rot != 0) {
                        graphics.rotate(rot);
                    }
                    graphics.scale(scaleX, scaleY);
                    rot = Math.toRadians(quadrant * 90.);
                    if (rot != 0) {
                        graphics.rotate(rot);
                    }
                    graphics.translate(-centerX, -centerY);
                }
                break;
            default:
                throw new RuntimeException("unexpected transform code " + ch);
        }
    }
}
Also used : Rectangle2D(java.awt.geom.Rectangle2D) AffineTransform(java.awt.geom.AffineTransform) PlaceableShape(org.apache.poi.sl.usermodel.PlaceableShape)

Aggregations

Rectangle2D (java.awt.geom.Rectangle2D)3 PlaceableShape (org.apache.poi.sl.usermodel.PlaceableShape)3 AffineTransform (java.awt.geom.AffineTransform)2 Dimension (java.awt.Dimension)1 Paint (java.awt.Paint)1 Insets2D (org.apache.poi.sl.usermodel.Insets2D)1 TextDirection (org.apache.poi.sl.usermodel.TextShape.TextDirection)1