Search in sources :

Example 1 with Insets2D

use of org.apache.poi.sl.usermodel.Insets2D 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 Insets2D

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

the class DrawTextParagraph method getWrappingWidth.

/**
     * Returns wrapping width to break lines in this paragraph
     *
     * @param firstLine whether the first line is breaking
     *
     * @return  wrapping width in points
     */
protected double getWrappingWidth(boolean firstLine, Graphics2D graphics) {
    TextShape<?, ?> ts = paragraph.getParentShape();
    // internal margins for the text box
    Insets2D insets = ts.getInsets();
    double leftInset = insets.left;
    double rightInset = insets.right;
    int indentLevel = paragraph.getIndentLevel();
    if (indentLevel == -1) {
        // default to 0, if indentLevel is not set
        indentLevel = 0;
    }
    Double leftMargin = paragraph.getLeftMargin();
    if (leftMargin == null) {
        // if the marL attribute is omitted, then a value of 347663 is implied
        leftMargin = Units.toPoints(347663L * (indentLevel + 1));
    }
    Double indent = paragraph.getIndent();
    if (indent == null) {
        indent = Units.toPoints(347663L * indentLevel);
    }
    Double rightMargin = paragraph.getRightMargin();
    if (rightMargin == null) {
        rightMargin = 0d;
    }
    Rectangle2D anchor = DrawShape.getAnchor(graphics, ts);
    TextDirection textDir = ts.getTextDirection();
    double width;
    if (!ts.getWordWrap()) {
        Dimension pageDim = ts.getSheet().getSlideShow().getPageSize();
        // if wordWrap == false then we return the advance to the (right) border of the sheet
        switch(textDir) {
            default:
                width = pageDim.getWidth() - anchor.getX();
                break;
            case VERTICAL:
                width = pageDim.getHeight() - anchor.getX();
                break;
            case VERTICAL_270:
                width = anchor.getX();
                break;
        }
    } else {
        switch(textDir) {
            default:
                width = anchor.getWidth() - leftInset - rightInset - leftMargin - rightMargin;
                break;
            case VERTICAL:
            case VERTICAL_270:
                width = anchor.getHeight() - leftInset - rightInset - leftMargin - rightMargin;
                break;
        }
        if (firstLine && !isHSLF()) {
            if (bullet != null) {
                if (indent > 0) {
                    width -= indent;
                }
            } else {
                if (indent > 0) {
                    // first line indentation
                    width -= indent;
                } else if (indent < 0) {
                    // hanging indentation: the first line start at the left margin
                    width += leftMargin;
                }
            }
        }
    }
    return width;
}
Also used : TextDirection(org.apache.poi.sl.usermodel.TextShape.TextDirection) Rectangle2D(java.awt.geom.Rectangle2D) Dimension(java.awt.Dimension) Insets2D(org.apache.poi.sl.usermodel.Insets2D) Paint(java.awt.Paint)

Example 3 with Insets2D

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

the class DrawTextParagraph method draw.

@Override
public void draw(Graphics2D graphics) {
    if (lines.isEmpty()) {
        return;
    }
    double penY = y;
    boolean firstLine = true;
    int indentLevel = paragraph.getIndentLevel();
    Double leftMargin = paragraph.getLeftMargin();
    if (leftMargin == null) {
        // if the marL attribute is omitted, then a value of 347663 is implied
        leftMargin = Units.toPoints(347663L * indentLevel);
    }
    Double indent = paragraph.getIndent();
    if (indent == null) {
        indent = Units.toPoints(347663L * indentLevel);
    }
    if (isHSLF()) {
        // special handling for HSLF
        indent -= leftMargin;
    }
    //        Double rightMargin = paragraph.getRightMargin();
    //        if (rightMargin == null) {
    //            rightMargin = 0d;
    //        }
    //The vertical line spacing
    Double spacing = paragraph.getLineSpacing();
    if (spacing == null) {
        spacing = 100d;
    }
    for (DrawTextFragment line : lines) {
        double penX;
        if (firstLine) {
            if (!isEmptyParagraph()) {
                // TODO: find out character style for empty, but bulleted/numbered lines
                bullet = getBullet(graphics, line.getAttributedString().getIterator());
            }
            if (bullet != null) {
                bullet.setPosition(x + leftMargin + indent, penY);
                bullet.draw(graphics);
                // don't let text overlay the bullet and advance by the bullet width
                double bulletWidth = bullet.getLayout().getAdvance() + 1;
                penX = x + Math.max(leftMargin, leftMargin + indent + bulletWidth);
            } else {
                penX = x + leftMargin;
            }
        } else {
            penX = x + leftMargin;
        }
        Rectangle2D anchor = DrawShape.getAnchor(graphics, paragraph.getParentShape());
        // Insets are already applied on DrawTextShape.drawContent
        // but (outer) anchor need to be adjusted
        Insets2D insets = paragraph.getParentShape().getInsets();
        double leftInset = insets.left;
        double rightInset = insets.right;
        TextAlign ta = paragraph.getTextAlign();
        if (ta == null) {
            ta = TextAlign.LEFT;
        }
        switch(ta) {
            case CENTER:
                penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset - leftMargin) / 2;
                break;
            case RIGHT:
                penX += (anchor.getWidth() - line.getWidth() - leftInset - rightInset);
                break;
            default:
                break;
        }
        line.setPosition(penX, penY);
        line.draw(graphics);
        if (spacing > 0) {
            // If linespacing >= 0, then linespacing is a percentage of normal line height.
            penY += spacing * 0.01 * line.getHeight();
        } else {
            // negative value means absolute spacing in points
            penY += -spacing;
        }
        firstLine = false;
    }
    y = penY - y;
}
Also used : TextAlign(org.apache.poi.sl.usermodel.TextParagraph.TextAlign) Rectangle2D(java.awt.geom.Rectangle2D) Paint(java.awt.Paint) Insets2D(org.apache.poi.sl.usermodel.Insets2D)

