[svgwg] Define equivalent paths for degenerate shapes

AmeliaBR has just created a new issue for 
https://github.com/w3c/svgwg:

== Define equivalent paths for degenerate shapes ==
In SVG 2, we:

a. [Define equivalent paths for basic 
shapes](https://svgwg.org/svg2-draft/shapes.html).
b. [Define the bounding box for a degenerate shape (height or width of
 0)](https://svgwg.org/svg2-draft/coords.html#BoundingBoxes) to 
include a valid position and the non-zero dimension.
c. [Clarify that zero-length paths, open or closed, should be stroked 
with the line-cap 
shape](https://svgwg.org/svg2-draft/painting.html#StrokeShape).
d. [Continue to require that degenerate shapes do not 
render](https://svgwg.org/svg2-draft/shapes.html), not even stroke.

That last one creates some problematic inconsistencies if you were to 
actually try to implement basic shapes according to their equivalent 
paths.  

If, for example, you were to create a `<path>` element that is 
equivalent to a zero-height by 100px wide rectangle, it would still be
 stroked as a 100px long horizontal line, with line-join shapes at 
either end.  If you were to create a path that is equivalent to a 
zero-radius circle, it should (according to the new guidance) be drawn
 as a spot line-cap shape.  But the `<rect>` element and `<circle>` 
element that created those equivalent paths are not stroked.

One solution would be to add a test in determining the equivalent 
path.  If any of the size dimensions are 0, the equivalent path is 
empty.  But then you wouldn't get a bounding box in the correct 
position.  

OK, so the equivalent path is just a _Mx,y_ statement, where x and y 
are determined from the x/y or cx/cy properties.  That gets the 
bounding box in the correct position, but it still doesn't expose the 
width of our zero-height rectangle.  

So, you'd need to have two consecutive _M_ statements, to define the 
extent of the shape, without having any line commands that would 
create a stroke between them:

- Circle where `r` = 0, equivalent path = M _cx_,_cy_
- Ellipse where `rx` or `ry` = 0, equivalent path = M _cx_ - 
_rx_,_cy_-_ry M _cx_ + _rx_,_cy_+_ry_
- Rect where `width` or `height` = 0, equivalent path =  M _x_,_y_ M 
_x_ + _width_,_y_+_height_

The above would get all the behavior we require for both stroking and 
bounding boxes, but it would make it difficult when trying to 
interpolate shapes to/from a zero dimension.  (And after all, the 
reason we care about zero-dimension shapes is because they get used in
 animations!)  However, SVG 1 defined the non-continuous behavior 
(strokes suddenly disappearing) when switching from almost-zero to 
zero dimensions, so some discontinuity is unavoidable without a major 
breaking change in rendering behavior.

**I don't think this is a blocking change for SVG 2**, because we 
don't actually expose the equivalent paths to authors.  Implementers 
will still have to muck around with special rules for degenerate 
shapes to get all these different outcomes, but we don't have to 
decide on a canonical solution just yet.  But I _would_ very much like
 to expose equivalent paths through the new path API (and #155 is a 
specific feature request for that), so it needs to be sorted for the 
SVG Paths module.  




Please view or discuss this issue at 
https://github.com/w3c/svgwg/issues/235 using your GitHub account

Received on Friday, 12 August 2016 23:26:20 UTC