[cairo] Turning off antialiasing
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
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