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