- From: Rik Cabanier <cabanier@gmail.com>
- Date: Wed, 9 Jan 2013 11:42:43 -0800
- To: Dean Jackson <dino@apple.com>
- Cc: Dirk Schulze <dschulze@adobe.com>, "whatwg@whatwg.org" <whatwg@whatwg.org>, Chris Jones <cjones@mozilla.com>, Ian Hickson <ian@hixie.ch>, James Ascroft-Leigh <jwal@jwal.me.uk>
On Wed, Jan 9, 2013 at 10:27 AM, Dean Jackson <dino@apple.com> wrote: > > On 09/01/2013, at 4:08 PM, Dirk Schulze <dschulze@adobe.com> wrote: > > > > > On Jan 8, 2013, at 9:35 AM, Rik Cabanier <cabanier@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. > > > > > > > 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 <ian@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. `._.-(,_..'--(,_..'`-.;.' > >> > > > >
Received on Wednesday, 9 January 2013 19:49:00 UTC