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