[comp.windows.x] Remembering Graphics

kall@mayo.EDU (Bruce Kall) (03/22/91)

We have 16 bit grayscale images that we sample down to 8 bit images based
on a particular (and changable) window/level setting into a Pixmap
that is then CopyArea'd onto a Window.  All graphics (text,lines etc..)
are drawn into the Pixmap and then re-CopyArea'd onto the window.  This
enables taking care of Expose events for those windows that have images
and graphics.

Our problem is when we re-sample the 16 bit image into the Pixmap (which is
often and can occur almost anywhere in our program) all of the text/lines are
then gone
because they were never in the 16 bit image but only in the Pixmap/Window.

How could we 'remember' the text/lines that were in the Pixmap and hence on
the window when all we want to do is remap the image (obviously a graphics
overlay plane would alleviate the problem.  This is a 8-bit Sun display).

- We do not want to limit the number of bits in the colormap by, say, 1 bit and
use plane masks to essentially, write protect the text in that bit
since this would leave us with only 128 gray levels instead of 256.
- We have thought about have text/lines in one Pixmap and the image in another
Pixmap and then combining them together when a window is Exposed.  None of
the GC functions seem to be correct to do this.  We use colormap locations
0-8 for colors and 9-256 for the grayscale image.

Does anyone have any suggestions??



\------------------------------------------------------------\
 \   Bruce Kall                \  Internet:   Kall@Mayo.edu   \
  \   Mayo Clinic (Foundation)  \  Phone: (507)-255-4768       \
   \   Rochester, MN 55905       \                              \
    \------------------------------------------------------------\

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (03/23/91)

> We have 16 bit grayscale images that we sample down to 8 bit images
> based on a particular (and changable) window/level setting into a
> Pixmap that is then CopyArea'd onto a Window.  All graphics
> (text,lines etc..) are drawn into the Pixmap and then re-CopyArea'd
> onto the window.  This enables taking care of Expose events for those
> windows that have images and graphics.

> Our problem is when we re-sample the 16 bit image into the Pixmap
> (which is often and can occur almost anywhere in our program) all of
> the text/lines are then gone [...].

[8-bit PseudoColor hardware]

> - We do not want to limit the number of bits in the colormap by, say,
>   1 bit and use plane masks [...].
> - We have thought about have text/lines in one Pixmap and the image
>   in another Pixmap and then combining them together when a window is
>   Exposed.

You could keep a bitmap that is, say, 0 where the image is to appear
and 1 where the annotations are to appear, then keep two pixmaps, one
for the picture and one for the annotations, using the bitmap as a
clip-mask when copying things to make sure you don't destroy more than
you want to.

If you are willing to require the server to support SHAPE (not
unreasonable IMO) and the annotations don't change often, you could
keep them in a separate window, shaped to fit them precisely, thus
sidestepping the problem entirely.

You could put the image in the window's background pixmap, then draw
the annotations as graphics; then the server deals with refreshing the
image for you, and you just need to redraw the annotations on expose.

There are probably other ways, but those are all that come to mind
right now.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

cjmchale@cs.tcd.ie (Ciaran McHale) (03/25/91)

In <9103211805.AA00981@neuro_dev.mayo.EDU> kall@mayo.EDU (Bruce Kall) writes:

>[An application which displays image data in a window (actually a
>pixmap which is then copied to the window upon exposure) and then
>draws some lines and text over the image. When the image changes, is
>there any way to avoid having to recompute/redraw the text and lines
>which are independant of the image data?]
>
>- We do not want to limit the number of bits in the colormap [...]
>- We have thought about have text/lines in one Pixmap and the image in another
>Pixmap and then combining them together when a window is Exposed.  None of
>the GC functions seem to be correct to do this.  We use colormap locations
>0-8 for colors and 9-256 for the grayscale image.

What you can do is have a pixmap for the image data. Also have a
_bitmap_ (a 1 bit deep pixmap) into which you will draw the text and
lines. To get the image & text/lines into a window you use XCopyArea()
to copy the image data from the pixmap and then use XCopyPlane() to copy
from the bitmap into the window. The GC used in XCopyPlane() should:

	o Have the clipmask set to the bitmap which is the source of
	  the XCopyPlane() call.
	o Have its foreground color set to the color that you want the
	  text and lines drawn in. (If you want the text and lines drawn
	  in different colors then you'll have to use several
	  bitmaps---one bitmap for text/lines to be drawn in red,
	  another for text/lines to be drawn in blue, and so on.)

You will, of course, need to use different GCs to draw into the pixmap
and bitmap (since they have different depths) but that shouldn't present
any difficulties. Also, note that I haven't tried what I've outlined
above, so I don't know how quickly XCopyPlane() will work when the GCs
clipmask is set to a bitmap. (Anybody know what sort or performance to
expect?)


Ciaran.
-- 
Ciaran McHale		"Verbosity says it all"			      ____
Department of Computer Science, Trinity College, Dublin 2, Ireland.   \  /
Telephone: +353-1-772941 ext 1538	FAX: +353-1-772204	       \/
Telex: 93782 TCD EI			email: cjmchale@cs.tcd.ie

cjmchale@cs.tcd.ie (Ciaran McHale) (03/25/91)

In <1991Mar24.180043.9052@cs.tcd.ie> I wrote:

>[...]
>What you can do is have a pixmap for the image data. Also have a
>_bitmap_ (a 1 bit deep pixmap) into which you will draw the text and
>lines. To get the image & text/lines into a window you use XCopyArea()
>to copy the image data from the pixmap and then use XCopyPlane() to copy
>from the bitmap into the window. The GC used in XCopyPlane() should:
>
>	o [...]
>	o [...]

