Re: Adding winding rules to Canvas

On Tue, Jan 15, 2013 at 2:14 PM, Dirk Schulze <dschulze@adobe.com> wrote:

>
> 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.


I believe that will make the Canvas API more complex.
In addition to 'fill(optional CanvasWindingRule w = "nonzero")' and
'fill(Path)' we would also have to add 'fill(PathSink, optional
CanvasWindingRule w = "nonzero")'

If a user was just interested in the path, they could make one at fill time:

fill(new Path(mypathsink))


One of the big advantage of having an atomic path is that UA's can optimize
it in the background (ie tesselate it or resolve the winding).


> 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.


Sure, I'm neutral on the naming convention.


>


> >
> >
> > 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:53:34 UTC