[cairo] cairo anti aliasing

Owen Taylor otaylor at redhat.com
Sun Feb 20 12:49:28 PST 2005


Tim Janik wrote:
> On Sun, 20 Feb 2005, Øyvind Kolås wrote:
> 
>> On Sat, 19 Feb 2005 16:45:52 +0100 (CET), Tim Janik <timj at gtk.org> wrote:
>>
>>> no, the result is different. i've attached a new image. the left 
>>> rectangle
>>> is rotated by 12.5 degrees with a feather edge of 3 pixels applied 
>>> before
>>> rotation. the right rectangle is rotated by 12.5 degrees and a gaussian
>>> blur (3x3 matrix) applied after rotation.
>>> edges in the right rectangle still contain step artefacts from the 
>>> rotation,
>>> just blurred, while edges in the left rectangle are properly 
>>> anti-aliased.
>>
>>
>> Cairo's anti aliasing is achieved by calculating the amount of each
>> component within a square (usually referred to as a "square" pixel)
>> surrounding the coordinates of the sample point. This kind of sampling
>> filter is called a box filter. And is the correct sampling given an
>> LCD display, and linear light, most web browsers etc. assume the RGB
>> values to be non linear light, (thus you might want to gamma adjust
>> the data cairo returns).
> 
> 
> ah, thanks. you got a pointer into the source as to where
> exactly this is implemented?

libpixman/fbtrap.c. But note that this is being rewritten at the
moment to improve performance.

>> For a CRT monitor a more expensive sampling operations, either based
>> on a gaussian integral centered on the sampling point would probably
>> be more correct, but give an unreasonably blurry result on an LCD
>> display.
>  
> yeah, a gaussian integral centered on the sampling point is essentially
> what i've been using in my rendering routines so far and is what i'd
> like to see implemented in cairo as well.

Box filters have the important property that it's possible to split
a polygon into trapezoids, rasterize each trapezoid and then add the
results and not get seams. With infinite precision, filtering wouldn't
affect this, but with limited precision, I think you'll get problems.

For that reason, and for performance, I suspect the best way to to
do non-box filtering is to render using box filtering to a temporary
surface, and then draw that with a filter. With the "shaken up"
API, that will look something like:

  cairo_begin_group_with_format (cr, CAIRO_FORMAT_ALPHA);
  cairo_fill (cr);
  cairo_pattern_t *pattern = cairo_end_group (cr);
  cairo_pattern_set_filter (pattern, <gaussian filter>);
  cairo_mask (cr, pattern);
  cairo_pattern_destroy (pattern);

Exactly how you'd specify the gaussian filter isn't worked out yet.

This should work fairly well for broad filters, but for narrow filters
(interlaced video optimized rendering, or whatever) you might want to
render the intermediate format at a higher resolution and scale down.

While that's possible with the current APIs by creating a temporary
surface and pattern manually, it doesn't fit so neatly into the group 
convenience API. You could imagine convienience APIs if people
want to do this a lot, or perhaps it belongs partially at the backend
level. Blurred primitives make sense for PDF ... but video optimized
rendering doesn't really make so much sense.

Regards,
						Owen



More information about the cairo mailing list