Hi Thomas,

>>> What I think will work best is for you to override
>>> 'JSVGComponent.calculateViewingTransform' to implement your

Ok, thanks alot for the very good hint -
helped me already to understand a " little bit".
Actually, if there is a ViewBox specified in the svg doc it's simple.
But for a doc w/o a ViewBox specified I need the "size of the
document".

I played around - w/o really understanding what I do - and
found - in a very short time - a solution which surprisingly
works quite good. Amazing well. Code, see end of this message.

I tested it with about 100 of examples from the http://www.openclipart.org/,
my part worked as expected.

With the samples in the batik folders it worked as expected (i think)
with all but:
* the cursor svg's  (wrong origin, scale?)
* the svg which changes the viewport in the onClick handler (but that's ok)

But I have a few questions:
=====================
* Overall, how far away is my "90%" solution from 100% ???
    As I stated - I'm not sure what I'm doing here
* I've an assert
        assert fragIdent == null;
    which never triggered in my tests, for what is this fragIdent ???
* I'm calling svgElt.getWidth() and getHeight(),
    Are those values always defined?
    Are those values always pixel based?
* to get the origin of the doc I call  svgElt.getX() and getY(),
    Is this correct?
    Are those values always pixel based?

With some help I would surely try to contribute a "98%" solution
to the community.

Greetings Heinz

Here my code:  !!! surely not 100% correct !!!!

Note: as of now
if autoFitToCanvas is true,
it basically disables the zoom actions

public class SvgCanvasXx extends JSVGCanvas {
   
    protected int xBorder= 8;
    protected int yBorder= 8;
    protected boolean autoFitToCanvas;
   

    public SvgCanvasXx() {
    }

    public SvgCanvasXx(SVGUserAgent ua, boolean eventsEnabled, boolean
selectableText) {
        super(ua, eventsEnabled, selectableText);
    }
   
    public void setAutoFitToCanvas(boolean autoFit) {
        this.autoFitToCanvas= autoFit;
    }
   
    @Override
    protected AffineTransform calculateViewingTransform(String
fragIdent, SVGSVGElement svgElt) {
        assert fragIdent == null;
        if (!autoFitToCanvas)
            return super.calculateViewingTransform(fragIdent, svgElt);
        // canvas size / additional border
        Dimension d = getSize();
        int xb= 0, yb= 0;
        if (d.width  < 1) d.width  = 1;
        if (d.height < 1) d.height = 1;
        if (d.width > 5 * xBorder) // if canvas is large enough add border
            d.width-= 2 * (xb= xBorder);
        if (d.height > 5 * yBorder) // if canvas is large enough add border
            d.height-= 2 * (yb= yBorder);
        //
        AffineTransform tf;
       //
        String viewBox= svgElt.getAttributeNS(null,
ViewBox.SVG_VIEW_BOX_ATTRIBUTE);
        if (viewBox.length() == 0) {
            // no viewbox specified, make an own one
            float[] vb= calculateDefaultViewbox(fragIdent, svgElt);
            tf= ViewBox.getPreserveAspectRatioTransform(
                    vb,
SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX, true, d.width,
d.height);
        } else {
            String aspectRatio= svgElt.getAttributeNS(null,
ViewBox.SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE);
            if (aspectRatio.length() > 0)
                tf= ViewBox.getPreserveAspectRatioTransform(svgElt,
viewBox, aspectRatio, d.width, d.height, bridgeContext);
            else {
                float[] vb= ViewBox.parseViewBoxAttribute(svgElt,
viewBox, bridgeContext);
                tf= ViewBox.getPreserveAspectRatioTransform(
                        vb,
SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX, true, d.width,
d.height);
            }
        }
        if (xb > 0 || yb > 0) { // center image
            AffineTransform tf2=
AffineTransform.getTranslateInstance(xb, yb);
            tf2.concatenate(tf);
            tf= tf2;
        }
        return tf;
    }
   
    protected float[] calculateDefaultViewbox(String fragIdent,
SVGSVGElement svgElt) {
        float[] vb= new float[4];
        // get doc's origin
        SVGAnimatedLength alx= svgElt.getX(); // todo: is this correct ???
        SVGLength x= alx != null ? alx.getBaseVal() : null;
        SVGAnimatedLength aly= svgElt.getY(); // todo: is this correct ???
        SVGLength y= aly != null ? aly.getBaseVal() : null;
        // get docs dimensions
        SVGAnimatedLength w= svgElt.getWidth();
        SVGLength bw= w != null ? w.getBaseVal() : null;
         SVGAnimatedLength h= svgElt.getHeight();
        SVGLength bh= h != null ?  h.getBaseVal() : null;
        //
        vb[0]= x != null ? x.getValue() : 0;
        vb[1]= y != null ? y.getValue() : 0;
        vb[2]= (bw != null ? bw.getValue() : 100); // 100 random value
        vb[3]= (bh != null ? bh.getValue() : 100);
        return vb;
    }

}




[email protected] schrieb:
>
> Hi Heinz Doerr,
>
> Heinz Doerr <[email protected]> wrote on 06/08/2009 06:20:46 AM:
>
> > I'm using the JSVGCanvas , very nice, but I need to scale the
> displayed SVG
> > image to fit the window size of the canvas.
> > So no scrolling, rotation or panning needed.
> > This should work for any SVG (with or w/o a ViewBox) - changing the svg
> > file itself it not an option.
> > The aspect ratio should always be unchanged.
> > Nice, would be to have an option to either scale down only or to allow
> > scale up and down.
>
>    That is quite a list of requirements.
>
> > Because I didn't found any 'scale-to-fit' hints, I was thinking if it
> > would be better to use
> > the BufferedImageTranscoder and convert the svg to an image. The
> transcoder
> > has the scale-to-fit build in (very nice - works with any SVG, keeps the
> > aspect ratio), but then I got problems loading some svg's. I'm not sure
> > how to get javascript, onLoad, references to elements, and security
> under
> > control. Having animation with the Canvas solution would also be a
> nice to have.
>
>    There are options to run onload scripts before the rendering.
>
> > So I think I'm looking for something like an Action AutoFit for the
> > canvas, and this action automatically triggered (at the right time?).
>
>    What I think will work best is for you to override
> 'JSVGComponent.calculateViewingTransform' to implement your
> desired scale to fit algorythem.  If you get it working you
> might consider contributing it back so others could make use
> of it.

Reply via email to