Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!swrinde!cs.utexas.edu!uunet!mcsun!ukc!acorn!john From: john@acorn.co.uk (John Bowler) Newsgroups: comp.windows.x Subject: Re: Remembering Graphics Summary: Another algorithm Keywords: overlays Message-ID: <6053@acorn.co.uk> Date: 26 Mar 91 13:49:46 GMT References: <9103211805.AA00981@neuro_dev.mayo.EDU> <1991Mar24.180043.9052@cs.tcd.ie> Organization: Acorn Computers Ltd, Cambridge, UK Lines: 93 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)