[comp.sys.mac.programmer] color "xor"

kw1r+@andrew.cmu.edu (Kevin Whitley) (12/15/88)

At long last I have been able to start work with color.  Unfortunately one of
the first things my coworkers asked me to implement was an xor mode that made
some sort of sense, namely:

1) If the same obect is drawn twice (with the same foreground & background
colors) in xor, the screen should remain unchanged.
2) Drawing in xor against pixels in the background color should give the
foreground color.  (Drawing against colors of any other pixel can be undefined).

I don't seem to be able to do this.  What follows is an account of what I've
tried and why it doesn't seem to work.


First, just using the good old xor modes gives property 1 just fine.  BUT, the
color of the resultant pixels is independent of the foreground color.  Namely,
drawing in xor against black ALWAYS gives white, whether the foreground is green
or red or whatever.  From this I assume that the xor operation works by
inverting the pixel values of each destination pixel.  Why, oh why, could we not
have xored the source pixel value with the destination pixel value.  The colors
would still be undefined but at least we would get different colors depending on
what the foreground is (and I could acheive property 2 by sneakily changing the
foreground color appropriately).


Ok, then I thought I would use the new arithmetic modes - addOver.  This takes
account of the background AND the foreground.  By properly setting the
foreground to some clever RGB value I could make the sum against the background
come out to the foreground.  This meant that I would have to have a different
kind of xor to remove the pixels (which would use subOver) but that turns out to
be ok for what we're doing.

To make this work you need to make sure that the clever foreground color and its
combination with all existing colors on the screen (some of these RGB values end
up pretty weird) exist on the palette - but that's not hard.  For starters I was
just using an 8 color palette, so I use up 8 more slots for xor, no big deal.

But this whole scheme runs afoul of the color inverse table used by the color
manager.  It doesn't maintain high enough resolution to know the difference
between the resulting weird colors (which often turn out to be things like
1,FFFF,0) and the real colors (like 0,FFFF,0)  (Note that there is a critical
difference in the eight (!) bit).  Putting the image on the screen works all
right, but when I take it off - I don't get back to the original.  So I have
property 2 but not property 1.


I made a detour into implementing my own color search and complement procedures
in the color manager but that turned out to be a dead end.  When you draw in
mode XOR the color search routines are only being called when the foreground and
background colors are set.  When drawing they just aren't called.  And, as
documented, the color search routines aren't called when drawing in arithmetic
modes.


Have I missed something?  To make this work I need some sort of drawing which
takes account of both background and foreground, but which lets me get in and
twiddle a bit to get it to come out the way I want.

Any help or comments would be appreciated.

Kevin Whitley
kw1r@andrew.cmu.edu

lsr@Apple.COM (Larry Rosenstein) (12/15/88)

In article <4XdeYOy00UgCNdM4Bj@andrew.cmu.edu> kw1r+@andrew.cmu.edu (Kevin Whitley) writes:
>1) If the same obect is drawn twice (with the same foreground & background
>colors) in xor, the screen should remain unchanged.
>2) Drawing in xor against pixels in the background color should give the
>foreground color.  (Drawing against colors of any other pixel can be undefined).

You can achieve (2) by using HiliteMode (p 61 of Inside Mac volume 5).  You
can pass hiliteMode instead of patXOR as your drawing mode.  The black bits
in the source determine which bits in the destination are affected (as in
XOR mode).  Those bits that are in the current background color are made to
be the current highlight color.

If you wanted to do this to a rectangular area, for example, you would set
the PenMode to hiliteMode, the PenPat to black, and use PaintRect.

To reverse the operation, you have to set up the highlight and background
colors appropriately.  (This is not like XOR where 2 successive calls undo
each other.)  In that sense, it doesn't directly satisfy (1), but it can be
made to do so.

-- 
		 Larry Rosenstein,  Object Specialist
 Apple Computer, Inc.  20525 Mariani Ave, MS 46-B  Cupertino, CA 95014
	    AppleLink:Rosenstein1    domain:lsr@Apple.COM
		UUCP:{sun,voder,nsc,decwrl}!apple!lsr

kw1r+@andrew.cmu.edu (Kevin Whitley) (12/16/88)

Larry Rosenstein (of Apple) suggested that I use the hilite mode to satisfy my
request for xor in color.  Although this doesn't do everything I wanted, it is
better than the alternative (which is to just use the ridiculous default xor).
But I should point out that there was an error in his note.

>To reverse the operation, you have to set up the highlight and background
>colors appropriately.  (This is not like XOR where 2 successive calls undo
>each other.)

In fact mode hilite IS like Xor.  Hilite swaps background & hilite color.
Drawing (with the same hilite color and background color, mind you) over the
same area swaps everything back.  So things are even rosier than he suggested.

I would like to add that although I was able to get this to work just fine by
twiddling bit 7 of the global variable hiliteMode, I didn't seem to be able to
get it to work by calling PenMode(HiliteMode).   This is a small detail, perhaps
I have overlooked something.

Thank you kindly Larry, I appreciate the help.

Kevin Whitley
kw1r@andrew.cmu.edu