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);
}
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;
}
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;
}
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>, <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));
}
Aggregations