Re: [whatwg] Blurry lines in 2D Canvas

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

 On Thu, 5 Sep 2013, Rik Cabanier wrote:
  On Thu, Sep 5, 2013 at 3:22 PM, Ian Hickson i...@hixie.ch 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-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 gl...@zewt.org wrote:

 On Fri, Sep 27, 2013 at 4:38 PM, Jasper St. Pierre jstpie...@mecheye.net
 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 Ian Hickson
On Thu, 5 Sep 2013, Rik Cabanier wrote:
 On Thu, Sep 5, 2013 at 3:22 PM, Ian Hickson i...@hixie.ch 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 (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 mights 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 bbirt...@mozilla.com 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 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 canvas.


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 

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 wha...@therealcha0s.net
 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-smoothinghttp://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 canvas.


 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=22674https://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 

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 jstpie...@mecheye.netwrote:

 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-05 Thread Rik Cabanier
On Thu, Sep 5, 2013 at 3:22 PM, Ian Hickson i...@hixie.ch 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 canvas.


 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 (and SVG)

2013-08-12 Thread Glenn Maynard
On Sat, Aug 10, 2013 at 9:43 PM, Rik Cabanier caban...@gmail.com 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 
 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-12 Thread Rik Cabanier
On Mon, Aug 12, 2013 at 6:45 PM, Glenn Maynard gl...@zewt.org wrote:

 On Sat, Aug 10, 2013 at 9:43 PM, Rik Cabanier caban...@gmail.com 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 
 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-10 Thread Rik Cabanier
On Fri, Aug 9, 2013 at 10:07 PM, Glenn Maynard gl...@zewt.org wrote:

 On Fri, Aug 9, 2013 at 11:07 PM, Rik Cabanier caban...@gmail.com 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
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 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 caban...@gmail.com 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-08-09 Thread Glenn Maynard
On Fri, Aug 9, 2013 at 4:17 PM, Stephen White senorbla...@chromium.orgwrote:

 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
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 gl...@zewt.org wrote:

 On Fri, Aug 9, 2013 at 4:17 PM, Stephen White senorbla...@chromium.orgwrote:

 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 Rik Cabanier
On Fri, Aug 9, 2013 at 2:17 PM, Stephen White senorbla...@chromium.orgwrote:

 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
On Fri, Aug 9, 2013 at 8:16 PM, Rik Cabanier caban...@gmail.com wrote:



 On Fri, Aug 9, 2013 at 2:17 PM, Stephen White senorbla...@chromium.orgwrote:

 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 Glenn Maynard
On Fri, Aug 9, 2013 at 7:16 PM, Rik Cabanier caban...@gmail.com 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 Rik Cabanier
On Fri, Aug 9, 2013 at 8:12 PM, Glenn Maynard gl...@zewt.org wrote:

 On Fri, Aug 9, 2013 at 7:16 PM, Rik Cabanier caban...@gmail.com 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 11:07 PM, Rik Cabanier caban...@gmail.com 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-07-26 Thread Glenn Maynard
On Thu, Jul 25, 2013 at 10:29 PM, Rik Cabanier caban...@gmail.com 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 Glenn Maynard
On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier caban...@gmail.com 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-25 Thread Rik Cabanier
On Thu, Jul 25, 2013 at 7:05 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier caban...@gmail.com 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 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 ddai...@zoominternet.net 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 Glenn Maynard
On Thu, Jul 25, 2013 at 2:36 PM, Rik Cabanier caban...@gmail.com wrote:

 On Thu, Jul 25, 2013 at 7:05 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier caban...@gmail.comwrote:

 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 Rik Cabanier
On Thu, Jul 25, 2013 at 1:28 PM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, Jul 25, 2013 at 2:36 PM, Rik Cabanier caban...@gmail.com wrote:

 On Thu, Jul 25, 2013 at 7:05 AM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, Jul 25, 2013 at 12:24 AM, Rik Cabanier caban...@gmail.comwrote:

 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 3:49 PM, Rik Cabanier caban...@gmail.com 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.

canvas width=110 height=110 style=width: 100px; height: 100px;

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 3:59 PM, Glenn Maynard gl...@zewt.org wrote:

 On Thu, Jul 25, 2013 at 3:49 PM, Rik Cabanier caban...@gmail.com 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.

 canvas width=110 height=110 style=width: 100px; height: 100px;

 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-24 Thread Dirk Schulze

On Jul 24, 2013, at 7:19 AM, Rik Cabanier caban...@gmail.com wrote:

 On Tue, Jul 23, 2013 at 6:20 PM, Glenn Maynard gl...@zewt.org 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 caban...@gmail.com 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-24 Thread Rik Cabanier
On Wed, Jul 24, 2013 at 6:20 AM, Glenn Maynard gl...@zewt.org wrote:

 On Tue, Jul 23, 2013 at 11:56 PM, Rik Cabanier caban...@gmail.com wrote:

   This happens because you offset 1 pixel and then draw a half pixel
 stroke
 on each side. Since it covers only half the pixel, the color gets
 mapped to
 50% gray.
 You can work around this by doing an extra offset of half the
 devicepixelratio,


 For Canvas, you should always add 0.5, since you're in the canvas
 coordinate space, before the pixel ratio is applied.


 That seemed like an OK idea until I thought about it some more.
 Doing a .5 scale will also affect your fills so a rect will now have
 aliased borders.


 I meant you always want to add 0.5 to offsets, not ratio / 2.


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


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


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


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



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


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



 Also adjusting for non-round device pixel ratio or as Kornel mentions,
 having transforms will still result in blurry lines (unless you do a bunch
 of math)


 Do you mean Canvas transforms or higher-level transforms, like CSS
 scaling?  I don't think Canvas can help with the latter.


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



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


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




 I agree that we can't change this, but maybe we can add something to make
 it better.

 In PDF there is a feature called strokeAdjust that will make the stroke
 align to pixel boundaries. I've attached a drawing that shows the feature.
 Basically, if you turn it on and the stroke doesn't fill the entire pixel,
 that pixel isn't drawn.
 Apple has a Core Graphics function called CGGStateSetStrokeAdjust so
 at least they would be able to implement this easily. :-)


 Isn't this simply disabling antialiasing?  That's what the illustration
 seems to show.


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



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


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


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 gl...@zewt.org wrote:

 On Wed, Jul 24, 2013 at 1:25 PM, Rik Cabanier caban...@gmail.com 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 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 

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


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?




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 Kornel Lesiński
On Wed, 24 Jul 2013 01:18:35 +0100, David Dailey  
ddai...@zoominternet.net 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 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 bbirt...@mozilla.com 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#**ShapeRenderingPropertyhttp://www.w3.org/TR/SVG11/painting.html#ShapeRenderingProperty



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
On Tue, Jul 23, 2013 at 5:34 PM, Kornel Lesiński kor...@geekhood.netwrote:

 On Wed, 24 Jul 2013 01:18:35 +0100, David Dailey ddai...@zoominternet.net
 wrote:

  Just affirming what you've said in SVG:
 http://cs.sru.edu/~ddailey/**svg/edgeblurs.svghttp://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 Rik Cabanier
I guess there's too many mights 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 bbirt...@mozilla.com 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
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 ddai...@zoominternet.netwrote:

 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 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 caban...@gmail.com 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 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 caban...@gmail.com
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 Rik Cabanier
On Tue, Jul 23, 2013 at 6:20 PM, Glenn Maynard gl...@zewt.org 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 caban...@gmail.com 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. :-)