我需要使用GXand
屏幕平面写入模式,
XSetFunction( display, gc, GXand );
(这是模拟两射线CRT所必需的。)它的工作原理与我期望的完全相同, 除外,一些特殊的ANDed彩色像素组合。 在我的最终应用程序中,我看到了奇怪的稀有文物。屏幕截图分析显示,说(0x80、0x61、0x20)像素与(0x9f,0x78、0x28)AND给出错误的(0x9f 0x48 0x28)红色像素,而0x79字节应代替0x48。
最后,我编写了一个简单的代码(如下)以对其进行深入测试,它显示了相当奇怪的结果,例如xlib中的GXand
实现是有问题的,或者我误用了该工具。
我使用Slackware64-current。
在图形编辑器中,我确保正确运行的AND功能将为我的所有颜色提供完美的混合效果。
我在哪里错了?
谢谢。
/* based on various Xlib drawing examples */
// to compile: rm ./test ; gcc -o test xlibtest.c -lX11 ; ./test
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Window
create_simple_window(Display* display, int width, int height, int x, int y)
{
int screen_num = DefaultScreen(display);
int win_border_width = 2;
Window win;
win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
x, y, width, height, win_border_width,
BlackPixel(display, screen_num),
WhitePixel(display, screen_num));
XMapWindow(display, win);
XFlush(display);
usleep(100000); // NOTE: do not remove! will disappear next elements!
return win;
}
GC
create_gc(Display* display, Window win, int reverse_video)
{
GC gc;
unsigned long valuemask = 0;
XGCValues values;
unsigned int line_width = 1;
int line_style = LineSolid;
int cap_style = CapButt;
int join_style = JoinBevel;
int screen_num = DefaultScreen(display);
gc = XCreateGC(display, win, valuemask, &values);
if (gc < 0) {
fprintf(stderr, "XCreateGC: \n");
}
if (reverse_video) {
XSetForeground(display, gc, WhitePixel(display, screen_num));
XSetBackground(display, gc, BlackPixel(display, screen_num));
}
else {
XSetForeground(display, gc, BlackPixel(display, screen_num));
XSetBackground(display, gc, WhitePixel(display, screen_num));
}
XSetLineAttributes(display, gc,
line_width, line_style, cap_style, join_style);
XSetFillStyle(display, gc, FillSolid);
return gc;
}
int main(int argc, char* argv[])
{
int i;
Display* display;
int screen_num;
Window win;
unsigned int display_width,
display_height;
unsigned int width, height;
char *display_name = getenv("DISPLAY");
GC gcx[256], gcy[256];
XColor xc;
Colormap cm;
display = XOpenDisplay(display_name);
if (display == NULL) {
fprintf(stderr, "%s: cannot connect to X server '%s'\n",
argv[0], display_name);
exit(1);
}
width = (356);
height = (356);
win = create_simple_window(display, width, height, 0, 0);
// gc = create_gc(display, win, 1);
cm = DefaultColormap(display, DefaultScreen(display));
XSync(display, False);
for (i=-128; i<127; i++) {
gcx[i+128] = create_gc(display, win, 0);
XSetFunction( display, gcx[i+128], GXand ); // NOTE 'AND' function!
xc.red = (0x80+(i/4)) * 255;
xc.green = (0x61+(i/4)) * 255;
xc.blue = (0x20+(i/4)) * 255;
XAllocColor(display, cm, &xc);
XSetForeground(display, gcx[i+128], xc.pixel);
XDrawLine(display, win, gcx[i+128], i+50+128, 0, i+50+128, 256+50+50);
}
sleep(2);
for (i=-128; i<127; i++) {
gcy[i+128] = create_gc(display, win, 0);
XSetFunction( display, gcy[i+128], GXand ); // NOTE 'AND' function!
xc.red = (0x9f+(i/4)) * 255;
xc.green = (0x78+(i/4)) * 255;
xc.blue = (0x28+(i/4)) * 255;
XAllocColor(display, cm, &xc);
XSetForeground(display, gcy[i+128], xc.pixel);
XDrawLine(display, win, gcy[i+128], 0, i+50+128, 256+50+50, i+50+128);
}
XFlush(display);
sleep(10);
XCloseDisplay(display);
return(0);
}