Re: [svgwg] Rect decomposition is invalid (#753)

I see, I understand better what you meant in your previous post by "As that likewise prevents the additional marker as well". I wasn't very familiar with markers, and just looked at the [spec](https://svgwg.org/svg2-draft/painting.html#Markers). There may be use cases and context I'm missing, but at first read of the spec for markers, all I can think is "wow, such a bad design". The issues you're highlighting here are a direct consequence of the bad design of markers, and would be non-issues if markers were better designed. In other words, the issue isn't really about closed paths themselves (IMHO, the design of closed paths is nice, especially with segment-completing Z operations), but how markers are mandated to behave with closed paths, which is inconsistent with general rules on how closed paths should be rendered.

Let's take a step back from the spec, and look at the starting point of this thread: the `rect` element. I think that if someone authors the following SVG, the intent is quite clear:

```
<rect x="0" y="0" width="100" height="100" style="marker-mid: url(#markerCircle);"/>
```

You'd want exactly one marker at each corner, so four markers in total:

![image](https://user-images.githubusercontent.com/4809739/69481286-5534a300-0e10-11ea-9a74-f9ed667cbbd6.png)


Indeed, why would one of the four corners behave differently from the others? Conceptually (that is, ignoring SVG for a moment), a rectangle doesn't "start" or "end" in any particular place. It is a closed shape with no start or end. So no `marker-start` or `marker-end` should be rendered, and one `marker-mid` should be rendered at each corner. This would be consistent with how rectangles (and more generally, closed paths) are rendered: each corner is rendered with `stroke-linejoin`, not `stroke-linecap`, as it should. No corner should be special. 

In other words, in a SVG closed path, the fact that one vertex must be arbitrarily chosen to be "the first" is merely an implementation detail, a limitation of how data is sequentially stored in a computer. The behavior of closed paths **should** be completely invariant to which vertex is chosen to be the first. That is, the SVG spec **should** be designed in such a way that these two paths are rendered and behave completely equivalently (aside from the translation):

```
<path transform="translate(20,20)"  d="M 100,100 L 200,100 L 200,200 Z" />
<path transform="translate(140,20)" d="M 200,100 L 200,200 L 100,100 Z" />
```

This is true for rendering: the spec mandates that all 3 corners of each path is rendered with `stroke-linejoin`. However, this is not true for markers: the spec mandates that a `mid-marker` is only placed at `200,100` and `200,200` for the first path, and `200,200` and `100,100` for the second. This is a serious design flaw of the spec, IMHO.

What the spec says, and what Chrome, Firefox, and Inkscape do:

![image](https://user-images.githubusercontent.com/4809739/69481567-bb222a00-0e12-11ea-8260-8bcea3a7995d.png)

What the spec **should** say, in my opinion:

![image](https://user-images.githubusercontent.com/4809739/69481511-3cc58800-0e12-11ea-8195-77117c321b85.png)

Here is the full SVG file which I used for testing:

```
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="300" version="1.1">
   <defs>
    <marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5">
        <circle cx="5" cy="5" r="3" fill-opacity=".25" style="stroke: none; fill:#000000"/>
    </marker>
</defs>
<style>
    path { stroke: #6666ff; stroke-width: 1px; fill: none; marker-mid: url(#markerCircle); }
</style>
<path transform="translate(20,20)"  d="M 100,100 L 200,100 L 200,200 Z" />
<path transform="translate(140,20)" d="M 200,100 L 200,200 L 100,100 Z" />
</svg>
```

Now, how about the `rect` element in particular? Well, honestly, like you, I'm not quite sure what the spec actually mandates in this case. As I said at the beginning of this post, what I think it **should** mandate is four mid-markers. But since the spec unambiguously mandates three mid-markers for `<path d="M 0,0 H 100 V 100 H 0 Z">`, and since the spec also seems to favor using segment-completing Z operations for the "equivalent paths" of basic shapes (rect, etc.), then it looks like the spec is saying that there should only be three mid-markers in a `rect` element.

In practice, with the following:

```
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="200" version="1.1">
   <defs>
    <marker id="markerCircle" markerWidth="8" markerHeight="8" refX="5" refY="5">
        <circle cx="5" cy="5" r="3" fill-opacity=".25" style="stroke: none; fill:#000000"/>
    </marker>
</defs>
<style>
    path, rect { stroke: #6666ff; stroke-width: 1px; fill: none; marker-mid: url(#markerCircle); }
</style>
<path  transform="translate(20,20)" d="M 0,0 H 100 V 100 H 0 z" />
<path transform="translate(140,20)" d="M 0,0 H 100 V 100 H 0 V 0 z" />
<rect transform="translate(260,20)" x="0" y="0" width="100" height="100" />
</svg>
```

Chrome and Firefox do this (they're quite confused about the rect...):

![image](https://user-images.githubusercontent.com/4809739/69480943-91fe9b00-0e0c-11ea-9977-c457e0556ff1.png)

Inkscape does this:

![image](https://user-images.githubusercontent.com/4809739/69480976-13eec400-0e0d-11ea-9977-416c94b87ce5.png)

My interpretation of the current spec is:

![image](https://user-images.githubusercontent.com/4809739/69482193-5ec20900-0e18-11ea-923c-a58b31aed795.png)

And what, in my opinion, the spec **should** mandate is: (that is, if markers where better designed, and if we have segment-completing Z operations for all drawto operations)

![image](https://user-images.githubusercontent.com/4809739/69481054-fa01b100-0e0d-11ea-82d5-f8df27da5840.png)


-- 
GitHub Notification of comment by dalboris
Please view or discuss this issue at https://github.com/w3c/svgwg/issues/753#issuecomment-557813533 using your GitHub account

Received on Saturday, 23 November 2019 16:47:26 UTC