Hi there, you'll love this one. Here's my compiler nickgmini:~/unix/cairo-1.2.4 nickg$ gcc -v Using built-in specs. Target: i686-apple-darwin8 Configured with: /private/var/tmp/gcc/gcc-5363.obj~28/src/configure --disable-checking -enable- werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program- transform-name=/^[cg][^.-]*$/s/$/-4.0/ --with-gxx-include-dir=/include/c++/4.0.0 --with- slibdir=/usr/lib --build=powerpc-apple-darwin8 --with-arch=nocona --with-tune=generic -- program-prefix= --host=i686-apple-darwin8 --target=i686-apple-darwin8 Thread model: posix gcc version 4.0.1 (Apple Computer, Inc. build 5363) I can hear the groans already. yes, it's mac os x. This compiler, at least with intel processors has a major bug which makes cairo useless. When compiling with -O3, the compiler miscasts the "alpha_short" value in _cario_color_t to a SIGNED short not a UNSIGNED short value causing color mayhem. When using the set_color_rgb function, the alpha channel is set to 0.5 not 1.0 !!! Here's proof: I added a printf statement at the end of static void _cairo_color_compute_shorts (cairo_color_t *color) { ... color->alpha_short = (unsigned)(color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON); printf("compute shorts: alpha is %f %d %f\n", color->alpha, color->alpha_short, color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON); } --> compute shorts: alpha is 1.000000 32767 65535.999990 As you see the short value SHOULD be 65535. This took about 6 hours to figure out. The fix is to add a cast to a unsigned int. casting to unsigned short does not work! around line 115 in cairo-color.c /** * The cast to (unsigned) is technically not needed, BUT the gcc * 4.0.1 compiler (used by Mac OS X 10.4.X) has a bug. Under -O3 * the double value gets converted to a SIGNED short (max 32673) * instead of a unsigned short. Explcity casting to (unsigned * short) does not work. First, casting to a normal unsigned int * appears to work (and then automatically cast to unsigned short). * This bug is not triggered under -O2. */ color->alpha_short = (unsigned)(color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON); Only the alpha channel is effected. The other channels are ok. This only occurs when compiling at -O3, -O2 is fine This only occurs when using the set_rgb, not set_rgba functions It does not matter if the image soruce is RGB24 or ARGB32 I have not checked to see if the same problem occurs with other cpus / os Given that this is the default compiler for Mac OS , this is bummer. If not a patch we should add a note in README not to use -O3 for this compiler. let me know if you need any more details, thanks, --nickg stupid sample program: #include <cairo.h> #include <cairo-pdf.h> #define WIDTH 400 #define HEIGHT 400 #define COMPOSITE_OP CAIRO_OPERATOR_OVER void paintit(cairo_surface_t* cs) { cairo_t* ctx = cairo_create (cs); cairo_set_operator(ctx, COMPOSITE_OP); cairo_set_source_rgb(ctx, 0.0, 1.0, 1.0); cairo_paint(ctx); cairo_set_source_rgb(ctx, 1.0, 0.0, 0.0); cairo_set_line_width(ctx, 15); cairo_move_to(ctx,200,100); cairo_line_to(ctx,300, 300); cairo_rel_line_to(ctx,-200,0); cairo_close_path(ctx); cairo_stroke(ctx); cairo_rectangle(ctx, 0, 0, 250, 250); cairo_set_source_rgb(ctx, 0, 0, 0); cairo_fill(ctx); cairo_show_page(ctx); cairo_destroy (ctx); } int main() { cairo_surface_t *cs; cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT); paintit(cs); cairo_surface_write_to_png (cs, "triangle_argb32.png"); cairo_surface_destroy(cs); return 0; }
Ughh, I goofed.. it should be """ I added a printf statement at the end of static void _cairo_color_compute_shorts (cairo_color_t *color) { ... color->alpha_short =color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON; printf("compute shorts: alpha is %f %d %f\n", color->alpha, color->alpha_short, color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON); } """ This correctly shows the bug... the version before has my patch in it. enjoy --nickg
We are going to rewrite that function in a more robust way. Marking urgent to make sure it doesn't slip.
Can you check the latest git trunk to see if this is fixed now? It should be.
Hi there... wow this was a nightmare to test.. I had to install new versions of git/autoconf/libtool/ automake... and the autoreconf'ed configure script has bugs in pkg-config part so I had to hack that too... but... the result is.... WORKS! -O3 produces the correct output. thanks everyone. --nickg
(In reply to comment #5) > Hi there... wow this was a nightmare to test.. I had to install new versions of git/autoconf/libtool/ > automake... and the autoreconf'ed configure script has bugs in pkg-config part so I had to hack that too... What was the pkg-config problem? We want to fix that too.
I filled my pkg-config/autotools mayhem in 8686... Let me know if you need more details. --nickg
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.