Re: Adding winding rules to Canvas

On Jan 15, 2013, at 1:49 PM, Rik Cabanier <cabanier@gmail.com> wrote:

> Hi Simon,
> 
> I completely agree with you.
> As specified today, hit regions don't have support for winding. In fact, it is even worse: if you have a set of drawing commands, you can't get their region.
> The reason for this is that the path object (as currently defined) simply accumulates path segments. This will wreak havoc with shapes that touch or that have strokes.
> 
> I have stated this a couple of times already on whatwg...
> What I would like to see is more like this:
> class PathSink implements CanvasPathMethods {
>   PathSink();
>   PathSink(DOMString); //takes SVG path syntax
> }
> 
> class Path {
>   Path();
>   Path(PathSink, CanvasWindingRule = "nonzero");
>   Path(DomString text, CanvasDrawingSTyles...); // to get text outline
> 
>   Path Transform(matrix Transformation);
>   Path Stroke(...);
> 
>   Path Add(Path); // <----
> }
> 
> The 'Add' method would not simply aggregate path segments. Instead, the area of resulting path will be a union.
> 
> So, for example, if you want to create a region with a stroke rectangle:
> var h = new PathSink();
> h.rect(100, 100, 200, 200);
> var P = new Path(h);
> P = P.Add(P.Stroke({'lineWidth': 10}));

I see a problem where the concept of PathSink and Path could be confusing for users. I am pretty sure that a lot of users just want to use the Path object as some kind of segment container. The proposed Path object here does more then these users would need and may make it more complicated. But it depends on how it is specified. I could imagine how you can archive both, the here mentioned PathSink would be the simple container as specified in the WHAT WG spec now (maybe even less). Just a container with all segments. A context would be able to take this container and fill and stroke with the style applied to the the context. But I would prefer naming this container Path, since it still is exactly that. The object with the actually path data, with winding rules and styling data could be called StyledPath. It would take a Path object, represent a stroke path and a lot of other things more.

Greetings,
Dirk

> 
> 
> On Tue, Jan 15, 2013 at 1:23 PM, Simon Sarris <simon.sarris@gmail.com> wrote:
> Before we comment on your proposal I have some notes I'd like to share because the current fillRule rules in the specification seem incomplete or at least ill-defined.
> 
> The new hit regions use a Path in the HitRegionOptions (the argument to addHitRegion) in order to function, but its not clear what fill rule these Path objects are using for hit-testing. Even-odd and winding fill rules create different holes in a path, so it matters a good deal for hit testing.
> 
> There seem to be three possibilities as implemented:
> 	• HitRegions only ever use winding paths. This seems like a bad idea.
> 	• Whichever fillRule is defined when context.addHitRegion is called determines the fillRule for that hit region's Path permanently. This seems acceptable but confusing and should be clarified if it is currently the case.
> 	• The fillRule of a hit region changes dynamically as context.fillRule changes. This would be a nightmare.
> 
> I hope it is #2, but the specification makes no mention of this.
> 
> Actually, I'd prefer that either HitRegionOptions or the Path object would need to have a fillRule attribute.
> 
> If the specification does adopt something similar to Cabanier's suggestions then that would need to be done anyway.
> 
> In short, if isPointInPath is changed to specify fillRule, HitRegionOptions (the argument to addHitRegion) or the Path given in the options needs to change too.
> 
> 
> Simon Sarris
> 
> 
> On Tue, Jan 15, 2013 at 3:42 PM, Rik Cabanier <cabanier@gmail.com> wrote:
> All,
> 
> there was a recent discussion on adding winding rules to canvas. As you may know until now, canvas only supported even-odd winding.
> Maybe graphics libraries and SVG also support non-zero winding.[1][2]
> 
> Mozilla exposes this currently with 'mozFillRule'. Making this part of the graphics state has several drawbacks.
> The biggest is that fill/clip will now have to check the state every time, or set/reset it. Winding is also part of path geometry.
> 
> I have the following proposal: 
> enum CanvasWindingRule { "nonzero", "evenodd" };
> void fill(optional CanvasWindingRule w = "nonzero");
> void clip(optional CanvasWindingRule w = "nonzero");
> boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule w = "nonzero");
> 
> proposed patches for this API can be found here:
> https://bugs.webkit.org/show_bug.cgi?id=105508
> https://bugzilla.mozilla.org/show_bug.cgi?id=827053
> 
> What do people think?
> 
> 1: http://www.w3.org/TR/SVG/painting.html#FillRuleProperty
> 2: http://en.wikipedia.org/wiki/Nonzero-rule
> 
> 

Received on Tuesday, 15 January 2013 22:15:00 UTC