T.R | Title | User | Personal Name | Date | Lines |
---|
696.1 | Do you want it to work, or work right? | HGOVC::KENBERKUN | People that melt | Sun Apr 30 1989 23:59 | 16 |
| I built a simple rubber box that runs under color. See note 126
in elktra::dw_examples. I use it in my Mandelbrot program. I'm
not wildly happy about it, but it works. Also, if you can find
the waters-chromatography demo (there are references to it scattered
around) it includes a rubber-box widget, from which I stole most
of my code.
I don't think it matters a great deal whether you are making rubber
lines, boxes or arches, the tricky part is the graphics context.
I messed around with different modes (xor, inverse, etc.) but I
don't really understand what they are doing. I found one that works
(inverse) but I'm not sure why I couldn't get xor to do what I wanted.
Ken B.
|
696.2 | example in DW_EXAMPLES #143 | GADOL::LANGFELDT | Complex lives are happy lives! | Mon May 01 1989 15:16 | 6 |
|
I've posted a couple of examples in ELKTRA::DW_EXAMPLES showing
one way to do rubberbanding. Note #143.
Sharon
|
696.3 | An additional mechanism for rubberbanding. | IO::MCCARTNEY | James T. McCartney III - DTN 381-2244 ZK02-2/N24 | Mon May 01 1989 18:10 | 24 |
|
The examples posted above use an Xor operation on the plane mask and two
graphics contexts to achieve rubberbanding. A slightly different way to do
this is to use the following settings for the rubberband GC:
gc.function = GXxor;
gc.foreground = highlight_color ^ background_color;
gc.line_style = LineSolid;
gc.line_width = 1;
This will allow you to use only one graphic context for drawing rubberband
lines. These settings of the GC take advantage of the Xor property that states
(A (+) B (+) A) = B
Thus by carefully choosing the forground for GXxor writing mode to be:
(A (+) B)
we can cause the background color of the window to become A and then restore
it using the same graphic context.
James
|
696.4 | | DECWIN::FISHER | Burns Fisher 381-1466, ZKO3-4/W23 | Mon May 01 1989 18:50 | 20 |
| .3 Only works fine when you draw over the background color. The
problem comes when you try to draw over some different color. There
are only two ways that I know of to make this work 100% of the time:
1. Save the junk underneath where you are drawing and draw two
contrasting lines in copy mode. When you move on, restore
the data you saved.
2. Use an entire plane for the rubber band. Unfortunately, this one
is even harder to do...you have to allocate all your colors in
one big hunk, and you must make them all writable.
Sigh.
As I have said before, if anyone has tried (1), it would be awfully
interesting to know if it worked fast enough.
Burns
|
696.5 | how about this | VWSENG::KLEINSORGE | Toys 'R' Us | Mon May 01 1989 22:56 | 56 |
|
Hmmm. I'm working on something right now for UIS emulation that
should work if I've read the documentation correctly (the documentation
is clear as mud) but I'm still doing the coding and haven't actually
tested it yet. **And** it's probably only pseudo-color specific,
I have to assume that a "true-color" machine would allow rubberbanding
sort-of like magic (isn't the complement of Green, Magenta?) by
INVERTing the entire pixel.
First, you need to allocate color cells (for exclusive use). Ask
for 1 color and n planes, where (1 * (2**n)) is the total number
of colors you need (according to the Xlib manual). Note that this
makes the number of colors a power of two. Since what you will be
returned is 'n' plane masks and a single pixel value. The planes
need not be contiguous.
Using the returned masks and the pixel, create a table of indexes
to match all the permutations of the pixel and the masks. The
table should be built so that the plane masks in the color definitions
complement each other... this is done by a strange little loop that
maybe I'll list here later. An example for 8 colors (the standard
ones for instance) might look like this:
Returned Values:
Plane masks [3] = ^b 1000, ^b 100000, ^b 1000000
Pixel = ^b 10
OR_Plane_masks = ^b 1101000
The index array of color definitions would look like:
Index Value Set to color
[0] = 0000010 ; Black
[1] = 0001010 ; Red
[2] = 0100010 ; Green
[3] = 0101010 ; Blue
[4] = 1000010 ; Yellow
[5] = 1001010 ; Magenta
[6] = 1100010 ; Cyan
[7] = 1101010 ; White
These color definitions become the values that you use for drawing.
When you want to rubberband -- you use the OR of the plane masks
for XOR drawing. This will always complement to a color that you
have defined.
If you want to use shared, named colors, then I can only shrug.
Maybe the DECwindows people at least set up the Black, Red, Green,
Blue, Yellow, Cyan, Magenta, White entries (at least) so that the
pixel values can be in some way arithmetically manipulated to allow
complement mode (it would have been a good idea!).
|
696.6 | | STAR::BRANDENBERG | Si vis pacem para bellum | Tue May 02 1989 11:19 | 5 |
|
re .3: Historical trivia... Burns, this is how the resize stretchy
box worked on UIS on the GPX. Of course, those were always horizontal
and vertical lines which simplified things a bit...
|
696.7 | Good idea! | DECWIN::FISHER | Burns Fisher 381-1466, ZKO3-4/W23 | Tue May 02 1989 11:21 | 11 |
| Hey, that's cute, Fred. I like it. It only uses up half the colormap
entries of my method. It should also work on DirectColor and GrayScale.
As to the contrast based on complementing the pixel value on a TrueColor
device, though, I don't think you can
count on it. For example, look at the complement of 0x0fff, which is
0x1000. This is a difference of only 1, probably not a visible difference.
Maybe you need to xor with 0x5555 or something (????).
Burns
|
696.8 | | DECWIN::FISHER | Burns Fisher 381-1466, ZKO3-4/W23 | Tue May 02 1989 11:22 | 7 |
| As to the other question: The only colors we preallocate are black and
white in the default colormap. Anything else is allocated when it is asked
for the first time. Thus the values are dependent on the order in which
they are requested.
Burns
|
696.9 | | DECWIN::FISHER | Burns Fisher 381-1466, ZKO3-4/W23 | Tue May 02 1989 11:30 | 8 |
| re .6: Yes, I know. Where do you think I got the idea? :-) Seriously,
though, that work was done in the driver. It is clearly practical if you
can do it at that level. What I am wondering is whether it is practical
to do it at the protocol level copying to pixmaps etc, or must we make a
stretchy-box extension? (Maybe not so bad an idea in any case)
Burns
|
696.10 | | VWSENG::KLEINSORGE | Toys 'R' Us | Tue May 02 1989 20:58 | 58 |
|
Hmmm. I'd have to think of some interesting permutation for true-color
systems... to be honest, until I actually have such a beast to play
with there will be a lot of things I won't really understand (like
plane masks on a true-color system). I am rather pleased that I
was able to decode the cryptic documentation.
A generic "rubberband" extension would be a *great* extension (that
is, add the rubberband line, square, rectangle, circle and ellipse
*and/or* maybe just a generic polyline for the rubberband!).
You know what might be an interesting trick on the server side for
the named colors? How about when a color is added, like "red" at
the same time you try to allocate it's complement so that the color
indexes can be bitwise inverted? Maybe it could be added as a
server setup feature. Ya, I know it's then not generic to all X11
implementations - but there are pragmatic considerations :-)
_Fred
The virtual color map can be built using the following (I've
skipped the code that takes a colormap size and figures out the
number of planes and rounds it up to a power of 2 as well as the
Alloc Color Cells call. The XOR mask is built from the OR of all
the plane mask entries):
int slot_size; /* The number of colors rounded
up to a power of 2 */
int plane_count; /* The number of planes required */
int plane_masks[]; /* The array of plane masks from the X allocation
call for color cells */
int pixel; /* The returned pixel value */
int vcm[]; /* Virtual colormap (index values) */
int color,
color_bits,
mask_num; /* some working values */
for (color = 0, color < slot_size, color += 1)
{
color_bits = color;
vcm[color] = pixel;
for (mask_num = 0, mask_num < plane_count; mask_num += 1)
{
if (color_bits & 1)
{
vcm[color] |= plane_masks[mask_num];
}
color_bits >>= 1;
}
}
|