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: batik-users-
[EMAIL PROTECTED]
> > For additional commands, e-mail: batik-users-
> > [EMAIL PROTECTED]
> >
>
>
>
---------------------------------------------------------------------
> 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]