W3C home > Mailing lists > Public > www-svg@w3.org > April 2006

Rendering of stroke-dasharray in special situations

From: Dr. Olaf Hoffmann <Dr.O.Hoffmann@gmx.de>
Date: Thu, 20 Apr 2006 19:51:57 +0200
To: www-svg@w3.org
Message-Id: <200604201951.58079.Dr.O.Hoffmann@gmx.de>


Testing the animation abilities of SVG-viewers I recognised
several difficulties with stroke-dasharray in special situations
and in combination with other properties as stroke-linecap and
Some of them are just surprising, because it is clear for me with 
the specification, but wrong in many or all SVG-viewers,
maybe because much information related to stroke-dasharray
can just be found somewhere else in the specification, but
not in the stroke-dasharray section. 

Complete defined and correct rendering of stroke-dasharray
is difficult, because it is complex.
Therefore maybe it is useful for developers and authors to
clarify stroke-dasharray rendering to get soon consistent
behaviour of different SVG-viewers.

1. Rendering of subpaths
Should the stroke-dasharray pattern restart with the
initial value of the pattern with the beginning of a
subpath or should it continue with the pattern?
In the stroke-dasharray section of the specification (1.1)
it is not mentioned, how to handle the continuation of dasharray 
in subpaths, but in the path chapter we find in the moveto
section (8.3.2):
'The "moveto" commands (M or m) establish a new current point. 
The effect is as if the "pen" were lifted and moved to a new location.'
This sounds more as a continuation of dasharray as like a restart,
but it is a very weak hint.
Defines the specification with a certain behaviour for this case 
somewhere else? 
If not, can we interprete the quote as continuation?
Shouldn't the stroke-dasharray section clarify the behaviour

   d="M50,100 L850,100
         M50,200 L850,200
         M50,300 L850,300"
   stroke="#00f" fill="none"
   stroke-dasharray="800,200" />

Should the visual effect be like (behaviour of gecko 1.8...):
<g  stroke="#00f" fill="none"
<path d="M50,100 L850,100" />
<path d="M50,200 L850,200" stroke-dashoffset="-200" />
<path d="M50,300 L850,300" stroke-dashoffset="-400" />

or like (behaviour of Opera, Adobe plugin):
<g  stroke="#00f" fill="none" stroke-width="30">
<path d="M50,100 L850,100" />
<path d="M50,200 L850,200" />
<path d="M50,300 L850,300" />

2. Definition of intervals for dashes and gaps
If we have stroke-dasharray="800,200" 
belongs 800 to the dash or to the gap?
This is getting important for stroke-dashoffset 
for paths with subpaths and for paths with edges
and corners and for animation.
I think it is useful to define this similar as for time 
intervals  in animation, this means in this example
0 belongs to a dash, 800 to a gap, 1000 to a dash
and so on.

3. Rendering of stroke-linecap
The stroke-dasharray section defines dasharray as a
pattern of dashes and gaps (therefore the dashes
are no subpaths).
Should the pattern continued forward and backward
into the linecaps or should the stroke-linecap have the
same behaviour as the related point of the stroke?

<path d="M100,100 L900,100"
   stroke="#00f" fill="none"
   stroke-linecap="square" />

look like

<path d="M20,100 L980,100"
   stroke="#00f" fill="none"
   stroke-linecap="butt" />

or like

<g stroke="#00f" fill="none" stroke-width="160">
<path d="M100,100 L900,100" stroke-dasharray="40,40" />
<path d="M20,100 L100,100" />

I prefer the first case, but this can get
a little bit more complicate with stroke-linecap="round"
and it needs a special rule for (sub)paths of zero length

<path d="M100,100 L100,100"
   stroke="#00f" fill="none"
   stroke-linecap="round" /> 
(or with d="M100,100 z", both in
combination with stroke-dasharray more 
useful as a subpath, not as a complete path
of course).
For this special case either the stroke-dasharray
should be ignored or the value of  stroke-dasharray
pattern at the position in the subpath should be
used. Alternatively a radial pattern might be useful,
using circular dashes. Then a starting position for
the pattern has to be defined, either at r=0 or at

4. Rendering of stroke-linejoin (especially miter)
If the path is not continuously differentiable 
(normally this means, there is a corner) at a
point with a border between a dash and a gap,
how should the stroke-linejoin be rendered?
If we use the interval definition from 2, the
behaviour of the pattern can be applied to the
stroke-linejoin. Or should the stroke-linejoin
be divided along the bisecting line half with a
dash and half with a gap? Or should the
stroke-dasharray be continued in the direction
of the bisecting line?
A detailed definition is especially useful for
And some examples for such an area with
a border between a dash and a gap near such
a corner might be very helpful for developers
and authors to understand, how such corners
have to look with different values for stroke-with
and stroke-dasharray.

5. stroke-dasharray as a pattern
Many SVG-viewers display the dashes as something
like subpathes (but not the gaps), but in the 
specification it is defined as a pattern.
Therefore it seems to be useful to explicitly mention that:
a) stroke-linecaps have not to be applied to the dashes
and gaps themselves. If this is needed, in the
specification 1.2 or 1.3 additional properties should
be defined as stroke-dashcap and stroke-gapcap or
more general something like stroke-dashborder and
(this could define the behaviour of the border 
between a dash and a gap or a gap and a dash
especially perpendicular to the stroke in more detail).
b) the stroke-dasharray pattern is never outside of
the stroke (if the pattern is covered with an identical
path without a stroke-dasharray, nothing of the
pattern will get visible.
Other things happen, if stroke-linecap="square" is
applied to the dashes).

But if the specification does not mean stroke-dasharray as
a (one-dimensional) pattern along a path, just as a 
simplification for defining subpaths, the words 
pattern, dash and gap should be avoided and
replaced by subpath to avoid further confusion. 

Best wishes
Received on Thursday, 20 April 2006 22:49:09 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 22:54:12 UTC