You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-users@xmlgraphics.apache.org by Tonny Kohar <to...@gmail.com> on 2008/02/21 08:38:06 UTC

Re: How to get bounds of text element in SVG doc (dimensions/size/width)

Hi,

On Wed, Feb 20, 2008 at 9:02 PM, Rob Davis <te...@robertjdavis.co.uk> wrote:
> How can batik be used to work out the bounds of a text element in an SVG doc?
>
>  For example return a Rectangle2D object? Or the width and height of
>  the element (a corner x,y co-ordinates are already defined in the
>  element, once I have the width and height to then I know the bounds)

Did you try elt.getBBox(); // check the API, the syntax is from my memory

>
>  I found the SVGTextElementBridge class which does have a getTextBounds
>  method that returns a Rectangle2D. This is exactly what I'm looking
>  for. HOWEVER, how do I initialise an instance of this class properly?
>  and for it to operate on the SVG text element I'm interested in?

Those classes are already initialized by Batik when you enabling the
boot css stuff. In Batik wiki / website there should be a
documentation regarding SVG boot css (forget the url), from there you
can get access to the bridge and bridgeContext class.

Note: those Bridge/BridgeContext and GVT is low level Batik graphics
rendering, normally people does not go into that deep, people are
usually at the SVG DOM API level.

Cheers
Tonny Kohar
-- 
Sketsa SVG Editor
imagine, design, create ...
http://www.kiyut.com

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org


SOLVED: How to get bounds of text element in SVG doc (dimensions/size/width)

Posted by Rob Davis-5 <te...@robertjdavis.co.uk>.
OK So I've binned JDOM. Really it is a waste of time. I've learnt the hard
way that you should use pure DOM always because that is going to be most
compatible with everything else - batik works with DOM and nothing else. Yes
there are adapters from JDOM to DOM but these weren't working - I think
things had to be validated in DOM in the first place for things to work.

The code to input the SVG XML and parse it into DOM is below. I've localised
my DTD - basically downloaded everything off w3c website - the SVG DTD *AND*
all the other files it needs from the same online directory on their
website.
I'm doing this locally because I won't have a net connection.

That's sorted - see the code at the end.

Now for the solution to this forum thread - here it is below. This uses
batik's SAX implementation. However I still also need to use a DOM
implementation because the SAX parser in batik ignores DOCTYPE and comments
- see thread:
http://www.nabble.com/DOCTYPE-and-COMMENTS-ignored-by-batik-parser-SAXSVGDocumentFactory-to16001432.html

Not ideal because it is duplicate work inputting the document but at least
it all works now.

Also, bear in mind that this solution doesn't consider the transform
attribute that may occur in an element and also its enclosing parents. BUT I
have a solution to that here:
http://www.nabble.com/Solution%3A-Code-to-combine-parent-elements-transform-applied-to-element-to16032287.html

It gives you a combined transform which you can then use the batik/w3c
libaries ( e.g. matrixTransform in w3c svg libraries or PathIterator with
AffineTransform) to apply the transform to the co-ords of the bounding box
to get its true co-ordinates in the viewport.



          SVGDocument    svgDoc;
          UserAgent      userAgent;
          DocumentLoader loader;
          BridgeContext  ctx;
          GVTBuilder     builder;
          GraphicsNode   rootGN;
          
          userAgent = new UserAgentAdapter();
          loader    = new DocumentLoader(userAgent);
          ctx       = new BridgeContext(userAgent, loader);
          ctx.setDynamicState(BridgeContext.DYNAMIC);
          builder   = new GVTBuilder();
          
          SAXSVGDocumentFactory docFactory = new SAXSVGDocumentFactory(
XMLResourceDescriptor.getXMLParserClassName() );
           svgDoc = docFactory.createSVGDocument( new File( "C:\\myfile.svg"
).toURI().toString() ); 
          
          
           
          rootGN    = builder.build(ctx, svgDoc);
          
          org.w3c.dom.svg.SVGElement svgElement =
