Re: Problems with SVG's CSS properties

On Mon, 26 Apr 1999, Jon Ferraiolo wrote:

> Thanks for the careful analysis and good points.

A pleasure.


>> Because SVG uses different conventions for <length>, in particular
>> because it allows unit-less numbers, the CSS2 'font' shorthand
>> property will be unparsable in SVG. [...] 
>> Two possible solutions are to either not use the 'font' shorthand
>> property in SVG, or to give user units a unit specifier such as 'uu'.
> Good point. My vote would be to define another unit specifier 'uu'
> as you suggest, with its use being optional in most places in SVG
> (e.g., coordinate values in a <path>), and require that units be
> specified if you want 'font: <number>' to be such that <number>
> represents a font size. I think we'll need to coordinate with the
> CSS working group on this one.

I think probably the best option would be to make it mandatory for all
numbers in CSS, and optional for attribute values. At least then it is
clear where the dividing line lies (this should not cause the problems
I outlined above, since none of the attributes can have multiple
keywords like CSS shorthand properties).


>> The current spec states that:
>># The standard set of text and font properties from CSS2 apply,
>># including 'text-align' and 'vertical-align'.
>> How is 'vertical-align' to be applied? In CSS, 'vertical-align' has
>> a pivotal role in the inline level formatting model. Will SVG use
>> the entire CSS inline level formatting model? This seems like
>> serious overkill since SVG uses a much more direct approach to
>> layout (namely, giving x and y coordinates).
> What I had in mind was that 'vertical-align' indicated how to align
> an SVG <text> element relative to the start point for the text
> string. For example, 'top' means the top of the first character
> would be at the start point for the text string, whereas 'bottom'
> means the bottom of the first character would be at the start point
> for the text string.

CSS's 'vertical-align' property, like the 'text-align' property, has
implications that are out-of-scope for SVG. It also has values that
are irrelevant to SVG. I suggest that both be replaced by SVG-specific
properties.

To define these properties in terms of paths and paths alone, text
that is _not_ on a path will be assumed to create a path that is an
infinite line which starts at the point specified by the x and y
attributes, and goes right for l-to-r text, left for r-to-l text, down
for t-to-b text, and up for b-to-t text. The length of this infinite
line shall be defined as being 0 (!) for the purposes of the algorithm
below. (In other words, text will not "run out of path" when it is
drawn on, but the line is really a point (zero length line).)

Ahem. Anyway.

This idea replaces the two CSS2 properties with two new ones,
'text-anchor' and 'line-anchor'.

They take the following values:

text-anchor := [ top | middle | baseline | bottom | <length> ] | inherit
 (inherited: yes; initial: baseline)

line-anchor := [ start | center | end ]  | inherit
 (inherited: yes; initial: start)

To draw text, UAs would use the following algorithm:

 Find the length of the text.

 Based on the value of the 'text-anchor' property, redefine the
 baseline of the text as being one of: the top of the glyphs, the
 middle of the glyphs, the natural baseline of the glpyhs, the bottom
 of the glyphs, or <length> from the baseline of the glpyhs (positive
 means up). It is this redefined baseline that is used with the
 '(text-)direction' property's definition to place the text on the
 path (see the spec, section 13.6).

 Based on the value of the 'line-anchor' property, decide whether the
 first glyph will be placed at text-offset from the start of the path,
 the last glyph will be placed at text-offset from the end of the
 path, or the center of the text will be placed at text-offset from
 the center of the path (text-offset being positive in the writing
 direction, so that an offset pointing towards the end of the path is
 positive for l-to-r and t-to-b, negative for r-to-l and b-to-t).

So to start text going up along the inner right edge of a box,
text-anchor should be set to "bottom" and line-anchor to "start" with
the x and y coordinates set to the (width+x position) and (height+y
position) of the box respectively. (The clipping could also be set to
the same coordinates as the box itself.)

For a big vertical banner like this:

   +---+
   |   |
   | H |
   | E |
   | L |
   | L |
   | O |
   |   |
   +---+

...with the text anchored around the center of the banner, the
declaration would be:

   direction: t-to-b; text-anchor: middle; line-anchor: center;

The x and y coordinates would be the center of the banner (if the
banner is actually the viewport, then 50% 50% could be used).

Right aligning text anchored to its baseline would be done by using:

   direction: l-to-r; text-anchor: baseline; line-anchor: end;

These properties even define the case of mixed fonts being all drawn
on the same path.

So, for example, 

   <textflow x=0 y=0>
    <text class=a> A </text>
    <text class=b> B </text>
    <text class=c> C </text>
   </textflow>

...with the following CSS:

   textflow { direction: l-to-r; line-anchor: start; text-anchor: top;
        font-family: "poor ascii art", sans-serif; }
   .a { font-size: 1em; }
   .b { font-size: 2em; }
   .c { font-size: 3em; }

...would be rendered as:
          __
  A  |)  /  \
     |)  |
         \__/

Examples of text on a path are difficult to do in an e-mail, but you
get the idea. What do people think?


> SVG would *not* do block text and word wrapping. Instead, leave that
> to engines that do real text layout, such as HTML+CSS or XML+CSS.

Good.


>> Exactly which font text and font properties will SVG borrow from CSS2? 
> My initial reaction is that, as a simply understood rule, SVG should
> support all CSS2 properties that begin with 'text' or 'font', but
> this opinion is before doing in-depth study. It is clear that some
> of the CSS text and font properties are a lot less important to SVG
> than to HTML, for example, so maybe this simple rule isn't such a
> good idea. What do you think?

'font-family': Yes.
'font-size': Yes.
'font-size-adjust': Yes.
'font-stretch': Yes.
'font-style': Yes.
'font-variant': Yes, but the exact ratio for 'small-caps' synthesis
  should be specified, and some algorithm to avoid smaller letters
  seeming to be of a different font-weight needs to be developed.
'font-weight': Yes.
'text-transform': Yes.
'letter-spacing': Yes (defines how far along the path to move after
  each glpyh - very useful for SVG I would think).
'word-spacing': Yes (added to letter-spacing after a white-space
  character appears in the text stream).
'text-align': No. Replace with 'line-anchor', see above.
'text-decoration': No. Nowhere near the level of control needed in
  SVG. It would be better to allow lines that use paths to only get
  drawn for the fragment of the path that a particular <textflow> or
  <text> or <t> element covers.
'text-indent': No. Replaced by "text-offset" attribute.
'text-shadow': No. Overlaps with filter effects.
'vertical-align': No. See 'text-anchor' above.
'white-space': No. I suggest that all whitespace in SVG should be
  significant. This is debatable, however.

So it appears that in fact, all the 'font-*' properties can be used,
but the 'text-*' and other related properties need more thought.

-- 
Ian Hickson 
U+2642 U+2651
U+262E U+2603 U+263A

Received on Tuesday, 27 April 1999 11:29:56 UTC