jarek-foksa/path-data-polyfill

First path's M should ideally be parsed as absolute (uppercase) command type

Closed this issue · 5 comments

Dear Jarek Foksa,

not exactly an issue, but an idea to facilitate path concatenations.

getPathData() flawlessly normalizes m commands introducing following relative l linetos (as well as a plethora of other shorthands...):

m 20 0 10 0 0 10 -10 0z

Unfortunately a lot of svg optimizers tend to output starting M commands in lower case while converting path data to relative.
Not a big deal – however, it would be great if path-data-polyfill would also sanitize this.

So it might be better to force the very first M command to be absolute(uppercase.

I've expanded on this here: Is there a way to merge two path elements (svg) using Javascript?

Codepen example
This example just overrides the first command by pathData[0].type='M';

This proposal seems to be against the spec. path.getPathData() should be only expanding the shorthand notation. Actual normalization should be performed only when you use path.getPathData({normalize: true}).

If the specification intended to retain repeated relative commands like so:

m 20 0 10 0 0 10 -10 0z

{ type:'m', values:[20, 0, 10, 0, 0, 10, -10, 0] }
it would make perfect sense.

My point is:
since getPathData() already includes a lot of sanitizing – most importantly "decomposing" repeated relative commands to somthing like this:

{ type:'m', values:[20, 0] },  
{ type:'l', values:[10, 0 ] },  
{ type:'l', values:[0, 10] },  
{ type:'l', values:[-10, 0] }

The relative/lowercase m command type letter becomes obsolete – no preceding points, no succeeding relative context depending on the lowercase command type.
Due to the aforementioned sanitizing, the lowercase m type is not only unnecessary but in fact wrong, since the first mcommand's coordinates are always absolute , hence it should use an uppercase notation.

Still seeing forward to a wide adoption of this svg draft.
But since the main purpose of this "new" (... one fine day) API method is to facilitate parsing for svg processing tasks, it should return the most accurate path data.

Unnecessary starting m commands are just as ... non ideal for a pathData array as 00.5.5.5 values.

Thanks your your excellent futurefill!

A path starting with an "m" command is not wrong as per the SVG 2 spec, it is just interpreted differently:

If a relative moveto (m) appears as the first element of the path, then it is treated as a pair of absolute coordinates. In this case, subsequent pairs of coordinates are treated as relative even though the initial moveto is interpreted as an absolute moveto. (link)

In my opinion getPathData() should not perform segment type conversion or removal of redundant/unnecessary segments unless this behavior is clearly stated in the spec.

I apologize for the late response – you can close this issue.

Of course, you're right – it's not wrong by means of invalid or against the specs.

My point:

  • the proposed command conversion (for the first M in a path ) would also be perfectly valid and spec compliant.
  • "getPathData() should not perform segment type conversion" – I totally agree! But honestly, I'd call the aforementioned (and perfectly sensible) " repeated shorthands" sanitizing – adding l commands – also as a kind of segment conversion.

However, it's not a big deal, and the solution for pathData concatenations is also quite simple.
It's just slightly annoying, to see "optimized" pathdata retrieved by API driven (all to relative) optimizers – introducing unnecessary m commands that screw up further processing steps like path concatenation.

Honestly, just hope we'll see getPathData() natively supported by major browsers some fine day – and implemented remotely as stable as your polyfill ;)

I'd call the aforementioned (and perfectly sensible) " repeated shorthands" sanitizing – adding l commands – also as a kind of segment conversion.

From my understanding of the spec there are no segments added or converted when parsing something like "m 0 0 l 10 10 20 20 30 30". The "l" commands are already there - they are just implicit rather than explicit.

If you believe the current behavior should be changed, please ask the SVG WG to add the necessary clarifications in the SVG 2 draft.