Unfortunately, png and xlib backends handle XOR operator in different ways.
Here is an example (from cairo_snippets)
snippet_normalize (cr, width, height);
cairo_set_operator (cr, CAIRO_OPERATOR_XOR);
cairo_set_source_rgba (cr, 1,0,0, 0.5);
cairo_rectangle (cr, 0.2,0.2, 0.5,0.5);
cairo_set_source_rgb (cr, 0,1,0);
cairo_rectangle (cr, 0.4,0.4, 0.4,0.4);
cairo_set_source_rgb (cr, 0,0,1);
cairo_rectangle (cr, 0.6,0.6, 0.3,0.3);
Results are attached below.
Created attachment 4854 [details]
operator xor in PNG backend
Created attachment 4855 [details]
xlib results of the same snippet
here is how xlib backend handles operator XOR.
Maybe XRenderFillRects is buggy, but I see the same behavior with glitz
In fact, results from OPERATOR_DEST_OUT and CAIRO_OPERATOR_XOR
are identical. And both differ from PNG ones
Are you comparing surfaces with destination alpha to surfaces with
Both surfaces are created with default parameters.
XRender and glitz surfaces may have no destination alpha,
but XOR operation still invalid: if I draw white square on
black background result should be white square. But it does not...
Pure Xlib works correctly in this case.
Note that XOR here is the Porter-Duff XOR operator, and is entirely different
from the Raster-Op XOR that you'd find in XLib.
If it is not a bitwise XOR, then maybe it works properly...
Maybe it have sense to highlight it in documentation somehow,
to avoid such a questions, frequent, i think?
PS. Is there any way to get an old bitwise XOR in cairo?
(In reply to comment #8)
> PS. Is there any way to get an old bitwise XOR in cairo?
A bitwise operation would not be well-defined in cairo. Many backends, (think
PostScript, PDF and SVG), do not have "bits" to be manipulated. So, at best,
this would have to be some backend-specific operation.
We don't like to put backend-specific drawing operations into cairo. If you
really need this, you can drop down to doing backend-specific drawing yourself
behind cairo's back, (for example, using Xlib to draw to the same drawable). If
you're going to do that, just call cairo_surface_flush when switching from cairo
to non-cairo drawing, and cairo_surface_mark_dirty before switching back).