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

> 
> On Jan 8, 2013, at 9:35 AM, Rik Cabanier <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).

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 <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 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.   `._.-(,_..'--(,_..'`-.;.'
>> 
> 

Reply via email to