[cairo] Re: fix pixel offsets in rotated image sources

Bertram Felgenhauer bertram.felgenhauer at googlemail.com
Fri Sep 16 01:17:30 PDT 2005

Bill Spitzak <spitzak at d2.com> wrote:
> I'm not sure if it is relevant, but this is how I fixed the XRender 
> backend of our code to handle the fact that it thinks 0,0 is at the 
> center of the pixel and not at the corner.

It is relevant; the pixman code in cairo is based on (identical to?)
the code used by the X.org Xserver for XRender.

> After calculating the XRender transformation matrix as though integers 
> were where I wanted (at the pixel corners), the following code fixes it 
> before using it to transform an image. This is the same as concatenating 
> the transform to move the image by .5,.5, the original transform, and 
> another transform by -.5,-.5:
>    xtransform.matrix[0][2] +=
>      (xtransform.matrix[0][0]+xtransform.matrix[0][1]-0x10000)>>1;
>    xtransform.matrix[1][2] +=
>      (xtransform.matrix[1][0]+xtransform.matrix[1][1]-0x10000)>>1;

It's right that this works on the matrix level; note, however, that the
translation by -.5, -.5 is only correct for bilinear filtering; for
'nearest' filtering you should leave that out, as I tried to explain
in my previous mail.

My patch does it in a slightly different way because it can not change
the transformation matrix but has access to the coordinates at the point
where they are transformed; the adjustment is done in two steps rather
than one because it needs to distinguish between nearest and bilinear
filtering. The other difference is that it tries to get the case of
projective transformations correct.

I wonder how many applications there are that rely on the current
behaviour of Xrender like that, i.e. if it's safe to fix that in the Xserver.

> Note that 0x10000 is 1.0 in XRender matrix integers and >>1 is a 
> divide-by-2.

cairo/pixman uses (IntToxFixed(1)) to get the appropriate value for 1.
Note that >>1 is not guaranteed to work for negative integers.


More information about the cairo mailing list