Re: Adding winding rules to Canvas

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:46 UTC