[cairo] Non-antialiased rendering in image surface

Bill Spitzak spitzak at gmail.com
Sat Jun 26 18:36:53 PDT 2010


On 06/26/2010 01:31 PM, cu wrote:
> I'll try to get a trace, but the issue is so common I don't think
> specific trace is needed. Essentially any polygon drawn using non-pixel
> aligned and non-axis-aligned edges causes this issue. All you need is
> two polygons that share a portion of their outline, draw one and fill,
> draw the other and fill. It's most visible when colors are the same.
>
> Attached is the image of two polygons sharing part of outline drawn with
> antialiasing turned on. Same area with antialiasing turned off looks
> like a square of plain uniform color, so I didn't bother attaching it -
> there is nothing there to see.

The problem is that "turn off antialiasing" is NOT the solution. This 
may solve the internal lines, but the outer edge of the polygon ends up 
aliased, and all the other lines look bad.

Anti aliasing by drawing a much higher resolution aliased image and then 
filtering it down (often called supersampling? multisampling?) would 
produce nice antialiased output without these artifacts. I think there 
are Cairo back ends that do exactly that, and the (even theoretical) 
existence of this solution shows that "turn off antialiasing" is not the 
right approach.

The official supported Cairo solution is to use a temporary image 
surface and composite using "SATURATE" and then composite the result 
atop the image.

An idea I had, but I'm not sure it would work, is to add bracketing 
calls to indicate that you are attempting exactly that:

  cairo_start_filled_mesh();
  draw polygons...;
  cairo_end_filled_mesh();

The default behavior of these calls is to start a temporary surface and 
set the function to SATURATE, and then end the temporary surface, put 
the function back, and draw it.

Backends that do not have antialiasing problems can just ignore these calls.

Or it could be implemented in a different way, perhaps with an extra 
temporary alpha channel that shows the coverage of the current mesh. Or 
make a higher-resolution aliased temporary surface.

Another idea I had is a flag you can set to say that a particular edge 
should be aliased. This would be set by the program on edges that it 
knows adjoin another polygon. I don't like this as much as it makes 
assumptions about the implementation, and the program would have to 
determine if the adjacent polygons are actually on opposite sides of the 
line (rather than overlapping each other).

Drawing surfaces in Cairo could also really use the ability to set the 
color at each vertex. The results for polygons with more than 3 points 
can be undefined (ie the triangulation is back-end dependent). This 
would also allow strokes to vary their color along their length, the 
need to do this is currently keeping me using OpenGL rather than Cairo 
for graphics.

It would also be really useful to set the UV of the vertex from the 
source image, to do texture mapping. However you will also have to set a 
'W' value so that the source texture position is U/W,V/W when U,V,W are 
linearly interpolated, that is the only way to get a correct 3-D 
projection. If that is not done users will have to divide flat 3D 
objects up into many thin triangles (this is also what they have to do 
today if they want to use Cairo to draw such images).


More information about the cairo mailing list