[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference bulova::decw_jan-89_to_nov-90

Title:DECWINDOWS 26-JAN-89 to 29-NOV-90
Notice:See 1639.0 for VMS V5.3 kit; 2043.0 for 5.4 IFT kit
Moderator:STAR::VATNE
Created:Mon Oct 30 1989
Last Modified:Mon Dec 31 1990
Last Successful Update:Fri Jun 06 1997
Number of topics:3726
Total number of notes:19516

1902.0. "GXxor Graphics function with Color lines" by FREZEN::PROJECTS () Tue Dec 12 1989 19:04

	Hi,

	Could you help me with this problem?


	I am using GXxor GC function to erase lines that I had previously
	drawn on my vax 3500 wkstation (Decwindows). The lines are erasing
	fine.

	My problem is if I can't attach a color to the lines that I am drawing 
	and erasing because GXxor is somehow clobbering the foreground color
	I set to black.

	Any suggestions much appreciated
T.RTitleUserPersonal
Name
DateLines
1902.1One possible way..EXLIB::DLUGOSZOpen foot, Insert MouthWed Dec 13 1989 09:4216
    That is a problem that you will run into when using color with
    rubberbanding techniques. There was a note soemwhere back in this
    conference that discussed his issue.
    
    One possibility is to use private color cells to set up an overlay.
    You could set the overlay color to your current drawing color. The
    disadvantage is that you will chew up a lot more color cells (if
    you need 8 base drawing colors and 1 overlay color you will need
    to allocate 8 * 2^1, or 16, color cells). But it does keep you line
    from changing colors as you draw across different colored objects.
    
    If this might be suitable and you need more info let me know.
    
    Ron
    
    
1902.2GXxor Graphics function with Color linesFREZEN::PROJECTSWed Dec 13 1989 10:4217

	Hello 	EXLIB::DLUGOSZ "Open foot, Insert Mouth"

	I thought there may be a quick way to get around this xor problem 
	of color lines... 

	How would someone traditionally erase a line
	without using an xor and could I implement that strategy. 

	Is there a way of using a certain color unintentionally such that
	my lines would look like they are erased?

	If my speculations are off then could you expand on your suggestion?


	Much appreciated
1902.3choose pixels and mask carefullyTOOLEY::B_WACKERWed Dec 13 1989 14:259
You have to think in terms of what bits you're going to get when you 
xor.  In simple fore/background if you xor the foreground and 
background pixels to get the mask for the xor you can get it to
reliably alternate.  If you want predictable color control you'll need
to construct your colors such that both the primary color and its xor
against the mask you define give the colors that you want.  The 
simplest way would be to set them up in pairs so you don't have to 
create a bunch of color map entries just to hold the complementary 
colors.
1902.4GXxor Graphics function with Color linesFREZEN::PROJECTSWed Dec 13 1989 17:0924

	hello		TOOLEY::B_WACKER


	In order to think in terms of which bits I am going to get I would have
	to know how the default color map assignment... you know like which
	map entry is dedicated to which color, screen, black, white etc..

	would you know this?

	To xor a blue line	0 0 255 	I would need to know which
	map entry the color blue is in the color map no? And then figure a mask
	that would give me that color back thru an XOR like color map entry 0.

			000000000000000000000
			0000000000000000000ff
			---------------------
					   ff

	Does this look right? It didn't work when I tried it... the color drawn
	was black.

	
1902.5Maybe this will help?EXLIB::DLUGOSZOpen foot, Insert MouthWed Dec 13 1989 19:35138
Here is an  example of how to set up the gcs and color cells to use private
color cells to achieve a rubberbandig effect (I assume that's what your
trying to do - or something very similar - from .0). Again this can eat
up color map cells pretty fast so watch out on 4 plane workstations.



#define MAXCOLORS		8	

/* colors */

#define RED			1
#define YELLOW			2
#define GREEN			3
#define BLUE			4
#define BLACK			5
#define CYAN			6
#define MAGENTA			7

Colormap colormap;
GC setGC, clearGC, drawGC;
XGCValues setGCV, clearGCV, drawGCV;
XColor colors[MAXCOLORS];
unsigned long pixels[MAXCOLORS], plane_mask;



void allocateDefaultColors()
{
    XColor grid[MAXCOLORS], exact_return;
    int n, flags;
    XVisualInfo vinfo;

    static char *color_names[] = {"white", "red", "yellow", "green", 
      "blue", "black", "cyan", "magenta"};

    /*
       find out what default visual is supported by this display and then
       allocate color resources accordingly. This being example only 
       supports the default 8-plane PSEUDOCOLOR visual. (i.e., it won't
       work without some simple modifications on a Firefox.
    */

    if (!(XMatchVisualInfo(display, screen, 8, PseudoColor, &vinfo))) {
	fputs("Couldn't find a default PseudoColor visual!", stderr);
	exit(1);
    }

    /* display and screen were declared and set in another function */
    
    colormap = DefaultColormap(display, screen);

    /*
       allocate 16 color cells for the primary and secondary colors
       and the overlay color.
     */

    if ((XAllocColorCells(display, colormap, True, &plane_mask, 1, 
      &pixels, MAXCOLORS)) == 0) {	
	fputs("Couldn't allocate color cells", stderr);
        exit(1);
    }

    flags = DoRed | DoGreen | DoBlue;

    for (n = 0; n < MAXCOLORS; n++) {

	/* store drawing colors in cell colors[n] */

	colors[n].pixel = pixels[n];
	XStoreNamedColor(display, colormap, color_names[n], colors[n].pixel,
	  flags);

	/* store grid color in pixels[n] | plane_mask */

	grid[n].pixel = pixels[n] | plane_mask;
	XStoreNamedColor(display, colormap, "black", grid[n].pixel, flags);

    }
}


void createGCs()
{
    /*
       create gc for setting object. This gc is used to temporarily
       (i.e., nondestructively) draw an object. plane_mask is set to
       the plane mask returned by XAllocColorCells.
    */
    
    setGCV.foreground = GXset;
    setGCV.foreground = colors[BLACK].pixel;
    setGCV.background = colors[WHITE].pixel;
    setGCV.plane_mask = plane_mask;
    setGC = XCreateGC(display, canvas, GCFunction | GCForeground |
      GCBackground | GCPlaneMask, &setGCV);

    /*
       create gc for clearing object. This gc is used to nondestructively
       remove an object that was drawn using setGC. plane_mask is set to
       the plane mask returned by XAllocColorCells.
    */

    clearGCV.foreground = GXclear;
    clearGCV.foreground = colors[BLACK].pixel;
    clearGCV.background = colors[WHITE].pixel;
    clearGCV.plane_mask = plane_mask;
    clearGC = XCreateGC(display, canvas, GCFunction | GCForeground |
      GCBackground | GCPlaneMask, &clearGCV);


    /*
       create gc for drawing the final object. Use this gc to draw the
       object in its final form. This is destructive. Set plane mask
       to the complement of the overlay plane mask to avoid drawing in
       the overlay plane.
    */

    drawGCV.foreground = GXcopy;
    drawGCV.foreground = colors[BLACK].pixel;
    drawGCV.background = colors[WHITE].pixel;
    drawGCV.plane_mask = ~plane_mask;
    drawGC = XCreateGC(display, canvas, GCFunction | GCForeground |
      GCBackground | GCPlaneMask, &drawGCV);
}

Drawing a line (into the overlay plane) using the setGC will make it
visible on the screen. Redrawing the same line using the clearGC will
erase it. This is all nondestructive since it is taking place in a
dedicated plane. When you want to set the line 'permanently' use the
drawGC. This will draw the line only into those planes that do not
include the overlay plane. This will have the same effect as repeatedly
drawing a line using the function GXxor and then making it peranent
with GXcopy - except that your line will alway be the specified color
no matter what background it's drawn on. I use this for rubberbanding
as well as gridding type applications.

Ron
1902.8GXxor Graphics function with Color linesFREZEN::PROJECTSThu Dec 14 1989 11:028

	Replies from this note are appreciated but...

	This topic is being debated over in 1905.


	Much appreciated
1902.9Holy color cells Batman - Whats goes on here?EXLIB::DLUGOSZOpen foot, Insert MouthThu Dec 14 1989 11:1234
    
    Re: .6

    Fred,
        
    > Since you're setting up a colormap using BLACK/R/G/B/C/M/Y/WHITE
    > A then it's a whole lot cheaper to allocate 8 planes and 1 pixel.
    > This returns you 8 plane masks and a single pixel value and only
    > consumes 8 entries (rather than 16) AND has a heck of a lot better
    > chance at being available than 1 plane and 8 colors.
                                    
    According to the definition of XAllocColorCells requesting 8 plane
    masks and 1 pixel values results in:
    
    	1 (pixel value) * 2^8 (plane masks) = 64 color cells
    
    Has Shiefler, Gettys, et all provided incorrect documentation to
    how this function works? I know that when I request 8 pixel values
    and one plane mask the above formula gives me:
    
    	8 (pixel values) * 2^1 (plane masks) = 16 color cells
    
    which is what has actually been allocated in my color map (I 
    checked).
    
    Also, I'm using an overlay to provide a grid function. As defined
    by XAllocColorCells the number of base drawing colors is equal to
    the number of pixels requested and the number of overlay colors
    is equal to the number of plane masks requested (and yes it works,
    I've been using it). The above allocation gives me 1 base drawing
    color and 8 overlay colors according to this scheme.
    
    Ron
 
1902.103 planes x 1 pixel = 8 color cellsHANNAH::MESSENGERBob MessengerThu Dec 14 1989 13:0718
Re: .6
    
>    Since you're setting up a colormap using BLACK/R/G/B/C/M/Y/WHITE
>    then it's a whole lot cheaper to allocate 8 planes and 1 pixel.
>    This returns you 8 plane masks and a single pixel value and only
>    consumes 8 entries (rather than 16) AND has a heck of a lot better
>    chance at being available than 1 plane and 8 colors.
    
I assume you meant 3 planes rather than 8.

>    According to the definition of XAllocColorCells requesting 8 plane
>    masks and 1 pixel values results in:
>    
>    	1 (pixel value) * 2^8 (plane masks) = 64 color cells
    
A nit: 2^8 is 256, not 64.

				-- Bob
1902.11You've heard of RPN - Ron's Polish Notation?EXLIB::DLUGOSZOpen foot, Insert MouthThu Dec 14 1989 13:4313
>    According to the definition of XAllocColorCells requesting 8 plane
>    masks and 1 pixel values results in:
>    
>    	1 (pixel value) * 2^8 (plane masks) = 64 color cells
    
> A nit: 2^8 is 256, not 64.

    
    That's why I went into the field of computers. Can't multiply for
    anything!
    
    Ron
1902.12GXxor Graphics function with Color linesFREZEN::PROJECTSThu Dec 14 1989 14:507

	Could one of you fellows explain the definition, purpose and
	functionality of a grid... possibly some examples?


	Thanx
1902.13Ok....EXLIB::DLUGOSZOpen foot, Insert MouthThu Dec 14 1989 15:3634
    It's a way of constraining user input. The progam that the example
    I posted was from is an interactive pxiel oriented graphics editor
    (like DECPaint). 
    
    To draw a line the user clicks at some starting location on the
    canvas, drags to the desired end location, and releases the mouse
    button. The canvas is, say, 400 X 400 pixels, so with no constraints
    imposed the user could select any of those n (i'm not going to try
    my luck at multiplication again!) points. The disadvantage is the
    lack of accuracy. if the user is drawing a polyline and wants to
    end it at the same point where it was started, he better have a
    good aim (my polyine routine does not automatically close the figure
    as some do). 
    
    If the user needs more accuracy he can turn on the grid feature.
    a nondestructive grid of points is drawn on the canvas at some
    specified interval. The method used for drawing the grid is similar
    to what I described in an earlier reply. The default grid interval
    for my program is 20 pixels. When the grid is on all points are
    automatically snapped (rounded) to the nearest grid point. So the
    user only has 400 selectable points to use vs 16,000. The advantage
    is accuracy. Grid interval can be reset to some other value if 
    desired.
    
    When the user is finished the grid is removed without effecting
    the drawing on the canvas.
    
    The best thing to do is start up DECPaint and select the grid option.
    It's in on of the pulldown menus. DECPaint only supoprts one grid
    interval however - a little constricting.
    
    Hope this helps.
    
    Ron 
1902.14SSPENG::KLEINSORGESo sue me.Thu Dec 14 1989 22:5241
    .9
    
    The answer is "ooops", the correction already appeared however...  it's
    all these late nights.  Excuse me if you missed my error :-)
    
    The long winded reply is that you take the number of colors and round
    it to the nearest power of 2 that will contain it - for 8 colors that
    is 8.  Then take the log2 of this (find the number of bits required
    to contain it) - for 8 colors this is 3 (i.e. 2^3 = 8).  Now taking
    this number do your calculation:
    
    		1 * 2^3 = 8
    
    Now, taking this value and assuming the following returns:
    
    		Pixel =	00000010
    
    		Mask1 = 00000001
    		Mask2 = 10000001
    		Mask3 = 00010000
    
    permute the bits ORed with the pixel value look like:
    
    0		00000010
    1		00000011
    2		10000010
    3		10000011
    4		00010010
    5		00010011
    6		10010010
    7		10010011
    				
    Now form the XOR mask as MASK1 | MASK2 |  MASK3 = 10010001
    
    
    And finally, ANY pixel value from the array above, XORed with the
    value 10010001 will result in not only another valid pixel from this
    list BUT if you build an array like the above you will get a
    "complementary" entries pixel value.