Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Boris Zbarsky

On 1/9/13 6:56 PM, James Ascroft-Leigh wrote:

How can the presence of the winding rule parameter of the fill() and clip()
operations be detected by client code?


This is a case where .length including optional arguments would have 
been useful.  :(


That said, you can detect this via hacks like this, I expect:

  var ruleArgSupported = false;
  try {
ctx.fill({ defaultValue: function() { ruleArgSupported = true; 
return false; } });

  } catch (e) {
// Really shouldn't happen, but who knows
  }

-Boris


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Rik Cabanier
On Wed, Jan 9, 2013 at 3:56 PM, James Ascroft-Leigh  wrote:

> Hi,
>
> Thanks Rik for your counter proposal and thanks everyone for helping to
> refine it.  I am in full agreement that an evenodd or nonzero argument to
> the fill() and clip() operations is better than a state property.  The only
> thing I can think of in favor of the fillRule property that prompted this
> discussion is for client code to discover whether the feature is
> implemented.
>
> pdf.js seems like a great example of a need for this.  They are going to
> need to check whether the fill() operation supports setting the winding
> rule and fall back to the mozFillRule property if not.  Some website might
> need to detect that neither feature is present and fall back to server-side
> rendering.
>
> How can the presence of the winding rule parameter of the fill() and
> clip() operations be detected by client code?  Perhaps I missed something
> in the discussion.
>

We did not discuss it. You can use 'isPointInPath' with the 'evenOdd'
parameter to see if it's being honored.


>
> Regards,
>
> James
>
> P.S. Looks like I might not get my first patch into WebKit as I had hoped.
> I am still happy to help out coding some of this and writing up test cases
> so please let me know if there is something you think I can contribute.
>

Do you want to take over my patch?


>
>
> On 9 January 2013 21:20, Rik Cabanier  wrote:
>
>> Thanks for your feedback!
>> Based on this, I propose the following:
>> 1. create an enum for the winding rule:
>>
>> enum CanvasWindingRule { "nonzero
>> <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
>> >",
>> "evenodd <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-evenodd
>> >"
>>
>> };
>>
>> Since this enum will likely be used by the path syntax (and possibly SVG),
>> maybe we can leave the 'Canvas' portion off
>> 2. extend fill:
>>
>> void fill <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fill
>> >(optional
>> CanvasWindingRule w = "nonzero
>> <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
>> >");
>>
>> 3. extend clip:
>>
>> void c <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fill
>> >lip(optional
>> CanvasWindingRule w = "nonzero
>> <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
>> >");
>>
>>
>> 4. extend isPointInPath:
>>
>> boolean isPointInPath
>> <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-ispointinpath
>> >(unrestricted
>>
>> double x, unrestricted double y, optional CanvasWindingRule w =
>> "nonzero <
>> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
>> >");
>>
>>
>>
>> Rik
>>
>> On Wed, Jan 9, 2013 at 11:59 AM, Tab Atkins Jr. > >wrote:
>>
>> > On Wed, Jan 9, 2013 at 11:42 AM, Rik Cabanier 
>> wrote:
>> > > Do people have an opinion on a boolean value vs an enum?
>> > > A boolean value is slightly faster to execute and type while an enum
>> is
>> > > more descriptive.
>> > >
>> > > So far, canvas has not used enum values before.
>> >
>> > I strongly prefer enums for cases where it's not a simple yes/no, and
>> > this clearly qualifies.
>> >
>> > (I also prefer enums generally even when this is true, but that's my
>> > CSS experience talking, where we have a history of changing things
>> > that were once booleans into multi-state when people ask for more
>> > features later.)
>> >
>> > ~TJ
>> >
>>
>
>


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread James Ascroft-Leigh
Hi,

Thanks Rik for your counter proposal and thanks everyone for helping to
refine it.  I am in full agreement that an evenodd or nonzero argument to
the fill() and clip() operations is better than a state property.  The only
thing I can think of in favor of the fillRule property that prompted this
discussion is for client code to discover whether the feature is
implemented.

pdf.js seems like a great example of a need for this.  They are going to
need to check whether the fill() operation supports setting the winding
rule and fall back to the mozFillRule property if not.  Some website might
need to detect that neither feature is present and fall back to server-side
rendering.

How can the presence of the winding rule parameter of the fill() and clip()
operations be detected by client code?  Perhaps I missed something in the
discussion.

Regards,

James

P.S. Looks like I might not get my first patch into WebKit as I had hoped.
I am still happy to help out coding some of this and writing up test cases
so please let me know if there is something you think I can contribute.


On 9 January 2013 21:20, Rik Cabanier  wrote:

> Thanks for your feedback!
> Based on this, I propose the following:
> 1. create an enum for the winding rule:
>
> enum CanvasWindingRule { "nonzero
> <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
> >",
> "evenodd <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-evenodd
> >"
> };
>
> Since this enum will likely be used by the path syntax (and possibly SVG),
> maybe we can leave the 'Canvas' portion off
> 2. extend fill:
>
> void fill <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fill
> >(optional
> CanvasWindingRule w = "nonzero
> <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
> >");
>
> 3. extend clip:
>
> void c <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fill
> >lip(optional
> CanvasWindingRule w = "nonzero
> <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
> >");
>
> 4. extend isPointInPath:
>
> boolean isPointInPath
> <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-ispointinpath
> >(unrestricted
> double x, unrestricted double y, optional CanvasWindingRule w =
> "nonzero <
> http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-fillrule-nonzero
> >");
>
>
> Rik
>
> On Wed, Jan 9, 2013 at 11:59 AM, Tab Atkins Jr.  >wrote:
>
> > On Wed, Jan 9, 2013 at 11:42 AM, Rik Cabanier 
> wrote:
> > > Do people have an opinion on a boolean value vs an enum?
> > > A boolean value is slightly faster to execute and type while an enum is
> > > more descriptive.
> > >
> > > So far, canvas has not used enum values before.
> >
> > I strongly prefer enums for cases where it's not a simple yes/no, and
> > this clearly qualifies.
> >
> > (I also prefer enums generally even when this is true, but that's my
> > CSS experience talking, where we have a history of changing things
> > that were once booleans into multi-state when people ask for more
> > features later.)
> >
> > ~TJ
> >
>


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Rik Cabanier
Thanks for your feedback!
Based on this, I propose the following:
1. create an enum for the winding rule:

enum CanvasWindingRule { "nonzero
",
"evenodd 
"
};

Since this enum will likely be used by the path syntax (and possibly SVG),
maybe we can leave the 'Canvas' portion off
2. extend fill:

void fill 
(optional
CanvasWindingRule w = "nonzero
");

3. extend clip:

void c 
lip(optional
CanvasWindingRule w = "nonzero
");

4. extend isPointInPath:

boolean isPointInPath
(unrestricted
double x, unrestricted double y, optional CanvasWindingRule w =
"nonzero 
");


Rik

On Wed, Jan 9, 2013 at 11:59 AM, Tab Atkins Jr. wrote:

> On Wed, Jan 9, 2013 at 11:42 AM, Rik Cabanier  wrote:
> > Do people have an opinion on a boolean value vs an enum?
> > A boolean value is slightly faster to execute and type while an enum is
> > more descriptive.
> >
> > So far, canvas has not used enum values before.
>
> I strongly prefer enums for cases where it's not a simple yes/no, and
> this clearly qualifies.
>
> (I also prefer enums generally even when this is true, but that's my
> CSS experience talking, where we have a history of changing things
> that were once booleans into multi-state when people ask for more
> features later.)
>
> ~TJ
>


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Tab Atkins Jr.
On Wed, Jan 9, 2013 at 11:42 AM, Rik Cabanier  wrote:
> Do people have an opinion on a boolean value vs an enum?
> A boolean value is slightly faster to execute and type while an enum is
> more descriptive.
>
> So far, canvas has not used enum values before.

I strongly prefer enums for cases where it's not a simple yes/no, and
this clearly qualifies.

(I also prefer enums generally even when this is true, but that's my
CSS experience talking, where we have a history of changing things
that were once booleans into multi-state when people ask for more
features later.)

~TJ


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Dirk Schulze


On Jan 9, 2013, at 11:42 AM, "Rik Cabanier" 
mailto:caban...@gmail.com>> wrote:



On Wed, Jan 9, 2013 at 10:27 AM, Dean Jackson 
mailto:d...@apple.com>> wrote:

On 09/01/2013, at 4:08 PM, Dirk Schulze 
mailto:dschu...@adobe.com>> wrote:

>
> On Jan 8, 2013, at 9:35 AM, Rik Cabanier 
> mailto:caban...@gmail.com>> wrote:
>
>> I looked at pdf2js which is using this fillRule property. As I expected, 
>> introduction of the property results in code like this:
>>eoFill: function CanvasGraphics_eoFill() {
>>  var savedFillRule = this.setEOFillRule();
>>  this.fill();
>>  this.restoreFillRule(savedFillRule);
>>},
>> ...
>>// We generally keep the canvas context set for
>>// nonzero-winding, and just set evenodd for the operations
>>// that need them.
>>setEOFillRule: function CanvasGraphics_setEOFillRule() {
>>  var savedFillRule = this.ctx.mozFillRule;
>>  this.ctx.mozFillRule = 'evenodd';
>>  return savedFillRule;
>>},
>>restoreFillRule: function CanvasGraphics_restoreFillRule(rule) {
>>  this.ctx.mozFillRule = rule;
>>},
>>
>> So, for even odd winding, all this code needs to run. With my proposal, this 
>> gets much simpler:
>>   eoFill: function CanvasGraphics_eoFill() {
>>  this.eoFill();
>>},
>>
>> You can find a pull request with the needed changes to pdf2js here:
>> https://github.com/cabanier/pdf.js/commit/8e80b086376013a5438087714a4d2abb6fe67de1
>
> For PDF.js it would probably be easier to set the fillRule every time right 
> before a fill or clip operation, then checking and storing the fill rule in 
> the background. This would reduce the code a lot more.
>
>>
>> I also created patches (with test files) for WebKit and mozilla:
>> https://bugs.webkit.org/show_bug.cgi?id=106188
>> https://bugzilla.mozilla.org/show_bug.cgi?id=827053
>
> I looked at the patch for webkit. There are two parts where I would disagree 
> and that are potentially confusing.
>
>   eoFill(), eoClip()
>
> It is not obvious what these functions do and how they are different to 
> fill() and clip(). The name should be clear about the usage. But I don't 
> think that introducing two new functions to the Canvas API is a lot better 
> either. An alternative proposal instead of new functions or attributes could 
> be an optional argument for the fill() and stroke() functions. This argument 
> would be an enumeration of 'nonzero' and 'evenodd'.
>
>   ctx.fill(); // fill with 'nonzero'
>   ctx.fill('nonzero') // fill with 'nonzero' as well
>   ctx.fill('evenodd') // fill with winding rule 'evenodd'

I prefer this approach over new methods.

In general, I tend to agree with Rik that winding rule is a geometric 
operation, rather than a context style. It's a shame that this may introduce 
inconsistency (I appreciate Ian's point on that).

Thanks Dean!

Do people have an opinion on a boolean value vs an enum?
A boolean value is slightly faster to execute and type while an enum is more 
descriptive.

So far, canvas has not used enum values before.

I definitely agree that an enum is more descriptive. I would not necessary 
expect that EO is used a lot anyway. A Boolean on the other side can also be 
easier to handle for authors. But how would we decide if 'false' stands for 
even odd or nonzero? How can it be done so that it is easy to remember for 
authors which Boolean to use for which fill rule?

Greetings
Dirk





>
> The boolean argument in isPointInPath seems not to be very descriptive as 
> well:
>
>   boolean isPointInPath(unrestricted double x, unrestricted double y, 
> boolean windingRule);
>
> It is not obvious if 'true' means 'nonzero' or 'evenodd'. I would recommend 
> to use an optional enumeration here, with the default value 'nonzero'.
>
> You mentioned that the winding rule should be a part of the Path object. I 
> can see the use case that you want to address with it. And things like a 
> union path of two path object with different winding rules (as you suggested 
> before) is possible, as long as the union path just needs to get drawn (can 
> be done with compositing or masking in the implementation). But the SVG WG 
> would like to use the Path object as a way to share path data between Canvas 
> and SVG. In this case, the implementation must be able to flatten a path and 
> provide the path data directly. This is beyond the capability of current 
> graphic libraries and requires third party planarizer. This needs to be 
> considered before adding this functionality to the Path API.
>
> Greetings,
> Dirk
>
>>
>> On Thu, Jan 3, 2013 at 3:38 PM, Ian Hickson 
>> mailto:i...@hixie.ch>> wrote:
>> On Fri, 10 Jun 2011, Chris Jones wrote:
>>>
>>> In 2D canvas, determining whether a point is "inside" a path is
>>> currently always done using the non-zero winding rule.  I propose
>>> extending 2D canvas to allow determining inside-ness using the even-odd
>>> rule.
>>
>> I've added this to the spec.
>>
>>
>> On Wed, 2 Jan 2013, Dirk Schul

Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Rik Cabanier
On Wed, Jan 9, 2013 at 10:27 AM, Dean Jackson  wrote:

>
> On 09/01/2013, at 4:08 PM, Dirk Schulze  wrote:
>
> >
> > On Jan 8, 2013, at 9:35 AM, Rik Cabanier  wrote:
> >
> >> I looked at pdf2js which is using this fillRule property. As I
> expected, introduction of the property results in code like this:
> >>eoFill: function CanvasGraphics_eoFill() {
> >>  var savedFillRule = this.setEOFillRule();
> >>  this.fill();
> >>  this.restoreFillRule(savedFillRule);
> >>},
> >> ...
> >>// We generally keep the canvas context set for
> >>// nonzero-winding, and just set evenodd for the operations
> >>// that need them.
> >>setEOFillRule: function CanvasGraphics_setEOFillRule() {
> >>  var savedFillRule = this.ctx.mozFillRule;
> >>  this.ctx.mozFillRule = 'evenodd';
> >>  return savedFillRule;
> >>},
> >>restoreFillRule: function CanvasGraphics_restoreFillRule(rule) {
> >>  this.ctx.mozFillRule = rule;
> >>},
> >>
> >> So, for even odd winding, all this code needs to run. With my proposal,
> this gets much simpler:
> >>   eoFill: function CanvasGraphics_eoFill() {
> >>  this.eoFill();
> >>},
> >>
> >> You can find a pull request with the needed changes to pdf2js here:
> >>
> https://github.com/cabanier/pdf.js/commit/8e80b086376013a5438087714a4d2abb6fe67de1
> >
> > For PDF.js it would probably be easier to set the fillRule every time
> right before a fill or clip operation, then checking and storing the fill
> rule in the background. This would reduce the code a lot more.
> >
> >>
> >> I also created patches (with test files) for WebKit and mozilla:
> >> https://bugs.webkit.org/show_bug.cgi?id=106188
> >> https://bugzilla.mozilla.org/show_bug.cgi?id=827053
> >
> > I looked at the patch for webkit. There are two parts where I would
> disagree and that are potentially confusing.
> >
> >   eoFill(), eoClip()
> >
> > It is not obvious what these functions do and how they are different to
> fill() and clip(). The name should be clear about the usage. But I don't
> think that introducing two new functions to the Canvas API is a lot better
> either. An alternative proposal instead of new functions or attributes
> could be an optional argument for the fill() and stroke() functions. This
> argument would be an enumeration of 'nonzero' and 'evenodd'.
> >
> >   ctx.fill(); // fill with 'nonzero'
> >   ctx.fill('nonzero') // fill with 'nonzero' as well
> >   ctx.fill('evenodd') // fill with winding rule 'evenodd'
>
> I prefer this approach over new methods.
>
> In general, I tend to agree with Rik that winding rule is a geometric
> operation, rather than a context style. It's a shame that this may
> introduce inconsistency (I appreciate Ian's point on that).


Thanks Dean!

Do people have an opinion on a boolean value vs an enum?
A boolean value is slightly faster to execute and type while an enum is
more descriptive.

So far, canvas has not used enum values before.


>
>
>
> >
> > The boolean argument in isPointInPath seems not to be very descriptive
> as well:
> >
> >   boolean isPointInPath(unrestricted double x, unrestricted double
> y, boolean windingRule);
> >
> > It is not obvious if 'true' means 'nonzero' or 'evenodd'. I would
> recommend to use an optional enumeration here, with the default value
> 'nonzero'.
> >
> > You mentioned that the winding rule should be a part of the Path object.
> I can see the use case that you want to address with it. And things like a
> union path of two path object with different winding rules (as you
> suggested before) is possible, as long as the union path just needs to get
> drawn (can be done with compositing or masking in the implementation). But
> the SVG WG would like to use the Path object as a way to share path data
> between Canvas and SVG. In this case, the implementation must be able to
> flatten a path and provide the path data directly. This is beyond the
> capability of current graphic libraries and requires third party
> planarizer. This needs to be considered before adding this functionality to
> the Path API.
> >
> > Greetings,
> > Dirk
> >
> >>
> >> On Thu, Jan 3, 2013 at 3:38 PM, Ian Hickson  wrote:
> >> On Fri, 10 Jun 2011, Chris Jones wrote:
> >>>
> >>> In 2D canvas, determining whether a point is "inside" a path is
> >>> currently always done using the non-zero winding rule.  I propose
> >>> extending 2D canvas to allow determining inside-ness using the even-odd
> >>> rule.
> >>
> >> I've added this to the spec.
> >>
> >>
> >> On Wed, 2 Jan 2013, Dirk Schulze wrote:
> >>>
> >>> There was a complain on the webkit bug report if fillRule should be
> part
> >>> of the graphics state or not. Did you investigate what current 2d
> >>> graphics libraries do (qt, Cairo, CG, ...)? Is it part of the graphics
> >>> state there?
> >>
> >> I have made it be part of the graphics state in the spec; it would be
> >> unusual in the API for it not to be. However, if this doesn't match
> >> impl

Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Rik Cabanier
Thanks for investigating this!
I opened a moderately complex file [1] and it had 19200 fills. The overhead
in ms then becomes
 enumboolean
Firefox  .5 .25
Safari.9 .6
Chrome 1.1   8
Opera3 1.6

This is assuming that the extra parsing time and validation on the c++ side
take no time.
A quick search on the web shows that mobile browsers are about 8 times
slower.

Considering that the file takes a couple of seconds to render, it seems
that the overhead is negligible.

1:
http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/showcase/illustrator/pdfs/magic-paintbrush-howto.pdf

On Wed, Jan 9, 2013 at 9:13 AM, Boris Zbarsky  wrote:

> On 1/9/13 1:20 AM, Rik Cabanier wrote:
>
>> Also, would there be a performance impact of having a string
>> argument for a call that happens very frequently?
>>
>
> That's an excellent question.  The answer is that it depends.
>
> Here's a testcase that exercises setting a property to a WebIDL enum and
> measures the time in ns per property set:
>
> 
>   var xhr = new XMLHttpRequest;
>   xhr.open("GET", "");
>   var count = 100;
>   var start = new Date;
>   for (var i = 0; i < count; ++i) {
> xhr.responseType = "text";
>   }
>   var stop = new Date;
>   alert((stop - start) / count * 1e6);
> 
>
> What I see on my hardware in a current Firefox nightly is that this takes
> about 27ns per set (this is on a 6-month-old fast laptop, for context, but
> of course you can measure on the hardware of your choice).  About 8-10ns of
> that is the general overhead associated with the loop counter, the setter
> invocation, etc.  If my profiler is not lying to me, another several ns is
> the actual implementation of the C++ responseType setter.  The rest of the
> time is spent dealing with the string.  For what it's worth, it's possible
> we could make the string bit faster for cases when a constant string is
> being used, as above; I'd have to think about it a bit.
>
> Here's a similar testcase that exercises a boolean:
>
> 
>   var xhr = new XMLHttpRequest;
>   xhr.open("GET", "");
>   var count = 100;
>   var start = new Date;
>   for (var i = 0; i < count; ++i) {
> xhr.withCredentials = false;
>   }
>   var stop = new Date;
>   alert((stop - start) / count * 1e6);
> 
>
> The time I see now is closer to 12-13ns.  So there is definitely overhead
> associated with the string: about 15ns per call.  How many calls are we
> expecting people to make here?
>
> But as I said, it depends.  The numbers are quite different in other UAs.
>  Testing a Chrome 25 dev channel build, a WebKit nightly (labeled "Safari"
> below), and and Opera build that claims to be "12.50 internal", I get
> numbers like so, in ns (all with a few ns plus or minus; I'm leaving off
> the error bars):
>
>  enumboolean
> Firefox   27   13
> Safari51   33
> Chrome58   40
> Opera158   82
>
> so how long this stuff takes is clearly pretty implementation-dependent.
>  And note that these are upper bounds, since I have no guarantees that the
> time taken by the actual C++ setters is negligible in these case (except
> for Firefox, where profiles show that it is).  For example, Chrome gets
> about 30% slower if I set responseType to "document" instead of "text", as
> far as I can tell, and that might be due to the C++ side.
>
> Hope that helps,
> Boris
>
> P.S.  For a real fun time, try doing xhr.responseType = false, as I
> accidentally did at some point while testing this and look at the resulting
> numbers.  ;)
>


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-09 Thread Dean Jackson

On 09/01/2013, at 4:08 PM, Dirk Schulze  wrote:

> 
> On Jan 8, 2013, at 9:35 AM, Rik Cabanier  wrote:
> 
>> I looked at pdf2js which is using this fillRule property. As I expected, 
>> introduction of the property results in code like this:
>>eoFill: function CanvasGraphics_eoFill() {
>>  var savedFillRule = this.setEOFillRule();
>>  this.fill();
>>  this.restoreFillRule(savedFillRule);
>>},
>> ...
>>// We generally keep the canvas context set for
>>// nonzero-winding, and just set evenodd for the operations
>>// that need them.
>>setEOFillRule: function CanvasGraphics_setEOFillRule() {
>>  var savedFillRule = this.ctx.mozFillRule;
>>  this.ctx.mozFillRule = 'evenodd';
>>  return savedFillRule;
>>},
>>restoreFillRule: function CanvasGraphics_restoreFillRule(rule) {
>>  this.ctx.mozFillRule = rule;
>>},
>> 
>> So, for even odd winding, all this code needs to run. With my proposal, this 
>> gets much simpler:
>>   eoFill: function CanvasGraphics_eoFill() {
>>  this.eoFill();
>>},
>> 
>> You can find a pull request with the needed changes to pdf2js here:
>> https://github.com/cabanier/pdf.js/commit/8e80b086376013a5438087714a4d2abb6fe67de1
> 
> For PDF.js it would probably be easier to set the fillRule every time right 
> before a fill or clip operation, then checking and storing the fill rule in 
> the background. This would reduce the code a lot more.
> 
>> 
>> I also created patches (with test files) for WebKit and mozilla:
>> https://bugs.webkit.org/show_bug.cgi?id=106188
>> https://bugzilla.mozilla.org/show_bug.cgi?id=827053
> 
> I looked at the patch for webkit. There are two parts where I would disagree 
> and that are potentially confusing.
> 
>   eoFill(), eoClip()
> 
> It is not obvious what these functions do and how they are different to 
> fill() and clip(). The name should be clear about the usage. But I don't 
> think that introducing two new functions to the Canvas API is a lot better 
> either. An alternative proposal instead of new functions or attributes could 
> be an optional argument for the fill() and stroke() functions. This argument 
> would be an enumeration of 'nonzero' and 'evenodd'.
> 
>   ctx.fill(); // fill with 'nonzero'
>   ctx.fill('nonzero') // fill with 'nonzero' as well
>   ctx.fill('evenodd') // fill with winding rule 'evenodd'

I prefer this approach over new methods.

In general, I tend to agree with Rik that winding rule is a geometric 
operation, rather than a context style. It's a shame that this may introduce 
inconsistency (I appreciate Ian's point on that).

Dean


> 
> The boolean argument in isPointInPath seems not to be very descriptive as 
> well: 
> 
>   boolean isPointInPath(unrestricted double x, unrestricted double y, 
> boolean windingRule);
> 
> It is not obvious if 'true' means 'nonzero' or 'evenodd'. I would recommend 
> to use an optional enumeration here, with the default value 'nonzero'.
> 
> You mentioned that the winding rule should be a part of the Path object. I 
> can see the use case that you want to address with it. And things like a 
> union path of two path object with different winding rules (as you suggested 
> before) is possible, as long as the union path just needs to get drawn (can 
> be done with compositing or masking in the implementation). But the SVG WG 
> would like to use the Path object as a way to share path data between Canvas 
> and SVG. In this case, the implementation must be able to flatten a path and 
> provide the path data directly. This is beyond the capability of current 
> graphic libraries and requires third party planarizer. This needs to be 
> considered before adding this functionality to the Path API.
> 
> Greetings,
> Dirk
> 
>> 
>> On Thu, Jan 3, 2013 at 3:38 PM, Ian Hickson  wrote:
>> On Fri, 10 Jun 2011, Chris Jones wrote:
>>> 
>>> In 2D canvas, determining whether a point is "inside" a path is
>>> currently always done using the non-zero winding rule.  I propose
>>> extending 2D canvas to allow determining inside-ness using the even-odd
>>> rule.
>> 
>> I've added this to the spec.
>> 
>> 
>> On Wed, 2 Jan 2013, Dirk Schulze wrote:
>>> 
>>> There was a complain on the webkit bug report if fillRule should be part
>>> of the graphics state or not. Did you investigate what current 2d
>>> graphics libraries do (qt, Cairo, CG, ...)? Is it part of the graphics
>>> state there?
>> 
>> I have made it be part of the graphics state in the spec; it would be
>> unusual in the API for it not to be. However, if this doesn't match
>> implementations, please let me know.
>> 
>> 
>> On Wed, 2 Jan 2013, Rik Cabanier wrote:
>>> 
>>> this features is not a trivial as it seems. Adding this will necessitate
>>> updates to the algorithms that deal with paths and the outlining of
>>> strokes and text.
>> 
>> Can you elaborate on what updates are needed? I couldn't see any that
>> actually needed to be changed.
>> 
>> 
>>> As Dirk mention

Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-08 Thread Rik Cabanier
On Tue, Jan 8, 2013 at 9:08 PM, Dirk Schulze  wrote:

>
> On Jan 8, 2013, at 9:35 AM, Rik Cabanier  wrote:
>
> > I looked at pdf2js which is using this fillRule property. As I expected,
> introduction of the property results in code like this:
> > eoFill: function CanvasGraphics_eoFill() {
> >   var savedFillRule = this.setEOFillRule();
> >   this.fill();
> >   this.restoreFillRule(savedFillRule);
> > },
> > ...
> > // We generally keep the canvas context set for
> > // nonzero-winding, and just set evenodd for the operations
> > // that need them.
> > setEOFillRule: function CanvasGraphics_setEOFillRule() {
> >   var savedFillRule = this.ctx.mozFillRule;
> >   this.ctx.mozFillRule = 'evenodd';
> >   return savedFillRule;
> > },
> > restoreFillRule: function CanvasGraphics_restoreFillRule(rule) {
> >   this.ctx.mozFillRule = rule;
> > },
> >
> > So, for even odd winding, all this code needs to run. With my proposal,
> this gets much simpler:
> >eoFill: function CanvasGraphics_eoFill() {
> >   this.eoFill();
> > },
> >
> > You can find a pull request with the needed changes to pdf2js here:
> >
> https://github.com/cabanier/pdf.js/commit/8e80b086376013a5438087714a4d2abb6fe67de1
>
> For PDF.js it would probably be easier to set the fillRule every time
> right before a fill or clip operation, then checking and storing the fill
> rule in the background. This would reduce the code a lot more.
>

that would be at the cost of setting it every time. pdf's can have tens of
thousands of fill calls...


>
> >
> > I also created patches (with test files) for WebKit and mozilla:
> > https://bugs.webkit.org/show_bug.cgi?id=106188
> > https://bugzilla.mozilla.org/show_bug.cgi?id=827053
>
> I looked at the patch for webkit. There are two parts where I would
> disagree and that are potentially confusing.
>
> eoFill(), eoClip()
>
> It is not obvious what these functions do and how they are different to
> fill() and clip(). The name should be clear about the usage.


I don't disagree. I was simply mimicking what other graphics libraries
(such as Core Graphics) do.


> But I don't think that introducing two new functions to the Canvas API is
> a lot better either. An alternative proposal instead of new functions or
> attributes could be an optional argument for the fill() and stroke()
> functions. This argument would be an enumeration of 'nonzero' and 'evenodd'.
>
> ctx.fill(); // fill with 'nonzero'
> ctx.fill('nonzero') // fill with 'nonzero' as well
> ctx.fill('evenodd') // fill with winding rule 'evenodd'
>
> The boolean argument in isPointInPath seems not to be very descriptive as
> well:
>
> boolean isPointInPath(unrestricted double x, unrestricted double
> y, boolean windingRule);
>
> It is not obvious if 'true' means 'nonzero' or 'evenodd'. I would
> recommend to use an optional enumeration here, with the default value
> 'nonzero'.
>

That was an oversight on my part. I believe I called it 'isEvenOdd' with
the mozilla patch.

As for boolean vs enums, the canvas 2d API has not used enums before (see
for instance imageSmoothingEnabled or anticlockwise) so this would be a
first. Also, would there be a performance impact of having a string
argument for a call that happens very frequently?


>
> You mentioned that the winding rule should be a part of the Path object. I
> can see the use case that you want to address with it. And things like a
> union path of two path object with different winding rules (as you
> suggested before) is possible, as long as the union path just needs to get
> drawn (can be done with compositing or masking in the implementation). But
> the SVG WG would like to use the Path object as a way to share path data
> between Canvas and SVG. In this case, the implementation must be able to
> flatten a path and provide the path data directly. This is beyond the
> capability of current graphic libraries and requires third party
> planarizer. This needs to be considered before adding this functionality to
> the Path API.


I agree. My point was that the path object (as defined today) is not what a
user would expect since it just aggregates path segments.
What's really needed is a way to union, intersect and subtract paths. This
functionality is also needed to create stroke and text outlines.

There are libraries out there (such as skia, qt and lib2geom) that offer
this functionality but I'm unaware of the quality (or performance) of their
implementations.


>


> >
> > On Thu, Jan 3, 2013 at 3:38 PM, Ian Hickson  wrote:
> > On Fri, 10 Jun 2011, Chris Jones wrote:
> > >
> > > In 2D canvas, determining whether a point is "inside" a path is
> > > currently always done using the non-zero winding rule.  I propose
> > > extending 2D canvas to allow determining inside-ness using the even-odd
> > > rule.
> >
> > I've added this to the spec.
> >
> >
> > On Wed, 2 Jan 2013, Dirk Schulze wrote:
> > >
> > 

Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-08 Thread Dirk Schulze

On Jan 8, 2013, at 9:35 AM, Rik Cabanier  wrote:

> I looked at pdf2js which is using this fillRule property. As I expected, 
> introduction of the property results in code like this:
> eoFill: function CanvasGraphics_eoFill() {
>   var savedFillRule = this.setEOFillRule();
>   this.fill();
>   this.restoreFillRule(savedFillRule);
> },
> ...
> // We generally keep the canvas context set for
> // nonzero-winding, and just set evenodd for the operations
> // that need them.
> setEOFillRule: function CanvasGraphics_setEOFillRule() {
>   var savedFillRule = this.ctx.mozFillRule;
>   this.ctx.mozFillRule = 'evenodd';
>   return savedFillRule;
> },
> restoreFillRule: function CanvasGraphics_restoreFillRule(rule) {
>   this.ctx.mozFillRule = rule;
> },
> 
> So, for even odd winding, all this code needs to run. With my proposal, this 
> gets much simpler:
>eoFill: function CanvasGraphics_eoFill() {
>   this.eoFill();
> },
> 
> You can find a pull request with the needed changes to pdf2js here:
> https://github.com/cabanier/pdf.js/commit/8e80b086376013a5438087714a4d2abb6fe67de1

For PDF.js it would probably be easier to set the fillRule every time right 
before a fill or clip operation, then checking and storing the fill rule in the 
background. This would reduce the code a lot more.

> 
> I also created patches (with test files) for WebKit and mozilla:
> https://bugs.webkit.org/show_bug.cgi?id=106188
> https://bugzilla.mozilla.org/show_bug.cgi?id=827053

I looked at the patch for webkit. There are two parts where I would disagree 
and that are potentially confusing.

eoFill(), eoClip()

It is not obvious what these functions do and how they are different to fill() 
and clip(). The name should be clear about the usage. But I don't think that 
introducing two new functions to the Canvas API is a lot better either. An 
alternative proposal instead of new functions or attributes could be an 
optional argument for the fill() and stroke() functions. This argument would be 
an enumeration of 'nonzero' and 'evenodd'.

ctx.fill(); // fill with 'nonzero'
ctx.fill('nonzero') // fill with 'nonzero' as well
ctx.fill('evenodd') // fill with winding rule 'evenodd'

The boolean argument in isPointInPath seems not to be very descriptive as well: 

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

It is not obvious if 'true' means 'nonzero' or 'evenodd'. I would recommend to 
use an optional enumeration here, with the default value 'nonzero'.

You mentioned that the winding rule should be a part of the Path object. I can 
see the use case that you want to address with it. And things like a union path 
of two path object with different winding rules (as you suggested before) is 
possible, as long as the union path just needs to get drawn (can be done with 
compositing or masking in the implementation). But the SVG WG would like to use 
the Path object as a way to share path data between Canvas and SVG. In this 
case, the implementation must be able to flatten a path and provide the path 
data directly. This is beyond the capability of current graphic libraries and 
requires third party planarizer. This needs to be considered before adding this 
functionality to the Path API.

Greetings,
Dirk

> 
> On Thu, Jan 3, 2013 at 3:38 PM, Ian Hickson  wrote:
> On Fri, 10 Jun 2011, Chris Jones wrote:
> >
> > In 2D canvas, determining whether a point is "inside" a path is
> > currently always done using the non-zero winding rule.  I propose
> > extending 2D canvas to allow determining inside-ness using the even-odd
> > rule.
> 
> I've added this to the spec.
> 
> 
> On Wed, 2 Jan 2013, Dirk Schulze wrote:
> >
> > There was a complain on the webkit bug report if fillRule should be part
> > of the graphics state or not. Did you investigate what current 2d
> > graphics libraries do (qt, Cairo, CG, ...)? Is it part of the graphics
> > state there?
> 
> I have made it be part of the graphics state in the spec; it would be
> unusual in the API for it not to be. However, if this doesn't match
> implementations, please let me know.
> 
> 
> On Wed, 2 Jan 2013, Rik Cabanier wrote:
> >
> > this features is not a trivial as it seems. Adding this will necessitate
> > updates to the algorithms that deal with paths and the outlining of
> > strokes and text.
> 
> Can you elaborate on what updates are needed? I couldn't see any that
> actually needed to be changed.
> 
> 
> > As Dirk mentioned, instead of making it part of the graphics state, it's
> > more likely better to make it part of the fill or clip operator like
> > SVG, PDF and PostScript.
> 
> That seems like it would be inconsistent with the rest of the canvas API.
> 
> 
> > In addition, the path object will need to be extended so it can deal
> > with this idiom.
> 
> Can you elaborate on how this affects the Path object? It seems like it
> would

Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-08 Thread Rik Cabanier
I looked at pdf2js which is using this fillRule property. As I expected,
introduction of the property results in code like this:

eoFill: function CanvasGraphics_eoFill() {
  var savedFillRule = this.setEOFillRule();
  this.fill();
  this.restoreFillRule(savedFillRule);
},

...
// We generally keep the canvas context set for
// nonzero-winding, and just set evenodd for the operations
// that need them.
setEOFillRule: function CanvasGraphics_setEOFillRule() {
  var savedFillRule = this.ctx.mozFillRule;
  this.ctx.mozFillRule = 'evenodd';
  return savedFillRule;
},
restoreFillRule: function CanvasGraphics_restoreFillRule(rule) {
  this.ctx.mozFillRule = rule;
},


So, for even odd winding, all this code needs to run. With my proposal,
this gets much simpler:

   eoFill: function CanvasGraphics_eoFill() {
  this.eoFill();
},


You can find a pull request with the needed changes to pdf2js here:
https://github.com/cabanier/pdf.js/commit/8e80b086376013a5438087714a4d2abb6fe67de1

I also created patches (with test files) for WebKit and mozilla:
https://bugs.webkit.org/show_bug.cgi?id=106188
https://bugzilla.mozilla.org/show_bug.cgi?id=827053

On Thu, Jan 3, 2013 at 3:38 PM, Ian Hickson  wrote:

> On Fri, 10 Jun 2011, Chris Jones wrote:
> >
> > In 2D canvas, determining whether a point is "inside" a path is
> > currently always done using the non-zero winding rule.  I propose
> > extending 2D canvas to allow determining inside-ness using the even-odd
> > rule.
>
> I've added this to the spec.
>
>
> On Wed, 2 Jan 2013, Dirk Schulze wrote:
> >
> > There was a complain on the webkit bug report if fillRule should be part
> > of the graphics state or not. Did you investigate what current 2d
> > graphics libraries do (qt, Cairo, CG, ...)? Is it part of the graphics
> > state there?
>
> I have made it be part of the graphics state in the spec; it would be
> unusual in the API for it not to be. However, if this doesn't match
> implementations, please let me know.
>
>
> On Wed, 2 Jan 2013, Rik Cabanier wrote:
> >
> > this features is not a trivial as it seems. Adding this will necessitate
> > updates to the algorithms that deal with paths and the outlining of
> > strokes and text.
>
> Can you elaborate on what updates are needed? I couldn't see any that
> actually needed to be changed.
>
>
> > As Dirk mentioned, instead of making it part of the graphics state, it's
> > more likely better to make it part of the fill or clip operator like
> > SVG, PDF and PostScript.
>
> That seems like it would be inconsistent with the rest of the canvas API.
>
>
> > In addition, the path object will need to be extended so it can deal
> > with this idiom.
>
> Can you elaborate on how this affects the Path object? It seems like it
> would be somewhat orthogonal.
>
>
> > The easiest way to implement this, would be to leave the core interface
> of
> > canvas alone and just extend the path object with winding rules and a
> > method to 'simplify' a path so it can be drawn with any winding rule.
>
> This doesn't seem like it would be easier... in particular, fillRule is
> now implemented in two browsers, so the implementation cost for them would
> be zero, and they don't yet implement Path at all, so the implementation
> cost for Path would be quite high, even without "simplify". :-)
>
>
> On Wed, 2 Jan 2013, Rik Cabanier wrote:
> >
> > However, just look at how stroke is implemented in the Canvas 2d spec or
> > how you can create paths by stroking or stroked text. They're all
> > affected by the winding rules.
>
> How so?
>
>
> > (The description on how to do strokes in the spec is very wrong, but
> > that can be addressed later)
>
> Can you elaborate on this? If there's a mistake obviously I'd like to fix
> it...
>
>
> > Dirk and I did a bit more research and found that SVG, PDF, Flash,
> > PostScript, Skia, Core Graphics and Direct2D all have the winding rules
> > as part of the fill operator. It seems strange that canvas would choose
> > to have a different interface...
>
> People using the canvas API are more likely to know the canvas API, and
> thus want extensions to be consistent with the canvas API, than they are
> to be familiar with PDF, Flash, PostScript, Skia, Core Graphics, or
> Direct2D. Incidentally, of those, I'm only familiar with SVG, and SVG is
> similar to what I specced (indeed I don't see how it could be part of the
> operator since it's a declarative language).
>
> --
> Ian Hickson   U+1047E)\._.,--,'``.fL
> http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
> Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'
>


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-03 Thread Rik Cabanier
On Thu, Jan 3, 2013 at 4:58 PM, Ian Hickson  wrote:

> On Thu, 3 Jan 2013, Rik Cabanier wrote:
> > >
> > > I have made it be part of the graphics state in the spec; it would be
> > > unusual in the API for it not to be. However, if this doesn't match
> > > implementations, please let me know.
> >
> > Do you mean browser implementations or graphic libraries? AFAIK all
> > graphic libraries except cairo are different. I'm unsure about the
> > browsers.
>
> Implementations of the spec (i.e. browsers).
>
>
> > > On Wed, 2 Jan 2013, Rik Cabanier wrote:
> > > >
> > > > this features is not a trivial as it seems. Adding this will
> > > > necessitate updates to the algorithms that deal with paths and the
> > > > outlining of strokes and text.
> > >
> > > Can you elaborate on what updates are needed? I couldn't see any that
> > > actually needed to be changed.
> >
> > One of the intents of the path object is so you can 'accumulate' the
> > regions that were drawn so you can set them up as hit regions.
>
> It is? I don't think that's one of the use cases I've seen before. It's an
> interesting use case, though, true.
>

A region can be a bunch of shapes so I assumed that the path object was
designed to accommodate this.
For instance a stroked rectangle would be a region and consist of a rect
path and the stroked rect path.


> > This means that a hit regions can contain shapes that were drawn with
> > different winding rules. The current path syntax does not allow you to
> > store this information so you can't set up a hit region that was drawn
> > with an [even-odd fill].
>
> The Path objects just store paths, not filled shapes, so you can't really
> store non-zero-based shapes any more than even-odd-based shaped, if you're
> going to mix them.
>

Exactly! This is my main problem with the path object and why you can't use
it for hit regions.
People (at least me) think of a path as an atomic region that is filled or
stroked. If you combine paths/regions, you expect that the
drawn area is preserved.


>
> If this (the region accumulation thing) is a use case we should support,
> then we need a way to add paths together in a way that converts all the
> paths to a specific fill rule type (ideally to be agnostic of the rule).
>

Yes, strokes and text outlines should be generated so any fill rule can
apply.
I think the spec needs to mention that
- sections of the path where both edges are filled should be removed
- winding needs to be done so eofill and fill give the same result


>
>
> > > > As Dirk mentioned, instead of making it part of the graphics state,
> > > > it's more likely better to make it part of the fill or clip operator
> > > > like SVG, PDF and PostScript.
> > >
> > > That seems like it would be inconsistent with the rest of the canvas
> > > API.
> >
> > Winding is specific per draw and unlikely to persist across several draw
> > commands. This makes it different than color or the stroke style.
>
> I'd have thought that would make it exactly like the stroke style.
>

No, usually a bunch of strokes of the same type and color are drawn
consecutively. Not so much with eofill which why it is not part of the
graphics state in almost all graphics libraries.


>
>
> > > > The easiest way to implement this, would be to leave the core
> > > > interface of canvas alone and just extend the path object with
> > > > winding rules and a method to 'simplify' a path so it can be drawn
> > > > with any winding rule.
> > >
> > > This doesn't seem like it would be easier... in particular, fillRule
> > > is now implemented in two browsers, so the implementation cost for
> > > them would be zero, and they don't yet implement Path at all, so the
> > > implementation cost for Path would be quite high, even without
> > > "simplify". :-)
> >
> > It's easier because of all the other work that's necessary to make this
> > feature work correctly. So, yes, it is easier now because they don't
> > rely on the spec to implement stroking and they don't have an
> > implementation for paths.
> >
> > However, the spec is supposed to be followed (right?) and at some point,
> > paths should be implemented. Going the easy way now will give a headache
> > later.
>
> I'm happy to defer to the browsers vendors on this -- browser vendosr,
> what would be simpler for you to implement?
>
>
> > > On Wed, 2 Jan 2013, Rik Cabanier wrote:
> > > >
> > > > However, just look at how stroke is implemented in the Canvas 2d
> > > > spec or how you can create paths by stroking or stroked text.
> > > > They're all affected by the winding rules.
> > >
> > > How so?
> >
> > For instance, take a figure eight that is stroked. If you draw it out,
> > you will see that you cross 2 lines to get to the middle which means
> > that there will be a gap when doing an [even-odd fill].
>
> Could you elaborate on this? How would you propose this should be changed?
>
>
> > > > (The description on how to do strokes in the spec is very wrong, but
> > > > that can be addressed la

Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-03 Thread Ian Hickson
On Thu, 3 Jan 2013, Rik Cabanier wrote:
> >
> > I have made it be part of the graphics state in the spec; it would be 
> > unusual in the API for it not to be. However, if this doesn't match 
> > implementations, please let me know.
> 
> Do you mean browser implementations or graphic libraries? AFAIK all 
> graphic libraries except cairo are different. I'm unsure about the 
> browsers.

Implementations of the spec (i.e. browsers).


> > On Wed, 2 Jan 2013, Rik Cabanier wrote:
> > >
> > > this features is not a trivial as it seems. Adding this will 
> > > necessitate updates to the algorithms that deal with paths and the 
> > > outlining of strokes and text.
> >
> > Can you elaborate on what updates are needed? I couldn't see any that 
> > actually needed to be changed.
> 
> One of the intents of the path object is so you can 'accumulate' the 
> regions that were drawn so you can set them up as hit regions.

It is? I don't think that's one of the use cases I've seen before. It's an 
interesting use case, though, true.


> This means that a hit regions can contain shapes that were drawn with 
> different winding rules. The current path syntax does not allow you to 
> store this information so you can't set up a hit region that was drawn 
> with an [even-odd fill].

The Path objects just store paths, not filled shapes, so you can't really 
store non-zero-based shapes any more than even-odd-based shaped, if you're 
going to mix them.

If this (the region accumulation thing) is a use case we should support, 
then we need a way to add paths together in a way that converts all the 
paths to a specific fill rule type (ideally to be agnostic of the rule).


> > > As Dirk mentioned, instead of making it part of the graphics state, 
> > > it's more likely better to make it part of the fill or clip operator 
> > > like SVG, PDF and PostScript.
> >
> > That seems like it would be inconsistent with the rest of the canvas 
> > API.
> 
> Winding is specific per draw and unlikely to persist across several draw 
> commands. This makes it different than color or the stroke style.

I'd have thought that would make it exactly like the stroke style.


> > > The easiest way to implement this, would be to leave the core 
> > > interface of canvas alone and just extend the path object with 
> > > winding rules and a method to 'simplify' a path so it can be drawn 
> > > with any winding rule.
> >
> > This doesn't seem like it would be easier... in particular, fillRule 
> > is now implemented in two browsers, so the implementation cost for 
> > them would be zero, and they don't yet implement Path at all, so the 
> > implementation cost for Path would be quite high, even without 
> > "simplify". :-)
> 
> It's easier because of all the other work that's necessary to make this 
> feature work correctly. So, yes, it is easier now because they don't 
> rely on the spec to implement stroking and they don't have an 
> implementation for paths.
> 
> However, the spec is supposed to be followed (right?) and at some point, 
> paths should be implemented. Going the easy way now will give a headache 
> later.

I'm happy to defer to the browsers vendors on this -- browser vendosr, 
what would be simpler for you to implement?


> > On Wed, 2 Jan 2013, Rik Cabanier wrote:
> > >
> > > However, just look at how stroke is implemented in the Canvas 2d 
> > > spec or how you can create paths by stroking or stroked text. 
> > > They're all affected by the winding rules.
> >
> > How so?
> 
> For instance, take a figure eight that is stroked. If you draw it out, 
> you will see that you cross 2 lines to get to the middle which means 
> that there will be a gap when doing an [even-odd fill].

Could you elaborate on this? How would you propose this should be changed?


> > > (The description on how to do strokes in the spec is very wrong, but 
> > > that can be addressed later)
> >
> > Can you elaborate on this? If there's a mistake obviously I'd like to 
> > fix it...
> 
> I'm unsure where to begin...

If you could just file bugs for each mistake, that would be great.

   http://whatwg.org/newbug

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-03 Thread Rik Cabanier
On Thu, Jan 3, 2013 at 3:38 PM, Ian Hickson  wrote:

> On Fri, 10 Jun 2011, Chris Jones wrote:
> >
> > In 2D canvas, determining whether a point is "inside" a path is
> > currently always done using the non-zero winding rule.  I propose
> > extending 2D canvas to allow determining inside-ness using the even-odd
> > rule.
>
> I've added this to the spec.
>
>
> On Wed, 2 Jan 2013, Dirk Schulze wrote:
> >
> > There was a complain on the webkit bug report if fillRule should be part
> > of the graphics state or not. Did you investigate what current 2d
> > graphics libraries do (qt, Cairo, CG, ...)? Is it part of the graphics
> > state there?
>
> I have made it be part of the graphics state in the spec; it would be
> unusual in the API for it not to be. However, if this doesn't match
> implementations, please let me know.
>

Do you mean browser implementations or graphic libraries?
AFAIK all graphic libraries except cairo are different.
I'm unsure about the browsers.


>
>
> On Wed, 2 Jan 2013, Rik Cabanier wrote:
> >
> > this features is not a trivial as it seems. Adding this will necessitate
> > updates to the algorithms that deal with paths and the outlining of
> > strokes and text.
>
> Can you elaborate on what updates are needed? I couldn't see any that
> actually needed to be changed.
>

One of the intents of the path object is so you can 'accumulate' the
regions that were drawn so you can set them up as hit regions.
This means that a hit regions can contain shapes that were drawn with
different winding rules. The current path syntax does not allow you to
store this information so you can't set up a hit region that was drawn with
an eofill.


> > As Dirk mentioned, instead of making it part of the graphics state, it's
> > more likely better to make it part of the fill or clip operator like
> > SVG, PDF and PostScript.
>
> That seems like it would be inconsistent with the rest of the canvas API.
>

Winding is specific per draw and unlikely to persist across several draw
commands. This makes it different than color or the stroke style.


>
>
> > In addition, the path object will need to be extended so it can deal
> > with this idiom.
>
> Can you elaborate on how this affects the Path object? It seems like it
> would be somewhat orthogonal.
>

See above


>
>
> > The easiest way to implement this, would be to leave the core interface
> of
> > canvas alone and just extend the path object with winding rules and a
> > method to 'simplify' a path so it can be drawn with any winding rule.
>
> This doesn't seem like it would be easier... in particular, fillRule is
> now implemented in two browsers, so the implementation cost for them would
> be zero, and they don't yet implement Path at all, so the implementation
> cost for Path would be quite high, even without "simplify". :-)
>

It's easier because of all the other work that's necessary to make this
feature work correctly.
So, yes, it is easier now because they don't rely on the spec to implement
stroking and they don't have an implementation for paths.

However, the spec is supposed to be followed (right?) and at some point,
paths should be implemented. Going the easy way now will give a headache
later.


> On Wed, 2 Jan 2013, Rik Cabanier wrote:
> >
> > However, just look at how stroke is implemented in the Canvas 2d spec or
> > how you can create paths by stroking or stroked text. They're all
> > affected by the winding rules.
>
> How so?
>

For instance, take a figure eight that is stroked.
If you draw it out, you will see that you cross 2 lines to get to the
middle which means that there will be a gap when doing an eofill.


>
>
> > (The description on how to do strokes in the spec is very wrong, but
> > that can be addressed later)
>
> Can you elaborate on this? If there's a mistake obviously I'd like to fix
> it...
>

I'm unsure where to begin...
Note that the issue with EOFill will also happen with regular fills of
intersecting paths and NZO filling. Part of the stroking process is to
remove path segments that have a fill on both sides.

Maybe the spec should say how you do strokes but instead show the results
of the different parameters.


>
>
> > Dirk and I did a bit more research and found that SVG, PDF, Flash,
> > PostScript, Skia, Core Graphics and Direct2D all have the winding rules
> > as part of the fill operator. It seems strange that canvas would choose
> > to have a different interface...
>
> People using the canvas API are more likely to know the canvas API, and
> thus want extensions to be consistent with the canvas API, than they are
> to be familiar with PDF, Flash, PostScript, Skia, Core Graphics, or
> Direct2D. Incidentally, of those, I'm only familiar with SVG, and SVG is
> similar to what I specced (indeed I don't see how it could be part of the
> operator since it's a declarative language).


In SVG everything is part of the fill operator since it doesn't rely on
state (except for 'inherit')


Re: [whatwg] Proposal: Add CanvasRenderingContext2D.fillRule with "nonzero" (default) and "evenodd" options

2013-01-03 Thread Ian Hickson
On Fri, 10 Jun 2011, Chris Jones wrote:
>
> In 2D canvas, determining whether a point is "inside" a path is 
> currently always done using the non-zero winding rule.  I propose 
> extending 2D canvas to allow determining inside-ness using the even-odd 
> rule.

I've added this to the spec.


On Wed, 2 Jan 2013, Dirk Schulze wrote:
> 
> There was a complain on the webkit bug report if fillRule should be part 
> of the graphics state or not. Did you investigate what current 2d 
> graphics libraries do (qt, Cairo, CG, ...)? Is it part of the graphics 
> state there?

I have made it be part of the graphics state in the spec; it would be 
unusual in the API for it not to be. However, if this doesn't match 
implementations, please let me know.


On Wed, 2 Jan 2013, Rik Cabanier wrote:
> 
> this features is not a trivial as it seems. Adding this will necessitate 
> updates to the algorithms that deal with paths and the outlining of 
> strokes and text.

Can you elaborate on what updates are needed? I couldn't see any that 
actually needed to be changed.


> As Dirk mentioned, instead of making it part of the graphics state, it's 
> more likely better to make it part of the fill or clip operator like 
> SVG, PDF and PostScript.

That seems like it would be inconsistent with the rest of the canvas API.


> In addition, the path object will need to be extended so it can deal 
> with this idiom.

Can you elaborate on how this affects the Path object? It seems like it 
would be somewhat orthogonal.


> The easiest way to implement this, would be to leave the core interface of
> canvas alone and just extend the path object with winding rules and a
> method to 'simplify' a path so it can be drawn with any winding rule.

This doesn't seem like it would be easier... in particular, fillRule is 
now implemented in two browsers, so the implementation cost for them would 
be zero, and they don't yet implement Path at all, so the implementation 
cost for Path would be quite high, even without "simplify". :-)


On Wed, 2 Jan 2013, Rik Cabanier wrote:
>
> However, just look at how stroke is implemented in the Canvas 2d spec or 
> how you can create paths by stroking or stroked text. They're all 
> affected by the winding rules.

How so?


> (The description on how to do strokes in the spec is very wrong, but 
> that can be addressed later)

Can you elaborate on this? If there's a mistake obviously I'd like to fix 
it...


> Dirk and I did a bit more research and found that SVG, PDF, Flash, 
> PostScript, Skia, Core Graphics and Direct2D all have the winding rules 
> as part of the fill operator. It seems strange that canvas would choose 
> to have a different interface...

People using the canvas API are more likely to know the canvas API, and 
thus want extensions to be consistent with the canvas API, than they are 
to be familiar with PDF, Flash, PostScript, Skia, Core Graphics, or 
Direct2D. Incidentally, of those, I'm only familiar with SVG, and SVG is 
similar to what I specced (indeed I don't see how it could be part of the 
operator since it's a declarative language).

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'