Search code examples
apachesvgbatikrotatetransform

SVG image within a Batik JSVGCanvas is scaled down after rotation and setting bounding box


I have a problem with the rotation within a JSVGCanvas.
The user can load SVG images into a document page (JLayeredPane).
Every image displays in his own JSVGCanvas and has his own class.
The user can resize the image by dragging the endpoints and also move the image around.

The rotation works perfectly (Basic and rotated situation)
Only the subsequent change of the bounding box of the Canvas results in a scaling, which no longer corresponds to the original size (Finally after setting Boundingbox)

Code fragment in UpdateManager():

....
// calculating new canvas bounding box
AffineTransform at = AffineTransform.getRotateInstance(rotation*Math.PI/180.0,
                              originalX + originalW/2.0,
                              originalY + originalH/2.0);
Rectangle2D.Double rect = new Rectangle2D.Double(originalX, originalY, originalW, originalH);
Shape s = at.createTransformedShape(rect);
xx = s.getBounds2D().getX();
yy = s.getBounds2D().getY();
ww = s.getBounds2D().getWidth();
hh = s.getBounds2D().getHeight();
canvas.setRenderingTransform(AffineTransform.getRotateInstance(rotation*Math.PI/180.0,
                              originalW/2.0, originalH/2.0));
// this.setBounds() will do the stuff and also change the Canvas Bounds
setBounds(xx, yy, ww, hh);
....

I am grateful for any help.


Solution

  • Solved...
    I have found the way to solve this problem:

    ....  
    // calculating new canvas bounding box
    AffineTransform at = AffineTransform.getRotateInstance(rotation*Math.PI/180.0,
                              originalX + originalW/2.0,
                              originalY + originalH/2.0);
    Rectangle2D.Double rect = new Rectangle2D.Double(originalX, originalY, originalW, originalH);
    Shape s = at.createTransformedShape(rect);
    xx = s.getBounds2D().getX();
    yy = s.getBounds2D().getY();
    ww = s.getBounds2D().getWidth();
    hh = s.getBounds2D().getHeight();
    double rotScale = originalW/ww;
    double diffX = (originalW * rotScale - originalW) / 2.0 * -1.0;
    double diffY = (originalH * rotScale - originalH) / 2.0 * -1.0;
    AffineTransform af = AffineTransform.getScaleInstance(rotScale, rotScale);
    af.preConcatenate(AffineTransform.getTranslateInstance(diffX, diffY));
    af.preConcatenate(AffineTransform.getRotateInstance(rotation*Math.PI/180.0, originalW/2.0, originalH/2.0));
    canvas.setRenderingTransform(af);
    // this.setBounds() will do the stuff and also change the Canvas Bounds
    setBounds(xx, yy, ww, hh);
    ....
    

    Maybe this will help others having the same problem. Picture solved