Re: [whatwg] Blurry lines in 2D Canvas

2013-09-28 Thread Rik Cabanier
Yeah, this should be specified somewhere.
As you point out, luckily everyone is in agreement.


On Fri, Sep 27, 2013 at 7:41 PM, Glenn Maynard  wrote:

> On Fri, Sep 27, 2013 at 4:38 PM, Jasper St. Pierre  >wrote:
>
> > The issue here is that the canvas API does not specify how pixels are
> sited
> > on the canvas: if you imagine pixels as enlarged squares on a grid
> (shush,
> > I know), does an X coordinate of 5 name the center of the square, or the
> > intersection between 4th and 5th squares?
> >
>
> That's not the issue this thread is about.  I don't know if it's specified
> (though I suspect is is), but WebKit, Firefox and IE10's Canvas
> implementations all use OpenGL's coordinate system.  This can be seen in
> the very first post in the thread, which renders consistently in all three
> browsers.  http://jsfiddle.net/V92Gn/128/
>
> --
> Glenn Maynard
>


Re: [whatwg] Blurry lines in 2D Canvas

2013-09-28 Thread Rik Cabanier
On Fri, Sep 27, 2013 at 2:08 PM, Ian Hickson  wrote:

> On Thu, 5 Sep 2013, Rik Cabanier wrote:
> > On Thu, Sep 5, 2013 at 3:22 PM, Ian Hickson  wrote:
> > > On Sat, 10 Aug 2013, Rik Cabanier wrote:
> > > >
> > > > I was wondering if this is something that happens in Flash as well.
> > > > It turns out that there's an option called "hinting: Keep stroke
> > > > anchors on full pixels to prevent blurry lines." There's a blog post
> > > > on what this does:
> > > >
> > > >
> http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html
> > > >
> http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html
> > > >
> > > > I created an example (in flash sorry) that shows the feature:
> > > > http://cabanier.github.io/BlendExamples/pixelsnap/pixelsnap.html 2
> > > > sets of strokes move across the screen and are also scaled.
> > > >
> > > > The top strokes behave like canvas does today. They start of blurry
> > > > and during the animation they slowly get ticker. For some reason it
> > > > doesn't look very smooth. The bottom strokes have hinting turned on.
> > > > They are sharp at the beginning and during the animation they stay
> > > > the same size until the internal stroke width is large enough. At
> > > > that point you see a 'jump'.
> > > >
> > > > I think canvas should have a similar feature...
> > >
> > > Can you elaborate on how exactly you would want this to work? How
> > > would you avoid the alignment and distortion problems when applying
> > > this to anything less trivial than a rectangle?
> >
> > Basically, this would *just* move the control points and the width of
> > paths so the strokes are always aligned to the pixel grid (This would
> > take pixel density and transformations into account). After this, you
> > would draw as usual.
>
> Can you define "aligned to the pixel grid"?
>
> If I have a line from x1,y to x2,y, followed by an arc from x2,y back to
> x1,y with radius r, what should happen and why?
>

Align the anchor points of all the segments. Don't change any of the
anti-aliasing behavior.


>
> What if they're draw as separate paths?


I'm unsure if I follow. That shouldn't make a different.
What might be different however, is if you draw a diagonal line in 1
segment or 2 since the middle point will be aligned to the grid in the
latter case.


Re: [whatwg] Blurry lines in 2D Canvas

2013-09-27 Thread Glenn Maynard
On Fri, Sep 27, 2013 at 4:38 PM, Jasper St. Pierre wrote:

> The issue here is that the canvas API does not specify how pixels are sited
> on the canvas: if you imagine pixels as enlarged squares on a grid (shush,
> I know), does an X coordinate of 5 name the center of the square, or the
> intersection between 4th and 5th squares?
>

That's not the issue this thread is about.  I don't know if it's specified
(though I suspect is is), but WebKit, Firefox and IE10's Canvas
implementations all use OpenGL's coordinate system.  This can be seen in
the very first post in the thread, which renders consistently in all three
browsers.  http://jsfiddle.net/V92Gn/128/

-- 
Glenn Maynard


Re: [whatwg] Blurry lines in 2D Canvas

2013-09-27 Thread Jasper St. Pierre
The issue here is that the canvas API does not specify how pixels are sited
on the canvas: if you imagine pixels as enlarged squares on a grid (shush,
I know), does an X coordinate of 5 name the center of the square, or the
intersection between 4th and 5th squares?

If we say that it names the center of the square itself, then we'll have
sharp strokes but blurry fills -- filling from x=5 to x=10 will only fill
half the area in the 5th square.
If we say that it names the intersection between the pixels then we'll have
blurry strokes but sharp fills.

For perspective, old APIs that didn't have support for antialiased graphics
like X11 and GDI say that it's the former, but the lack of antialiasing
made it not noticeable.

Modern APIs like cairo, Quartz 2D and Direct2D say it's the latter, and
stick by it. The recommended solution is either to use even line widths
with pixel-perfect coordinates or add 0.5 to all lines you draw so they're
offset by half a pixel. [0]

Neither of these are perfect solutions when you have transforms; perhaps
optional support for crisp lines or otherwise turning off AA would be a
good idea.

But whatever we do, we should certainly pick a pixel citing system (and I'd
highly suggest the latter) and make it explicit in the spec.

http://cairographics.org/FAQ/#sharp_lines


On Fri, Sep 27, 2013 at 5:21 PM, Ruben Rodriguez II  wrote:

