我不明白 Xwindows 中字体的行为
I don't understand the behavior of fonts in Xwindows
给定示例程序:
/*
* Study for multiple windows.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Window w1, w2;
XEvent e;
const char* msg1 = "Hello, window 1";
const char* msg2 = "Hello, window 2";
int s1;
int s2;
GC gracxt1;
GC gracxt2;
XFontStruct* font;
XFontStruct* font2;
Display* d1;
Display* d2;
d1 = XOpenDisplay(NULL);
if (d1 == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
printf("d1: %p\n", d1);
d2 = XOpenDisplay(NULL);
if (d2 == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
printf("d2: %p\n", d2);
s1 = DefaultScreen(d1);
s2 = DefaultScreen(d1);
printf("s1: %d\n", s1);
printf("s2: %d\n", s2);
gracxt1 = XDefaultGC(d1, s1);
#if 0
gracxt2 = XDefaultGC(d2, s2);
#else
gracxt2 = XDefaultGC(d1, s2);
#endif
font = XLoadQueryFont(d1,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-200-200-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d1, gracxt1, font->fid);
font2 = XLoadQueryFont(d1,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-400-400-m-0-iso8859-1");
if (!font2) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d1, gracxt2, font2->fid);
w1 = XCreateSimpleWindow(d1, RootWindow(d1, s1), 10, 10, 640, 480, 5,
BlackPixel(d1, s1), WhitePixel(d1, s1));
XSelectInput(d1, w1, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d1, w1);
w2 = XCreateSimpleWindow(d1, RootWindow(d1, s1), 10, 10, 640, 480, 5,
BlackPixel(d1, s2), WhitePixel(d1, s2));
XSelectInput(d1, w2, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d1, w2);
while (1) {
XNextEvent(d1, &e);
if (e.type == Expose) {
if (e.xany.window == w1) XDrawString(d1, e.xany.window, gracxt1, 10, 50, msg1, strlen(msg1));
else XDrawString(d1, e.xany.window, gracxt2, 10, 50, msg2, strlen(msg2));
}
if (e.type == KeyPress) break; /* exit on any key */
}
XCloseDisplay(d1);
XCloseDisplay(d2);
return 0;
}
设置两个windows和select两种不同的字体,window各一种,然后打印。我对 XWindows 的理解是字体被 selected 到图形上下文中,即 GC。但是,根据使用的 Display*,我会得到两种不同的行为:
#if 1
IE,每个 window 具有不同大小的字体,或者:
#if 0
我认为,并且文档强烈暗示,字体是通过 XSetFont() 调用 selected 到上下文 gracxt1 或 gracxt2 的。因此,我从两个 GC 开始这个示例,但一个 Display* 和一个屏幕 select。但是,在我为每个 window 赋予其自己的 Display*.
之前,我没有得到每个 window 的字体 select 的行为
打印显示:
d1: 0x55a5694692a0
d2: 0x55a569477170
s1: 0
s2: 0
对于两者,不同的 Display* 但相同的屏幕索引。那么 window 的字体 select 存储在哪里呢?显示器*?
文档说“字体 selected 到 GC,显示仅指定与 X 服务器的连接”。
OS: Ubuntu 20.04
我打印了每个 gracxt1 和 gracxt2 的 GContext 编号:
#if 1(工作案例)
d1: 0x55b4ae3d82a0
d2: 0x55b4ae3e6170
s1: 0
s2: 0
GCContext 1: 69206016
GCContext 2: 71303168
#if 0(失败案例)
d1: 0x55b4149672a0
d2: 0x55b414975170
s1: 0
s2: 0
GCContext 1: 69206016
GCContext 2: 69206016
为正常运行而重构的程序:
/*
* Study for multiple windows.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Window w1, w2;
GC gracxt1, gracxt2;
XEvent e;
const char* msg1 = "Hello, window 1";
const char* msg2 = "Hello, window 2";
int s;
XFontStruct* font;
Display* d;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
s = DefaultScreen(d);
w1 = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w1, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w1);
gracxt1 = XCreateGC(d, w1, 0, NULL);
w2 = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w2, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w2);
gracxt2 = XCreateGC(d, w2, 0, NULL);
font = XLoadQueryFont(d,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-200-200-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d, gracxt1, font->fid);
font = XLoadQueryFont(d,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-400-400-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d, gracxt2, font->fid);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
if (e.xany.window == w1) XDrawString(d, e.xany.window, gracxt1, 10, 50, msg1, strlen(msg1));
else XDrawString(d, e.xany.window, gracxt2, 10, 50, msg2, strlen(msg2));
}
if (e.type == KeyPress) break; /* exit on any key */
}
XCloseDisplay(d);
return 0;
}
字体是图形上下文的一部分。每个图形上下文都有自己独立的字体设置。
我认为您的 post 扭转了 #if 0
和 #if 1
案例的行为。如果是这样,那么您描述的行为就很有意义了。
XOpenDisplay
creates one graphics context per screen after connecting to the server. 所以 d1
有屏幕 0 的图形上下文,而 d2
有屏幕 0 的单独图形上下文。因此:
在这两种情况下,gracxt1
使用 d1
屏幕 0 的图形上下文。
在#if 0
情况下,gracxt2
使用d2
屏幕0的图形上下文,与分开 gracxt1
。您将每个 GC 的字体设置为不同的值。这是我们在您的第一个屏幕截图中看到的行为:两个 GC 具有不同的字体。
在#if 1
情况下,gracxt2
使用d1
屏幕0的图形上下文,与相同[=48] =] gracxt1
。当你设置gracxt2
的字体时,你也在也设置了gracxt1
的字体,覆盖了之前的设置(因为它们是同一个GC)。这是我们在您的第二个屏幕截图中看到的行为。
给定示例程序:
/*
* Study for multiple windows.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Window w1, w2;
XEvent e;
const char* msg1 = "Hello, window 1";
const char* msg2 = "Hello, window 2";
int s1;
int s2;
GC gracxt1;
GC gracxt2;
XFontStruct* font;
XFontStruct* font2;
Display* d1;
Display* d2;
d1 = XOpenDisplay(NULL);
if (d1 == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
printf("d1: %p\n", d1);
d2 = XOpenDisplay(NULL);
if (d2 == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
printf("d2: %p\n", d2);
s1 = DefaultScreen(d1);
s2 = DefaultScreen(d1);
printf("s1: %d\n", s1);
printf("s2: %d\n", s2);
gracxt1 = XDefaultGC(d1, s1);
#if 0
gracxt2 = XDefaultGC(d2, s2);
#else
gracxt2 = XDefaultGC(d1, s2);
#endif
font = XLoadQueryFont(d1,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-200-200-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d1, gracxt1, font->fid);
font2 = XLoadQueryFont(d1,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-400-400-m-0-iso8859-1");
if (!font2) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d1, gracxt2, font2->fid);
w1 = XCreateSimpleWindow(d1, RootWindow(d1, s1), 10, 10, 640, 480, 5,
BlackPixel(d1, s1), WhitePixel(d1, s1));
XSelectInput(d1, w1, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d1, w1);
w2 = XCreateSimpleWindow(d1, RootWindow(d1, s1), 10, 10, 640, 480, 5,
BlackPixel(d1, s2), WhitePixel(d1, s2));
XSelectInput(d1, w2, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d1, w2);
while (1) {
XNextEvent(d1, &e);
if (e.type == Expose) {
if (e.xany.window == w1) XDrawString(d1, e.xany.window, gracxt1, 10, 50, msg1, strlen(msg1));
else XDrawString(d1, e.xany.window, gracxt2, 10, 50, msg2, strlen(msg2));
}
if (e.type == KeyPress) break; /* exit on any key */
}
XCloseDisplay(d1);
XCloseDisplay(d2);
return 0;
}
设置两个windows和select两种不同的字体,window各一种,然后打印。我对 XWindows 的理解是字体被 selected 到图形上下文中,即 GC。但是,根据使用的 Display*,我会得到两种不同的行为:
#if 1
#if 0
我认为,并且文档强烈暗示,字体是通过 XSetFont() 调用 selected 到上下文 gracxt1 或 gracxt2 的。因此,我从两个 GC 开始这个示例,但一个 Display* 和一个屏幕 select。但是,在我为每个 window 赋予其自己的 Display*.
之前,我没有得到每个 window 的字体 select 的行为打印显示:
d1: 0x55a5694692a0 d2: 0x55a569477170 s1: 0 s2: 0
对于两者,不同的 Display* 但相同的屏幕索引。那么 window 的字体 select 存储在哪里呢?显示器*?
文档说“字体 selected 到 GC,显示仅指定与 X 服务器的连接”。
OS: Ubuntu 20.04
我打印了每个 gracxt1 和 gracxt2 的 GContext 编号:
#if 1(工作案例)
d1: 0x55b4ae3d82a0
d2: 0x55b4ae3e6170
s1: 0
s2: 0
GCContext 1: 69206016
GCContext 2: 71303168
#if 0(失败案例)
d1: 0x55b4149672a0
d2: 0x55b414975170
s1: 0
s2: 0
GCContext 1: 69206016
GCContext 2: 69206016
为正常运行而重构的程序:
/*
* Study for multiple windows.
*/
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
Window w1, w2;
GC gracxt1, gracxt2;
XEvent e;
const char* msg1 = "Hello, window 1";
const char* msg2 = "Hello, window 2";
int s;
XFontStruct* font;
Display* d;
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
s = DefaultScreen(d);
w1 = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w1, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w1);
gracxt1 = XCreateGC(d, w1, 0, NULL);
w2 = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 640, 480, 5,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w2, ExposureMask|KeyPressMask|PointerMotionMask|StructureNotifyMask);
XMapWindow(d, w2);
gracxt2 = XCreateGC(d, w2, 0, NULL);
font = XLoadQueryFont(d,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-200-200-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d, gracxt1, font->fid);
font = XLoadQueryFont(d,
"-bitstream-courier 10 pitch-bold-r-normal--0-0-400-400-m-0-iso8859-1");
if (!font) {
fprintf(stderr, "*** No font ***\n");
exit(1);
}
XSetFont(d, gracxt2, font->fid);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
if (e.xany.window == w1) XDrawString(d, e.xany.window, gracxt1, 10, 50, msg1, strlen(msg1));
else XDrawString(d, e.xany.window, gracxt2, 10, 50, msg2, strlen(msg2));
}
if (e.type == KeyPress) break; /* exit on any key */
}
XCloseDisplay(d);
return 0;
}
字体是图形上下文的一部分。每个图形上下文都有自己独立的字体设置。
我认为您的 post 扭转了 #if 0
和 #if 1
案例的行为。如果是这样,那么您描述的行为就很有意义了。
XOpenDisplay
creates one graphics context per screen after connecting to the server. 所以 d1
有屏幕 0 的图形上下文,而 d2
有屏幕 0 的单独图形上下文。因此:
在这两种情况下,
gracxt1
使用d1
屏幕 0 的图形上下文。在
#if 0
情况下,gracxt2
使用d2
屏幕0的图形上下文,与分开gracxt1
。您将每个 GC 的字体设置为不同的值。这是我们在您的第一个屏幕截图中看到的行为:两个 GC 具有不同的字体。在
#if 1
情况下,gracxt2
使用d1
屏幕0的图形上下文,与相同[=48] =]gracxt1
。当你设置gracxt2
的字体时,你也在也设置了gracxt1
的字体,覆盖了之前的设置(因为它们是同一个GC)。这是我们在您的第二个屏幕截图中看到的行为。