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.  The motivation is

 (1) Many/most 2D graphics libraries have this feature; canvas should have it 
for completeness.  Some other languages/libraries that support even-odd fill 
(in alphabetical order): cairo, Direct2D, GDI, PDF, PostScript, Quartz, skia, 
and SVG.

 (2) While the nonzero-winding and even-odd rules are equivalent in the sense 
that there's nothing that can be drawn with one that can't be drawn with the 
other, some figures are simpler to draw with one rule instead of the other.  We 
should add even-odd fill for author convenience.

 (3) Using one rule over the other may result in better performance, by 
decomposing to less geometry.

The concrete proposal is

  interface CanvasRenderingContext2D {
    //...
    attribute fillRule;  // "nonzero", "evenodd" (default "nonzero")
    //...
  };

The names "nonzero" and "evenodd" were chosen to match the SVG specification 
[1].  The SVG specification can be used as a reference for the semantics of 
even-odd fill.

|fillRule| applies to all operations currently "hard-coded" to use the 
nonzero-winding rule to determine inside-ness.  The change proposed here is, 
when computing inside-ness, use the rule currently specified by |fillRule|.

The default value of |fillRule| is "nonzero", for backwards compatibility.  The 
|fillRule| attribute is part of the canvas state saved by save() and restored 
by restore().  Script attempting to set |fillRule| to a string not one of 
"nonzero" or "evenodd", say "garbage", would have no effect (i.e. *not* change 
the value of |fillRule|).

Mozilla has implemented this proposed spec as |mozFillRule| [2].  It will be 
available in Firefox "Nightly" builds starting June 11th.

Cheers,
Chris

[1] http://www.w3.org/TR/SVG/painting.html#FillProperties
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=655926

Reply via email to