[cairo] Drawing diagonal lines with antialiasing off

Bill Spitzak spitzak at d2.com
Tue Oct 18 13:47:11 PDT 2005


Carl Worth wrote:

> A linewidth of "0" giving a non-zero width result will not happen. I
> don't want magic like that in cairo. That kind of thing can lead to
> scaling an image down only to have lines suddenly "pop-out" again when
> after they have "disappeared".

With floating-point numbers you can get very small values that are 
non-zero. However I see your point, and perhaps a different API to turn 
the "hairline" mode on/off may be necessary. The biggest problem is that 
the linewidth is ignored in this mode, making the call look somewhat 
redundant, and that every other API I have ever seen that supports this 
does it by setting the linewidth to zero.

> If it's "a single-device-pixel-wide line, unless that's too small, in
> which case it should be some real-world size instead, and oh, the
> stroked result should always align with device-pixel boundaries", then
> I think this really belongs as an application-level feature, rather
> than in cairo.

This is an accurate description. See below for what I think it should do.

The problem making this "application level" is that it makes it 
impossible to reuse the path to draw a hairline version of a filled 
object, as all the coordinates change in complex ways. This will force 
drawing programs to use a wrapper instead of cairo directly, the wrapper 
has a lot of unfortunate side effects such as having to track or do all 
the transformations itself, and has to divide all curves into straight 
lines itself. Also it should be obvious that this mode is highly desired 
by GUI designers and the lack of it means they cannot use cairo without 
a wrapper either.

Here I will attempt to describe what this should do:

0. First: this is NOT "turn off antialiasing". In fact the diagonal 
lines WILL be antialiased.

1. This mode forces the linewidth to a specific device-dependent value, 
an integer number of pixels wide, designed to be a human-visible 
hairline. The cairo linewidth and endcap settings are ignored (mostly to 
discourage use of this mode for not-hairline graphics).

2. Horizontal and vertical lines are rectangles of exactly this width 
and 100% opacity, except possibly the end pixels. They are placed so 
that the antialiased edge of a rectangle drawn with the same coordinates 
  would be completely obscured.

3. All other lines are drawn *with antialiasing*, but in such a way that 
they connect to the horizontal and vertical lines nicely, do not jump 
unexpectedly if animated to rotate around an end point, and the end 
points are drawn as close as possible to the actual coordinates. The 
exact algorithim can be back-end specific, but a likely solution is to 
adjust all verticies toward the middle of pixels with a weighing factor 
depending on the slope of the adjacent lines, then stroke the resulting 
path.

4. Any path section or point where all the verticies fit into a single 
pixel will instead draw a small fixed pattern (such as a circle) of 
pixels, this pattern must fit into the intersection of a horizontal and 
vertical line drawn through this point and contain at least one opaque 
pixel.

5. Very small paths, even if they hit more than one pixel, should draw 
something with at least the intensity of #4. This may be very difficult 
to achieve in all cases, but should be attempted.

6. Backends like pdf designed for high-resolution devices or with no 
concept of pixels can just set the linewidth to a fixed small 
scale-independent value to emulate this.


More information about the cairo mailing list