[cairo] Turning off antialiasing

Bill Spitzak spitzak at d2.com
Mon Oct 18 11:39:48 PDT 2004


I changed the subject line from "conference call" but here are some more 
comments of mine on antialiasing.

These are of course my opinions:

1. There is an absolute requirement to be able to easily draw very thin and 
totally opaque horizontal and vertical lines. Most toolkits rely on doing 
this easily in order to render sharp widgets. Code that draws such lines also 
assummes that moving one pixel perpendicular to the line and drawing another 
line will produce a line touching that first one.

2. There is no requirement to draw such lines at any other angle. I do not 
think the "radio button" example is at all convincing, in my opinion the 
anti-aliased version is vastly superior. Also you can just draw a bitmap of 
the radio button image. Same thing for the checkmark in SWF.

I do not think the proposed solution in the FAQ will do the job. First it 
does not work if you do any scaling, making it impossible to make sharp 
outlined rectangles at any transform other than the identity. More 
importantly the .5 addition is painful as you cannot reuse pixel arrays for 
the fill and stroke and you cannot use an integer API.

My proposal is that Cairo must support a special mode for stroking the path. 
The requirements of this mode are:

1. Lines drawn parallel with the pixel rows and columns must be 100% opaque 
and positioned so that they completely obscure the antialiased edge made by 
filling the same path.

2. Zero-length lines (dots) draw a 100% opaque dot that fills at least one 
pixel.

3. If the user translates one unit in a direction parallel to the pixel grid 
and draws perpendicular lines they will touch or overlap such that no 
partially transparent pixels are between them. Drawing a row of dots 1 unit 
apart must also produce a solid line. I think this means it must be able to 
draw integer thicknesses greater than 1 and that dots must be rectangles.

4. There are no requirements for lines drawn at angles not parallel with the 
pixels. Ideally they should look nice, which means antialiased, and the same 
darkness as the parallel lines.

I believe this can be done by setting the line width to the larger of the 
horizontal or vertical scale of the current transform and adjusting the end 
points of horizontal and vertical lines and dots to lie 1/2 line width from 
an integer, then doing the normal stroke algorithim. As Keith proposed this 
could be done by only moving points that are adjacent to horizontal/vertical 
lines, this may produce better scaled output than moving all the points.

I also believe the api to control this should be one of these:

1. A new method that you call instead of "stroke". This eliminates the need 
for a switch between algorithims in the stroke call, and allows zero line 
widths to draw the mathematically correct thing.

2. It is done by setting the line width to zero and calling the normal 
stroke. The advantage here is that it matches a lot of existing API's and 
there is one fewer API in Cairo.

I think API's where you use different calls to construct the path, or use a 
different call to draw the horizontal and vertical lines, while sensible, 
would be much too difficult to emulate existing API's on top of.



More information about the cairo mailing list