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 Thomas DeWeese <Th...@Kodak.com> on 2005/02/01 03:09:15 UTC

Re: Obtaining glyph bounding box

Hi James,

James Shaw wrote:

> I am loading an SVG file containing an embedded font (and nothing else) 
> as an SVGDocument.
> I wish to obtain bounding boxes for glyphs in the embedded font, without 
> actually inserting that glyph in the DOM.
> 
> What is the best way to obtain this data?

   Insert the glyph into the DOM (set visibility to hidden or even
just insert and then remove it before your script returns).  If you
really want to muck with Batik internals there are other ways
but AFAIK there are no SVG DOM methods for the glyph elements
that provide this functionality.

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


Re: Obtaining glyph bounding box

Posted by James Shaw <he...@btopenworld.com>.
Thomas DeWeese wrote:

> Hi James,
>
> You will need to build the GVT tree (which is what the
> JSVGCanvas calls do except you aren't waiting for the build
> events, you are also not making the canvas ALWAYS_DYNAMIC
> so for a simple document it won't link the DOM to graphics).
>
> The code to build the graphics tree for the DOM explicitly
> rather than relying on the JSVGCanvas (which is kinda ugly):
>
> UserAgent userAgent = new UserAgentAdapter();
> DocumentLoader loader = new DocumentLoader(userAgent);
> BridgeContext ctx = new BridgeContext(userAgent,loader);
> ctx.setDynamicState(BridgeContext.DYNAMIC);
> GVTBuilder builder = new GVTBuilder();
> builder.build(ctx, document);
>
> Most of the classes are from the bridge package.
>
Wow, it works! Thanks so much!
James Shaw

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


Re: Obtaining glyph bounding box

Posted by Thomas DeWeese <Th...@Kodak.com>.
Hi James,

    You will need to build the GVT tree (which is what the
JSVGCanvas calls do except you aren't waiting for the build
events, you are also not making the canvas ALWAYS_DYNAMIC
so for a simple document it won't link the DOM to graphics).

    The code to build the graphics tree for the DOM explicitly
rather than relying on the JSVGCanvas (which is kinda ugly):

         UserAgent userAgent   = new UserAgentAdapter();
         DocumentLoader loader = new DocumentLoader(userAgent);
         BridgeContext ctx     = new BridgeContext(userAgent,loader);
         ctx.setDynamicState(BridgeContext.DYNAMIC);
         GVTBuilder builder    = new GVTBuilder();
         builder.build(ctx, document);

    Most of the classes are from the bridge package.

James Shaw wrote:

> Thomas DeWeese wrote:
> 
>> Hi James,
>>
>>    To get back to your original question if all you want is the
>> bounding box of elements in the DOM, you can do this right with
>> the SVG DOM (svgelem.getBBox()).  The only advantage of this is
>> that you can using getElementById to avoid the need to walk the
>> whole tree.  Also using the SVG DOM you can even get the
>> location/size of individual glyphs from a text node.  Take a look
>> at:  samples/tests/spec/scripting/text_content.svg
>>
>>
> This method looks promising, but I've failed to make it work.  A 
> NullPointerException is raised when I do bbox.getX() (or any other 
> method of SVGRect).
> I think this is due to a null SVGContext.  Presumably some intermediate 
> steps need to be taken before I can invoke the SVGRect methods.
> 
> My code looks like this:
> 
> Element textNode = doc.createElementNS(SVG_NS, "svg:text");
> textNode.setAttributeNS(null, "font-family", "LilyPond-feta-20");
> textNode.setAttributeNS(null, "font-size",   "18pt");
> textNode.setAttributeNS(null, "x", "0");
> textNode.setAttributeNS(null, "y", "0");
> 
> Element altGlyph = doc.createElementNS(SVG_NS, "svg:altGlyph");
> altGlyph.setAttributeNS(XLINK_NS, "xlink:href", "#sixtyfourthrest");
> altGlyph.appendChild(doc.createTextNode("?"));
> 
> textNode.appendChild(altGlyph);
> doc.getDocumentElement().appendChild(textNode);
> 
> // not sure if the following two lines are needed
> JSVGComponent svg = new JSVGComponent();
> svg.setSVGDocument((SVGDocument)doc);
> 
> SVGRect bbox = ((SVGOMTextElement)textNode).getBBox();
> System.out.println("MinX: " + bbox.getX());
> 
> Thanks
> James Shaw
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
> 


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


Re: Obtaining glyph bounding box

Posted by James Shaw <he...@btopenworld.com>.
Thomas DeWeese wrote:

> Hi James,
>
>    To get back to your original question if all you want is the
> bounding box of elements in the DOM, you can do this right with
> the SVG DOM (svgelem.getBBox()).  The only advantage of this is
> that you can using getElementById to avoid the need to walk the
> whole tree.  Also using the SVG DOM you can even get the
> location/size of individual glyphs from a text node.  Take a look
> at:  samples/tests/spec/scripting/text_content.svg
>
>
This method looks promising, but I've failed to make it work.  A 
NullPointerException is raised when I do bbox.getX() (or any other 
method of SVGRect).
I think this is due to a null SVGContext.  Presumably some intermediate 
steps need to be taken before I can invoke the SVGRect methods.

My code looks like this:

Element textNode = doc.createElementNS(SVG_NS, "svg:text");
textNode.setAttributeNS(null, "font-family", "LilyPond-feta-20");
textNode.setAttributeNS(null, "font-size",   "18pt");
textNode.setAttributeNS(null, "x", "0");
textNode.setAttributeNS(null, "y", "0");

Element altGlyph = doc.createElementNS(SVG_NS, "svg:altGlyph");
altGlyph.setAttributeNS(XLINK_NS, "xlink:href", "#sixtyfourthrest");
altGlyph.appendChild(doc.createTextNode("?"));

textNode.appendChild(altGlyph);
doc.getDocumentElement().appendChild(textNode);

// not sure if the following two lines are needed
JSVGComponent svg = new JSVGComponent();
svg.setSVGDocument((SVGDocument)doc);

SVGRect bbox = ((SVGOMTextElement)textNode).getBBox();
System.out.println("MinX: " + bbox.getX());

Thanks
James Shaw

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


Re: Obtaining glyph bounding box

Posted by Thomas DeWeese <Th...@Kodak.com>.
Hi James,

    To get back to your original question if all you want is the
bounding box of elements in the DOM, you can do this right with
the SVG DOM (svgelem.getBBox()).  The only advantage of this is
that you can using getElementById to avoid the need to walk the
whole tree.  Also using the SVG DOM you can even get the
location/size of individual glyphs from a text node.  Take a look
at:  samples/tests/spec/scripting/text_content.svg

James Shaw wrote:

> Andres Toussaint wrote:
> 
>> In order to get an instance of the GVT Tree, you need to assign a 
>> listener to a JSVGComponent, that will notify you when the GVT Tree is 
>> built. At this stage, you can walk the tree until you find the 
>> Component you are looking for.
>>
>>
> Thankyou, Andres!  I've used your code as a basis; I check (node 
> instanceof TextNode), then use its TextPainter to obtain the bounding box.
> 
> Here's the code snippet, for anyone else who might have the same problem:
> 
> JSVGComponent svg = new JSVGComponent();
> svg.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {
> 
>    public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
>        GVTTreeWalker tw = new GVTTreeWalker(e.getGVTRoot());
>        GraphicsNode node = tw.firstChild();
>        while (node != null) {
>            if (node instanceof TextNode) {
>                TextPainter painter = ((TextNode)node).getTextPainter();
>                Rectangle2D bbox = painter.getBounds2D((TextNode) node);
>            }
>                      node = tw.nextGraphicsNode();
>        }
>    }
> });
> 
> svg.setSVGDocument(doc);
> 
> James Shaw
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
> 


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


