[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
fills.


> 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
possible.


>
>
>> 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