You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DrawShape.java 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package org.apache.poi.sl.draw;
  2. import java.awt.Graphics2D;
  3. import java.awt.geom.AffineTransform;
  4. import java.awt.geom.Rectangle2D;
  5. import org.apache.poi.sl.usermodel.PlaceableShape;
  6. import org.apache.poi.sl.usermodel.Shape;
  7. public class DrawShape<T extends Shape> implements Drawable {
  8. protected final T shape;
  9. public DrawShape(T shape) {
  10. this.shape = shape;
  11. }
  12. /**
  13. * Apply 2-D transforms before drawing this shape. This includes rotation and flipping.
  14. *
  15. * @param graphics the graphics whos transform matrix will be modified
  16. */
  17. public void applyTransform(Graphics2D graphics) {
  18. if (!(shape instanceof PlaceableShape)) return;
  19. PlaceableShape ps = (PlaceableShape)shape;
  20. AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
  21. final Rectangle2D anchor = (tx != null)
  22. ? tx.createTransformedShape(ps.getAnchor()).getBounds2D()
  23. : ps.getAnchor();
  24. // rotation
  25. double rotation = ps.getRotation();
  26. if (rotation != 0.) {
  27. // PowerPoint rotates shapes relative to the geometric center
  28. double centerX = anchor.getCenterX();
  29. double centerY = anchor.getCenterY();
  30. // normalize rotation
  31. rotation %= 360.;
  32. if (rotation < 0) rotation += 360.;
  33. int quadrant = (((int)rotation+45)/90)%4;
  34. double scaleX = 1.0, scaleY = 1.0;
  35. // scale to bounding box (bug #53176)
  36. if (quadrant == 1 || quadrant == 3) {
  37. // In quadrant 1 and 3, which is basically a shape in a more or less portrait orientation
  38. // (45-135 degrees and 225-315 degrees), we need to first rotate the shape by a multiple
  39. // of 90 degrees and then resize the bounding box to its original bbox. After that we can
  40. // rotate the shape to the exact rotation amount.
  41. // It's strange that you'll need to rotate the shape back and forth again, but you can
  42. // think of it, as if you paint the shape on a canvas. First you rotate the canvas, which might
  43. // be already (differently) scaled, so you can paint the shape in its default orientation
  44. // and later on, turn it around again to compare it with its original size ...
  45. // graphics coordinate space
  46. AffineTransform txg = new AffineTransform();
  47. txg.translate(centerX, centerY);
  48. txg.rotate(Math.toRadians(90));
  49. txg.translate(-centerX, -centerY);
  50. boolean oldVariant = true;
  51. Rectangle2D anchor2;
  52. if (oldVariant) {
  53. // shape coordinate space
  54. AffineTransform txs = new AffineTransform(tx);
  55. txs.translate(centerX, centerY);
  56. txs.rotate(Math.toRadians(90));
  57. txs.translate(-centerX, -centerY);
  58. txg.concatenate(txs);
  59. anchor2 = txg.createTransformedShape(ps.getAnchor()).getBounds2D();
  60. } else {
  61. anchor2 = txg.createTransformedShape(anchor).getBounds2D();
  62. }
  63. scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth();
  64. scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight();
  65. graphics.translate(centerX, centerY);
  66. graphics.rotate(Math.toRadians(rotation-quadrant*90.));
  67. graphics.scale(scaleX, scaleY);
  68. graphics.rotate(Math.toRadians(quadrant*90));
  69. graphics.translate(-centerX, -centerY);
  70. } else {
  71. graphics.translate(centerX, centerY);
  72. graphics.rotate(Math.toRadians(rotation));
  73. graphics.scale(scaleX, scaleY);
  74. graphics.translate(-centerX, -centerY);
  75. }
  76. // transformation is applied reversed ...
  77. }
  78. //flip horizontal
  79. if (ps.getFlipHorizontal()) {
  80. graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
  81. graphics.scale(-1, 1);
  82. graphics.translate(-anchor.getX(), -anchor.getY());
  83. }
  84. //flip vertical
  85. if (ps.getFlipVertical()) {
  86. graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
  87. graphics.scale(1, -1);
  88. graphics.translate(-anchor.getX(), -anchor.getY());
  89. }
  90. }
  91. public void draw(Graphics2D graphics) {
  92. }
  93. public void drawContent(Graphics2D context) {
  94. }
  95. public static Rectangle2D getAnchor(Graphics2D graphics, PlaceableShape shape) {
  96. return getAnchor(graphics, shape.getAnchor());
  97. }
  98. public static Rectangle2D getAnchor(Graphics2D graphics, Rectangle2D anchor) {
  99. if(graphics == null) {
  100. return anchor;
  101. }
  102. AffineTransform tx = (AffineTransform)graphics.getRenderingHint(Drawable.GROUP_TRANSFORM);
  103. if(tx != null) {
  104. anchor = tx.createTransformedShape(anchor).getBounds2D();
  105. }
  106. return anchor;
  107. }
  108. }