From: mouse@thunder.mcrcim.mcgill.edu (der Mouse)
Newsgroups: fj.mail-lists.x-window
Subject: Re: Blitting through a clipmask
Date: 30 Jul 92 08:27:01 GMT
Distribution: fj
Organization: McGill Research Centre for Intelligent Machines

Date: Thu, 30 Jul 92 00:24:56 GMT
Message-Id: <1992Jul30.002456.6378@thunder.mcrcim.mcgill.edu>
Newsgroups: comp.windows.x

In article <9207232018.AA00192@yellowpig.mathworks.com>, debbieg@mathworks.UUCP writes:

> I'm having a problem with clipmasks and blitting.

[has a (rectangular) clip area set in a GC already, wants to blit a
non-rectangular image to a position where it may be partially clipped
by the GC's clip.]

> How do I blit the image through my clipmask through the GC's clipmask
> onto the screen?  I've tried a lot of things and none of them seems
> to work.

Okay, as I understand it you have

	- GC whose clip is set to what you want.
	- Pixmap (depth matching that of the window) containing your
	    picture in some pixels, with unspecified values in the
	    other pixels.
	- Bitmap containing 1 where the pixmap has stuff of interest, 0
	    elsewhere.

It should work to:

	- CopyArea the pixmap into a temporary pixmap of the same size
	    and depth, using a GC with no clipping.
	- CopyPlane the bitmap into this temporary pixmap, with fg=~0,
	    bg=0, function=GXand.
	- CopyPlane the bitmap onto the window with fg=0, bg=~0,
	    function=GXand, using the clipping GC.
	- CopyArea the temporary pixmap to the window with
	    function=GXor, using the clipping GC.

If you don't mind destroying the don't-care pixels in the pixmap, you
can skip the first item and do the rest using the pixmap itself as the
temporary.

If you don't like the way this briefly flashes a piece of the window
with pixel value 0, then you can CopyArea that piece of the window to a
temporary, do the above on the temporary without clipping, and then
CopyArea back with clipping.

> Here is the final way I tried:
> 1) Create a 1 bit blank pixmap and a Screen Depth blank pixmap.
> 2) Create the clipmask image and the data image.
> 3) Do an XPutImage using the window's gc to put the clipmask image
>      into the Screen Depth blank pixmap.
> 4) Create a 1 bit gc (its drawable is the 1 bit pixmap) with
>      foreground 1 and background 0.
> 5) XCopyPlane the Screen Depth pixmap to the 1 bit blank pixmap.
> 6) Set the window's gc's clipmask to the 1 bit pixmap.
> 7) Set the window's gc's cliporigin to where the image is going in
>      the window.
> 8) XPutImage the image into the window.

This has lots of things wrong with it.  To list them as I notice them,
reading over it...

- The PutImage in step 3 will be clipped by a clipping area designed
    for clipping the whole window, not just this little part of it.
    There's really no reason to clip at this step, though if you want
    to you *might* be able to make it work by setting the clip origin
    of the GC to the negative of the small area's position in the
    window.

- I don't know *what* step 5 is supposed to do.  You're picking out one
    of the bitplanes (you don't say which one); Murphy's law says
    you'll get one that's constant across the whole pixmap....

- Step 6 looks mildly sensible, except that you probably want to use
    the clipmask bitmap instead of one containing whatever weirdness
    step 5 resulted in.  You probably also want to combine the clips,
    not replace it, or you'll lose the clip you had already set up.

- If step 6 is fixed, the rest looks fine.

> How can I get the Screen Depth pixmap to contain the clipmask image
> ANDed with the window's gc's clipmask?????

Why would you want to?  You'd want in a bitmap, not a deep pixmap.
Also, why would you care?  Just do all the operations except for the
final drawing to the window with GCs that don't clip at all....

					der Mouse

			    mouse@larry.mcrcim.mcgill.edu