Re: [whatwg] Stroking algorithm in Canvas 2d

On Thu, Oct 10, 2013 at 11:29 AM, Ian Hickson <ian@hixie.ch> wrote:

> On Thu, 10 Oct 2013, Jasper St. Pierre wrote:
> > >
> > > If there's a good reason to do this, other than "we've always done it
> > > this way", then it's certainly a good thing to consider. If none of
> > > the browsers are willing to implement it the way the spec describes
> > > it, that's also a reason to change the spec. But just that it's always
> > > been done that way isn't a reason at all.
> >
> > Differentiating from the drawing model we've always been used that can
> > easily be used by their underlying libraries seems like churn for both
> > people used to vector graphics libraries (a number of people using cairo
> > are porting their projects over to <canvas>), and implementers.
>
> Sure, but if it results in a better model overall, it seems worth it.
>
> The problem I see with the "reset at every move" model is that there's no
> way to _not_ reset at every move. As Justin points out, you could easily
> adjust the "no-reset" model to reset by just inserting annotations into
> the path that cause it to reset.
>
>
> On Thu, 10 Oct 2013, Justin Novosad wrote:
> > >
> > >    http://goo.gl/hwK7fv
> >
> > So in the case of a box, it makes perfect sense for the corners to be
> > start/stop points in the dashing pattern.  It gives a reassuring sense
> > of symmetry to the drawing.
>
> That would be a third dashing model, different from both the spec and
> Rik's proposal.
>

It's not "rik's proposal". It's how dashing and stroking is implemented in
the real world.
What Justin is proposing is similar to Illustrator's "Align dashes to
corners". The could be a boolean in the graphics state.

However, before we start adding new features, we should agree on what is
happening today. Otherwise this thread will get very confusing.


> > On the other hand, if you are drawing a continuous curve in a graphing
> > application, you would want constant density in the dashing pattern even
> > though the curve way be built from a series of subpaths.
>
> Right, that's the basis on which I wrote the proposal in the spec.
>
>
> > The algorithm suggested by Rik allows for both, but is not ideal.
>
> Rik's proposal is different from both of those, as I see it: it resets at
> every move, so the density will be biased towards the start of the dash
> pattern, and it doesn't reset at corners, so it doesn't give the symmetry
> you mention above.
>
>
> > Basically: dashing is continuous over joins. If you want to insert a
> > break point in the dashing pattern, you just end the current path and
> > start a new one, or break continuity by calling moveTo like you (Ian)
> > did in the fiddle cited above.
>
> Right. That biases the density to the start of the pattern.
>
>
> > The main issue I see with that algorithm is that it does not solve the
> > case where you would want a join and a dashing break at the same point.
> > I think that is an important case to support, in particular for drawing
> > rectangles.
>
> It also doesn't support the case where you want a new subpath but not a
> break in the pattern.
>
>
> > One way we could address this by adding a new path method that inserts a
> > break in the dashing pattern (without unjoining the subpaths).
>
> That would solve one of the two limitations, yes.
>
>
> > Also, I think it should be implicit in the rect() path primitive that
> > the corners are joined and that they are also stop/start points for the
> > dashing pattern.
>
> If we provide the option to annotate the path in this way, we should
> probably just provide an argument to control that.
>
>
> On Thu, 10 Oct 2013, Rik Cabanier wrote:
> > >
> > > One way we could address this by adding a new path method that inserts
> > > a break in the dashing pattern (without unjoining the subpaths). Also,
> > > I think it should be implicit in the rect() path primitive that the
> > > corners are joined and that they are also stop/start points for the
> > > dashing pattern.
> >
> > That would break current behavior . We will need a new API or additional
> > arguments (a dash array?)
>
> Can you elaborate? What would break?
>

If you draw a rect with dashes today, the dashing will be applied normally.
Justin wants to change this behavior so we will need something to trigger
that. Othewise, existing applications that use dashed rectangles will start
looking different.


>
>
> On Thu, 10 Oct 2013, Rik Cabanier wrote:
> >
> > I think in your mind, you put the path down and then the stroke follows
> > that path. It's as if you take one continuous stroked and dashed line,
> > then cut it in pieces and then drape over the path.
>
> Right.
>
>
> > This is not how stroking works.
>
> It's not how stroking works in PDF, but there's no reason that I can see
> that it shouldn't be how stroking works.
>

This is how stroking works *everywhere *including canvas today.


>
> Why is your model superior?
>

This is not my model.
We can't change the current implementations anyway because they are already
used.


>
>
> > > > They're not always lines though. What about curves?
> > >
> > > Curves are lines too. The spec uses the term "path", though.
> >
> > We've touched on this before. Curves can't simply be offset and still be
> > bezier curves.
> >
> > For instance, if you take the following snippet of SVG:
> >
> > <path fill="none" stroke="#000000" stroke-miterlimit="10"
> > d="M50,150C50,50,82.908,42.906,150,62.886"/>
> >
> > The outlined stroke will look like this:
> >
> > <path
> d="M256.5,150h-1*c*0-47.957,7.732-76.057,24.333-88.435*c*18.433-13.744,47.57-7.718,76.31,0.841l-0.285,0.958
> >
> *c*-38.963-11.603-60.816-11.894-75.427-0.998*C*264.104,74.54,256.5,102.386,256.5,150z"/>
> >
> > Note how there are now 2 beziers on each edge to approximate the stroke.
>
> I agree with what you're saying but I don't see why this is a problem.
>
> Why is approximating a problem? It's not like we're doing pure math paths
> here, they're all approximated at the end of the day. The spec doesn't
> specify how you implement it exactly, it just requires that we have
> consistent results that, within the limitations of the hardware (e.g. only
> 1 pixel for every 10 microns) are indistinguishable from the theoretical
> results.


this is why drawings/pictures of what the stroke should look like are more
important.
Saying "inflate the path perpendicular" is not good enough since it could
mean anything.
You either write out the math (which no spec has done afaik) or you give
examples (like
https://developer.apple.com/library/ios/documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_paths/dq_paths.html
)

Received on Thursday, 10 October 2013 18:53:28 UTC