[whatwg] Stroking algorithm in Canvas 2d

Jasper St. Pierre jstpierre at mecheye.net
Thu Oct 10 16:19:55 PDT 2013

On Thu, Oct 10, 2013 at 6:57 PM, Rik Cabanier <cabanier at gmail.com> wrote:

> On Thu, Oct 10, 2013 at 3:36 PM, Ian Hickson <ian at hixie.ch> wrote:
>> On Thu, 10 Oct 2013, Justin Novosad wrote:
>> > On Thu, Oct 10, 2013 at 5:48 PM, Ian Hickson <ian at hixie.ch> wrote:
>> > > On Thu, 10 Oct 2013, Rik Cabanier wrote:
>> > > >
>> > > > setLineDash([30]);
>> > > > rect(10, 10, 100, 100);
>> > > > rect(10, 110, 100, 100);
>> > > > rect(10, 210, 100, 100);
>> > > > stroke();
>> > > >
>> > > > These rectangles should look the same.
>> > >
>> > > I presume you mean "I want those rectangles to look the same". I don't
>> > > see any a priori objective reason why they should look the same.
>> >
>> > And is there an a priori objective reason why they should look
>> > different? It seem pretty obvious to me that there would be way more
>> > designers wanting the rects to look the same than there would be wanting
>> > the rects to look different.
>> >
>> > [...] should we not provide the most desirable behavior by default?
>> We should definitely provide the most desirable behaviour by default. The
>> question is, what is it? The only argument one way or the other I've seen
>> on this so far is the idea that if we don't reset, we get a more balanced
>> distribution of the dash density, whereas if we do reset, the dash density
>> is biased towards the start of the dash pattern.
>> The actual most desireable behaviour may in fact be neither Rik's proposal
>> nor mine, but something more like yours, where we somehow balance the
>> dashes between each node in the path, but I don't really know exactly how
>> to do that.
> I think we should have that as an option. Doing it for rects is
> straightforward, but I suspect that it might be more difficult for
> arbitrary shapes.
>> Just so we're clear, I really don't have a strong opinion on this issue. I
>> just want to make sure we apply the same rigour to deciding what the model
>> should be as we do to everything else, and that means not just doing
>> things because they've always been done that way, but instead either
>> figuring out why they've always been done that way, or starting from first
>> principles or data and deriving the right behaviour.
> I think that's totally reasonable. "That's how we've always done it" often
> no longer applies.

I really think there are better things we could be spending our time doing
than figuring out what the best stroking model is -- it seems that a
combination of dashOffset and closing paths means we can make all three
models draw the same shapes with the dash primitives. It's not like one
model is more powerful than any other, as I understand it.

Consistency with every other drawing model out there is probably more
important than you first imagine. Documentation, testing, interoperability
between browsers, and developer learning are all big motivations to keep
things the same.

If we do decide on something that's different from how we usually do it,
I'd really like some documentation on this, along with some rationale.

I can imagine an implementer assuming it's a direct translation of their
underlying API.

And as I said before, my coworkers and I are working on porting a bunch of
old cairo programs to the web, and it's nice to have a familiar API without
having to get tripped up on a small detail. There's already a bunch of
different vector graphics APIs, all based on the PostScript drawing model:
OpenVG/SVG/PDF/cairo/skia/Quartz/Direct2D, and differentiating "just
because" doesn't seem like a strong argument to me.

Additionally, I remember there were some similar concerns with
border-radius / border-style interaction where things where there were
interoperability concerns and it was a very similar pain to get things
consistent across all browsers.

Calling attention to these sort of small differences is very important.

Additionally, though we should have them anyway for whatever we decide, I'd
like some canvas conformance tests for this behavior with proposed renders
to help implementers.

> So far, the proposals seem to be to reset on each subpath, to not reset on
>> each subpath, and to add more features to the API.
>> If we don't want to add more features (features are expensive), then we're
>> left with reset and not reset. You can do everything you can do with
>> resetting in the no-resetting case; you can't do everything you can do
>> without resetting in the reset case. So the only strong argument there is
>> that one of the two ways provides more power to authors.
> dashOffset is there for authors who want to implement the behavior you are
> looking for.
> They would have to calculate the length of the previous sub paths. As
> Stephan and Justin have pointed out, the current implemented behavior is
> less surprising to authors.


More information about the whatwg mailing list