[motion-1] On path syntax

Copying this to www-svg because it is relevant for SVG in general as well
as FX.  Previous relevant discussion:

   - "On path syntax" from public-fx, starting with Shane Stephen's
   questions here:
   https://lists.w3.org/Archives/Public/public-fx/2016JanMar/0023.html
   - "SVG-ACTION-3834: Ask csswg if disallowing fill rule in path() for d
   is good" Comments by Dirk Schulze in response to the action notification on
   the internal SVG WG list:
   https://lists.w3.org/Archives/Public/public-svg-wg/2016JanMar/0006.html
   - "Topic: initial value of 'd' property" at the Sydney Face to Face, 4
   February 2016 Sydney time, starting 23:18 GMT on the IRC log:
   https://www.w3.org/2016/02/03-svg-irc.html#T23-18-02

To summarize those messages and discussion:

*The working group has agreed that the `d` attribute for <path> will be
specifiable with CSS in SVG 2.* (In other words, like other geometry
attributes, it is being upgraded to a presentation attribute.) This is
important because it allows non-SMIL declarative animation of shape
morphing, using CSS animation syntax.  Declarative animation is important
because it means it can run in HTML-as-img. Non-SMIL is important because
key user agents have failed to support and/or made plans to remove support
for SMIL.  I'm not going to get into the same arguments again about whether
or not that's a good thing, I'm just stating it as a reality we are working
within.

Multiple CSS modules have already adopted a means of specifying shapes with
a function notation: circle(), ellipse(), inset(), and polygon() were all
defined in CSS Shapes 1 (for creating non-rectangular floats) and are also
used in the clip-path property as defined in CSS Masking 1. A path()
function has been added to that list for CSS Motion Path and would also be
used in the other properties that accept a shapes function.  The shape of
the path would be defined using a path-data string, inside the functional
notation, that follows the accepted SVG syntax (and any future extensions
to it).

*The CSS shapes functions create a complete definition of geometry,
including the fill-rule* for defining which parts of a polygon or path are
"inside" or "outside" the shape.  This is required for that shape to be
used as a clip-path or a container for text (shape-inside property in CSS
Shapes 2).  The fill-rule is specified by an optional first parameter
inside the functional notation, like polygon(evenodd, [list-of-points]) or
path(nonzero, [path-data-string]).

Shane and Cameron have proposed that the functional notation for defining a
path be used for the `d` attribute when set with CSS.  However, the
fill-rule for that path element would still be controlled by the separate
fill-rule property.  Shane initially suggested that we could just drop the
fill-rule parameter from the path() function, but that would cause problems
for the other properties that use shape functions.

*Their current proposal is to define a separate path function syntax, with
only the path data and no fill-rule*, that would represent a different CSS
data type from the CSS shapes functions used by clip-path and
shape-inside.  Each CSS property would define whether it accepted the full
CSS shapes function (with fill-rule) or merely the path outline function
(no fill-rule allowed).  Both would still use path(), however, and this
causes possible concerns with the general CSS approach to functional
notation.  Shane took an action (ACTION-3834) to follow up with the CSS WG.

Alternatives that have been discussed:

   - Just use the plain path data string, like path.triangle {d: M10,0 L0,5
   10,10 Z;}
   This is very problematic from the perspective of CSS parsing, since the
   CSS parser would need to tokenize & determine the validity of the entire
   path data string in its initial scan. (And we all know path data strings
   can get very long and complex.)
   - Use the plain path data string as a quoted string in CSS, like
   path.triangle {d: "M10,0 L0,5 10,10 Z";}
   I honestly don't think I got a clear answer as to why this would be
   bad.  However, it would mean that the CSS parser would not do any validity
   testing on the contents of the string: the value, as far as the CSS
   parser is concerned, would just be "any string".  In future when new path
   data commands are introduced (like the bearing command or smooth spline
   curve command), you would not be able to use @supports or normal CSS error
   handling to define fallbacks.  Instead, the existing error handling rules
   (for partially unrecognized path data) would apply.
   - Use the CSS shapes functional notation, with optional fill-rule, but
   ignore it if specified for the `d` property.
   This creates a logical conflict if authors are allowed to specify a
   fill-rule value but it has no effect.
   - Use the CSS shapes functional notation, with optional fill-rule, and
   let that fill-rule override the fill-rule property.
   This makes utter chaos of how the CSS cascade and shorthand properties
   works, and would be basically impossible to implement.
   - (Not yet discussed, but might as well add it here) use 2
   different functional notations, with different names, one to describe
   path outline versus one used to describe a complete shape, like
   path.triangle.clipped {
     d:             d("M10,0 L0,5 10,10 Z");
     clip-path: path("M2,2 L2,8 8,5Z");
   }
   This makes things easy from a CSS data types/parsing perspective: each
   function has a clear and distinct data type it returns, and each property
   has a clear and distinct data type that it accepts.  But, it means that
   authors would have to remember which property took which type of path
   function.

Some other aspects that have been briefly discussed:

   - If a path function notation is used for `d` in CSS, should that also
   be allowed in the `d` attribute?  (The existing notation would of course
   continue to be supported in the attribute.)  Does this cause parsing
   problems?
   - If the `d` attribute accepts a standard or modified CSS shapes
   function, should it also accept the other shapes functions, such as
   polygon(), circle() or ellipse()?


I think that covers most of the main arguments & issues.

~Amelia

Received on Thursday, 4 February 2016 22:50:33 UTC