Re: [whatwg] Path API feedback
On Wed, 18 Sep 2013, Rik Cabanier wrote: On Tue, Sep 17, 2013 at 10:20 AM, Ian Hickson i...@hixie.ch wrote: On Tue, 20 Aug 2013, Rik Cabanier wrote: On Sat, 23 Mar 2013, Rik Cabanier wrote: The current path APIs suffer from conflating path segments and geometry. To fix this, I proposed to modify the API so path just describe the path segments. http://blogs.adobe.com/webplatform/2013/01/31/revised-canvas-paths/ I disagree with the premise of this post -- it's not the case that you never want to add segments. It is in fact quite common to add segments to a path -- that's what constructing a path is. I disagree. How many times does an author want to add segments to an existing path? Pretty much every time they create a path with more than one segment. Maybe I phrased that wrong. The existing path is a path that was created earlier (and could have already been used to draw). It's not often that you would want to append to such a path. Right, the current API is only about building paths, not about later combining paths. We haven't added that feature yet. That would be covered by: https://www.w3.org/Bugs/Public/show_bug.cgi?id=21835 Let's say an application stores a circle in a path and now want to draw a rectangle too. You propose that the application just appends the rectangle. No, not necessarily. It depends on what they want to do. If they want a single path that is constructed of a circle and a rectangle in the same way that it would be if they did: x.beginPath(); x.arc(...); x.rect(...); x.fill(); ...then yeah, they should just append the rectangle. But if they want the same effect as: x.beginPath(); x.arc(); x.fill(); x.rect(...); x.fill(); ...then they should not just append them, since as you say, it won't work. Yes, but for hit regions, you would have to calculate the area that these 2 fill operations covered. This is why we need the extra 'union' API. I don't think anyone is arguing that we don't eventually need such an API. Once the Path API is implemented, we can add any number of features, such as adding a path so as to form the union of both paths, adding a path so as to form the intersection of both paths, etc. OK. In order to make that possible, 'addPath', 'addPathByStrokingPath', 'addText' and 'addTextByStrokingText' should be cut from the interface. Why? Sure, for that you need a new API function, e.g. union, which as I've mentioned before, I think would be a logical addition to the API in due course. But I don't think we should add features too quickly, lest we get too far ahead of browsers. That sounds reasonable. So please remove the APIs such as AddPathByStrokingPath that rely on these difficult algorithms. I don't understand why one implies the other. Can you elaborate on your reasoning here? -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Path API feedback
On Wed, Oct 16, 2013 at 3:01 PM, Ian Hickson i...@hixie.ch wrote: On Wed, 18 Sep 2013, Rik Cabanier wrote: On Tue, Sep 17, 2013 at 10:20 AM, Ian Hickson i...@hixie.ch wrote: On Tue, 20 Aug 2013, Rik Cabanier wrote: On Sat, 23 Mar 2013, Rik Cabanier wrote: The current path APIs suffer from conflating path segments and geometry. To fix this, I proposed to modify the API so path just describe the path segments. http://blogs.adobe.com/webplatform/2013/01/31/revised-canvas-paths/ I disagree with the premise of this post -- it's not the case that you never want to add segments. It is in fact quite common to add segments to a path -- that's what constructing a path is. I disagree. How many times does an author want to add segments to an existing path? Pretty much every time they create a path with more than one segment. Maybe I phrased that wrong. The existing path is a path that was created earlier (and could have already been used to draw). It's not often that you would want to append to such a path. Right, the current API is only about building paths, not about later combining paths. We haven't added that feature yet. That would be covered by: https://www.w3.org/Bugs/Public/show_bug.cgi?id=21835 Let's say an application stores a circle in a path and now want to draw a rectangle too. You propose that the application just appends the rectangle. No, not necessarily. It depends on what they want to do. If they want a single path that is constructed of a circle and a rectangle in the same way that it would be if they did: x.beginPath(); x.arc(...); x.rect(...); x.fill(); ...then yeah, they should just append the rectangle. But if they want the same effect as: x.beginPath(); x.arc(); x.fill(); x.rect(...); x.fill(); ...then they should not just append them, since as you say, it won't work. Yes, but for hit regions, you would have to calculate the area that these 2 fill operations covered. This is why we need the extra 'union' API. I don't think anyone is arguing that we don't eventually need such an API. Once the Path API is implemented, we can add any number of features, such as adding a path so as to form the union of both paths, adding a path so as to form the intersection of both paths, etc. OK. In order to make that possible, 'addPath', 'addPathByStrokingPath', 'addText' and 'addTextByStrokingText' should be cut from the interface. Why? Paths are a construct that can be filled with a fill rule or stroked. After this, they are no longer paths but regions of a certain color. The same is true for text. (Your recent addition that describes a stroke as sweeping a line following the path, is starting to align with that.) The path object should represent the path in the graphics state. You can't add a stroked path or text outline to the graphics state and then fill/stroke it. currentPath which was added by WebKit and Blink, makes that clear. Sure, for that you need a new API function, e.g. union, which as I've mentioned before, I think would be a logical addition to the API in due course. But I don't think we should add features too quickly, lest we get too far ahead of browsers. That sounds reasonable. So please remove the APIs such as AddPathByStrokingPath that rely on these difficult algorithms. I don't understand why one implies the other. Can you elaborate on your reasoning here? Those APIs have to know how to turn strokes and text into paths (which is not trivial and no UA does by default). In addition if you want to have useful output (= not getting unexpected interactions of the winding rules), the APIs would need to use planarization for stroke and text outlines. See http://blogs.adobe.com/webplatform/2013/01/31/revised-canvas-paths/ for a description of the issue.
Re: [whatwg] Path API feedback
On Tue, Sep 17, 2013 at 10:20 AM, Ian Hickson i...@hixie.ch wrote: On Tue, 20 Aug 2013, Rik Cabanier wrote: On Sat, 23 Mar 2013, Rik Cabanier wrote: The current path APIs suffer from conflating path segments and geometry. To fix this, I proposed to modify the API so path just describe the path segments. http://blogs.adobe.com/webplatform/2013/01/31/revised-canvas-paths/ I disagree with the premise of this post -- it's not the case that you never want to add segments. It is in fact quite common to add segments to a path -- that's what constructing a path is. I disagree. How many times does an author want to add segments to an existing path? Pretty much every time they create a path with more than one segment. Maybe I phrased that wrong. The existing path is a path that was created earlier (and could have already been used to draw). It's not often that you would want to append to such a path. Let's say an application stores a circle in a path and now want to draw a rectangle too. You propose that the application just appends the rectangle. No, not necessarily. It depends on what they want to do. If they want a single path that is constructed of a circle and a rectangle in the same way that it would be if they did: x.beginPath(); x.arc(...); x.rect(...); x.fill(); ...then yeah, they should just append the rectangle. But if they want the same effect as: x.beginPath(); x.arc(); x.fill(); x.rect(...); x.fill(); ...then they should not just append them, since as you say, it won't work. Yes, but for hit regions, you would have to calculate the area that these 2 fill operations covered. This is why we need the extra 'union' API. Also, it's not at all clear to me that there's really a distinction between a shape and a path. They're really the same thing -- sets of path segments. No. A shape is no longer a group of line segments. You *could* convert it to such a thing but that requires a bunch of complex math (ie http://www.youtube.com/watch?v=OmfliNQsk88) For now, I'm not proposing to add that to the canvas API. Once the Path API is implemented, we can add any number of features, such as adding a path so as to form the union of both paths, adding a path so as to form the intersection of both paths, etc. OK. In order to make that possible, 'addPath', 'addPathByStrokingPath', 'addText' and 'addTextByStrokingText' should be cut from the interface. The resulting 'path' will once again have no winding. This is very confusing and extremely hard to implement I don't understand why it's hard to implement. It's just the non-Path API, but stored away for future use. Right now we have two options (ignoring the text parts of the path API): concatenating path segments, and concatenating path segments after having first outlined one of them. FYI the outlining algorithm is also not correct. It suffers from the same issue that strokes are segments. Can you elaborate? (I think I may have asked already, in which case, my apologies for asking again.) I started it in http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-September/040810.html On the long run I think it would make sense to add other methods, e.g. one combining two or more paths together such that the resulting path would outline the union of the insides of the provided paths, or the intersections, or whatnot. I think that would be much more confusing and difficult to implement. I didn't come up with this on my own :-). This is done by graphics libraries that offers path manipulation support. For instance: skia: http://skia-autogen.googlecode.com/svn/docs/html/classSkPathEffect.html lib2geom: http://wiki.inkscape.org/wiki/index.php/WorkingWith2GeomFAQ Direct2D: http://msdn.microsoft.com/en-us/library/windows/desktop/dd756653(v=vs.85).aspx#path_geometries I'm confused. Are these examples of how to make confusing APIs, or examples of how the current API is confusing? Those look really, really complicated relative to what Canvas looks like today. Those are examples how path composition is defined in graphic libraries. I'm not proposing that we copy the APIs :-) None of the libraries I listed, is working on the path operations themselves (like you defined in canvas) On Thu, 5 Sep 2013, Rik Cabanier wrote: The problem happens when you call fill or stroke multiple times. [...] Now I want to create a region that covers what was drawn. [...] 'p' won't describe the same area as what was filled. Sure, for that you need a new API function, e.g. union, which as I've mentioned before, I think would be a logical addition to the API in due course. But I don't think we should add features too quickly, lest we get too far ahead of browsers. That sounds reasonable. So please remove the APIs such as AddPathByStrokingPath that rely on these difficult
Re: [whatwg] Path API feedback
On Tue, 20 Aug 2013, Rik Cabanier wrote: On Sat, 23 Mar 2013, Rik Cabanier wrote: The current path APIs suffer from conflating path segments and geometry. To fix this, I proposed to modify the API so path just describe the path segments. http://blogs.adobe.com/webplatform/2013/01/31/revised-canvas-paths/ I disagree with the premise of this post -- it's not the case that you never want to add segments. It is in fact quite common to add segments to a path -- that's what constructing a path is. I disagree. How many times does an author want to add segments to an existing path? Pretty much every time they create a path with more than one segment. Let's say an application stores a circle in a path and now want to draw a rectangle too. You propose that the application just appends the rectangle. No, not necessarily. It depends on what they want to do. If they want a single path that is constructed of a circle and a rectangle in the same way that it would be if they did: x.beginPath(); x.arc(...); x.rect(...); x.fill(); ...then yeah, they should just append the rectangle. But if they want the same effect as: x.beginPath(); x.arc(); x.fill(); x.rect(...); x.fill(); ...then they should not just append them, since as you say, it won't work. Also, it's not at all clear to me that there's really a distinction between a shape and a path. They're really the same thing -- sets of path segments. No. A shape is no longer a group of line segments. You *could* convert it to such a thing but that requires a bunch of complex math (ie http://www.youtube.com/watch?v=OmfliNQsk88) For now, I'm not proposing to add that to the canvas API. Once the Path API is implemented, we can add any number of features, such as adding a path so as to form the union of both paths, adding a path so as to form the intersection of both paths, etc. The resulting 'path' will once again have no winding. This is very confusing and extremely hard to implement I don't understand why it's hard to implement. It's just the non-Path API, but stored away for future use. Right now we have two options (ignoring the text parts of the path API): concatenating path segments, and concatenating path segments after having first outlined one of them. FYI the outlining algorithm is also not correct. It suffers from the same issue that strokes are segments. Can you elaborate? (I think I may have asked already, in which case, my apologies for asking again.) On the long run I think it would make sense to add other methods, e.g. one combining two or more paths together such that the resulting path would outline the union of the insides of the provided paths, or the intersections, or whatnot. I think that would be much more confusing and difficult to implement. I didn't come up with this on my own :-). This is done by graphics libraries that offers path manipulation support. For instance: skia: http://skia-autogen.googlecode.com/svn/docs/html/classSkPathEffect.html lib2geom: http://wiki.inkscape.org/wiki/index.php/WorkingWith2GeomFAQ Direct2D: http://msdn.microsoft.com/en-us/library/windows/desktop/dd756653(v=vs.85).aspx#path_geometries I'm confused. Are these examples of how to make confusing APIs, or examples of how the current API is confusing? Those look really, really complicated relative to what Canvas looks like today. On Thu, 5 Sep 2013, Rik Cabanier wrote: The problem happens when you call fill or stroke multiple times. [...] Now I want to create a region that covers what was drawn. [...] 'p' won't describe the same area as what was filled. Sure, for that you need a new API function, e.g. union, which as I've mentioned before, I think would be a logical addition to the API in due course. But I don't think we should add features too quickly, lest we get too far ahead of browsers. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: [whatwg] Path API feedback
On Tue, Aug 20, 2013 at 3:36 PM, Ian Hickson i...@hixie.ch wrote: On Fri, 26 Apr 2013, Rik Cabanier wrote: I think an author would expect that 'addPathByStrokingPath' and other path methods render as if you stroked/outlined directly on the canvas context. Same goes for 'addPath'. I believe very few people actually want the current behavior that's in the spec. I don't know how true that is. It seems logical to me that this: context.beginPath(); context.rect(0,0,100,100); context.rect(50,50,150,150); context.fill(); ...should do the same as this: var p1 = new Path(); p1.rect(0,0,100,100); var p2 = new Path();s p2.rect(50,50,150,150); var p = new Path(); p.addPath(p1); p.addPath(p2); context.fill(p); ...for any combination of path commands where I've put the rect()s. Yes, that would be reasonable behavior since a path is just an aggregation of segments. The problem happens when you call fill or stroke multiple times. For instance: context.beginPath(); context.rect(0,0,100,100); context.fill(); context.beginPath(); context.rect(200,50,-150,150); context.fill(); Now I want to create a region that covers what was drawn. p1.rect(0,0,100,100); var p2 = new Path();s p2.rect(200,50,-150,150); var p = new Path(); p.addPath(p1); p.addPath(p2); 'p' won't describe the same area as what was filled. I think the spec needs to mention that - sections of the path where both edges are filled should be removed - winding needs to be done so eofill and fill give the same result I've filed a bug for adding something like this: https://www.w3.org/Bugs/Public/show_bug.cgi?id=21835 I'm not sure exactly what the algorithm should be (as we discussed on IRC today), so if anyone has any input here, please don't hesitate to comment. I can help if needed. I know the skia people are working on this as well. The algorithm is fairly straightforward to describe in prose. Implementation is very hard though... Please do add such help as comments on the bug, that would be very helpful. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
[whatwg] Path API feedback
On Fri, 26 Apr 2013, Rik Cabanier wrote: I think an author would expect that 'addPathByStrokingPath' and other path methods render as if you stroked/outlined directly on the canvas context. Same goes for 'addPath'. I believe very few people actually want the current behavior that's in the spec. I don't know how true that is. It seems logical to me that this: context.beginPath(); context.rect(0,0,100,100); context.rect(50,50,150,150); context.fill(); ...should do the same as this: var p1 = new Path(); p1.rect(0,0,100,100); var p2 = new Path();s p2.rect(50,50,150,150); var p = new Path(); p.addPath(p1); p.addPath(p2); context.fill(p); ...for any combination of path commands where I've put the rect()s. I think the spec needs to mention that - sections of the path where both edges are filled should be removed - winding needs to be done so eofill and fill give the same result I've filed a bug for adding something like this: https://www.w3.org/Bugs/Public/show_bug.cgi?id=21835 I'm not sure exactly what the algorithm should be (as we discussed on IRC today), so if anyone has any input here, please don't hesitate to comment. I can help if needed. I know the skia people are working on this as well. The algorithm is fairly straightforward to describe in prose. Implementation is very hard though... Please do add such help as comments on the bug, that would be very helpful. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'