W3C home > Mailing lists > Public > whatwg@whatwg.org > January 2013

Re: [whatwg] Adding winding rules to Canvas

From: Rik Cabanier <cabanier@gmail.com>
Date: Thu, 17 Jan 2013 15:04:19 -0800
Message-ID: <CAGN7qDBqmACF19X7JcNHfGtB+NUYW-=gfFxqFU1B4x7MdaoqHA@mail.gmail.com>
To: public-canvas-api@w3.org, whatwg@whatwg.org
Cc: Dirk Schulze <dschulze@adobe.com>, schneider@jancona.com
All,

so after talking to Dirk, maybe it's better to rename the classes so Path
is the one that has the geometry and StyledPath contains the region.
Prototype IDL:

[Constructor,

Constructor(path), // creates a copy

Constructor(DOMString)] //takes SVG path syntax

interface Path {
};
Path implements CanvasPathMethods;

[Constructor,
Constructor(Path, CanvasWindingRule = "nonzero"), // creates a copy of path
Constructor(DomString text, CanvasDrawingSTyles, SVGMatrix?, unrestricted
double , unrestricted double , optional unrestricted double)]

interface StyledPath {

StyledPath Transform(matrix); // returns a transformed path
StyledPath Stroke(CanvasDrawingStyles); // returns a stroked path
StyledPath Add(StyledPath); // returns a path that is the union of the 2
paths

boolean isPointInPath(unrestricted double x, unrestricted double y);

};

interface CanvasRenderingContext2D {

....
void Fill(StyledPath);

}

dictionary HitRegionOptions {

StyledPath? path = null;
....

}



Any comments?

On Tue, 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}));
>
>
>
> 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:
>>
>>    1. HitRegions only ever use winding paths. This seems like a bad idea.
>>    2. 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.
>>    3. 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 Thursday, 17 January 2013 23:04:44 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 30 January 2013 18:48:12 GMT