The ability to flow text into an arbitrary shape or even a simple box has been a feature long in demand in SVG. Thus it is on the list of required features for SVG 2. The SVG 1.2 draft specification included the ablility to flow text (and graphics!) into arbitrary shapes. Unfortunately, SVG 1.2 never got off the ground and only Inkscape and Batik seem to have implemented parts of flowed text.
Inkscape’s implementation supports text flowed into arbitrary paths. If the path has a hole, text will wrap around it. Inkscape also supports text flowed into multiple shapes. Inkscape (nor Batik) implemented flowing images or some of the fancier elements that control line and paragraph breaks.
Flowed text in SVG 1.2 does have some problems. First, it is complicated. There are eleven separate elements (Inkscape supports five, Batik seven). Second, there is some missing functionality. For example, there is no way to set a margin (as seen in the above examples). Third, the reality is that none of the browsers will implement SVG 1.2 flowed text even if it were part of SVG 2. They want a solution that works for both HTML and SVG.
Enter CSS and a step forward
Almost nine years after the SVG 1.2 draft came out, interest in flowing text into and around shapes has made it to HTML. The CSS working group has produced a draft specification for text flowing and wrapping. The specification is fairly simple and straight forward. One specifies shapes to flow text into (‘shape-inside’) and shapes to flow text around (‘shape-ouside’). Then one specifies how the text should wrap (e.g. only wrap on the left side of a ‘shape-outside’ shape) and how close the text should come to the shapes (‘wrap-margin’ for outside shapes and ‘wrap-padding’ for inside shapes). There are a set of canned shapes defined (rectangle, circle, ellipse, or polygon) or one can link to an SVG shape or path. One can also use the alpha value of an image to generate a shape.
With this, 95% of the work for getting text wrapping in SVG is done. A few small changes are needed to adapt to the spec to SVG. For example, in HTML, one always has a box to provide a ‘wrapping-context’. In SVG you must supply the wrapping context using the ‘shape-outside’ property. In SVG, you might want to limit shapes to actual SVG shapes or paths (rather than using the canned shapes). SVG would need to add the value ‘justified’ to ‘text-align’ and add the property ‘line-height’ (already defined in CSS). The ‘x’ and ‘y’ attributes on <text> and <tspan> would be ignored (but left for use as a fallback). The trickiest part is figuring out how SVG would specify linebreaks and paragraphs since SVG does not have the <br/> and <p></p> elements.
Here is a simple example of how CSS Exclusions might work in SVG:
<def> <circle id="mycircle" cx="150" cy="150" r="125"/> </def> <text x="100" y="100" font-size="18px" text-align="justified" line-height="125%" wrap-margin="25" shape-inside="url(#myshape)">This is a mockup of...</text>
And one step back
I just knocked off adding hatches to SVG 2 this week and was ready to take a closer look at text wrapping so I could present a plan for its specification at the upcoming SVG Working Group meeting. I looked at the lastest CSS Exclusions public working draft and started formulating a plan. Things looked easy. But then, a few days ago, it was announced on the CSS Working Group mailing list that the CSS Exclusions draft had been split into an Exclusions specification and a Shapes specifications. This seemed OK at first but in looking at the current editor’s drafts (a step before publishing a public working draft) I noticed two problems. In the Exclusions editors draft ‘shape-inside’ had been removed, to be postponed to a future specification; and in the Shapes draft, it was no longer possible to reference SVG shapes and paths. These are the VERY two things that are most required for having flowed text in SVG are gone. Hopefully we can get these back.