Text Wrapping

From Svg wiki

In SVG1.2, there will be native capability to do textwrapping to arbitrary shapes, such as circles, polygons, or complex paths. It will take into account margins and line-heights.

For earlier versions of SVG, you must use <tspan> or <textPath>.

Contents

tspan

The idea of wrapping text via the use of a tspan element is simple. Each line of the text is a tspan element, with its width restricted to the width of the target area (keeping margins in mind).

Hand Coding

This is simple to do by eye. You simply check the length of the text to that of the line above it. The only exception comes with entities that are a different size than their text-editor length (such as <, > or different glyph proportions).

<rect x='20' y='50' width='150' height='200' fill='green'/>
<text x='25' y='50' font-size='16px' fill='gold'>
 <tspan x='25' dy='1em'>This is a line of text</tspan>
 <tspan x='25' dy='1em'>wrapped to fit within</tspan>
 <tspan x='25' dy='1em'>a rectangle. It is</tspan>
 <tspan x='25' dy='1em'>composed of a</tspan>
 <tspan x='25' dy='1em'><text> element</tspan>
 <tspan x='25' dy='1em'>with several child</tspan>
 <tspan x='25' dy='1em'><tspan> elements.</tspan>
 <tspan x='25' dy='1em'>Each <tspan> is</tspan>
 <tspan x='25' dy='1em'>one line, with the</tspan>
 <tspan x='25' dy='1em'>'dy' attribute value</tspan>
 <tspan x='25' dy='1em'>'1em' regulates the</tspan>
 <tspan x='25' dy='1em'>line height.</tspan>
</text>

To see this example, along with a circle-wrap, see Text Wrapping using 'tspan'.

Script

To do this in script, you simply find the bounding box of the shape you want to fit the text to (using the DOM method "getBBox()"), then take the text and split it up into 'tspan' chunks that fit in that space. Just add a word at a time until the bounding box of the 'tspan' is too wide, remove that last word, and insert the 'tspan' into the parent 'text'. The height of each line is taken care of by using the dy attribute, as above. Rectangles are easy to wrap to, since the getBBox() method returns a box the exact dimensions of the rect element. An example of this can be found at XML.com. However, it is not as easy to wrap to an arbitrary shape, especially since ASV does not implement the getIntersectionList method.

textPath

If you want the text content or font-size to be able to change dynamically, but don't want to use script, or want to wrap to an arbitrary shape, you can use a 'textPath'. It's not perfect, and still requires some hands-on work, but if you're using a graphical editor, it's very easy to do, by simply drawing lines that fit into your shape (considering margins). One flaw of this method is that, depending on the implementation, words may be split at odd places.

For an example, see Text Wrapping using 'textPath'.

As with tspan, it is not easy to do this in script without the the getIntersectionList method.