Opened 3 years ago

Closed 18 months ago

#13095 closed defect (fixed)

XOR mode not being respected in OSX

Reported by: dhyams Owned by: csomor
Priority: normal Milestone:
Component: wxOSX (any toolkit) Version:
Keywords: xor, graphics, drawing Cc:
Blocked By: Blocking:
Patch: no

Description

Cross reference to the following thread for pictures and an example Python script that demonstrates the problem: https://groups.google.com/forum/#!topic/wxpython-users/YX4OgsnKglE

In the latest version of wxwidgets (2.9.1 in at the time of writing), the XOR drawing mode is not respected. There seem to be some #defines that are misplaced or incorrect in

http://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/graphics.cpp#L1851

And, on line http://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/graphics.cpp#L1888, kCGBlendModeXOR needs to be kCGBlendModeExclusion. Why they act differently I have no idea, but if you dig into the include files (specifically CGContext.h), each mode has its own number (one is 11, the other is 25). Sure enough, if you make that change, the xor'ing in wxwidgets starts working again.

As far as the #defines are concerned, all of the blend modes are turned off if the mac compatibility
version is 10.4 (which it is by default). This is in
http://trac.wxwidgets.org/browser/wxWidgets/trunk/src/osx/carbon/graphics.cpp#L1851. I can't imagine this is intentional, because the blending modes work fine in wx 2.8.11. So, if as long as you ./configure the 2.9.1.1
source code with --with-macosx-version-min=10.6 (10.5 will probably
work too), that enables the blending modes again. But this problem can be fixed with proper placing of the #defines in that routine.

With these two fixes implemented, the sample script optest.py in the original post (see the cross referenced thread) returns the correct results, and rubberbanding works again.

Change History (3)

comment:1 Changed 3 years ago by csomor

  • Owner set to csomor
  • Status changed from new to accepted

thanks for spotting this, indeed when using white color kCGBlendModeExclusion seems fine, and r59094 changed things the wrong way, I'll look at it

comment:2 Changed 18 months ago by vadz

I'm actually not sure at all about what is the right thing to do here as the documentation of kCGBlendModeXOR describes it as giving

R = S*(1 - Da) + D*(1 - Sa)

which is pretty similar to the documentation of CAIRO_OPERATOR_XOR that we use for wxCOMPOSITION_XOR under Linux and which specifies

xR = (xaA·(1−aB) + xaB·(1−aA))/aR

while kCGBlendModeExclusion is something rather weird.

But I'll still change it if people think this is how it should work...

comment:3 Changed 18 months ago by VZ

  • Resolution set to fixed
  • Status changed from accepted to closed

(In [72893]) Use kCGBlendModeExclusion for wxCOMPOSITION_XOR operation.

The previously used kCGBlendModeXOR doesn't seem to be the right mode to use.

Closes #13095.

Note: See TracTickets for help on using tickets.