double rotation = getRotation();\r
if (rotation != 0.) {\r
// PowerPoint rotates shapes relative to the geometric center\r
- double centerX = anchor.getX() + anchor.getWidth() / 2;\r
- double centerY = anchor.getY() + anchor.getHeight() / 2;\r
-\r
+ double centerX = anchor.getCenterX();\r
+ double centerY = anchor.getCenterY();\r
+\r
+ // normalize rotation\r
+ rotation = (360.+(rotation%360.))%360.;\r
+ int quadrant = (((int)rotation+45)/90)%4;\r
+ double scaleX = 1.0, scaleY = 1.0;\r
+\r
+ // scale to bounding box (bug #53176)\r
+ if (quadrant == 1 || quadrant == 3) {\r
+ // In quadrant 1 and 3, which is basically a shape in a more or less portrait orientation (45°-135° and 225°-315°),\r
+ // we need to first rotate the shape by a multiple of 90° and then resize the bounding box \r
+ // to its original bbox. After that we can rotate the shape to the exact rotation amount.\r
+ // It's strange that you'll need to rotate the shape back and forth again, but you can\r
+ // think of it, as if you paint the shape on a canvas. First you rotate the canvas, which might\r
+ // be already (differently) scaled, so you can paint the shape in its default orientation\r
+ // and later on, turn it around again to compare it with its original size ...\r
+ AffineTransform txg = new AffineTransform(); // graphics coordinate space\r
+ AffineTransform txs = new AffineTransform(tx); // shape coordinate space\r
+ txg.translate(centerX, centerY);\r
+ txg.rotate(Math.toRadians(quadrant*90));\r
+ txg.translate(-centerX, -centerY);\r
+ txs.translate(centerX, centerY);\r
+ txs.rotate(Math.toRadians(-quadrant*90));\r
+ txs.translate(-centerX, -centerY);\r
+ txg.concatenate(txs);\r
+ Rectangle2D anchor2 = txg.createTransformedShape(getAnchor()).getBounds2D();\r
+ scaleX = anchor.getWidth() == 0. ? 1.0 : anchor.getWidth() / anchor2.getWidth();\r
+ scaleY = anchor.getHeight() == 0. ? 1.0 : anchor.getHeight() / anchor2.getHeight();\r
+ }\r
+\r
+ // transformation is applied reversed ...\r
graphics.translate(centerX, centerY);\r
- graphics.rotate(Math.toRadians(rotation));\r
+ graphics.rotate(Math.toRadians(rotation-(double)(quadrant*90)));\r
+ graphics.scale(scaleX, scaleY);\r
+ graphics.rotate(Math.toRadians(quadrant*90));\r
graphics.translate(-centerX, -centerY);\r
}\r
\r