[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