[cairo] several questions about cairo with image backend

M Joonas Pihlaja jpihlaja at cc.helsinki.fi
Mon Jul 19 14:40:54 PDT 2010


Hi Chen,

On Mon, 19 Jul 2010, xigcw wrote:

> I am learning cairo with image backend for several weeks , and 
> I have several questions whitch troubles me a lot.

Your questions indicate to me that you're probably looking at the <= 
1.8 cairo code.  The 1.9 code paths for the image backend have changed 
a lot.

> 1. There are two data changes in cairo:
>    (1) fdx = _cairo_fixed_from_double(dx)
>    (2) x_off_fixed = pixman_int_to_fixed(x_off)
>    that , fdx = dx * 256  , x_off_fixed = x_off * 256 * 256,
>    What's the meaning about the two changes?

These are conversions from doubles (_cairo_fixed_from_double) or 
integers (pixman_int_to_fixed) into fixed point formats used by cairo 
and pixman.  Cairo internally uses 24.8 and pixman uses 16.16 fixed 
point representation.

http://en.wikipedia.org/wiki/Fixed-point_arithmetic

> 2. I use a debugger to see how the thick stroking works.
>    After cairo_traps_add_trap,the polygon will be reduced 
>    to trapezoid, and then the pixman will compute the right and
>    left edge of the trapezoid .is that right?

Yes.

>    When compute the edge of trapezoid ,the algorithms is different
>    from Bresenham algorithms, so I would like to know what computer 
>    graphics algorithms does cairo use?(draw line)

The trapezoid stepper is a fairly straight forward DDA over a 17x15 
subpixel grid.

http://en.wikipedia.org/wiki/Digital_Differential_Analyzer_(graphics_algorithm)

> 3.  #define RENDER_EDGE_STEP_SMALL(edge)
>    {  edge->x += edge->stepx_small;
>       edge->e += edge->dx_small;
>       if(edge->e > 0)
>       {  edge->e -= edge->dy;
>          edge->x += edge->signdx;
>       }
>    }

>    What's the meaning of edge->e 

The edge->e field is the "excess" of the x coordinate and represents 
the fractional part of the x coordinate along the edge for the current 
y.  For an edge which goes dx units to the right and dy units down the 
excess is (dx mod dy) - dy.  The bias -dy is added to make checking of 
the overflow condition in the DDA a comparison against zero rather 
than dy.

> or What's the meaning of if(edge->e > 0)?

Without the bias -dy in edge->e, the test for overflow would require 
fetching dy into a register just for the test, so comparison against 
zero is usually faster.

>    What's the different between  RENDER_EDGE_STEP_SMALL(edge)  and
>    RENDER_EDGE_STEP_BIG(edge)?

One advances the edge by the amount STEP_Y_SMALL(8) downwards and the 
other by STEP_Y_BIG(8).

For the purposes of rasterization the pixel grid is subdivided into a 
subpixel grid of size 17 x 15.  Within each subpixel in the 17 x 15 
grid there is a sample in the middle of the subpixel, and if the 
sample falls within the trapezoid defined by two edges, then it 
contributes to the coverage of its pixel by 1/255.

That's the ideal anyway, but remember that pixman uses 16.16 fixed 
point, so it can't represent the height or width of a subpixel 
_exactly_ correctly (65536 is not divisible by 15 or 17.)  So instead 
of having 15 rows of subpixels of uniform height (which it can't 
represent), pixman uses 14 rows of subpixels of the same, nearly 
correct but representable height, and one one slightly larger row 
cover the space between the 14th subpixel row and the bottom of the 
full pixel.  The height of the smaller subpixels is STEP_Y_SMALL(8) 
and the height of the larger subpixels is STEP_Y_BIG(8).

Hope that helps,

Joonas


More information about the cairo mailing list