Thomas,
Okay, I thought I had this working. Thought I had a good result, cleaned
up the code and came back two weeks later to discover it's not working!
To review, what I'm trying to do is present an initial view exactly as is
produced by appending the URI fragment identifier "#svgView(viewBox(...))"
to the URL. The main reason I don't want to use the fragment identifier to
present my view is I want to retain the outer SVG's viewBox as the "top"
view (control-T on the canvas will take the user back to view the whole
picture).
One bug I had in my initial code below is that parseFloats were failing on
the trailing "px" while parsing the outer SVG's width and height
attributes. So, rather than try to parse them myself, I went after width
and height by going for
svgelm.getWidth().getBaseVal().getValue()
and
svgelm.getHeight().getBaseVal().getValue()
which seem to return the width and height from the outer SVG element just
fine.
I parse the desired viewBox from my own custom element as below, and I
modified the code to use underlying call as Thomas suggested below. I now
doubt my previous implementation worked. Here's my (still) not working
code. This code presents a view that is too far to the left, to far above,
and the scaling isn't right (it scales the picture up too much). Note here
that svgelm is the SVGSVGELement returned from
SVGDocument.getRootElement().
SVGRect vp = svgelm.getViewport();
float w = vp.getWidth();
float h = vp.getHeight();
float[] vb = ViewBox.parseViewBoxAttribute(defpicelm,
viewbox, null);
AffineTransform at =
ViewBox.getPreserveAspectRatioTransform(vb,
SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID, true, w, h);
canvas_.setRenderingTransform(at);
Couple of things I'm wonder are:
1. Should the width and height I pass to getPreserveAspectRatioTransform() be
the width and height from the outer SVG element or the width and
height of the viewport? I'm thinking the latter, but either one returns an
incorrect result.
2. What am I doing wrong?
Thanks in advance,
Randy
Message from [EMAIL PROTECTED] received on 05/14/2007 05:05 AM
05/14/2007 05:05 AM
[EMAIL PROTECTED]
Please respond to [email protected]
Sent by [EMAIL PROTECTED]
To: [email protected]
cc: [email protected]
Subject: Re: JSVGCanvas.setRenderingTransform()
Hi Randy,
See answers below..
Randy Kunkee <[EMAIL PROTECTED]> wrote on 05/13/2007 04:37:56 PM:
> Here's what I ended up with:
> void initPictureSize(Document doc, String viewbox)
> {
> Element svgelm = doc.getDocumentElement();
> if (svgelm.getAttributeNS(null, "viewBox").equals(viewbox))
> return;
> float w = Float.parseFloat(svgelm.getAttributeNS(null,
> "width"));
> float h = Float.parseFloat(svgelm.getAttributeNS(null,
> "height"));
> float[] vb = ViewBox.parseViewBoxAttribute((Element)
> (elements.item(0)), viewbox);
> AffineTransform at = ViewBox.getPreserveAspectRatioTransform
> (svgelm, vb, w, h);
> canvas_.setRenderingTransform(at);
> }
> I used the particular version of
> ViewBox.getPreserveAspectRatioTransform() above because it did not
> require a BridgeContext. [...]
>
> I later noticed that Batik-1.7 does not have this particular form of
> getPreserveAspectRatio(), so I'll have to do something a little
> different whenever I get around to that. Any reason in particular
> this was removed?
This form required parsing the preserveAspectRatio attribute and
we needed the BridgeContext in order to generate a usable Error message
(file and line number). There is still the real underlying call:
public static
AffineTransform getPreserveAspectRatioTransform(float [] vb,
short align,
boolean meet,
float w,
float h);
Good luck.
>
> On Apr 27, 2007, at 8:20 PM, [EMAIL PROTECTED] wrote:
>
> > Hi Randy,
> >
> > [EMAIL PROTECTED] wrote on 04/24/2007 03:48:37 PM:
> >
> >> Since the batik.bridge.ViewBox doesn't take an x and y argument,
> >> only width and height, I'm not sure how to use this.
> >
> > public static
> > AffineTransform getPreserveAspectRatioTransform(Element e,
> > float[] vb,
> > float w,
> > float h,
> >
> > BridgeContext ctx)
> > {
> >
> > The 'vb' is an array of 4 floats: x, y, w, h.
> >
> >> Would I do this
> >> through a separate URL? Could it start with '#', e.g.
> >> '#svgView(viewBox(...))'?
> >
> > You could do this...
> >
> >> There is something else that does almost exactly what I need. It is
> >> the viewBox element in the outer <svg:svg> element. If I put my
> >> viewBox parameters in there, it presents the view exactly the way I
> >> want it.
> >
> > The code that handles that is the ViewBox.
> >
> >> Except that I can't zoom out - the picture is clipped by
> >> the outer viewBox. If I could only zoom out and pan. Is there a way
> >> to stop this clipping?
> >
> > You can set overflow="visible" on the root SVG element.
> >
> >> Perhaps another approach would be to use the
> >> viewBox in the <svg:svg> and then make some calls to enable
> >> panning out?
> >
> >
> > You can do this, but setting the viewBox can be expensive.
> >
> >> Message from [EMAIL PROTECTED] received on 04/19/2007 07:31 AM
> >>
> >> 04/19/2007 07:31 AM
> >
> >>
> >> [EMAIL PROTECTED]
> >>
> >> Please respond to [email protected]
> >> Sent by [EMAIL PROTECTED]
> >>
> >> To: [email protected]
> >> cc: [email protected]
> >> Subject: Re: JSVGCanvas.setRenderingTransform()
> >>
> >>
> >>
> >> Hi Randy,
> >>
> >> [EMAIL PROTECTED] wrote on 04/17/2007 04:10:19 PM:
> >>
> >>>
> >>> I hope somebody can shed some light on this.
> >>>
> >>> Basically, I want to do in software what could be done with a
> >>> control-drag-mousebutton1. Seems like there could be a simple
> >>> interface to call to do this, but I haven't found it yet.
> >>
> >> See batik.bridge.ViewBox
> >>
> >> /**
> >> * Parses the specified reference (from a URI) and returns the
> >> appropriate
> >> * transform.
> >> *
> >> * @param ref the reference of the URI that may specify additional
> >> attribute
> >> * values such as the viewBox, preserveAspectRatio or a
> >> transform
> >> * @param e the element interested in its view transform
> >> * @param w the width of the effective viewport
> >> * @param h The height of the effective viewport
> >> * @param ctx The BridgeContext to use for error information
> >> * @exception BridgeException if an error occured while
> >> computing the
> >> * preserveAspectRatio transform
> >> */
> >> public static AffineTransform getViewTransform(String ref,
> >> Element e,
> >> float w,
> >> float h,
> >> BridgeContext
> >> ctx) {
> >>
> >>
> >>> I'm trying to implement what I call a "pre-zoomed" SVG file. In my
> >>> SVG file, I have added an element <x:defaultpicturesize
> >>> viewBox="x y w
> >
> >> h"/>.
> >>
> >> You probably want to look at:
> >> http://www.w3.org/TR/SVG11/linking.html#SVGFragmentIdentifiers
> >>
> >> As this is more or less already built into Batik.
> >>
> >>> Since I haven't found a call to "zoom it to this box", I tried using
> >>> setRenderingTransform(). After loading the SVG file (and after
> >>> gvtRenderingCompleted() is called), I look for this element. If I
> >>> find one, I create an AffineTransform and call
> >>> setRenderingTransform()
> >
> >>>
> >>> The problem is that this thing does not do what I expect it to.
> >>
> >> Affine transforms rarely do what you expect them to do unless
> >> you have been working with them for quite a while. My guess is that
> >> you aren't considering the viewBox transform which it sounds like may
> >> be introducing a small scale and or translate.
> >>
> >>> It is easy enough to center up the picture (if that's all I wanted
> >>> to do). I simply calculate the difference between the center of the
> >>> <svg:svg viewbox="..."> and the center of my desired viewbox. This
> >>> is straightforward and produces a view that looks close to centered
> >>> (but clearly is not exactly centered)
> >>>
> >>> When I apply a scaling transformation things go very off. First of
> >>> all, scaling appears to happen based on the upper left-hand corner
> >>> of the picture. For example, if I only scale (say 2x) what
> >>> previously was in the upper left-hand corner now fills the entire
> >> display.
> >>>
> >>> So I think, translate the upper left-hand corner of the desired
> >>> viewbox to the x and y of the <svg:svg> viewbox and then scale.
> >>> Still not right. Then I think, okay, it's scaling first so my
> >>> translation values actually need to be multiplied by the scale
> >>> factor - better but still not right.
> >>>
> >>> What am I missing here? Seems like this should be an easy thing
> >>> to do.
> >
> >>>
> >>> Regards,
> >>> Randy
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: batik-users-
> >> [EMAIL PROTECTED]
> >> For additional commands, e-mail: batik-users-
> >> [EMAIL PROTECTED]
> >>
> >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: batik-users-
> > [EMAIL PROTECTED]
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]