I forgot to say:

	o The `function' component of the GC should be GXCopy (the default).

Ciaran.
-- 
Ciaran McHale		"Verbosity says it all"			      ____
Department of Computer Science, Trinity College, Dublin 2, Ireland.   \  /
Telephone: +353-1-772941 ext 1538	FAX: +353-1-772204	       \/
Telex: 93782 TCD EI			email: cjmchale@cs.tcd.ie

mouse@lightning.mcrcim.mcgill.EDU (der Mouse) (03/26/91)

>> [An application which displays image data in a window (actually a
>> pixmap which is then copied to the window upon exposure) and then
>> draws some lines and text over the image.  When the image changes,
>> is there any way to avoid having to recompute/redraw the text and
>> lines which are independant of the image data?]

>> - We have thought about have text/lines in one Pixmap and the image
>>   in another Pixmap and then combining them together [...].

> What you can do is have a pixmap for the image data.  Also have a
> _bitmap_ (a 1 bit deep pixmap) into which you will draw the text and
> lines.  To get the image & text/lines into a window you use
> XCopyArea() to copy the image data from the pixmap and then use
> XCopyPlane() to copy from the bitmap into the window.  The GC used in
> XCopyPlane() should:

> 	o Have the clipmask set to the bitmap which is the source of
> 	  the XCopyPlane() call.

If you do that, you don't need to XCopyPlane(); you can
XFillRectangle() instead.

Note that you need to reset the clip-mask every time, if you've drawn
into it since you last set it; you can't depend on the GC noticing
changes you make to the bitmap after you set it as the clip-mask.

The original poster also said (in text I've deleted) that they're using
colormap cells 0-8 for annotations.  This implies more than one bit's
worth of annotations.

Possibilities: keep a separate bitplane for each color of annotation,
which you suggested, or perhaps keep a pixmap for annotations and then
XCopyArea() it using your notion of an appropriate clip-mask in the GC.

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

john@acorn.co.uk (John Bowler) (03/26/91)

In article <1991Mar24.180043.9052@cs.tcd.ie> cjmchale@cs.tcd.ie (Ciaran McHale) writes:
>What you can do is have a pixmap for the image data. Also have a
>_bitmap_ (a 1 bit deep pixmap) into which you will draw the text and
>lines. To get the image & text/lines into a window you use XCopyArea()
>to copy the image data from the pixmap and then use XCopyPlane() to copy
>from the bitmap into the window. The GC used in XCopyPlane() should:
>
>	o Have the clipmask set to the bitmap which is the source of
>	  the XCopyPlane() call.
>	o Have its foreground color set to the color that you want the
>	  text and lines drawn in. (If you want the text and lines drawn
>	  in different colors then you'll have to use several
>	  bitmaps---one bitmap for text/lines to be drawn in red,
>	  another for text/lines to be drawn in blue, and so on.)
>
>You will, of course, need to use different GCs to draw into the pixmap
>and bitmap (since they have different depths) but that shouldn't present
>any difficulties. Also, note that I haven't tried what I've outlined
>above, so I don't know how quickly XCopyPlane() will work when the GCs
>clipmask is set to a bitmap. (Anybody know what sort or performance to
>expect?)

I suspect that the performance will be terrible, at least with the sample
server implementation.  It converts the bitmap into a set of regions (using
a piece of code which can be speeded up quite a lot...) then combines
this with the window clip region.  Not only does this require a lot
of work whenever the clipmask is reset (whenever the text/lines are
changed), but the resultant clipping region for any drawing operation is
likely to consume a large amount of memory and slow down drawing a lot.

I once considered doing bitmap clipping in-line in a server, but the
consequences for the low level graphics code seemed to be an extra dimension
of complexity.

An alternative algorithm, which is likely to have more consistent cost
across a range of servers and is unlikely to have unbounded memory costs
in the server, is:-

1) Draw text/lines into one pixmap, maintain the image as another.  Draw
   the text/lines using pixel values 128->136 (rather than 0->8), maintain
   the text/line pixmap background as pixel value 0.  The image *can* use
   pixel values 0->8 if it needs to.

2) When an expose event requires a window redraw:-

	i) Use XCopyArea to copy the image to the window.
	ii) Use XCopyPlane with:-
		source - the text/lines pixmap
		dest - the window
		foreground - ~0 (ie all ones)
		background - 0
		rop - AndInverted  (GXAndInverted)
		bit-plane - binary 10000000 (128)
		(plane mask - ~0; all ones)

	    This clears all pixels in the window which correspond to
	    drawn areas in the text/lines pixmap.
	iii) Use XCopyArea with:-
		source - the text/lines pixmap
		dest - the window
		(foreground/background don't care)
		rop - Or  (GXOr)
		plane mask - binary 01111111 (127)

	   This copies the text/lines colours (with the top bit cleared
	   by the plane mask) into the window without changing the non-drawn
	   pixels.  In other words (ii/iii) perform an overlay operation
	   where the text/line colours overlay the image.

This algorithm has many variations - it may be more efficient to maintain
a bitmap of drawn text/lines pixels, and XCopyPlane from this at step (ii),
then the plane mask is not required in (iii).  (This avoids the need for
the server to extract the bit-plane at step (ii), but this may actually be 
slower with some implementations as the src/dst are then different depths.
It also avoids the plane mask at (iii), which may be faster on some
implementations).

Another answer to this general problem (that of handling overlays in X)
would be a server extension.  This is likely to be more efficient (at least
a factor of 2?).  Something like:-

XOverlayArea
	src-drawable, dst-drawable: DRAWABLE
	gc: GCONTEXT
	src-x, src-y: INT16
	width, height: CARD16
	dst-x, dst-y: INT16
	transparent: CARD32

The src/dst are combined as in XCopyArea, except that pixels with value
``transparent'' in the src are not changed.

John Bowler  (jbowler@acorn.co.uk)