Interesting, so I've taken your advice but it appears the
SVGTextPositioningElement.getExtentOfChar method throws a
NullPointerException because SVGTextContentSupport.getExtentOfChar is
unable to execute getNumberOfChars due to a null returned by
getSVGContext. Is there some other initialization I need to do before
I attempt to use this method?
The exception:
---
Exception in thread "main" java.lang.NullPointerException
at
org
.apache
.batik
.dom
.svg.SVGTextContentSupport.getNumberOfChars(SVGTextContentSupport.java:
45)
at
org
.apache
.batik
.dom
.svg.SVGTextContentSupport.getExtentOfChar(SVGTextContentSupport.java:
55)
at
org
.apache
.batik
.dom
.svg
.SVGOMTextContentElement.getExtentOfChar(SVGOMTextContentElement.java:
219)
at com.brendonwilson.kindleberg.Test.main(Test.java:27)
---
The SVG:
---
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.2" xmlns="http://www.w3.org/2000/svg">
<flowRoot xml:space="preserve">
<flowRegion vertical-align="middle">
<rect x="0" y="0" width="500" height="100"/>
</flowRegion>
<flowDiv>
<flowPara font-size="72" id="test"> This is a test paragraph.</
flowPara>
</flowDiv>
</flowRoot>
</svg>
---
The code:
---
import java.io.File;
import java.io.IOException;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.util.XMLResourceDescriptor;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGRect;
import org.w3c.dom.svg.SVGTextPositioningElement;
public class Test
{
public static void main(String[] args)
{
try
{
// Open the SVG template.
String parser =
XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory f = new
SAXSVGDocumentFactory(parser);
SVGDocument doc = f.createSVGDocument(new
File("test.svg").toURI().toString());
Element testElement = doc.getElementById("test");
SVGTextPositioningElement positioning = (SVGTextPositioningElement)
testElement;
SVGRect testBounds = positioning.getExtentOfChar(3);
if (testBounds != null)
{
System.out.println("No overflow!");
}
else
{
System.out.println("Overflow!");
}
}
catch (IOException ex)
{
System.out.println("Unable to read the template SVG
file!");
}
}
}
---
Thanks in advance,
Brendon
On Dec 14, 2009, at 5:30 AM, [email protected] wrote:
Hi Brendon,
"Brendon J. Wilson" <[email protected]> wrote on 12/13/2009
11:24:25 PM:
> The Desired Result: An area of text that uses the largest font size
> possible while still fitting into a given rectangle.
>
> The Proposed Solution: Use the 'flowroot' element, check for
overflow,
> and iteratively adjust the font size of the text.
>
> The Problem: Based on emails from this list dating from 2006, it
does
> not appear overflow events are implemented, and my alternative
> attempts to formulate my own overflow detection mechanism have been
> unsuccessful.
I haven't checked the recently but my recollection is that there
were some issues with the way those events were specified that made
it problematic to implement them.
> but a similar call to attempt to get the bounding box for the laid
out
> text (I presume, I'm actually shooting in the dark at this point)
> results in an uncaught exception:
>
> ---
> SVGElement svgElement = (SVGElement) doc.getElementById("title");
> SVGLocatable locatable = (SVGLocatable) svgElement;
> SVGRect altbounds = locatable.getBBox();
The problem is that the flowDiv/flowPara/flowSpan implement the
SVG Text positioning interface rather than SVG Locatable. You should
be able to detect overflow by checking if the 'getExtentOfChar' for
the last 'printing char' is empty (i.e. the flow text hid it).
> Is there another, easier way to figure out the actual dimensions of
> the laid out text in a flowDiv, or check the flowRoot for
overflow? Or
> are overflow events still not implemented?
The layout code actually tracks if overflow occurs but it isn't
exposed anywhere. In 'FlowTextPainter.getTextRuns' the 'textWrap'
function called at the end returns true if there was overflow, but
that return value is propagated anywhere.
Thanks,
Brendon
---
Brendon J. Wilson
www.brendonwilson.com
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]