Xlib窗口背景Pixmap镜像反转问题求助
Xlib设置窗口背景Bitmap时图案镜像反转的原因分析
问题描述
我在用Xlib给窗口设置背景Bitmap时,出现了图案镜像反转的问题——每个方块的阴影本该在左上角,实际却显示在右上角。用注释里的棋盘格Bitmap数据时显示正常,但当前带阴影的方块图案就会反转,求原因?
复现代码
// test1.c // compile command: gcc -o test1 test1.c -lX11 #include <X11/Xlib.h> #include <X11/Xutil.h> #define backing_width 16 #define backing_height 16 /* static unsigned char backing_bits[] = { 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }; */ static unsigned char backing_bits[] = { 0xBF, 0xBF, 0x00, 0x00, 0xBF, 0xBF, 0xBF, 0xBF, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xBF, 0xBF, 0x00, 0x00, 0xBF, 0xBF, 0xBF, 0xBF, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0 }; int main (int argc, char *argv[]) { Display *mydisplay; XSetWindowAttributes myat; Window mywindow; XSizeHints wmsize; XWMHints wmhints; XTextProperty windowName, iconName; XEvent myevent; char *window_name = "Test"; char *icon_name = "Te"; int screen_num, done; unsigned long valuemask; Pixmap back; mydisplay = XOpenDisplay(""); screen_num = DefaultScreen(mydisplay); myat.background_pixel = WhitePixel(mydisplay, screen_num); myat.border_pixel = BlackPixel(mydisplay, screen_num); myat.event_mask = ButtonPressMask; valuemask = CWBackPixel | CWBorderPixel | CWEventMask; mywindow = XCreateWindow(mydisplay, RootWindow(mydisplay, screen_num), 200, 300, 350, 250, 2, // x, y, height, width, border width DefaultDepth(mydisplay, screen_num), InputOutput, DefaultVisual(mydisplay, screen_num), valuemask, &myat); back = XCreatePixmapFromBitmapData(mydisplay, mywindow, backing_bits, backing_width, backing_height, BlackPixel(mydisplay, screen_num), WhitePixel(mydisplay, screen_num), DefaultDepth(mydisplay, screen_num)); XSetWindowBackgroundPixmap(mydisplay, mywindow, back); wmsize.flags = USPosition | USSize; XSetWMNormalHints(mydisplay, mywindow, &wmsize); wmhints.initial_state = NormalState; wmhints.flags = StateHint; XSetWMHints(mydisplay, mywindow, &wmhints); XStringListToTextProperty(&window_name, 1, &windowName); XSetWMName(mydisplay, mywindow, &windowName); XStringListToTextProperty(&icon_name, 1, &iconName); XSetWMIconName(mydisplay, mywindow, &iconName); XMapWindow(mydisplay, mywindow); done = 0; while (done == 0) { XNextEvent(mydisplay, &myevent); switch (myevent.type) { case ButtonPress: done = 1; break; } } XUnmapWindow(mydisplay, mywindow); XDestroyWindow(mydisplay, mywindow); XCloseDisplay(mydisplay); }
效果对比
- 预期效果:每个带阴影的方块,阴影位于方块左上角,光影方向符合视觉习惯。
- 实际效果:每个带阴影的方块,阴影位于方块右上角,整体图案呈现垂直镜像反转的状态。
原因分析与解决方案
核心原因
Xlib的Bitmap数据存储规则是按行从下到上排列,但你定义的backing_bits是按从上到下的顺序编写的,导致渲染时整个图案上下颠倒。因为棋盘格是上下对称的图案,颠倒后视觉无变化,所以之前测试时没发现问题;而带阴影的方块是非对称图案,上下颠倒后阴影位置就明显反转了。
解决方案
将backing_bits数组的行顺序反转,把原本的最后一行移到最前面,依次类推即可修正。
以你当前的16x16 Bitmap为例,每行占用2字节,原数组的行顺序是第0行到第15行,需要调整为第15行、第14行……第0行的顺序。
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