(SVGElement)svgDoc.getElementById("myElementId");

          /* e.g. as in <rect x="0.0" y="0.0" width="10.0" height="10.0"
id="myElementId"/> */
          
          SVGLocatable locatable = (SVGLocatable)svgElement;
          
          SVGRect rect = locatable.getBBox();
          
	        System.out.println("X: " + rect.getX() + "\nY: " + rect.getY() +
	        		"\nHeight: " + rect.getHeight() + "\nWidth: " + rect.getWidth());




import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;

import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;

 public class LocalDTDResolver implements LSResourceResolver {
         
   String myLocalDTDFileAsString;
   URI localDTDFileAsUri;
   String myLocalDTDPath;
   LSInput LSInput;
         
   public LocalDTDResolver( String localDTDPath, String localSVGDTDFilename
) throws MalformedURLException
   {

           myLocalDTDPath = localDTDPath;
           
           myLocalDTDFileAsString = localDTDPath + localSVGDTDFilename;
       
        LSInput = new LSInput(myLocalDTDFileAsString );
   }
         
   public LSInput resolveResource(String type, String namespaceURI, String
publicId, String systemId, String baseURI)
   {
     //Allow the application to resolve external resources.
           
         // the occasion where systemId == null
         // is where the LSParser has finished looking at the
         // DTD and is now looking at the XML document itself
         // so at this point, make the systemid the same as the
         // baseuri - the XML document location
     if ( systemId == null )
     {
       System.out.println( "systemId:" + systemId );
                             
           LSInput.setSystemId( baseURI );
           LSInput.setPublicId( null );
           LSInput.setBaseURI( baseURI );

           return LSInput;
         }

         if (systemId.endsWith("mydtd.dtd"))
         {
           return LSInput;
         }
         else
         {
           System.out.println( "myLocalDTDPath + systemId:" + myLocalDTDPath
+ systemId );
                 
           LSInput.setSystemId( myLocalDTDPath + systemId );
         
           return LSInput;
         }  
   }
 }
 
 
 /*
 System.out.println( "\nDEBUG" );
 System.out.println( "type: " + type );
 System.out.println( "namespaceURI:" + namespaceURI );
 System.out.println( "publicId:" + publicId );
 System.out.println( "systemId:" + systemId );
 System.out.println( "baseURI:" + baseURI );
 System.out.println( "\n" );





import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.net.URI;


import org.w3c.dom.ls.LSInput;

public class LSInput implements LSInput {

        private String myLocalDtdFileAsString;
       
        public LSInput( String localDtdFileAsString )
        {
                setSystemId( localDtdFileAsString );
               
        }
       
        @Override
        public String getBaseURI() {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public InputStream getByteStream() {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public boolean getCertifiedText() {
                // TODO Auto-generated method stub
                return false;
        }

        @Override
        public Reader getCharacterStream() {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public String getEncoding() {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public String getPublicId() {
                // TODO Auto-generated method stub
                return null; //"-//W3C//DTD SVG 1.1//EN";
        }

        @Override
        public String getStringData() {
                // TODO Auto-generated method stub
                return null;
        }

        @Override
        public String getSystemId() {
                // TODO Auto-generated method stub
               
                URI localDtdFileAsUri = (new File( myLocalDtdFileAsString
)).toURI();
               
                return localDtdFileAsUri.toString();
        }

        @Override
        public void setBaseURI(String arg0) {
                // TODO Auto-generated method stub

        }

        @Override
        public void setByteStream(InputStream arg0) {
                // TODO Auto-generated method stub

        }

        @Override
        public void setCertifiedText(boolean arg0) {
                // TODO Auto-generated method stub

        }

        @Override
        public void setCharacterStream(Reader arg0) {
                // TODO Auto-generated method stub

        }

        @Override
        public void setEncoding(String arg0) {
                // TODO Auto-generated method stub

        }

        @Override
        public void setPublicId(String arg0) {
                // TODO Auto-generated method stub

        }

        @Override
        public void setStringData(String arg0) {
                // TODO Auto-generated method stub

        }

        @Override
        public void setSystemId( String localDtdFileAsString )
        {
                myLocalDtdFileAsString = localDtdFileAsString;
        }

}



// part based on Oreilly Java and XML book



      File file = new File("C:\\myfile.svg");
     
      URI localFileAsUri = file.toURI();
     

     
          DOMImplementationRegistry registry =
                  DOMImplementationRegistry.newInstance( );
         
          DOMImplementationLS lsImpl =
                  (DOMImplementationLS)registry.getDOMImplementation("LS");
         
          LSParser parser =
                 
lsImpl.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS,
                  null);
         
          // Set options on the parser
          DOMConfiguration config = parser.getDomConfig( );
          config.setParameter("validate", Boolean.TRUE);
         
           
         
          config.setParameter("resource-resolver", LocalDTDResolver );
         
         
          org.w3c.dom.Document doc =
parser.parseURI(localFileAsUri.toString());




-- 
View this message in context: http://www.nabble.com/How-to-get-bounds-of-text-element-in-SVG-doc-%28dimensions-size-width%29-tp15590430p16032990.html
Sent from the Batik - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org


Re: How to get bounds of text element in SVG doc (dimensions/size/width)

Posted by Rob Davis-5 <te...@robertjdavis.co.uk>.
If you look at the other thread mentioned in the last post,
i.e. :
http://www.nabble.com/DOMOutputter-problem%3A-getElementById-to-get-DOM-Element-from-resultant-DOM-Document-returns-null-to15616657.html

You'll see that I'm a little closer to solving my own problem.
The problem has now shifted from Apache batik - I think I know how to set
this up. The problem now is converting from a JDOM document to a W3C DOM
Document - which batik requires to give me access to the rectangle bounds
for the text element. At the moment I'm getting null and that may be because
of validation and schema features being deliberately disabled by me.

I'll let you know to confirm my findings - and a solution. In the meantime
feel free to contribute. :)

-- 
View this message in context: http://www.nabble.com/How-to-get-bounds-of-text-element-in-SVG-doc-%28dimensions-size-width%29-tp15590430p15641299.html
Sent from the Batik - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org


Re: How to get bounds of text element in SVG doc (dimensions/size/width)

Posted by Rob Davis-5 <te...@robertjdavis.co.uk>.




Tonny Kohar-2 wrote:
> 
> Those classes are already initialized by Batik when you enabling the
> boot css stuff. In Batik wiki / website there should be a
> documentation regarding SVG boot css (forget the url), from there you
> can get access to the bridge and bridgeContext class.
> 

Yes I am nearly there...

Yes I realize now that I have to "boot the SVG and CSS DOM."
Basically this means that Batik is initialized with all the visual
attributes of the SVG document, like for example the rectangle bounds of a
text element.

"boot the SVG and CSS DOM" instructions here:
http://wiki.apache.org/xmlgraphics-batik/BootSvgAndCssDom

However batik works with W3C DOM java interfaces.

I am working with JDOM so I need to convert my JDOM text element to a DOM
text element.

There is a JDOM utility class to do this - DOMOutputter 
But there is a problem: I get the DOM Document object OK from the
DOMOutputter 
BUT I get null returned when I use getElementById to get the text element
object (I have the 'id' of the element so expect this to work)

This problem is discussed in separate Nabble JDOM Forum thread
http://www.nabble.com/DOMOutputter-problem%3A-getElementById-to-get-DOM-Element-from-resultant-DOM-Document-returns-null-to15616657.html

Any ideas? 

I'm guessing it might be a namespace problem or formatting problem related
to how I present the 'id' value.

I want to stick with JDOM (a lot of my code relies upon it).



Tonny Kohar-2 wrote:
> 
> Did you try elt.getBBox(); // check the API, the syntax is from my memory
> 

I haven't tried this.  I can't do this until I've been able to get the DOM
Element as described above.

-- 
View this message in context: http://www.nabble.com/How-to-get-bounds-of-text-element-in-SVG-doc-%28dimensions-size-width%29-tp15590430p15630512.html
Sent from the Batik - Users mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: batik-users-help@xmlgraphics.apache.org