[comp.source.wanted] NEEDED: Color "OR" operation

gilgalad@caen.engin.umich.edu (Ralph Seguin) (05/15/91)

Hi.  I need the ability to specify a color dominance in graphics operations
in X.  More or less a graphics "OR" routine.  I need an efficient means
of doing this with XPutImage (I DO NOT want to copy back the pixmap section
and do the "OR" locally since that would involve multiple transfers, very
inefficient).  The situation is this:  I have a bitmap (1 plane pixmap)
locally, and I wish to place it onto a server (color or bw) and I want to
be able to specify this behavior:

source	dest	result
------	----	------
fg	fg	fg
fg	bg	fg
bg	fg	fg
bg	bg	bg

bg represents the background (or actually, any) color (index)
fg represents the foreground (or color to dominate) color (index)

As you can see, whenever either pixel is the foreground (or specified
dominant color), the result will be a foreground, ...
More or less an "OR" operation.

Is there some efficient means of implementing this?
Is there a way of mapping all pixels of a certain color within a region
to be another color (on the server)?
Is there a friendly way of allocating a color to be at indices 0 and 1
without screwing up the global color map?
Will R5 take care of this :) ?

			Thanks, Ralph

Ralph Seguin			rps@arbortext.com
536 South Forest Apt. #915	gilgalad@zip.eecs.umich.edu
Ann Arbor, MI 48104		(313) 662-4805

mrm@nss1.com (Michael R. Miller) (05/17/91)

In article <1991May15.052219.26586@engin.umich.edu> gilgalad@caen.engin.umich.edu (Ralph Seguin) writes:
>Hi.  I need the ability to specify a color dominance in graphics operations
>in X.  More or less a graphics "OR" routine.  I need an efficient means
>of doing this with XPutImage (I DO NOT want to copy back the pixmap section
>and do the "OR" locally since that would involve multiple transfers, very
>inefficient).  The situation is this:  I have a bitmap (1 plane pixmap)
>locally, and I wish to place it onto a server (color or bw) and I want to
>be able to specify this behavior:
>
>source	dest	result
>------	----	------
>fg      fg      fg
>fg      bg      fg
>bg      fg      fg
>bg      bg      bg

	Assuming the dest is always made of fg or bg pixels ...  If not,
	you may have to do the multiple xfers.

>Is there some efficient means of implementing this?
>Is there a friendly way of allocating a color to be at indices 0 and 1
>without screwing up the global color map?

	Allocate your own colormap and associate it with a
	particular window (see XChangeWindowAttributes()).

	Your fillStyle will be OpaqueStipple or Stipple.
	
	For this to work you must obtain the correct visual first.
	Also you will need to deal with EnterLeave events and
	FocusIn/FocusOut events as well as the colormap events.
	Keep track of what map has been installed (similar to
	window manager code.  Look at twm or, if you have it,
	mwm) and where the cursor is.

	Caveat:  If your visual is of a static type, you may not
	be able to do this without the multiple xfers.  If you have
	multiple visuals, use the best one suited for your screen.
	Some B&W server screens especially will have static visuals
	where black is 0 and 1 is white (or vice versa).

	Your suggestion of using indices 0 and 1 is the easiest way 
	logically OR one color to another.  In your newly allocated
	but never used colormap, allocate your background color and
	then your foreground.  These should get pixels 0 and 1 (if
	not, use the kludge method and FORCE it; afterall it IS your
	colormap and no one else should use it).  Then when you want
	to do the OR operation, do just that.  A GCor operation will
	do what you want.

	If you have more than one pair of colors, you can do the same
	type of operation by setting the planemask appropriately.  The
	background is always an even numbered pixel and the foreground
	is odd.  The planemask is always 1 and the operation is GCset.
	Using GCclear with planemask 1 will go back to the background
	color.

>Is there a way of mapping all pixels of a certain color within a region
>to be another color (on the server)?

	Can we presume "region" to be a window?  If we can, the following
	will work ....

	To change all the pixels of one color to another, muck with the
	colors associated with the pixels in the colormap.  If all pixels
	numbered, say 5, are blue and you want them red, just store the
	color red at pixel 5's location.  The change should be immediate
	if that colormap is currently active or will be accomplished when
	the colormap is made active.

	If a "region" is not a window and cannot be made a window, there
	may be a way to do this (only in some cases where you have enough
	pixel values will this work).

	Use a different set of pixels initially filled with the same rgb
	values to populate the region.  The user will not be able to tell
	the difference until you alter that second set of pixels.  Slide
	the region around using GCclear on the old and GCset on the new
	region.  Change colors in the region by mucking the colormap.

	eg.  If the colormap has 16 entries and you want 8 colors, allocate
	each color twice.  The first set using pixels 0-7 and the second set
	pixels 8-15.  Pixels inside the region get populated with pixel
	values greater than 8 where as the rest of the window is populated
	with 0-7 valued pixels.  To change the colors of the region, you
	simply alter the pixel values 8-15.  If the region moves later on,
	simply GCclear with planemask 0x00000008 where the region currently
	exists and then GCset with the same planemask where the new region
	is to be drawn.  Use clip masks to draw unusually shaped regions.
	Make sure you either GCclear before changing the window contents or
	draw with the right pixel value as you change things.  GCclear is
	easier but may cause color changes your human user may find annoying.