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.
