[comp.windows.x] inverting areas

guido@cwi.nl (Guido van Rossum) (05/17/88)

I am porting a group of applications that were written for a monochrome
window system to X11.  Unfortunately they use the notion of 'inverting'
areas of the screen (e.g., to indicate a text selection).  This should
swap the foreground and background colors.  Inverting the same area
twice should have a null net effect.  My problem: how to do this on
arbitrary color displays!  I've found a trick that works, but I don't
know if it is kosher.  Please comment!

To invert an arbitrary rectangle, use XFillRectangle with function set
to GXinvert and plane mask set to the XOR of foreground and background
color.  This will change all pixels that have fg color to bg color and
vice versa (and do semi-random things to pixels in other colors, but
since we can assume the picture is monochrome, that's no problem).
Code fragment (fill in the obvious declarations):

	XSetFunction(dpy, gc, GXinvert);
	XSetPlaneMask(dpy, gc, gc->values.foreground ^ gc->values.background);
		/* '^' is the not-so-well-known XOR operator in C */
	XFillRectangle(dpy, w, gc, x, y, width, height);

I've seen similar code in clients/xterm/menu.c.

Questions:
1) is it kosher to retrieve the fg and bg pixels using gc->values?
   (if not, what is in general the recommended way to get a value out of a GC?)
2) is this the recommended way to do "invert" an area?

--
Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
guido@piring.cwi.nl or mcvax!piring!guido or guido%piring.cwi.nl@uunet.uu.net

RWS@ZERMATT.LCS.MIT.EDU (Robert Scheifler) (05/18/88)

    Date: 17 May 88 16:25:32 GMT
    From: mcvax!guido@uunet.uu.net  (Guido van Rossum)

    1) is it kosher to retrieve the fg and bg pixels using gc->values?

No.  The GC structure is supposed to be opaque, and is not guaranteed to
be identical in all implementations.

       (if not, what is in general the recommended way to get a value out of a GC?)

In the C Xlib, there is no way.  You must remember values yourself.  (In
the CommonLisp interface, it is possible to extract values.)

    2) is this the recommended way to do "invert" an area?

It is one perfectly good way for monochrome images.  An alternative is
to use function GXxor, and use a "foreground" value that is the XOR of
the foreground and background pixel values.  Which method is faster will
depend on the server implementation.

guido@cwi.nl (Guido van Rossum) (05/19/88)

I asked:
>>    1) is it kosher to retrieve the fg and bg pixels using gc->values?

Robert Scheifler replied:
>No.  The GC structure is supposed to be opaque, and is not guaranteed to
>be identical in all implementations.

Then perhaps the protocol and/or Xlib should be extended to allow
retrieval of GC values.  It strikes me as odd that I would have to
maintain copies of information that's already stored somewhere (except
for efficiency, but that's where Xlib's caching scheme should help,
too).  After all, there are primitives to get all the information you
want about windows; why not about GC's ?
--
Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
guido@piring.cwi.nl or mcvax!piring!guido or guido%piring.cwi.nl@uunet.uu.net

fisher@decwin.dec.com (Burns Fisher ZK3-4/W23 381-1466) (05/19/88)

Subject: inverting areas
 
>To invert an arbitrary rectangle, use XFillRectangle with function set
>to GXinvert and plane mask set to the XOR of foreground and background
>color.  This will change all pixels that have fg color to bg color and
>vice versa (and do semi-random things to pixels in other colors, but
>since we can assume the picture is monochrome, that's no problem).
>Code fragment (fill in the obvious declarations):
> 
>	XSetFunction(dpy, gc, GXinvert);
>	XSetPlaneMask(dpy, gc, gc->values.foreground ^ gc->values.background);
>		/* '^' is the not-so-well-known XOR operator in C */
>	XFillRectangle(dpy, w, gc, x, y, width, height);
> 
>I've seen similar code in clients/xterm/menu.c.
> 
>Questions:
>1) is it kosher to retrieve the fg and bg pixels using gc->values?
>   (if not, what is in general the recommended way to get a value out of a GC?)
 
I don't believe it is Kosher to use gx->* for anything.  You can't
guarantee that some other client did not modify the GC.
 
