7

Although there's some standardized options for hinting the browser about anti-aliasing in svg, none of them seems to work for my case where I have rectangles with rounded corners - and therefore can't afford turning off anti-aliasing.

Although my rectangles are sized to leave no vertical spaces between them, a thin line shows between them, due to the effects of anti-aliasing. E.g. my svg has one rectangle end at pixel 80 and the next one starts at 81, but still they get a thin background line show between them.

There's no way to force latest version browsers to avoid anti-aliasing for straight lines (crispEdges doesn't force that for my rounded rectangles).

I read some about tweaking by adding 0.5 of a pixel to the y values and about tweaking only even or only odd y values (I believe this is related to the fact that most contemporary LCD screens comprise two hardware vertical pixels per software exposed pixel). I am unsure how precisely this mitigates the problem, and would like to get a definite account of why exactly this makes sense and what is the most correct/solid tweaking approach.

matanster
  • 14,583
  • 17
  • 83
  • 152

1 Answers1

19

two hardware vertical pixels per software exposed pixel

No that's wrong.

When you specify a coordinate like "81" in an SVG, that coordinate falls on the imaginary line between pixel 80 and 81. If your line has width "1", then the renderer will attempt to draw that by placing 50% of the colour on the 80 pixel and 50% on the 81 pixel. This is anti-aliasing. If you want the one pixel line to not be anti-aliased like that, give it coordinate 81.5. That way the whole line will fall within pixel 81.

However if your line had width 2 (or any other even width) you should not use 81.5 but stay with 81. Because it will render 50% (ie. 1) in pixel 80 and 50% (1) in pixel 81. Resulting in no anti-aliasing effect.

enter image description here

This applies for both horizontal and vertical lines. And applies whether you are on an LCD or old CRT.

Does this explanation make sense now?

Paul LeBeau
  • 91,047
  • 8
  • 141
  • 167
  • Does the coordinate interpretation as an imaginary location between pixels, only apply in the case of antialiasing? only in SVG? I couldn't find something definitive about this "imaginary line" approach. – matanster Apr 29 '14 at 23:05
  • 1
    It's a conceptual/imaginary line. This behaviour is specified in the SVG specification, but is not unique to SVG. – Paul LeBeau Apr 29 '14 at 23:12
  • 3
    I added an explanatory diagram. – Paul LeBeau Apr 29 '14 at 23:32
  • hmmm what about a rectangle with zero width stroke then? – matanster Apr 30 '14 at 07:48
  • From the description of `stroke-width` in the SVG spec: "A zero value causes no stroke to be painted". http://www.w3.org/TR/SVG/painting.html#StrokeWidthProperty – Paul LeBeau Apr 30 '14 at 17:55
  • Thanks, sorry for not being entirely clear. I meant how shall an svg `rect` be manipulated to avoid the anti-aliasing effect.... does the `rect` height matter for deciding whether to use halves, instead of the stroke width? – matanster Apr 30 '14 at 18:24
  • If there is no stroke, then placing your rect (x,y) at whole number coordinates and having whole number width and heights should prevent any anti-aliasing happening. – Paul LeBeau Apr 30 '14 at 21:18
  • So you're saying, if the stroke width is 1 and the location of the stroke is on an odd number, then the stroke will be anti-aliased? Is there a property to anti-anti-alias? IOW to make it snap to the nearest pixel? – 1.21 gigawatts Dec 11 '15 at 18:06
  • 1
    No. It doesn't matter if the coordinate is odd. Only if the stroke width is. If the stroke width is odd, use a half-pixel coordinate. To turn off anti-aliasing for an element (and any of its descendants), you can use the property `shape-rendering="crispEdges"`. – Paul LeBeau Dec 11 '15 at 18:13
  • Spent some more time on this so adding notes. All of this might make more sense if you understand the stroke is drawn after the fill and that in SVG in the browser the stroke is drawn on the edge of the shape. In some software you can specify that a stroke is drawn around the outside of the shape, centered on the edge of the shape or inside the shape. So when you a have an odd width stroke that is centered on the edge it causes that anti aliasing. If there was a way to draw the stroke inside or outside the edge you would be able to get rid of aliasing when using whole number coordinates. – 1.21 gigawatts Jul 12 '17 at 18:07
  • Yes. In case it is not obvious, the stroke is drawn so that half the stroke width is drawn on either side of the line/edge. – Paul LeBeau Nov 15 '18 at 05:29