[cairo] drawing inconsistency
Adi Oanca
adioanca at gmail.com
Mon Jan 21 04:09:18 PST 2008
Hi,
> > ... is overwriting the top and the right side of the white
> > rectangle previously stroked.
> >
> > Anyone has any idea what I am doing wrong?
>
> Yes. cairo_stroke() draws a line that extends symmetrically to both
> sides of the current path. At a line width of 1, the part that lies
> outside the path will have width 1/2. Now cairo_fill() fills the
> interior of the current path (not stroke!), so on a vector surface
> you'd end up with a 120x40 rectangle with a 1/2 unit border around it.
> Without antialiasing, cairo will miss a 1/2 unit wide horizontal or
> vertical line 50% of the time.
I've put my hands on cairo about a couple weeks ago. In that time,
I did not find some information about how Cairo maps logical
coordinates onto pixels.
Something like:
http://www.sffjunkie.co.uk/beos/BeBook/TheInterfaceKit_The_Coordinate_Space.html
So, the question here goes:
How does the 1.0 logical coordinate maps to the pixels?
IMO it should be like this: (at least that what I expect, but I can adapt)
-------------------------
| | | | | | |
-------------------------
| | + | - | - | + | |
-------------------------
| | | | | | | | |
-------------------------
| | + | - | - | + | |
-------------------------
The 1.0 horizontal(/vertical) line would go through the middle of the
pixels. 0.5 would also paint the pixels at row 1, as it would 1.49.
0.9 would paint the pixel on line 0 and 1.50 the pixel on line 2.
I need pixel precision, so could you please point me to a
page/document on how cairo maps logical coordinates to physical
pixels?
If there is none, then I hope you would not mind if we continue to
discuss the information you gave me on your first reply. :)
> There are a few ways to fix this:
> - use a line width of 2 (which is, incidentally, cairo's default).
AFAIR it gives the same result, only that the line is thicker at
the left/bottom side.
> - accept the sampling artifacts, but fill before stroking.
Cannot do that. :) The contents of the rectangle is changing color
in an animation effect.
> - use a different path for the stroke:
> cairo_rectangle(cr, 99.5, 99.5, 121, 41);
That I could do, but I think it has to be different for filling not
for stroking.
> > I think I am to blame, or SDL, because if I create the surface this way:
> > cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 480);
> > ... and write that into a .png, the result is OK.
>
> I can't reproduce that. Did you add the cairo_set_line_width(cr, 1)
> line after testing that, perhaps?
Strange.
In the code snippet I gave, cairo_set_line_width(cr, 1) is present.
To reproduce:
1) - take the code from the first mail, add
cairo_surface_write_to_png(cairoSurface, "image2.png");
right before
cairo_destroy(cr);
cairo_surface_destroy(cairoSurface);
=> check image2.png and see the inconsistency.
2) let cairo_surface_write_to_png(cairoSurface, "image2.png");
to be where it was pointed at 1)
then replace:
cairoSurface = cairo_image_surface_create_for_data(
(unsigned char*)screen->pixels,
CAIRO_FORMAT_ARGB32,
gWidth,
gHeight,
screen->pitch);
with:
cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 480);
=> check the image and see that the result is correct (the rectangle
is properly shown/visible)
So, this is why I'm puzzled. If I provide a pre-allocated drawing
buffer, Cairo won't draw properly, but if I tell it to allocate the
drawing buffer, the result is just fine.
Strange, very strange.
Thanks for your time,
Adi.
More information about the cairo
mailing list