Re: Obtaining glyph bounding box

Posted by James Shaw <he...@btopenworld.com>.
Andres Toussaint wrote:

> In order to get an instance of the GVT Tree, you need to assign a 
> listener to a JSVGComponent, that will notify you when the GVT Tree is 
> built. At this stage, you can walk the tree until you find the 
> Component you are looking for.
>
>
Thankyou, Andres!  I've used your code as a basis; I check (node 
instanceof TextNode), then use its TextPainter to obtain the bounding box.

Here's the code snippet, for anyone else who might have the same problem:

JSVGComponent svg = new JSVGComponent();
svg.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {

    public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
        GVTTreeWalker tw = new GVTTreeWalker(e.getGVTRoot());
        GraphicsNode node = tw.firstChild();
        while (node != null) {
            if (node instanceof TextNode) {
                TextPainter painter = ((TextNode)node).getTextPainter();
                Rectangle2D bbox = painter.getBounds2D((TextNode) node);
            }
           
            node = tw.nextGraphicsNode();
        }
    }
});

svg.setSVGDocument(doc);

James Shaw

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


Re: Obtaining glyph bounding box

Posted by Andres Toussaint <an...@onemileup.com>.
In order to get an instance of the GVT Tree, you need to assign a 
listener to a JSVGComponent, that will notify you when the GVT Tree is 
built. At this stage, you can walk the tree until you find the 
Component you are looking for.

