To ask my question a different way...

I've been looking at the difference between using #svgView(viewBox (...)) fragment identifier and applying my own transformation after the GVTTree is rendered.

The important part of my SVG file for this purpose is:

<svg height="647" width="1024" viewBox="-334 -78 649 410" ...> ... </ svg>

and the fragment identifier that shows what I want to initially see is (and that works is):

#svgView(viewBox((32.0,-63.0,269.0,169.0))

The following calls are made to ViewBox.getPreserveAspectRatioTransform() (the lowest level one) when the document is loading without the fragment identifier in the URI:

getPreserveAspectRatioTransform((-334.0,-78.0,649.0,410.0), 6,true, 1024.0,647.0) getPreserveAspectRatioTransform((-334.0,-78.0,649.0,410.0), 6,true, 826.0,616.0)

826x616 is the actual dimensions of the SVGCanvas on the display.

Then my code calls getPreserveAspectRatioTransform ((32.0,-63.0,269.0,169.0), 6,true,826.0,616.0) to zoom in on my desired initial viewing area, and the display transforms to give me a view of basically the upper left-hand corner of the original picture and zoomed in too far. I should get a view of a portion of the upper right-hand quadrant of the original canvas.

On the other hand, if I put in the fragment identifier on the URL of the document, the following calls occur while loading the file:

getPreserveAspectRatioTransform((-334.0,-78.0,649.0,410.0), 6,true, 1024.0,647.0) getPreserveAspectRatioTransform((32.0,-63.0,269.0,169.0), 6,true, 826.0,616.0)

And the display shows exactly what I want (but for technical reasons I cannot use this solution).

One might think that if I call setRenderingTransformation() with the results of the second call above, nothing would change (but no - calling it with the identity AffineTransform causes no change). In fact, if I call setRenderingTransform() with the results of getPreserveAspectRatioTransform((32.0,-63.0,269.0,169.0), 6,true, 826.0,616.0), it zooms in further and moves the view up (what should be on the top edge of my display moves to near the middle).

It seems that whatever AffineTransform I apply to the canvas gets added to the existing transformations that have already been applied.

How do I get around this?

I suspect I need to get the existing transformation and invert it, but at this point I haven't figured out where to get it from. GetRenderingTransform() returns the identity AffineTransform even though I'm certain that's not right. GetPaintingTransform returns null.

Any thoughts on my assertion that getRenderingTransform() does not return the correct transformation matrix?

Regards,
Randy


On May 25, 2007, at 1:23 PM, [EMAIL PROTECTED] wrote:


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]




Reply via email to