- From: Dean McNamee <deanm@chromium.org>
- Date: Thu, 16 Jul 2009 17:44:10 +0200
Currently the spec says that if you call lineTo(), quadraticCurveTo(), bezierCurveTo(), etc without a "current point" (having called moveTo() first), they should do nothing. The compatibility problem we've run into is that since Firefox just calls directly into Cairo, they don't follow this behavior and they inherit the Cairo behavior. For lineTo(), this means if there is no current point (there was no call to moveTo first), it is equivalent to calling moveTo(), and then lineTo() (creating a zero length line). This has led people to write code like this: for (...) { ctx.lineTo(...); } I understand why that style is desirable, it's much simpler than writing (the correct): for (...) { if (i == 0) { ctx.moveTo(...); } else { ctx.lineTo(...); } } It happens to look ok in Firefox, so people don't notice it's wrong. Things get more interesting when you make a Bezier curve. The Cairo behavior (and thus the Firefox behavior) is to moveTo() to the first control point. Since the control points of a Bezier don't generally lie on the path, this is behavior looks quite odd. While the current spec is most pure, I am interested in opinions of bending it a little to meet somewhere in the middle. I just committed a patch to WebKit so that if a current point doesn't exist, moveTo() is called on the endpoint (of a line or a curve), but no line or curve is emitted. This means WebKit went from following the spec to violating the spec, but working on pages that people expect to work. This behavior still works for multiple calls to lineTo without a moveTo, the first lineTo doesn't create a zero-length line, it just does the moveTo(). Further calls actually start creating lines. This also avoids the control point problem, as you don't emit the first curve, just set the endpoint as the current point. I haven't looked at arcTo(), so I'm not sure how it should behave. Thoughts? Thanks Dean
Received on Thursday, 16 July 2009 08:44:10 UTC