On Jan 9, 2013, at 11:42 AM, "Rik Cabanier" 
<[email protected]<mailto:[email protected]>> wrote:



On Wed, Jan 9, 2013 at 10:27 AM, Dean Jackson 
<[email protected]<mailto:[email protected]>> wrote:

On 09/01/2013, at 4:08 PM, Dirk Schulze 
<[email protected]<mailto:[email protected]>> wrote:

>
> On Jan 8, 2013, at 9:35 AM, Rik Cabanier 
> <[email protected]<mailto:[email protected]>> 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 
>> <[email protected]<mailto:[email protected]>> 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