What I would do is to set the plane mask to the XOR right away when you
create the GC (and you know what the fg and bg are).  It won't hurt any writing
you plan to do using the GC, as long as you make sure that the window background
attribute is set to be one of the two values that you XORed. (This forces
the window to be initialized correctly with the bits which you can't write
using the plane mask).  You have a bonus that you are guaranteed to be using
colors that you "own" (unless you use one of the less-common writing modes like
AND or OR.
 
>2) is this the recommended way to do "invert" an area?
>
 
It is the way that I recommend.  
 
Burns
 
fisher@decwin.dec.com
 
========================================================================
Received: by decwrl.dec.com (5.54.4/4.7.34)
	id AA00459; Thu, 19 May 88 09:01:16 PDT

mtoy@xman.SGI.COM (Michael Toy -- The S.G.I. XMAN) (05/21/88)

XOR is not my idea of a good way to highlight (or "invert" an area).
Consider a not-at-all-hypothetical machine which has a lot of horsepower
dedicated to graphics operations.  Almost any graphics operations happens
"instantly", text, lines, rects, fills, you can draw these things 10,000's
of times a second.  In order to get this performance, this machine is designed
so that the frame buffer memory is not on the CPU memory bus, making the
READ/XOR/WRITE time quite slow (in comparison to the time to draw things).
On this architecture, it is much faster to invert an object by drawing
again with the "foreground" and "background" colors switched than it is
to do an XOR.

(( ok, I'll fess up, the machine in question is the S.G.I. machine, which
   I freely admit to having in my office.  In fact, I even work at S.G.I.
   In fact, I'm the server implementor at S.G.I. so I guess you have to
   take my opinion about "the way things should be done" with a grain of
   salt.
))
--
"The programmer, like the poet, works only slightly removed from pure thought-
stuff.  He builds his castles in the air, from air, creating by exertion of
the imagination."  -- Frederick P. Brooks, Jr.  "The Mythical Man Month"

"Yeah, (*burp*), what he said." --  Michael Toy, the XMAN at Silicon Graphics
						{ames,decwrl,sun}!sgi!mtoy

guido@cwi.nl (Guido van Rossum) (05/22/88)

Michael Toy -- The S.G.I. XMAN writes:
>XOR is not my idea of a good way to highlight (or "invert" an area).
>...
>On this architecture, it is much faster to invert an object by drawing
>again with the "foreground" and "background" colors switched than it is
>to do an XOR.

Yes.  But redrawing with changed background is also not a good way to
highlight or "invert" an area.  On some architectures redrawing with
different fg/bg colors is slower than XOR-ing some bit planes, on other
architectures it is slower.  What have we learned?  It depends.  It is
unavoidable that some programs will perform sub-optimal on some
architectures (although most programs perform sub-optimal on all
architectures :-).

Is your SGI architecture also slow at copying pixmaps around on the
screen?  This is another operation where the source is already in the
frame buffer.  I believe it is quite an essential assumption of the X
design (in fact of any window system's design) that such operations are
fast, so moving windows around is fast.

Returning to XOR, maybe this can be recognized as an important graphics
operation and the primitives for XOR-ing bit planes in-place built in
the hardware...
--
Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
guido@piring.cwi.nl or mcvax!piring!guido or guido%piring.cwi.nl@uunet.uu.net

jon@nsc.nsc.com (Jon Ryshpan) (05/23/88)

In article <15077@sgi.SGI.COM> mtoy@xman.SGI.COM
			       (Michael Toy -- The S.G.I. XMAN) writes:
>XOR is not my idea of a good way to highlight (or "invert" an area).
>Consider a not-at-all-hypothetical machine which has a lot of horsepower
>dedicated to graphics operations.  Almost any graphics operations happens
>"instantly", text, lines, rects, fills, you can draw these things 10,000's
>of times a second.  In order to get this performance, this machine is designed
>so that the frame buffer memory is not on the CPU memory bus, making the
>READ/XOR/WRITE time quite slow (in comparison to the time to draw things).
>On this architecture, it is much faster to invert an object by drawing
>again with the "foreground" and "background" colors switched than it is
>to do an XOR.

This will be the situation with systems using many of the graphics
display chips which have been introduced in the last few years.  Both
the NSC and the TI chips lend themselves to systems like this.  Their
performance will drive out systems which use the same processor for
computation and graphics.  Their prices are appropriate for systems as
low as the upper end of the AT range.  So we are not talking about high
end systems like Silicon Graphics.  Therefor beware the very dangerous
XOR.