Example 4 with Insets2D

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

the class SLGraphics method drawString.

/**
     * Renders the text specified by the specified <code>String</code>,
     * using the current text attribute state in the <code>Graphics2D</code> context.
     * The baseline of the first character is at position
     * (<i>x</i>,&nbsp;<i>y</i>) in the User Space.
     * The rendering attributes applied include the <code>Clip</code>,
     * <code>Transform</code>, <code>Paint</code>, <code>Font</code> and
     * <code>Composite</code> attributes. For characters in script systems
     * such as Hebrew and Arabic, the glyphs can be rendered from right to
     * left, in which case the coordinate supplied is the location of the
     * leftmost character on the baseline.
     * @param s the <code>String</code> to be rendered
     * @param x the x coordinate of the location where the
     * <code>String</code> should be rendered
     * @param y the y coordinate of the location where the
     * <code>String</code> should be rendered
     * @throws NullPointerException if <code>str</code> is
     *         <code>null</code>
     * @see #setPaint
     * @see java.awt.Graphics#setColor
     * @see java.awt.Graphics#setFont
     * @see #setTransform
     * @see #setComposite
     * @see #setClip
     */
public void drawString(String s, float x, float y) {
    TextBox<?, ?> txt = _group.createTextBox();
    TextRun rt = txt.getTextParagraphs().get(0).getTextRuns().get(0);
    rt.setFontSize((double) _font.getSize());
    rt.setFontFamily(_font.getFamily());
    if (getColor() != null)
        rt.setFontColor(DrawPaint.createSolidPaint(getColor()));
    if (_font.isBold())
        rt.setBold(true);
    if (_font.isItalic())
        rt.setItalic(true);
    txt.setText(s);
    txt.setInsets(new Insets2D(0, 0, 0, 0));
    txt.setWordWrap(false);
    txt.setHorizontalCentered(false);
    txt.setVerticalAlignment(VerticalAlignment.MIDDLE);
    TextLayout layout = new TextLayout(s, _font, getFontRenderContext());
    float ascent = layout.getAscent();
    float width = (float) Math.floor(layout.getAdvance());
    /**
         * Even if top and bottom margins are set to 0 PowerPoint
         * always sets extra space between the text and its bounding box.
         *
         * The approximation height = ascent*2 works good enough in most cases
         */
    float height = ascent * 2;
    /*
          In powerpoint anchor of a shape is its top left corner.
          Java graphics sets string coordinates by the baseline of the first character
          so we need to shift up by the height of the textbox
        */
    y -= height / 2 + ascent / 2;
    /*
          In powerpoint anchor of a shape is its top left corner.
          Java graphics sets string coordinates by the baseline of the first character
          so we need to shift down by the height of the textbox
        */
    txt.setAnchor(new Rectangle((int) x, (int) y, (int) width, (int) height));
}
Also used : Rectangle(java.awt.Rectangle) TextRun(org.apache.poi.sl.usermodel.TextRun) Insets2D(org.apache.poi.sl.usermodel.Insets2D) TextLayout(java.awt.font.TextLayout)

Aggregations

Insets2D (org.apache.poi.sl.usermodel.Insets2D)4 Rectangle2D (java.awt.geom.Rectangle2D)3 Paint (java.awt.Paint)2 TextDirection (org.apache.poi.sl.usermodel.TextShape.TextDirection)2 Dimension (java.awt.Dimension)1 Rectangle (java.awt.Rectangle)1 TextLayout (java.awt.font.TextLayout)1 AffineTransform (java.awt.geom.AffineTransform)1 PlaceableShape (org.apache.poi.sl.usermodel.PlaceableShape)1 TextAlign (org.apache.poi.sl.usermodel.TextParagraph.TextAlign)1 TextRun (org.apache.poi.sl.usermodel.TextRun)1