[whatwg] Blurry lines in 2D Canvas (and SVG)

Rik Cabanier cabanier at gmail.com
Wed Jul 24 11:25:54 PDT 2013

On Wed, Jul 24, 2013 at 6:20 AM, Glenn Maynard <glenn at zewt.org> wrote:

> On Tue, Jul 23, 2013 at 11:56 PM, Rik Cabanier <cabanier at gmail.com> wrote:
>>   This happens because you offset 1 pixel and then draw a half pixel
>>>> stroke
>>>> on each side. Since it covers only half the pixel, the color gets
>>>> mapped to
>>>> 50% gray.
>>>> You can work around this by doing an extra offset of half the
>>>> devicepixelratio,
>>> For Canvas, you should always add 0.5, since you're in the canvas
>>> coordinate space, before the pixel ratio is applied.
>> That seemed like an OK idea until I thought about it some more.
>> Doing a .5 scale will also affect your fills so a rect will now have
>> aliased borders.
> I meant you always want to add 0.5 to offsets, not ratio / 2.

sorry, that was a typo. I meant to say 'translate(.5, .5)' will offset your

> On a device with a pixel ratio of 2, you still want to add 0.5, not 1.

> You want to add 0.5 if you're drawing a 1px stroke, so the rect ends at
> 0.5 and the stroke extends to the edge of the pixel at 0.  If you're
> drawing a filled rect with no stroke, you don't want to add 0.5, so the
> rect itself goes to the edge of the pixel rather than the stroke.

That is very confusing. So, if there's a scale, you have to unapply the
scale to the .5 offset?

> I agree this isn't all that obvious.  What if there was an option for
> strokes to align themselves to the inside or outside of the path, instead
> of centering over the path?  That way, drawing 5x5-10x10 would cause both
> the stroke and the edge of the fill to be pixel-aligned.  This is
> Photoshop's "Position" stroke option, which can be set to "inside",
> "outside" or "center".  I don't know if that makes sense with the way paths
> work, and it would make the stroke's path dependent on its width.

That's a cool feature, but doesn't solve the problem. Users would still
need to be aware that they need to align to whole pixels to stroke.

> Also adjusting for non-round device pixel ratio or as Kornel mentions,
>> having transforms will still result in blurry lines (unless you do a bunch
>> of math)
> Do you mean Canvas transforms or higher-level transforms, like CSS
> scaling?  I don't think Canvas can help with the latter.

Canvas transforms. I agree the resampling or transforming the canvas bitmap
after the fact is not something we can control.

> Non-integer pixel ratios lead to all kinds of aliasing and quality
> problems.  I suspect trying to fix them is futile...

A lot of people have zoom turned on and there are quite a few devices that
have non-integer pixel ratios. I'd like to solve the problem everywhere if

>> I agree that we can't change this, but maybe we can add something to make
>> it better.
>> In PDF there is a feature called "strokeAdjust" that will make the stroke
>> align to pixel boundaries. I've attached a drawing that shows the feature.
>> Basically, if you turn it on and the stroke doesn't fill the entire pixel,
>> that pixel isn't drawn.
>> Apple has a Core Graphics function called "CGGStateSetStrokeAdjust" so
>> at least they would be able to implement this easily. :-)
> Isn't this simply disabling antialiasing?  That's what the illustration
> seems to show.

It tells the renderer not to use over-scan but center-scan for strokes. I
was under the impression that GPU have centerscan by default and that
implementors have to add a bunch of code to work around this.

> That'll work in certain cases, with the caveats that have been mentioned:
> you don't want it when animating lines, for diagonals, if you have rounded
> corners, etc.

I *think* we still alias in certain cases. I will check.

More information about the whatwg mailing list