> I would just like to note that sometimes we do not WANT to draw precise
> shapes. :) Many people enjoy the aesthetic of 2d pixel-based graphics, and
> it should be a viable choice for the graphical style of a game, for
> instance. Canvas makes this more difficult, and it shouldn't be so!
>
> Why can't we have a global option to turn this off if we want to? I'm not
> trying to advocate for throwing away all antialiasing... I understand that
> most applications will probably want it by default, and agree with having
> it as the default.
>
> Basically all it is is http://www.whatwg.org/specs/**
> web-apps/current-work/**multipage/the-canvas-element.**
> html#image-smoothing...
>  except that we're not talking about scaling.
>
> On 09/05/2013 05:22 PM, Ian Hickson wrote:
>
>> On Tue, 23 Jul 2013, Rik Cabanier wrote:
>>
>>> we've noticed that if you draw lines in canvas or SVG, they always end
>>> up blurry. For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>>>
>> Not always, only if you don't draw the line aligned with the pixel grid
>> (e.g. you draw a diagonal line, or a horizontal or vertical line that
>> isn't centered in the middle of pixels on the pixels grid, or a horizontal
>> or vertical line whose width isn't an integral number of pixels, etc).
>>
>> The options, on a pixel grid display, are:
>>
>>   - don't honour the position precisely -- this leads to very ugly
>> artifacts when animating (lines jerk around), and basically means that
>> the graphics aren't accurate.
>>
>>   - instead of describing the shapes as vectors, describe them using
>> programs that can adapt to the position and size they're being drawn
>> at, such that they automatically snap to the pixel grid in a pretty
>> fashion -- this is what fonts do.
>>
>>   - try to trick the eye by using anti-aliasing when things don't line up
>> exactly on the pixel grid.
>>
>> The first two really aren't plausible options for .
>>
>>
>> On Wed, 24 Jul 2013, Kornel Lesiński wrote:
>>
>>> For 1-pixel lines it could be fixed by allowing authors to specify that
>>> path should be stroked with lines aligned to inside/outside of the path
>>> (which is a useful feature on its own).
>>>
>> https://www.w3.org/Bugs/**Public/show_bug.cgi?id=22674
>>
>>
>> On Tue, 23 Jul 2013, Rik Cabanier wrote:
>>
>>> Sure, but how can we fix this?
>>>
>> What is there to fix? The options above are basically the only options.
>> You can't not do one of them -- there's no way to draw a crisp line that
>> isn't pixel aligned. There's no pixels there. Similarly, there's no way to
>> draw a line that's neither horizontal nor vertical yet is crisp and
>> doesn't look jaggy. The pixels are squares, they don't rotate on modern
>> pixel displays.
>>
>>
>> On Wed, 24 Jul 2013, Kornel Lesiński wrote:
>>
>>> Should arc() and bezier curves also be snapped? What if you want a line
>>> that touches the curve?
>>>
>> That's precisely the problem with snapping -- it is far worse than
>> antialiasing. You can't draw precise shapes if you have snapping.
>>
>>
>> On Wed, 24 Jul 2013, Dirk Schulze wrote:
>>
>>> Means implementations would need to take viewport, transformations of
>>> the document, transformations on elements in the DOM hierarchy, zoom
>>> level, aspect ratio of the canvas, position of the canvas in the
>>> document, transformations in the canvas and device pixel resolution into
>>> account to snap lines to the correct position on the i

Re: [whatwg] Blurry lines in 2D Canvas

2013-09-27 Thread Ruben Rodriguez II
I would just like to note that sometimes we do not WANT to draw precise 
shapes. :) Many people enjoy the aesthetic of 2d pixel-based graphics, 
and it should be a viable choice for the graphical style of a game, for 
instance. Canvas makes this more difficult, and it shouldn't be so!


Why can't we have a global option to turn this off if we want to? I'm 
not trying to advocate for throwing away all antialiasing... I 
understand that most applications will probably want it by default, and 
agree with having it as the default.


Basically all it is is 
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-smoothing 
... except that we're not talking about scaling.


On 09/05/2013 05:22 PM, Ian Hickson wrote:

On Tue, 23 Jul 2013, Rik Cabanier wrote:

we've noticed that if you draw lines in canvas or SVG, they always end
up blurry. For instance see this fiddle: http://jsfiddle.net/V92Gn/128/

Not always, only if you don't draw the line aligned with the pixel grid
(e.g. you draw a diagonal line, or a horizontal or vertical line that
isn't centered in the middle of pixels on the pixels grid, or a horizontal
or vertical line whose width isn't an integral number of pixels, etc).

The options, on a pixel grid display, are:

  - don't honour the position precisely -- this leads to very ugly
artifacts when animating (lines jerk around), and basically means that
the graphics aren't accurate.

  - instead of describing the shapes as vectors, describe them using
programs that can adapt to the position and size they're being drawn
at, such that they automatically snap to the pixel grid in a pretty
fashion -- this is what fonts do.

  - try to trick the eye by using anti-aliasing when things don't line up
exactly on the pixel grid.

The first two really aren't plausible options for .


On Wed, 24 Jul 2013, Kornel Lesiński wrote:

For 1-pixel lines it could be fixed by allowing authors to specify that
path should be stroked with lines aligned to inside/outside of the path
(which is a useful feature on its own).

https://www.w3.org/Bugs/Public/show_bug.cgi?id=22674


On Tue, 23 Jul 2013, Rik Cabanier wrote:

Sure, but how can we fix this?

What is there to fix? The options above are basically the only options.
You can't not do one of them -- there's no way to draw a crisp line that
isn't pixel aligned. There's no pixels there. Similarly, there's no way to
draw a line that's neither horizontal nor vertical yet is crisp and
doesn't look jaggy. The pixels are squares, they don't rotate on modern
pixel displays.


On Wed, 24 Jul 2013, Kornel Lesiński wrote:

Should arc() and bezier curves also be snapped? What if you want a line
that touches the curve?

That's precisely the problem with snapping -- it is far worse than
antialiasing. You can't draw precise shapes if you have snapping.


On Wed, 24 Jul 2013, Dirk Schulze wrote:

Means implementations would need to take viewport, transformations of
the document, transformations on elements in the DOM hierarchy, zoom
level, aspect ratio of the canvas, position of the canvas in the
document, transformations in the canvas and device pixel resolution into
account to snap lines to the correct position on the individual device,
right?Otherwise it sounds to be hard to guarantee that you don't see
antialiased strokes and lines might snap more then just one device
pixel. This would also be a problem for aligning shapes to each other in
the canvas I guess. What happens on the next transformation after a
drawing operation. Say you draw a line that was snapped to the grid and
then you do scale(1.1, 1.1). Shall the implementation redraw the canvas?
After all it is an pixel image. A vector based drawing format would be
better suited for such a task.

Indeed.


On Sat, 10 Aug 2013, Rik Cabanier wrote:

I was wondering if this is something that happens in Flash as well. It
turns out that there's an option called "hinting: Keep stroke anchors on
full pixels to prevent blurry lines." There's a blog post on what this
does:
http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html


I created an example (in flash sorry) that shows the feature:
http://cabanier.github.io/BlendExamples/pixelsnap/pixelsnap.html
2 sets of strokes move across the screen and are also scaled.

The top strokes behave like canvas does today. They start of blurry and
during the animation they slowly get ticker. For some reason it doesn't
look very smooth.
The bottom strokes have hinting turned on. They are sharp at the beginning
and during the animation they stay the same size until the internal stroke
width is large enough. At that point you see a 'jump'.

I think canvas should have a similar feature...

Can you elaborate on how exactly you would want this to work? How would
you avoid the alignment and distortion problems when applying this to
anything less trivial than a

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

2013-09-27 Thread Ruben Rodriguez II
It seems like those should be two separate things instead of lumped all 
together in a monolithic "You can do this if you want... or whatever!"


"Snapping" is definitely something different than antialiasing. It's a 
huge pain for anyone trying to provide a(n accurate) simple 2D primitive 
library.


On 07/23/2013 08:16 PM, Rik Cabanier wrote:

I guess there's too many "might"s in there :-)

I want to "adjust line positions and line widths to align edges with device
pixels" but not "the user agent might turn off anti-aliasing for all lines
and curves"

On Tue, Jul 23, 2013 at 6:11 PM, Brian Birtles  wrote:


(2013/07/24 10:07), Rik Cabanier wrote:


yeah, at first blush that seemed what was needed.
However, this simply turns off antialiasing completely so regular
artwork looks terrible.


That's a quality of implementation issue. The description of the property
value says,

"Indicates that the user agent shall attempt to emphasize the contrast
between clean edges of artwork over rendering speed and geometric
precision. To achieve crisp edges, the user agent might turn off
anti-aliasing for all lines and curves or possibly just for straight lines
which are close to vertical or horizontal. Also, the user agent might
adjust line positions and line widths to align edges with device pixels."

I'm not sure what use case you have in mind though. Perhaps it's something
that doesn't fit that description?






Re: [whatwg] Blurry lines in 2D Canvas

2013-09-27 Thread Ian Hickson
On Thu, 5 Sep 2013, Rik Cabanier wrote:
> On Thu, Sep 5, 2013 at 3:22 PM, Ian Hickson  wrote:
> > On Sat, 10 Aug 2013, Rik Cabanier wrote:
> > >
> > > I was wondering if this is something that happens in Flash as well. 
> > > It turns out that there's an option called "hinting: Keep stroke 
> > > anchors on full pixels to prevent blurry lines." There's a blog post 
> > > on what this does:
> > >
> > > http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html
> > > http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html
> > >
> > > I created an example (in flash sorry) that shows the feature: 
> > > http://cabanier.github.io/BlendExamples/pixelsnap/pixelsnap.html 2 
> > > sets of strokes move across the screen and are also scaled.
> > >
> > > The top strokes behave like canvas does today. They start of blurry 
> > > and during the animation they slowly get ticker. For some reason it 
> > > doesn't look very smooth. The bottom strokes have hinting turned on. 
> > > They are sharp at the beginning and during the animation they stay 
> > > the same size until the internal stroke width is large enough. At 
> > > that point you see a 'jump'.
> > >
> > > I think canvas should have a similar feature...
> >
> > Can you elaborate on how exactly you would want this to work? How 
> > would you avoid the alignment and distortion problems when applying 
> > this to anything less trivial than a rectangle?
> 
> Basically, this would *just* move the control points and the width of 
> paths so the strokes are always aligned to the pixel grid (This would 
> take pixel density and transformations into account). After this, you 
> would draw as usual.

Can you define "aligned to the pixel grid"?

If I have a line from x1,y to x2,y, followed by an arc from x2,y back to 
x1,y with radius r, what should happen and why?

What if they're draw as separate paths?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


Re: [whatwg] Blurry lines in 2D Canvas

2013-09-05 Thread Rik Cabanier
On Thu, Sep 5, 2013 at 3:22 PM, Ian Hickson  wrote:

> On Tue, 23 Jul 2013, Rik Cabanier wrote:
> >
> > we've noticed that if you draw lines in canvas or SVG, they always end
> > up blurry. For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>
> Not always, only if you don't draw the line aligned with the pixel grid
> (e.g. you draw a diagonal line, or a horizontal or vertical line that
> isn't centered in the middle of pixels on the pixels grid, or a horizontal
> or vertical line whose width isn't an integral number of pixels, etc).
>
> The options, on a pixel grid display, are:
>
>  - don't honour the position precisely -- this leads to very ugly
>artifacts when animating (lines jerk around), and basically means that
>the graphics aren't accurate.
>
>  - instead of describing the shapes as vectors, describe them using
>programs that can adapt to the position and size they're being drawn
>at, such that they automatically snap to the pixel grid in a pretty
>fashion -- this is what fonts do.
>
>  - try to trick the eye by using anti-aliasing when things don't line up
>exactly on the pixel grid.
>
> The first two really aren't plausible options for .
>
>
> On Wed, 24 Jul 2013, Kornel Lesiński wrote:
> >
> > For 1-pixel lines it could be fixed by allowing authors to specify that
> > path should be stroked with lines aligned to inside/outside of the path
> > (which is a useful feature on its own).
>
> https://www.w3.org/Bugs/Public/show_bug.cgi?id=22674
>
>
> On Tue, 23 Jul 2013, Rik Cabanier wrote:
> >
> > Sure, but how can we fix this?
>
> What is there to fix? The options above are basically the only options.
> You can't not do one of them -- there's no way to draw a crisp line that
> isn't pixel aligned. There's no pixels there. Similarly, there's no way to
> draw a line that's neither horizontal nor vertical yet is crisp and
> doesn't look jaggy. The pixels are squares, they don't rotate on modern
> pixel displays.
>
>
> On Wed, 24 Jul 2013, Kornel Lesiński wrote:
> >
> > Should arc() and bezier curves also be snapped? What if you want a line
> > that touches the curve?
>
> That's precisely the problem with snapping -- it is far worse than
> antialiasing. You can't draw precise shapes if you have snapping.
>
>
> On Wed, 24 Jul 2013, Dirk Schulze wrote:
> >
> > Means implementations would need to take viewport, transformations of
> > the document, transformations on elements in the DOM hierarchy, zoom
> > level, aspect ratio of the canvas, position of the canvas in the
> > document, transformations in the canvas and device pixel resolution into
> > account to snap lines to the correct position on the individual device,
> > right?Otherwise it sounds to be hard to guarantee that you don't see
> > antialiased strokes and lines might snap more then just one device
> > pixel. This would also be a problem for aligning shapes to each other in
> > the canvas I guess. What happens on the next transformation after a
> > drawing operation. Say you draw a line that was snapped to the grid and
> > then you do scale(1.1, 1.1). Shall the implementation redraw the canvas?
> > After all it is an pixel image. A vector based drawing format would be
> > better suited for such a task.
>
> Indeed.
>
>
> On Sat, 10 Aug 2013, Rik Cabanier wrote:
> >
> > I was wondering if this is something that happens in Flash as well. It
> > turns out that there's an option called "hinting: Keep stroke anchors on
> > full pixels to prevent blurry lines." There's a blog post on what this
> > does:
> >
> http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html
> > <
> http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html
> >
> >
> > I created an example (in flash sorry) that shows the feature:
> > http://cabanier.github.io/BlendExamples/pixelsnap/pixelsnap.html
> > 2 sets of strokes move across the screen and are also scaled.
> >
> > The top strokes behave like canvas does today. They start of blurry and
> > during the animation they slowly get ticker. For some reason it doesn't
> > look very smooth.
> > The bottom strokes have hinting turned on. They are sharp at the
> beginning
> > and during the animation they stay the same size until the internal
> stroke
> > width is large enough. At that point you see a 'jump'.
> >
> > I think canvas should have a similar feature...
>
> Can you elaborate on how exactly you would want this to work? How would
> you avoid the alignment and distortion problems when applying this to
> anything less trivial than a rectangle?


Basically, this would *just* move the control points and the width of paths
so the strokes are always aligned to the pixel grid (This would take pixel
density and transformations into account).
After this, you would draw as usual.


Re: [whatwg] Blurry lines in 2D Canvas

2013-09-05 Thread Ian Hickson
On Tue, 23 Jul 2013, Rik Cabanier wrote:
> 
> we've noticed that if you draw lines in canvas or SVG, they always end 
> up blurry. For instance see this fiddle: http://jsfiddle.net/V92Gn/128/

Not always, only if you don't draw the line aligned with the pixel grid 
(e.g. you draw a diagonal line, or a horizontal or vertical line that 
isn't centered in the middle of pixels on the pixels grid, or a horizontal 
or vertical line whose width isn't an integral number of pixels, etc).

The options, on a pixel grid display, are:

 - don't honour the position precisely -- this leads to very ugly 
   artifacts when animating (lines jerk around), and basically means that 
   the graphics aren't accurate.

 - instead of describing the shapes as vectors, describe them using 
   programs that can adapt to the position and size they're being drawn 
   at, such that they automatically snap to the pixel grid in a pretty 
   fashion -- this is what fonts do.

 - try to trick the eye by using anti-aliasing when things don't line up 
   exactly on the pixel grid.

The first two really aren't plausible options for .


On Wed, 24 Jul 2013, Kornel Lesiński wrote:
> 
> For 1-pixel lines it could be fixed by allowing authors to specify that 
> path should be stroked with lines aligned to inside/outside of the path 
> (which is a useful feature on its own).

https://www.w3.org/Bugs/Public/show_bug.cgi?id=22674


On Tue, 23 Jul 2013, Rik Cabanier wrote:
> 
> Sure, but how can we fix this?

What is there to fix? The options above are basically the only options. 
You can't not do one of them -- there's no way to draw a crisp line that 
isn't pixel aligned. There's no pixels there. Similarly, there's no way to 
draw a line that's neither horizontal nor vertical yet is crisp and 
doesn't look jaggy. The pixels are squares, they don't rotate on modern 
pixel displays.


On Wed, 24 Jul 2013, Kornel Lesiński wrote:
> 
> Should arc() and bezier curves also be snapped? What if you want a line 
> that touches the curve?

That's precisely the problem with snapping -- it is far worse than 
antialiasing. You can't draw precise shapes if you have snapping.


On Wed, 24 Jul 2013, Dirk Schulze wrote:
> 
> Means implementations would need to take viewport, transformations of 
> the document, transformations on elements in the DOM hierarchy, zoom 
> level, aspect ratio of the canvas, position of the canvas in the 
> document, transformations in the canvas and device pixel resolution into 
> account to snap lines to the correct position on the individual device, 
> right?Otherwise it sounds to be hard to guarantee that you don't see 
> antialiased strokes and lines might snap more then just one device 
> pixel. This would also be a problem for aligning shapes to each other in 
> the canvas I guess. What happens on the next transformation after a 
> drawing operation. Say you draw a line that was snapped to the grid and 
> then you do scale(1.1, 1.1). Shall the implementation redraw the canvas? 
> After all it is an pixel image. A vector based drawing format would be 
> better suited for such a task.

Indeed.


On Sat, 10 Aug 2013, Rik Cabanier wrote:
> 
> I was wondering if this is something that happens in Flash as well. It 
> turns out that there's an option called "hinting: Keep stroke anchors on 
> full pixels to prevent blurry lines." There's a blog post on what this 
> does: 
> http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html 
> 
> 
> I created an example (in flash sorry) that shows the feature:
> http://cabanier.github.io/BlendExamples/pixelsnap/pixelsnap.html
> 2 sets of strokes move across the screen and are also scaled.
> 
> The top strokes behave like canvas does today. They start of blurry and
> during the animation they slowly get ticker. For some reason it doesn't
> look very smooth.
> The bottom strokes have hinting turned on. They are sharp at the beginning
> and during the animation they stay the same size until the internal stroke
> width is large enough. At that point you see a 'jump'.
> 
> I think canvas should have a similar feature...

Can you elaborate on how exactly you would want this to work? How would 
you avoid the alignment and distortion problems when applying this to 
anything less trivial than a rectangle?

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

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

2013-08-12 Thread Rik Cabanier
On Mon, Aug 12, 2013 at 6:45 PM, Glenn Maynard  wrote:

> On Sat, Aug 10, 2013 at 9:43 PM, Rik Cabanier  wrote:
>
>> Ah, so you are relying on pixel snapping (=rounded up to 2 pixels).
>>
>
> Rounded to the nearest integer pixel.  If you give 1.25, the width would
> be 1.
>
>
>> If you can do that with your approach, why not with strokes that are
>> drawn from the center?
>>
>
> It might be possible, in principle, to only snap the "border" of the
> stroke instead of the whole thing, but I don't know how to do that or if
> it'd be worthwhile.  It seems like sharp lines are only particularly
> important for thin strokes (especially 1px), and in those cases the
> difference between a center and an outer stroke are minor.  (I don't know
> if it's harder to implement, eg. so there's no gap between a fill followed
> by an outer stroke.)
>
> I was wondering if this is something that happens in Flash as well. It
>> turns out that there's an option called "hinting: Keep stroke anchors on
>> full pixels to prevent blurry lines." There's a blog post on what this
>> does:
>> http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html 
>> 
>>
>
> I don't know about this, but the description sounds similar to what I'm
> suggesting.
>

Great! I think we're both on the same page on how the problem can be solved.
Do you still believe it's up to the author to do so, or are you leaning
towards solving it on the browser side?

I would also like to know if people see this as a problem that is worth
solving. Many of our Illustrator customers complain about this. We've tried
to fix it on the authoring side but it doesn't always work.


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

2013-08-12 Thread Glenn Maynard
On Sat, Aug 10, 2013 at 9:43 PM, Rik Cabanier  wrote:

> Ah, so you are relying on pixel snapping (=rounded up to 2 pixels).
>

Rounded to the nearest integer pixel.  If you give 1.25, the width would be
1.


> If you can do that with your approach, why not with strokes that are drawn
> from the center?
>

It might be possible, in principle, to only snap the "border" of the stroke
instead of the whole thing, but I don't know how to do that or if it'd be
worthwhile.  It seems like sharp lines are only particularly important for
thin strokes (especially 1px), and in those cases the difference between a
center and an outer stroke are minor.  (I don't know if it's harder to
implement, eg. so there's no gap between a fill followed by an outer
stroke.)

I was wondering if this is something that happens in Flash as well. It
> turns out that there's an option called "hinting: Keep stroke anchors on
> full pixels to prevent blurry lines." There's a blog post on what this
> does:
> http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html 
> 
>

I don't know about this, but the description sounds similar to what I'm
suggesting.

-- 
Glenn Maynard


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

2013-08-10 Thread Rik Cabanier
On Fri, Aug 9, 2013 at 10:07 PM, Glenn Maynard  wrote:

> On Fri, Aug 9, 2013 at 11:07 PM, Rik Cabanier  wrote:
>
>> How would you fix a 1.5 pixel width for the stroke or a 1.5 transform?
>>
>
> By snapping the final, post-transform width of the stroke to an integer.
> If you scale by 1.25, eg. ctx.scale(1.25, 1.25), then draw a stroke with a
> lineWidth of 1.5, the resulting width is 1.875 pixels.  That would be
> rounded up to 2 pixels, after applying the transform (scale) and before
> invoking the "trace a path" algorithm.
>

Ah, so you are relying on pixel snapping (=rounded up to 2 pixels). If you
can do that with your approach, why not with strokes that are drawn from
the center?


>
>>
>>  Chrome seems ignore stroke widths that are smaller than 1 (which is
 reasonable).

>>>
>>> (That seems wrong to me--it should continue to draw based on pixel
>>> coverage--but that's a separate issue...)
>>>
>>
>>  Is it? Obviously you can't draw less than a pixel, but the user did
>> specify that he wants it too look black.
>>
>
> strokeStyle = "black" doesn't mean "every pixel in the stroke should be
> black".  It's the color of the pen.  If you draw over half of a pixel with
> a black pen, you get 50% grey.
>

Yes.
Does the author want to see the appearance of the 'thin-ness' of the
stroke, or is he more interested in the color?

I was wondering if this is something that happens in Flash as well. It
turns out that there's an option called "hinting: Keep stroke anchors on
full pixels to prevent blurry lines." There's a blog post on what this
does:
http://www.kaourantin.net/2005/08/stroke-hinting-in-flash-player-8-aka.html


I created an example (in flash sorry) that shows the feature:
http://cabanier.github.io/BlendExamples/pixelsnap/pixelsnap.html
2 sets of strokes move across the screen and are also scaled.

The top strokes behave like canvas does today. They start of blurry and
during the animation they slowly get ticker. For some reason it doesn't
look very smooth.
The bottom strokes have hinting turned on. They are sharp at the beginning
and during the animation they stay the same size until the internal stroke
width is large enough. At that point you see a 'jump'.

I think canvas should have a similar feature...


> It'd be one thing if Chrome didn't antialias at all, but if Chrome is
> antialiasing a stroke with a lineWidth of 1.5, it doesn't make sense that
> it's not antialiasing a stroke with a lineWidth of 0.75.  I don't think
> this is strictly specified; the only mention of anti-aliasing is an example
> of how to do it (oversampling).
>
> This is tangental, though.  Might want to start another thread if you want
> to go over this more, or we'll derail this one...
>


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

2013-08-09 Thread Glenn Maynard
On Fri, Aug 9, 2013 at 11:07 PM, Rik Cabanier  wrote:

> How would you fix a 1.5 pixel width for the stroke or a 1.5 transform?
>

By snapping the final, post-transform width of the stroke to an integer.
If you scale by 1.25, eg. ctx.scale(1.25, 1.25), then draw a stroke with a
lineWidth of 1.5, the resulting width is 1.875 pixels.  That would be
rounded up to 2 pixels, after applying the transform (scale) and before
invoking the "trace a path" algorithm.

>
> Chrome seems ignore stroke widths that are smaller than 1 (which is
>>> reasonable).
>>>
>>
>> (That seems wrong to me--it should continue to draw based on pixel
>> coverage--but that's a separate issue...)
>>
>
> Is it? Obviously you can't draw less than a pixel, but the user did
> specify that he wants it too look black.
>

strokeStyle = "black" doesn't mean "every pixel in the stroke should be
black".  It's the color of the pen.  If you draw over half of a pixel with
a black pen, you get 50% grey.

It'd be one thing if Chrome didn't antialias at all, but if Chrome is
antialiasing a stroke with a lineWidth of 1.5, it doesn't make sense that
it's not antialiasing a stroke with a lineWidth of 0.75.  I don't think
this is strictly specified; the only mention of anti-aliasing is an example
of how to do it (oversampling).

This is tangental, though.  Might want to start another thread if you want
to go over this more, or we'll derail this one...

-- 
Glenn Maynard


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

2013-08-09 Thread Rik Cabanier
On Fri, Aug 9, 2013 at 8:12 PM, Glenn Maynard  wrote:

> On Fri, Aug 9, 2013 at 7:16 PM, Rik Cabanier  wrote:
>
>> In addition if
>> the corners of the path don't align with the grid, you will get a blurry
>> outline again.
>>
>
> That's the purpose of the second half of my proposal: snapping coordinates
> and line widths to integers.
>
> As an experiment, I drew 4 rectangles in JSFiddle with stroke width of .5,
>> .75, 1, 1.5 and 2: http://jsfiddle.net/6KS4V/2/
>> I aligned them to the grid as Glenn suggested.
>> This is a blown up screenshot from IE (Firefox looked the same):
>> http://bit.ly/16FVCKd
>> and here's one from Chrome: http://bit.ly/19Tf9Ko
>>
>> The rectangle that's 2 points wide is somewhat blurry, but the one that is
>> 1.5  is very bad.
>>
>
> Right.  In case anyone's not following, this is what's happening:
> https://zewt.org/~glenn/stroke-alignment.png  The red box is the
> rectangle being drawn.  The blue lines are the actual strokes.  (This was
> created by hand, it's not an actual Canvas rendering.)
>
> The top row is drawing with integer coordinates.  With a 1px stroke, the
> stroke sits across two pixels, so it aliases.  With a 2px stroke, it fully
> covers two pixels and doesn't alias.  With a 3px stroke, it aliases again.
>
> The middle row is drawing with half-coordinates.  The pattern is reversed:
> clean, aliased, clean.  Additionally, fills (with no stroke) always
> aliases, since the red box lies between pixels.
>

How would you fix a 1.5 pixel width for the stroke or a 1.5 transform?


>
> The bottom row is an outer stroke and integer coordinates: neither strokes
> nor fills alias, in all three cases.  This is the mode I'm suggesting.
>
> Chrome seems ignore stroke widths that are smaller than 1 (which is
>> reasonable).
>>
>
> (That seems wrong to me--it should continue to draw based on pixel
> coverage--but that's a separate issue...)
>

Is it? Obviously you can't draw less than a pixel, but the user did specify
that he wants it too look black.
I admit that this is not a clear cut problem. Our applications also have
different ways of rendering depending on what the user is trying to
accomplish.
If the intent is to mimic high resolution printed output, we blur the lines
like Canvas and SVG currently do.
If the screen is considered the output device (like  in Acrobat), we snap
the line art because it looks better (ie grids for spreadsheets). This is
most likely why CSS snaps too.


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

2013-08-09 Thread Glenn Maynard
On Fri, Aug 9, 2013 at 7:16 PM, Rik Cabanier  wrote:

> In addition if
> the corners of the path don't align with the grid, you will get a blurry
> outline again.
>

That's the purpose of the second half of my proposal: snapping coordinates
and line widths to integers.

As an experiment, I drew 4 rectangles in JSFiddle with stroke width of .5,
> .75, 1, 1.5 and 2: http://jsfiddle.net/6KS4V/2/
> I aligned them to the grid as Glenn suggested.
> This is a blown up screenshot from IE (Firefox looked the same):
> http://bit.ly/16FVCKd
> and here's one from Chrome: http://bit.ly/19Tf9Ko
>
> The rectangle that's 2 points wide is somewhat blurry, but the one that is
> 1.5  is very bad.
>

Right.  In case anyone's not following, this is what's happening:
https://zewt.org/~glenn/stroke-alignment.png  The red box is the rectangle
being drawn.  The blue lines are the actual strokes.  (This was created by
hand, it's not an actual Canvas rendering.)

The top row is drawing with integer coordinates.  With a 1px stroke, the
stroke sits across two pixels, so it aliases.  With a 2px stroke, it fully
covers two pixels and doesn't alias.  With a 3px stroke, it aliases again.

The middle row is drawing with half-coordinates.  The pattern is reversed:
clean, aliased, clean.  Additionally, fills (with no stroke) always
aliases, since the red box lies between pixels.

The bottom row is an outer stroke and integer coordinates: neither strokes
nor fills alias, in all three cases.  This is the mode I'm suggesting.

Chrome seems ignore stroke widths that are smaller than 1 (which is
> reasonable).
>

(That seems wrong to me--it should continue to draw based on pixel
coverage--but that's a separate issue...)

-- 
Glenn Maynard


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

2013-08-09 Thread Stephen White
On Fri, Aug 9, 2013 at 8:16 PM, Rik Cabanier  wrote:

>
>
> On Fri, Aug 9, 2013 at 2:17 PM, Stephen White wrote:
>
>> I think one problem you might run into is that, if you consider a stroked
>> line to be centered on pixel centers rather than pixel edges, then the same
>> path when filled and stroked would touch different pixels along each edge.
>>
>> Consider a 10x10 rectangle, drawn at coordinates coordinates 5, 5. If
>> filled, this would fill pixels 5-14 in X and 5-14 in Y. If stroked, this
>> will draw 1-pixel wide rectangles centered along (5, 5) -> (14, 5) -> (14,
>> 14) -> (5, 5). With antialiasing this will touch pixels 4->15 in each
>> dimension.  http://jsfiddle.net/6KS4V/
>>
>> If the stroke was instead drawn centered over half pixels, the stroked
>> rects would be centered along (5.5, 5.5) -> (14.5, 5.5) -> (14.5, 14.5) ->
>> (14.5, 5.5) -> (5.5, 5.5). This would touch pixels 5->15 in each dimension.
>> If drawn with transparency, the resulting left and top edges would look
>> different than the bottom and right edges.  E.g.,
>> http://jsfiddle.net/9xbkX/.
>>
>> (Please ignore blurriness induced by the CSS upscaling; you can remove
>> the CSS and use a zooming tool if you prefer).
>>
>>
> Yes, I agree that strokes and fills should be treated the same to avoid
> this problem.
> I'm unsure if Glenn's suggestion for an outer and inner stroke fix the
> problem. An inner or outer stroke will look very different.
>

Sure, but it's up to the developer to choose. It looks like Illustrator has
something very similar; see the "Align Stroke" buttons here:
http://help.adobe.com/en_US/illustrator/cs/using/WSA1E31D7D-13E6-41ac-AA8C-4AD129B9FC1Ca.html.
I don't have a copy of Illustrator to try it, though.

In addition if the corners of the path don't align with the grid, you will
> get a blurry outline again.
>

Well, as long as you choose the right mitering style, I think the corners
would be fine. It's basically the same algorithm as normal path stroking,
except instead of translating half the stroke width on either side of the
path along the tangent, you'd just use the path as one edge and translate
the other the full stroke width.

As an experiment, I drew 4 rectangles in JSFiddle with stroke width of .5,
> .75, 1, 1.5 and 2: http://jsfiddle.net/6KS4V/2/
> I aligned them to the grid as Glenn suggested.
> This is a blown up screenshot from IE (Firefox looked the same):
> http://bit.ly/16FVCKd
> and here's one from Chrome: http://bit.ly/19Tf9Ko
>
> The rectangle that's 2 points wide is somewhat blurry, but the one that is
> 1.5  is very bad.
> Chrome seems ignore stroke widths that are smaller than 1 (which is
> reasonable).
>

I think this more like what the "outer" stroke style would do:
http://jsfiddle.net/ZrbQh/

The interior rectangle is the same in each one, with the outer edge nudged
outwards along the tangent (the sizes may be wrong for the <1 lineWidth
cases; I didn't spend too long on it).

Stephen


> I then recreated the content in Illustrator, opened the file in Acrobat
> and took a screenshot: http://bit.ly/15loBhu
> As you can see, Acrobat doesn't apply any anti-aliasing. It seems to
> 'snap' the points to the grid and adjust the stroke width so it fills whole
> pixels. I ran some experiments and I *think* this is also what CSS does.
>
> I believe that this could be accomplished with a new attribute in the
> graphics state. Doing it programmatically should also work but is quite
> difficult.
> I wonder if our mozilla friends that work on shumway and pdf.js are
> running into this...
>


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

2013-08-09 Thread Rik Cabanier
On Fri, Aug 9, 2013 at 2:17 PM, Stephen White wrote:

> I think one problem you might run into is that, if you consider a stroked
> line to be centered on pixel centers rather than pixel edges, then the same
> path when filled and stroked would touch different pixels along each edge.
>
> Consider a 10x10 rectangle, drawn at coordinates coordinates 5, 5. If
> filled, this would fill pixels 5-14 in X and 5-14 in Y. If stroked, this
> will draw 1-pixel wide rectangles centered along (5, 5) -> (14, 5) -> (14,
> 14) -> (5, 5). With antialiasing this will touch pixels 4->15 in each
> dimension.  http://jsfiddle.net/6KS4V/
>
> If the stroke was instead drawn centered over half pixels, the stroked
> rects would be centered along (5.5, 5.5) -> (14.5, 5.5) -> (14.5, 14.5) ->
> (14.5, 5.5) -> (5.5, 5.5). This would touch pixels 5->15 in each dimension.
> If drawn with transparency, the resulting left and top edges would look
> different than the bottom and right edges.  E.g.,
> http://jsfiddle.net/9xbkX/.
>
> (Please ignore blurriness induced by the CSS upscaling; you can remove the
> CSS and use a zooming tool if you prefer).
>
>
Yes, I agree that strokes and fills should be treated the same to avoid
this problem.
I'm unsure if Glenn's suggestion for an outer and inner stroke fix the
problem. An inner or outer stroke will look very different. In addition if
the corners of the path don't align with the grid, you will get a blurry
outline again.

As an experiment, I drew 4 rectangles in JSFiddle with stroke width of .5,
.75, 1, 1.5 and 2: http://jsfiddle.net/6KS4V/2/
I aligned them to the grid as Glenn suggested.
This is a blown up screenshot from IE (Firefox looked the same):
http://bit.ly/16FVCKd
and here's one from Chrome: http://bit.ly/19Tf9Ko

The rectangle that's 2 points wide is somewhat blurry, but the one that is
1.5  is very bad.
Chrome seems ignore stroke widths that are smaller than 1 (which is
reasonable).

I then recreated the content in Illustrator, opened the file in Acrobat and
took a screenshot: http://bit.ly/15loBhu
As you can see, Acrobat doesn't apply any anti-aliasing. It seems to 'snap'
the points to the grid and adjust the stroke width so it fills whole
pixels. I ran some experiments and I *think* this is also what CSS does.

I believe that this could be accomplished with a new attribute in the
graphics state. Doing it programmatically should also work but is quite
difficult.
I wonder if our mozilla friends that work on shumway and pdf.js are running
into this...


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

2013-08-09 Thread Stephen White
That's an interesting idea. I suppose the fully general solution would be
to have a "stroke offset". E.g., with a stroke width of 4 and and offset of
2 you'd get "outer", offset -2 you'd get "inner", offset 1 you'd get 3
pixels outer and 1 pixel inner, etc. Dunno how useful that is, though.

Stephen


On Fri, Aug 9, 2013 at 5:24 PM, Glenn Maynard  wrote:

> On Fri, Aug 9, 2013 at 4:17 PM, Stephen White wrote:
>
>> If the stroke was instead drawn centered over half pixels, the stroked
>>
> rects would be centered along (5.5, 5.5) -> (14.5, 5.5) -> (14.5, 14.5) ->
>> (14.5, 5.5) -> (5.5, 5.5). This would touch pixels 5->15 in each
>> dimension.
>> If drawn with transparency, the resulting left and top edges would look
>> different than the bottom and right edges.  E.g.,
>> http://jsfiddle.net/9xbkX/
>
>
> My proposal addresses this, by adding an "outer" stroke mode.
> http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/040252.html
>
> --
> Glenn Maynard
>
>


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

2013-08-09 Thread Glenn Maynard
On Fri, Aug 9, 2013 at 4:17 PM, Stephen White wrote:

> If the stroke was instead drawn centered over half pixels, the stroked
>
rects would be centered along (5.5, 5.5) -> (14.5, 5.5) -> (14.5, 14.5) ->
> (14.5, 5.5) -> (5.5, 5.5). This would touch pixels 5->15 in each dimension.
> If drawn with transparency, the resulting left and top edges would look
> different than the bottom and right edges.  E.g.,
> http://jsfiddle.net/9xbkX/


My proposal addresses this, by adding an "outer" stroke mode.
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2013-July/040252.html

-- 
Glenn Maynard


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

2013-08-09 Thread Stephen White
I think one problem you might run into is that, if you consider a stroked
line to be centered on pixel centers rather than pixel edges, then the same
path when filled and stroked would touch different pixels along each edge.

Consider a 10x10 rectangle, drawn at coordinates coordinates 5, 5. If
filled, this would fill pixels 5-14 in X and 5-14 in Y. If stroked, this
will draw 1-pixel wide rectangles centered along (5, 5) -> (14, 5) -> (14,
14) -> (5, 5). With antialiasing this will touch pixels 4->15 in each
dimension.  http://jsfiddle.net/6KS4V/

If the stroke was instead drawn centered over half pixels, the stroked
rects would be centered along (5.5, 5.5) -> (14.5, 5.5) -> (14.5, 14.5) ->
(14.5, 5.5) -> (5.5, 5.5). This would touch pixels 5->15 in each dimension.
If drawn with transparency, the resulting left and top edges would look
different than the bottom and right edges.  E.g., http://jsfiddle.net/9xbkX/
.

(Please ignore blurriness induced by the CSS upscaling; you can remove the
CSS and use a zooming tool if you prefer).

Stephen



On Tue, Jul 23, 2013 at 7:19 PM, Rik Cabanier  wrote:

> All,
>
> we've noticed that if you draw lines in canvas or SVG, they always end up
> blurry.
> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>
> 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, but ideally this should never happen.
>
> Is this behavior specified somewhere?
> Is there a way to turn this off?
>


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

2013-07-26 Thread Glenn Maynard
On Fri, Jul 26, 2013 at 11:24 AM, Rik Cabanier  wrote:

> - First, add the inner and/or outer stroke modes.  This seems useful in
>> and of itself, but the purpose here is to make it so integer coordinates
>> give hard edges, whether or not you have a 1px stroke.
>>
>
> I'm unsure why this is a requirement... (Not that it wouldn't be nice to
> have)
>

Without this, snapping to integer pixels doesn't prevent aliasing, since to
get a hard-edged 1px stroke you need to use half-pixel coordinates.
 (Instead, it would cause it.)


>
>
>>  - Second, add a mode which causes coordinates to be snapped to
>> integers.  This would happen when you make the API call, and be applied
>> after the canvas transform.
>>
>> If you're in scale(1.25), and you call rect(100, 100, 75, 75), it would
>> draw a rect from 100x100 to 194x194, instead of to 193.75x193.75.
>>
>
> You probably mean 125x125 to 194x194. Also, if there's a stroke width of
> 1, it would stay the same thickness.
>

Rather, 125x125 to 238x238 (both the origin and the size are affected by
the scale).


> Basically, Canvas would draw artwork like CSS does. A 1 pixel line would
> stay 1 pixel until the pixel ratio is 2.
>

Yeah, you would need to round line widths too.  A 1.5 pixel line width
would round to 2px.


>
>
>> This would give clean output for rounded edges, since you're adjusting
>> the size of the path as a whole.  It would work for fills (which also get
>> aliased edges when transformed).  It also works if the fill is a pattern,
>> where turning off antialiasing would make the pattern ugly.
>>
>
> I *think* you only want to do it for strokes because otherwise you might
> get seams.
>

I'm not sure.  Edges that should be aligned should round to the same value.

The same aliasing happen with filled rects (a rect from 0x0-10.25x10x25
will be aliased on the right and bottom edges), so this is trying to
address it in general rather than just for strokes...

-- 
Glenn Maynard


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

2013-07-26 Thread Rik Cabanier
On Fri, Jul 26, 2013 at 7:45 AM, Glenn Maynard  wrote:

> On Thu, Jul 25, 2013 at 10:29 PM, Rik Cabanier  wrote:
>
>> We're getting a bit off track here :-)
>>
>
> We're figuring out an unclear use case.  That's as on-track as it gets.  :)
>
>
>> No, you need to scale, otherwise the content of your canvas won't scale
>> up.
>> For instance, if you have a 100x100 device pixel rect, it has to become a
>> 110x110 device pixel rect if you zoom by 10%
>>
>
> Okay, that wasn't clear to me.  Pixel ratios are peripheral to what you're
> describing: you could ask for the same thing any time you're rendering to a
> dynamically-sized canvas, which simplifies the discussion.  I don't know if
> a complex semi-antialiasing mode is a good approach, though.  It'll always
> have issues (rounded corners won't "connect" cleanly; it's not clear if it
> works for fills, or if it works for patterned fills).
>
> I don't know if this would work well in practice, or if it's
> implementable, but here's a two-part approach that might work:
>
> - First, add the inner and/or outer stroke modes.  This seems useful in
> and of itself, but the purpose here is to make it so integer coordinates
> give hard edges, whether or not you have a 1px stroke.
>

I'm unsure why this is a requirement... (Not that it wouldn't be nice to
have)


> - Second, add a mode which causes coordinates to be snapped to integers.
>  This would happen when you make the API call, and be applied after the
> canvas transform.
>
> If you're in scale(1.25), and you call rect(100, 100, 75, 75), it would
> draw a rect from 100x100 to 194x194, instead of to 193.75x193.75.
>

You probably mean 125x125 to 194x194. Also, if there's a stroke width of 1,
it would stay the same thickness.
Basically, Canvas would draw artwork like CSS does. A 1 pixel line would
stay 1 pixel until the pixel ratio is 2.


>
> This would give clean output for rounded edges, since you're adjusting the
> size of the path as a whole.  It would work for fills (which also get
> aliased edges when transformed).  It also works if the fill is a pattern,
> where turning off antialiasing would make the pattern ugly.
>

I *think* you only want to do it for strokes because otherwise you might
get seams.


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

2013-07-26 Thread Glenn Maynard
On Thu, Jul 25, 2013 at 10:29 PM, Rik Cabanier  wrote:

> We're getting a bit off track here :-)
>

We're figuring out an unclear use case.  That's as on-track as it gets.  :)


> No, you need to scale, otherwise the content of your canvas won't scale
> up.
> For instance, if you have a 100x100 device pixel rect, it has to become a
> 110x110 device pixel rect if you zoom by 10%
>

Okay, that wasn't clear to me.  Pixel ratios are peripheral to what you're
describing: you could ask for the same thing any time you're rendering to a
dynamically-sized canvas, which simplifies the discussion.  I don't know if
a complex semi-antialiasing mode is a good approach, though.  It'll always
have issues (rounded corners won't "connect" cleanly; it's not clear if it
works for fills, or if it works for patterned fills).

I don't know if this would work well in practice, or if it's implementable,
but here's a two-part approach that might work:

- First, add the inner and/or outer stroke modes.  This seems useful in and
of itself, but the purpose here is to make it so integer coordinates give
hard edges, whether or not you have a 1px stroke.
- Second, add a mode which causes coordinates to be snapped to integers.
 This would happen when you make the API call, and be applied after the
canvas transform.

If you're in scale(1.25), and you call rect(100, 100, 75, 75), it would
draw a rect from 100x100 to 194x194, instead of to 193.75x193.75.

This would give clean output for rounded edges, since you're adjusting the
size of the path as a whole.  It would work for fills (which also get
aliased edges when transformed).  It also works if the fill is a pattern,
where turning off antialiasing would make the pattern ugly.

-- 
Glenn Maynard


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

2013-07-25 Thread Rik Cabanier
On Thu, Jul 25, 2013 at 3:59 PM, Glenn Maynard  wrote:

> On Thu, Jul 25, 2013 at 3:49 PM, Rik Cabanier  wrote:
>
>> You still need the scale though, otherwise the canvas content isn't
>> zoomed (which is what the user requested)
>>
>
> (We were talking about device pixel ratios, not zooming--user zooming
> scales the backing store, which is what we can't do anything about.)
>
> I think we're misunderstanding each other, but I'm not sure where.  If
> you're on a 1.1x device, a 100x100 CSS "pixel" (px) box has 110x100
> physical pixels.  To draw cleanly into that box, you create a canvas with a
> 110x110 pixel backing store, and display it in the 100x100px region, eg.
>
> 
>
> You don't do any scaling within the 2d canvas itself, you just draw to it
> like a 110x110-pixel canvas.
>

We're getting a bit off track here :-)

No, you need to scale, otherwise the content of your canvas won't scale up.
For instance, if you have a 100x100 device pixel rect, it has to become a
110x110 device pixel rect if you zoom by 10%


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

2013-07-25 Thread Glenn Maynard
On Thu, Jul 25, 2013 at 3:49 PM, Rik Cabanier  wrote:

> You still need the scale though, otherwise the canvas content isn't zoomed
> (which is what the user requested)
>

(We were talking about device pixel ratios, not zooming--user zooming
scales the backing store, which is what we can't do anything about.)

I think we're misunderstanding each other, but I'm not sure where.  If
you're on a 1.1x device, a 100x100 CSS "pixel" (px) box has 110x100
physical pixels.  To draw cleanly into that box, you create a canvas with a
110x110 pixel backing store, and display it in the 100x100px region, eg.



You don't do any scaling within the 2d canvas itself, you just draw to it
like a 110x110-pixel canvas.

-- 
Glenn Maynard


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

2013-07-25 Thread Rik Cabanier
On Thu, Jul 25, 2013 at 1:28 PM, Glenn Maynard  wrote:

> On Thu, Jul 25, 2013 at 2:36 PM, Rik Cabanier  wrote:
>
>> On Thu, Jul 25, 2013 at 7:05 AM, Glenn Maynard  wrote:
>>
>>> On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier wrote:
>>>
>>> Yes, that's what I had in mind: the developer detects the device pixel
 ratio and scales up the canvas so the pixels match.

>>>
>>> That reduces to the simple case, then.  The pixel ratio gets out of the
>>> picture entirely if you adjust the canvas so it's rendered 1:1 to pixels,
>>> so the rules for getting hard edges are the same (half-pixels for strokes,
>>> integer pixels for fills).
>>>
>>
>> Unfortunately, no.
>> Let's say you have a device pixel ratio of 1.1 and a canvas of 100x100px.
>> The underlying canvas bitmap should now be created as 110 x 110 pixels
>> and your content should be scaled by 1.1. This will make everything blurry
>> :-(
>>
>
> If you have a pixel ratio of 1.1 (100 CSS pixels = 110 device pixels), and
> you're displaying in a 100x100 box in CSS pixels, then you create a canvas
> of 110x110 pixels, so the backing store has the same resolution as the
> final device pixels.
>

You still need the scale though, otherwise the canvas content isn't zoomed
(which is what the user requested)


>
> If you don't do that--if you create a 100x100 backing store and then
> display it in 100x100 CSS pixels--then nothing Canvas can do will prevent
> it from being blurry, because the backing store is being upscaled by 10%
> after it's already been drawn.
>

Correct. Any scaling to the Canvas bitmap is not something that you can
control when you draw the pixels.


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

2013-07-25 Thread Glenn Maynard
On Thu, Jul 25, 2013 at 2:36 PM, Rik Cabanier  wrote:

> On Thu, Jul 25, 2013 at 7:05 AM, Glenn Maynard  wrote:
>
>> On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier wrote:
>>
>> Yes, that's what I had in mind: the developer detects the device pixel
>>> ratio and scales up the canvas so the pixels match.
>>>
>>
>> That reduces to the simple case, then.  The pixel ratio gets out of the
>> picture entirely if you adjust the canvas so it's rendered 1:1 to pixels,
>> so the rules for getting hard edges are the same (half-pixels for strokes,
>> integer pixels for fills).
>>
>
> Unfortunately, no.
> Let's say you have a device pixel ratio of 1.1 and a canvas of 100x100px.
> The underlying canvas bitmap should now be created as 110 x 110 pixels and
> your content should be scaled by 1.1. This will make everything blurry :-(
>

If you have a pixel ratio of 1.1 (100 CSS pixels = 110 device pixels), and
you're displaying in a 100x100 box in CSS pixels, then you create a canvas
of 110x110 pixels, so the backing store has the same resolution as the
final device pixels.

If you don't do that--if you create a 100x100 backing store and then
display it in 100x100 CSS pixels--then nothing Canvas can do will prevent
it from being blurry, because the backing store is being upscaled by 10%
after it's already been drawn.

-- 
Glenn Maynard


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

2013-07-25 Thread Kevin Marks
On chrome android I see the opposite - the left rests are sharp, the middle
ones fuzzy. Sounds like tests needed.
On Jul 23, 2013 5:18 PM, "David Dailey"  wrote:

> Hi Rik,
>
> Just affirming what you've said in SVG:
> http://cs.sru.edu/~ddailey/svg/edgeblurs.svg
>
> The middle rects are crisp, having been merely translated leftward and
> downward by half a pixel. Zooming in from the browser rectifies the problem
> (as expected) after a single tick.
>
> I remember folks discussing sub-pixel antialiasing quite a bit on the SVG
> lists circa fall/winter 2011. It seemed to cause some troubles for D3. Is
> that the same issue?
>
> Cheers
> David
>
>
> -Original Message-
> From: whatwg-boun...@lists.whatwg.org
> [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Rik Cabanier
> Sent: Tuesday, July 23, 2013 7:19 PM
> To: wha...@whatwg.org
> Subject: [whatwg] Blurry lines in 2D Canvas (and SVG)
>
> All,
>
> we've noticed that if you draw lines in canvas or SVG, they always end up
> blurry.
> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>
> 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, but ideally this should never happen.
>
> Is this behavior specified somewhere?
> Is there a way to turn this off?
>
>
>


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

2013-07-25 Thread Rik Cabanier
On Thu, Jul 25, 2013 at 7:05 AM, Glenn Maynard  wrote:

> On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier  wrote:
>
> Yes, that's what I had in mind: the developer detects the device pixel
>> ratio and scales up the canvas so the pixels match.
>>
>
> That reduces to the simple case, then.  The pixel ratio gets out of the
> picture entirely if you adjust the canvas so it's rendered 1:1 to pixels,
> so the rules for getting hard edges are the same (half-pixels for strokes,
> integer pixels for fills).
>

Unfortunately, no.
Let's say you have a device pixel ratio of 1.1 and a canvas of 100x100px.
The underlying canvas bitmap should now be created as 110 x 110 pixels and
your content should be scaled by 1.1. This will make everything blurry :-(


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

2013-07-25 Thread Glenn Maynard
On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier  wrote:

Yes, that's what I had in mind: the developer detects the device pixel
> ratio and scales up the canvas so the pixels match.
>

That reduces to the simple case, then.  The pixel ratio gets out of the
picture entirely if you adjust the canvas so it's rendered 1:1 to pixels,
so the rules for getting hard edges are the same (half-pixels for strokes,
integer pixels for fills).

-- 
Glenn Maynard


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

2013-07-24 Thread Rik Cabanier
On Wed, Jul 24, 2013 at 4:54 PM, Glenn Maynard  wrote:

> On Wed, Jul 24, 2013 at 1:25 PM, Rik Cabanier  wrote:
>
>> sorry, that was a typo. I meant to say 'translate(.5, .5)' will offset
>> your fills.
>>
>
> (All I meant in the first place was that the pixel ratio isn't a factor
> here.  Maybe it's SVG that needs the ratio-dependent adjustment.)
>
>
>> That is very confusing. So, if there's a scale, you have to unapply the
>> scale to the .5 offset?
>>
>
> If there's a scale, the width of the stroke is going to be scaled too.  In
> that case, you either have to do adjustments across the board (no
> translation is going to make a 0.9-pixel stroke fill a pixel), or you need
> to do something like disabling antialiasing.
>
>
>>  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.
>>
>
> It solves the problem that it's a bit of a pain to have to supply
> edge-aligned coordinates when you're filling and centered coordinates when
> you're using a 1px stroke.  It eliminates the need to do any half-pixel
> offsetting at all in a lot of cases.
>
>
>> 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.
>>
>
> If zoom is on, then that's the above: a compositing-stage transform that
> happens after rendering, which Canvas probably can't help with.
>
> If you have a non-integer pixel ratio, and no "HD" canvas backing store
> (it sounds like those may be getting dropped), then that seems like the
> same issue: the canvas will be rescaled at compositing time and there's
> nothing Canvas itself can do to prevent blurriness.  (The developer could
> still work around it by hand, by using a higher-resolution Canvas so the
> backing store doesn't actually get resized at compositing time.  They'll
> need to do this anyway, or everything will be blurry, not just strokes.)
>

Yes, that's what I had in mind: the developer detects the device pixel
ratio and scales up the canvas so the pixels match.


>
>
>
>>  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.
>>
>
> I don't follow the terminology, but from your image and description ("If
> there's less than a pixel total, you expand the stroke to at least a
> pixel", that sounds like disabling antialiasing (maybe only for certain
> lines).
>

It's more that the pixel is shrunk but is clamped to at least 1 pixel.

I asked our rendering people and it sounds like the feature is implemented
quite as described in the book. I'm still trying to find out the details...


>
>  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.
>>
>
> You could get more complex and turn off antialiasing for lines that aren't
> exactly vertical or horizontal.  I suspect that would cause odd issues; for
> example, seams at the boundary between a horizontal line and a rounded
> edge, or a rounded edge being dimmer than the hard edges it connects.  (I
> also don't know enough about paths and their implementations to know how
> feasible this is.)
>

Yeah, it's quite complex.


>
> It sounds complex and with its own problems, and the only case

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

2013-07-24 Thread Glenn Maynard
On Wed, Jul 24, 2013 at 1:25 PM, Rik Cabanier  wrote:

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

(All I meant in the first place was that the pixel ratio isn't a factor
here.  Maybe it's SVG that needs the ratio-dependent adjustment.)


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

If there's a scale, the width of the stroke is going to be scaled too.  In
that case, you either have to do adjustments across the board (no
translation is going to make a 0.9-pixel stroke fill a pixel), or you need
to do something like disabling antialiasing.


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

It solves the problem that it's a bit of a pain to have to supply
edge-aligned coordinates when you're filling and centered coordinates when
you're using a 1px stroke.  It eliminates the need to do any half-pixel
offsetting at all in a lot of cases.


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

If zoom is on, then that's the above: a compositing-stage transform that
happens after rendering, which Canvas probably can't help with.

If you have a non-integer pixel ratio, and no "HD" canvas backing store (it
sounds like those may be getting dropped), then that seems like the same
issue: the canvas will be rescaled at compositing time and there's nothing
Canvas itself can do to prevent blurriness.  (The developer could still
work around it by hand, by using a higher-resolution Canvas so the backing
store doesn't actually get resized at compositing time.  They'll need to do
this anyway, or everything will be blurry, not just strokes.)


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

I don't follow the terminology, but from your image and description ("If
there's less than a pixel total, you expand the stroke to at least a
pixel", that sounds like disabling antialiasing (maybe only for certain
lines).

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

You could get more complex and turn off antialiasing for lines that aren't
exactly vertical or horizontal.  I suspect that would cause odd issues; for
example, seams at the boundary between a horizontal line and a rounded
edge, or a rounded edge being dimmer than the hard edges it connects.  (I
also don't know enough about paths and their implementations to know how
feasible this is.)

It sounds complex and with its own problems, and the only case where it
might help is if you want to draw hard lines after calling
canvas.scale(0.9, 0.9), which seems uncommon to me.  In all typical cases,
being able to set strokes to inside or outside seem to handle the rest (if
that's something that fits in Canvas's path design; I don't know the
algorithm).

-- 
Glenn Maynard


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

2013-07-24 Thread Rik Cabanier
On Wed, Jul 24, 2013 at 6:20 AM, Glenn Maynard  wrote:

> On Tue, Jul 23, 2013 at 11:56 PM, Rik Cabanier  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.


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

2013-07-24 Thread Glenn Maynard
On Tue, Jul 23, 2013 at 11:56 PM, Rik Cabanier  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.  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.

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.

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.

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


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

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.

-- 
Glenn Maynard


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

2013-07-24 Thread Dirk Schulze

On Jul 24, 2013, at 7:19 AM, Rik Cabanier  wrote:

> On Tue, Jul 23, 2013 at 6:20 PM, Glenn Maynard  wrote:
> 
>> (The below is about Canvas only; I'm not very familiar with SVG.  I think
>> they should be two separate discussions.)
>> 
> 
> Agreed. Sorry to confuse the issue.
> 
> 
>> 
>> On Tue, Jul 23, 2013 at 6:19 PM, Rik Cabanier  wrote:
>> 
>>> we've noticed that if you draw lines in canvas or SVG, they always end up
>>> blurry.
>>> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>>> 
>>> 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.
> 
> 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)
> 
> 
>> 
>> This is the same coordinate system used by OpenGL and Direct3D 10 (and
>> up), with pixels centered around 0.5x0.5.  That is, a pixel sits between
>> 0x0 and 1x1.  If you're specifying the center of the line (eg. where the
>> stroke grows outwards from), you need to add a half pixel.  (When you're
>> specifying a bounding box, such as drawImage, you don't, since you're at
>> the edge rather than the center of a pixel.)
>> 
>> I'm not sure if there's a way to disable antialiasing for paths.
>> Disabling antialiasing to allow people to specify wrong coordinates only
>> seems like it would be more confusing, though.
>> 
> 
> Disabling it is not a solution. The 'crispEdges' option does this and the
> results look bad.
> 
> 
>> The only solution is to educate people about when and why they need to add
>> a half pixel; even if there was a way to avoid this in general (I'm not
>> sure there is, for an API with Canvas's functionality), it's much too late
>> to change this.
>> 
> 
> 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. Basically, if you turn it on strokeAdjust and
> the stroke doesn't fill the entire pixel, that pixel isn't drawn. If
> there's less than a pixel total, you expand the stroke to at least a pixel.
> 
> Apple has a Core Graphics function called "CGGStateSetStrokeAdjust" so they
> would be able to implement this easily. :-)

Means implementations would need to take viewport, transformations of the 
document, transformations on elements in the DOM hierarchy, zoom level, aspect 
ratio of the canvas, position of the canvas in the document, transformations in 
the canvas  and device pixel resolution into account to snap lines to the 
correct position on the individual device, right?Otherwise it sounds to be hard 
to guarantee that you don't see antialiased strokes and lines might snap more 
then just one device pixel. This would also be a problem for aligning shapes to 
each other in the canvas I guess.
What happens on the next transformation after a drawing operation. Say you draw 
a line that was snapped to the grid and then you do scale(1.1, 1.1). Shall the 
implementation redraw the canvas? After all it is an pixel image. A vector 
based drawing format would be better suited for such a task.

Greetings,
Dirk

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

2013-07-23 Thread Rik Cabanier
On Tue, Jul 23, 2013 at 6:20 PM, Glenn Maynard  wrote:

> (The below is about Canvas only; I'm not very familiar with SVG.  I think
> they should be two separate discussions.)
>

Agreed. Sorry to confuse the issue.


>
> On Tue, Jul 23, 2013 at 6:19 PM, Rik Cabanier  wrote:
>
>> we've noticed that if you draw lines in canvas or SVG, they always end up
>> blurry.
>> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>>
>> 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.

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)


>
> This is the same coordinate system used by OpenGL and Direct3D 10 (and
> up), with pixels centered around 0.5x0.5.  That is, a pixel sits between
> 0x0 and 1x1.  If you're specifying the center of the line (eg. where the
> stroke grows outwards from), you need to add a half pixel.  (When you're
> specifying a bounding box, such as drawImage, you don't, since you're at
> the edge rather than the center of a pixel.)
>
> I'm not sure if there's a way to disable antialiasing for paths.
> Disabling antialiasing to allow people to specify wrong coordinates only
> seems like it would be more confusing, though.
>

Disabling it is not a solution. The 'crispEdges' option does this and the
results look bad.


> The only solution is to educate people about when and why they need to add
> a half pixel; even if there was a way to avoid this in general (I'm not
> sure there is, for an API with Canvas's functionality), it's much too late
> to change this.
>

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. Basically, if you turn it on strokeAdjust and
the stroke doesn't fill the entire pixel, that pixel isn't drawn. If
there's less than a pixel total, you expand the stroke to at least a pixel.

Apple has a Core Graphics function called "CGGStateSetStrokeAdjust" so they
would be able to implement this easily. :-)


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

2013-07-23 Thread David Dailey
Seeing what Kornel wrote about a solution to the problem for canvas, makes 
persuasive support, to me, for Glenn Maynard's argument that [concerning SVG 
and canvas]
" I think they should be two separate discussions."

One of the intentions (at least historically) of SVG is to allow declarative 
rather than scripted solutions. As I read this conversation from a declarative 
perspective (trying to transcode script into markup) I am seeing a dozen little 
flag-attributes that all interact with one another in a grand logical 
hyperplane. Sorry, for what might be a flawed metaphor, but I've been stuck in 
a logical hyperplane for the past few days and I am cursing it! 

Cheers
D
(Lie algebra is even worse than Lie geometry!  -- 
https://en.wikipedia.org/wiki/Sophus_Lie )

-Original Message-
From: whatwg-boun...@lists.whatwg.org [mailto:whatwg-boun...@lists.whatwg.org] 
On Behalf Of Kornel Lesinski
Sent: Tuesday, July 23, 2013 10:09 PM
To: Rik Cabanier
Cc: whatwg@lists.whatwg.org
Subject: Re: [whatwg] Blurry lines in 2D Canvas (and SVG)

On Wed, 24 Jul 2013 02:13:19 +0100, Rik Cabanier 
wrote:

>> It's not intuitive. It's a pretty common pitfall, but it's logical.
>>
>> For 1-pixel lines it could be fixed by allowing authors to specify 
>> that path should be stroked with lines aligned to inside/outside of 
>> the path (which is a useful feature on its own).
>
>
> Sure, but how can we fix this?
> It's not very intuitive that I have to keep track of the 
> devicePixelRatio (and the current CTM?) to get crisp lines.

To what extent does it need to be "fixed"?

"Manually" snapping lines to canvas pixels isn't too hard, e.g.  
subtracting 0.5 from x/y and adding 1 to width/height to get pixel-aligned 
rectangle outside the box. It does get trickier with transforms indeed :(


Is it enough to snap to canvas pixels? (future of "HD" canvas is uncertain, so 
authors may need to resize canvas to match devicePixelRatio anyway).

Is it enough if there was strokeOutside()/strokeInside() that makes 
untransformed lines pixel-aligned? Or is it necessary to have snapping for 
odd-width lines that are stroked centered on a path?

Do authors expect lines in canvas with non-integer transforms to be crisp?

Should arc() and bezier curves also be snapped? What if you want a line that 
touches the curve?


> What we need is that artwork 'snaps' to the native pixels while still 
> being antialiased.

How should snapping be done?

If fill() of a 2x2 rect draws:

  XX
  XX

how would stroke() look like?


.XX.
.XX.


or

  ..
  ..

or

  ...
  .X.
  ...


If you have path that is 2.5 device pixels wide, is it going to be snapped to 
different width depending whether you draw it at (0, 0) or (0.1, 0)?  
Would that also make circles ellipses?


Snapping makes animated slow movement choppy, so authors may also want ability 
to disable it for selected paths/drawing operations or even for each axis 
separately (e.g. to smoothly animate horizontal movement while object is 
snapped to pixels vertically, etc.)

--
regards, Kornel




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

2013-07-23 Thread Kornel Lesiński
On Wed, 24 Jul 2013 02:13:19 +0100, Rik Cabanier   
wrote:



It's not intuitive. It's a pretty common pitfall, but it's logical.

For 1-pixel lines it could be fixed by allowing authors to specify that
path should be stroked with lines aligned to inside/outside of the path
(which is a useful feature on its own).



Sure, but how can we fix this?
It's not very intuitive that I have to keep track of the devicePixelRatio
(and the current CTM?) to get crisp lines.


To what extent does it need to be "fixed"?

"Manually" snapping lines to canvas pixels isn't too hard, e.g.  
subtracting 0.5 from x/y and adding 1 to width/height to get pixel-aligned  
rectangle outside the box. It does get trickier with transforms indeed :(



Is it enough to snap to canvas pixels? (future of "HD" canvas is  
uncertain, so authors may need to resize canvas to match devicePixelRatio  
anyway).


Is it enough if there was strokeOutside()/strokeInside() that makes  
untransformed lines pixel-aligned? Or is it necessary to have snapping for  
odd-width lines that are stroked centered on a path?


Do authors expect lines in canvas with non-integer transforms to be crisp?

Should arc() and bezier curves also be snapped? What if you want a line  
that touches the curve?



What we need is that artwork 'snaps' to the native pixels while still  
being antialiased.


How should snapping be done?

If fill() of a 2x2 rect draws:

 XX
 XX

how would stroke() look like?


.XX.
.XX.


or

 ..
 ..

or

 ...
 .X.
 ...


If you have path that is 2.5 device pixels wide, is it going to be snapped  
to different width depending whether you draw it at (0, 0) or (0.1, 0)?  
Would that also make circles ellipses?



Snapping makes animated slow movement choppy, so authors may also want  
ability to disable it for selected paths/drawing operations or even for  
each axis separately (e.g. to smoothly animate horizontal movement while  
object is snapped to pixels vertically, etc.)


--
regards, Kornel


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

2013-07-23 Thread Glenn Maynard
(The below is about Canvas only; I'm not very familiar with SVG.  I think
they should be two separate discussions.)

On Tue, Jul 23, 2013 at 6:19 PM, Rik Cabanier  wrote:

> we've noticed that if you draw lines in canvas or SVG, they always end up
> blurry.
> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>
> 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.

This is the same coordinate system used by OpenGL and Direct3D 10 (and up),
with pixels centered around 0.5x0.5.  That is, a pixel sits between 0x0 and
1x1.  If you're specifying the center of the line (eg. where the stroke
grows outwards from), you need to add a half pixel.  (When you're
specifying a bounding box, such as drawImage, you don't, since you're at
the edge rather than the center of a pixel.)

I'm not sure if there's a way to disable antialiasing for paths.  Disabling
antialiasing to allow people to specify wrong coordinates only seems like
it would be more confusing, though.  The only solution is to educate people
about when and why they need to add a half pixel; even if there was a way
to avoid this in general (I'm not sure there is, for an API with Canvas's
functionality), it's much too late to change this.

-- 
Glenn Maynard


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

2013-07-23 Thread Rik Cabanier
Good memory!
I'll dig up that conversation to see what the conclusion was.

On Tue, Jul 23, 2013 at 5:18 PM, David Dailey wrote:

> Hi Rik,
>
> Just affirming what you've said in SVG:
> http://cs.sru.edu/~ddailey/svg/edgeblurs.svg
>
> The middle rects are crisp, having been merely translated leftward and
> downward by half a pixel. Zooming in from the browser rectifies the problem
> (as expected) after a single tick.
>
> I remember folks discussing sub-pixel antialiasing quite a bit on the SVG
> lists circa fall/winter 2011. It seemed to cause some troubles for D3. Is
> that the same issue?
>
> Cheers
> David
>
>
> -Original Message-
> From: whatwg-boun...@lists.whatwg.org
> [mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Rik Cabanier
> Sent: Tuesday, July 23, 2013 7:19 PM
> To: wha...@whatwg.org
> Subject: [whatwg] Blurry lines in 2D Canvas (and SVG)
>
> All,
>
> we've noticed that if you draw lines in canvas or SVG, they always end up
> blurry.
> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>
> 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, but ideally this should never happen.
>
> Is this behavior specified somewhere?
> Is there a way to turn this off?
>
>
>


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

2013-07-23 Thread Rik Cabanier
I guess there's too many "might"s in there :-)

I want to "adjust line positions and line widths to align edges with device
pixels" but not "the user agent might turn off anti-aliasing for all lines
and curves"

On Tue, Jul 23, 2013 at 6:11 PM, Brian Birtles  wrote:

> (2013/07/24 10:07), Rik Cabanier wrote:
>
>> yeah, at first blush that seemed what was needed.
>> However, this simply turns off antialiasing completely so regular
>> artwork looks terrible.
>>
>
> That's a quality of implementation issue. The description of the property
> value says,
>
> "Indicates that the user agent shall attempt to emphasize the contrast
> between clean edges of artwork over rendering speed and geometric
> precision. To achieve crisp edges, the user agent might turn off
> anti-aliasing for all lines and curves or possibly just for straight lines
> which are close to vertical or horizontal. Also, the user agent might
> adjust line positions and line widths to align edges with device pixels."
>
> I'm not sure what use case you have in mind though. Perhaps it's something
> that doesn't fit that description?
>
>


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

2013-07-23 Thread Rik Cabanier
On Tue, Jul 23, 2013 at 5:34 PM, Kornel Lesiński wrote:

> On Wed, 24 Jul 2013 01:18:35 +0100, David Dailey 
> wrote:
>
>  Just affirming what you've said in SVG:
>> http://cs.sru.edu/~ddailey/**svg/edgeblurs.svg
>>
>> The middle rects are crisp, having been merely translated leftward and
>> downward by half a pixel. Zooming in from the browser rectifies the
>> problem
>> (as expected) after a single tick.
>>
>> I remember folks discussing sub-pixel antialiasing quite a bit on the SVG
>> lists circa fall/winter 2011. It seemed to cause some troubles for D3. Is
>> that the same issue?
>>
>
> It's not a bug, it's a feature ;)
>
> The line is centered around edge of the box. You haven't specified whether
> you want the line to be outside or inside the box (or overlapping left edge
> of the box, but not the right, etc.), so you get line in the middle
> approximated as well as possible.
>
> It's not intuitive. It's a pretty common pitfall, but it's logical.
>
> For 1-pixel lines it could be fixed by allowing authors to specify that
> path should be stroked with lines aligned to inside/outside of the path
> (which is a useful feature on its own).


Sure, but how can we fix this?
It's not very intuitive that I have to keep track of the devicePixelRatio
(and the current CTM?) to get crisp lines.

What we need is that artwork 'snaps' to the native pixels while still being
antialiased.

Illustrator tries to work around this by offering a 'snap to grid' option
but users are running into lots of issues (just do a google search for
'illustrator snap to grid')


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

2013-07-23 Thread Brian Birtles

(2013/07/24 10:07), Rik Cabanier wrote:

yeah, at first blush that seemed what was needed.
However, this simply turns off antialiasing completely so regular
artwork looks terrible.


That's a quality of implementation issue. The description of the 
property value says,


"Indicates that the user agent shall attempt to emphasize the contrast 
between clean edges of artwork over rendering speed and geometric 
precision. To achieve crisp edges, the user agent might turn off 
anti-aliasing for all lines and curves or possibly just for straight 
lines which are close to vertical or horizontal. Also, the user agent 
might adjust line positions and line widths to align edges with device 
pixels."


I'm not sure what use case you have in mind though. Perhaps it's 
something that doesn't fit that description?




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

2013-07-23 Thread Rik Cabanier
yeah, at first blush that seemed what was needed.
However, this simply turns off antialiasing completely so regular artwork
looks terrible.

On Tue, Jul 23, 2013 at 5:31 PM, Brian Birtles  wrote:

> (2013/07/24 8:19), Rik Cabanier wrote:
>
>> we've noticed that if you draw lines in canvas or SVG, they always end up
>> blurry.
>> For instance see this fiddle: http://jsfiddle.net/V92Gn/128/
>>
>
> As discussed with Rik privately, SVG has shape-rendering: crispEdges for
> this.[1]
>
> [1] 
> http://www.w3.org/TR/SVG11/**painting.html#**ShapeRenderingProperty
>


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

2013-07-23 Thread Kornel Lesiński
On Wed, 24 Jul 2013 01:18:35 +0100, David Dailey  
 wrote:



Just affirming what you've said in SVG:
http://cs.sru.edu/~ddailey/svg/edgeblurs.svg

The middle rects are crisp, having been merely translated leftward and
downward by half a pixel. Zooming in from the browser rectifies the  
problem

(as expected) after a single tick.

I remember folks discussing sub-pixel antialiasing quite a bit on the SVG
lists circa fall/winter 2011. It seemed to cause some troubles for D3. Is
that the same issue?


It's not a bug, it's a feature ;)

The line is centered around edge of the box. You haven't specified whether  
you want the line to be outside or inside the box (or overlapping left  
edge of the box, but not the right, etc.), so you get line in the middle  
approximated as well as possible.


It's not intuitive. It's a pretty common pitfall, but it's logical.

For 1-pixel lines it could be fixed by allowing authors to specify that  
path should be stroked with lines aligned to inside/outside of the path  
(which is a useful feature on its own).


--
regards, Kornel


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

2013-07-23 Thread Brian Birtles

(2013/07/24 8:19), Rik Cabanier wrote:

we've noticed that if you draw lines in canvas or SVG, they always end up
blurry.
For instance see this fiddle: http://jsfiddle.net/V92Gn/128/


As discussed with Rik privately, SVG has shape-rendering: crispEdges for 
this.[1]


[1] http://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty


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

2013-07-23 Thread David Dailey
Hi Rik,

Just affirming what you've said in SVG:
http://cs.sru.edu/~ddailey/svg/edgeblurs.svg

The middle rects are crisp, having been merely translated leftward and
downward by half a pixel. Zooming in from the browser rectifies the problem
(as expected) after a single tick.

I remember folks discussing sub-pixel antialiasing quite a bit on the SVG
lists circa fall/winter 2011. It seemed to cause some troubles for D3. Is
that the same issue?

Cheers
David


-Original Message-
From: whatwg-boun...@lists.whatwg.org
[mailto:whatwg-boun...@lists.whatwg.org] On Behalf Of Rik Cabanier
Sent: Tuesday, July 23, 2013 7:19 PM
To: wha...@whatwg.org
Subject: [whatwg] Blurry lines in 2D Canvas (and SVG)

All,

we've noticed that if you draw lines in canvas or SVG, they always end up
blurry.
For instance see this fiddle: http://jsfiddle.net/V92Gn/128/

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, but ideally this should never happen.

Is this behavior specified somewhere?
Is there a way to turn this off?




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

2013-07-23 Thread Rik Cabanier
All,

we've noticed that if you draw lines in canvas or SVG, they always end up
blurry.
For instance see this fiddle: http://jsfiddle.net/V92Gn/128/

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, but ideally this should never happen.

Is this behavior specified somewhere?
Is there a way to turn this off?