As an example, look at the following code:

	svg = new JSVGComponent();
             svg.addSVGDocumentLoaderListener(new 
SVGDocumentLoaderAdapter() {
                 public void 
documentLoadingStarted(SVGDocumentLoaderEvent e) {
                 }
                 public void 
documentLoadingCompleted(SVGDocumentLoaderEvent e) {
                    //System.out.println("SaveAsDXF-ExportCache 
succesfully loaded");
                 }
             });

///////////////////////// RELEVANT PART STARTS HERE 
//////////////////////////
             svg.addGVTTreeBuilderListener(new GVTTreeBuilderAdapter() {
                 public void gvtBuildStarted(GVTTreeBuilderEvent e) {
                     
//System.out.println("SaveAsDXF-ExportCache-GVTBuilder Starting.....");
                 }
                 public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
                     //System.out.println("SaveAsDXF-ExportCache 
succesfully GVT built");

                     GVTTreeWalker tw = new 
GVTTreeWalker(e.getGVTRoot());
                     GraphicsNode node = tw.firstChild();
                     while (node != null) {
			if (node instanceof org.apache.batik.gvt.YOUR_ELEMENT_HERE)) {
				//////////////////////////WHATEVER YOU WANT TO DO WITH YOUR NODE 
/////////////
			}
                         node = tw.nextGraphicsNode();
                     }
                 }
             });




On Feb 1, 2005, at 9:36 AM, James Shaw wrote:

> Thomas DeWeese wrote:
>
>>
>> James Shaw wrote:
>>
>>> I am loading an SVG file containing an embedded font (and nothing 
>>> else) as an SVGDocument.
>>> I wish to obtain bounding boxes for glyphs in the embedded font, 
>>> without actually inserting that glyph in the DOM.
>>>
>>> What is the best way to obtain this data?
>>
>>
>> Insert the glyph into the DOM (set visibility to hidden or even
>> just insert and then remove it before your script returns).
>
> Visibility shouldn't be a problem since I'm not actually displaying 
> the document.
>
>> If you really want to muck with Batik internals there are other ways
>> but AFAIK there are no SVG DOM methods for the glyph elements
>> that provide this functionality.
>>
> Looking at the API docs, I'm trying to get hold of an instance of 
> org.apache.batik.gvt.font.Glyph,
> then invoke its getBounds2D object. However, I have yet to find a way 
> of obtaining a handle to
> the GVT.
>
> Cheers,
> James Shaw
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
> For additional commands, e-mail: batik-users-help@xml.apache.org
>
>



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


Re: Obtaining glyph bounding box

Posted by James Shaw <he...@btopenworld.com>.
Thomas DeWeese wrote:

>
> James Shaw wrote:
>
>> I am loading an SVG file containing an embedded font (and nothing 
>> else) as an SVGDocument.
>> I wish to obtain bounding boxes for glyphs in the embedded font, 
>> without actually inserting that glyph in the DOM.
>>
>> What is the best way to obtain this data?
>
>
> Insert the glyph into the DOM (set visibility to hidden or even
> just insert and then remove it before your script returns).

Visibility shouldn't be a problem since I'm not actually displaying the 
document.

> If you really want to muck with Batik internals there are other ways
> but AFAIK there are no SVG DOM methods for the glyph elements
> that provide this functionality.
>
Looking at the API docs, I'm trying to get hold of an instance of 
org.apache.batik.gvt.font.Glyph,
then invoke its getBounds2D object. However, I have yet to find a way of 
obtaining a handle to
the GVT.

Cheers,
James Shaw

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