'GXand'Xlib绘图模式导致颜色错误

时间:2018-07-13 13:04:23

标签: linux x11 xlib crt slackware

我需要使用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);
}

0 个答案:

没有答案