Hi again !

I solved it, although the solution might not be 100% (only supprots 
matrix-transformations, not translate, scale, and skew-commands). But since I 
always use matrix-tranformations in my software, it works perfectly for me.

So if anyone is having the same problem as I had, here's a bit of code that 
will solve it:

This code is extracted from a special FlowRootSVGElement-class where 
getElement() returns the flowRoot-element.



        /**
         * Retrieves the total transformation Matrix from the documents root to 
this element
         * Since the flowRoot-object itself is not Locatable, get the first 
Element in flowRegion and calculate the transformation-matrix to that object 
instead. 
         * @return
         */
        public SVGMatrix getDocumentTransformToThisElement()
        {
                try
                {
                        NodeList nl = getFlowRegionNodes(getElement());
                        Element e = null;
                        if (nl != null && nl.getLength() > 0)
                                for (int x = 0; x < nl.getLength(); x++)
                                        if (nl.item(x).getNodeType() == 
Node.ELEMENT_NODE)
                                        {
                                                e = (Element)nl.item(x);
                                                break;
                                        }
                        
                        if (e != null)
                                return getTransformToElement(e).inverse();
                }
                catch(Exception ex)
                {
                ex.printStackTrace();
                }
                
                return null;
        }


        /**
         * A number of the flowRoot:s elements doesn't support SVGLocatable, 
which has the effect that
         * that getDocumentElement().getTransformToElement() will not work. So 
this method retrieves
         * all the transform-data by getting it from SVGLocatable when 
possible, and otherwise extracting
         * it from the matrix-data in the transform-tag - all the way from the 
object up to the DocumentElement. 
         *  
         * @param e
         * @return
         */
        protected SVGMatrix getTransformToElement(Element e)
        {
            // Initialize our node's Current Transformation Matrix

                
            SVGMatrix CTM = new SVGOMMatrix(new AffineTransform(1d, 0d, 0d, 1d, 
0d, 0d));
            // Work our way bacwards through the ancestor nodes stopping at the
            // SVG Document
            do
            {
                if (e.getNodeType() == Node.ELEMENT_NODE)
                {
                        // Multiply the new CTM with what we've accumulated so 
far
                            try {
                        SVGLocatable loc_e = (SVGLocatable)e;
                        CTM = loc_e.getCTM().multiply(CTM);
                            } catch (Exception ex)
                            {
                                // Not SVGLocatable, extract the matrix-data 
manually from the transform-tag
                                AffineTransform af = 
FlowRootSvgElement.GetObjTransform(e, true);
                                if (af != null)
                                {
                                        SVGMatrix m = new SVGOMMatrix(af);
                                        CTM = m.multiply(CTM);
                                }
                            }
                }
            }
            while ( ( e = (Element)e.getParentNode() ) != 
e.getOwnerDocument().getDocumentElement() );

            return CTM;
        }


        /**
         *  Will return the current transformation of the Element
         * @param el
         * @param includeTranslation If the translation-data should be removed 
from the translation or not
         * @return
         */
        public static AffineTransform GetObjTransform(Element el, boolean 
includeTranslation)
        {
                float values[] = new float[] {1, 0, 0, 1, 0, 0};

                // get the value of the transform-node
                String tmpTransform = el.getAttribute("transform");
                
                // if transform exists, extract the values
                if (tmpTransform != null && tmpTransform != "")
                {
                        try
                        {
                                Pattern p = 
Pattern.compile("matrix\\((\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\s(\\-{0,1}\\d{1,}\\.{0,1}[\\dE+-]{0,})\\)");
       
                                Matcher m = p.matcher(tmpTransform);
                                m.find();
                                
                                for(int x = 0; x < 6; x++)
                                        values[x] = 
Float.valueOf(m.group(x+1)).floatValue();
                                
                                if (!includeTranslation)        // Remove the 
translation
                                        values[4] = values[5] = 0;
                                
                        }
                        catch (Exception ex)
                        {
                                System.out.println(tmpTransform);
                                ex.printStackTrace();
                                return null;
                        }
                }       
                
                // Create a transformation-object from the values in transfom
                return new AffineTransform(values);
        }

Regards
Henric Rosvall


-----Original Message-----
From: Henric Rosvall [mailto:[EMAIL PROTECTED] 
Sent: den 12 oktober 2006 16:52
To: [email protected]
Subject: flowRoot and getTransformToElement


Hi !

I'm, trying to implement multiline-text in my software by adding support for 
modifying flowRoot-elements. To get information about where an element is 
located, I traverse down to the objects in flowRegion, and get the BBox of 
those objects (since flowRoot, flowRegion and such doesn't implement 
SVGLocatable), and it works perfectly - at least until I try to get the 
transform from the document root down to the obects in the flowRegion. It 
doesn't seem to matter how much I've moved or rotated the flowRoot-Element, 
getTransformToElement() still returns a SVGMatrix that shows no transformation 
what so ever.

Here's a cut out example of the outputted SVG after I've opened the example SVG 
in Batik (flowText.svg), and played around with it a bit:

      <flowRoot font-size="20" id="maintext_0" transform="matrix(0.9591868 
8.604429E-4 -0.41767913 0.73524845 188.0 46.0)">
         <flowRegion>
            <rect x="17" width="200" height="400" y="80"/>
            <rect x="233" width="200" height="400" y="80"/>
         </flowRegion>

         <flowDiv>
            <flowPara indent="20" margin-bottom="10">This is an <flowSpan 
fill="crimson" font-size="40">ex­ample</flowSpan> of a very long string that 
is split ‍across multi­ple lines via text wrap­ping.</flowPara>
         </flowDiv>
      </flowRoot>

As you can see there are some interesting matrix-transformations on the 
flowRoot-element, but when trying to get the transform to the first rect in 
flowRegion, it still returns a SVGMatrix without any transform - dispite the 
fact that the rendering works perfectly.

The call I make to get the transform to the SVGElement e (which in this case 
just happens to be the first rect in flowRegion): 
((SVGSVGElement)e.getOwnerDocument().getDocumentElement()).getTransformToElement((SVGElement)e);

I'm using Batik 1.6. Would it help to upgrade to the latest build, or are there 
some other way to solve this? Or am I simply doing something very wrong?

Regards
Henric Rosvall



---------------------------------------------------------------------
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]

Reply via email to