11 Handling Text And Fonts

除了在窗口上绘制图形外,我们经常想要绘制文本。文本字符串有两个主要属性 - 要绘制的字符和用于绘制的字体。为了绘制文本,我们首先需要请求X服务器加载字体。然后我们将字体分配给GC,最后我们使用GC在窗口中绘制文本。

11.1 The Font Structure

为了支持灵活的字体,定义了一种类型为XFontStruct的字体结构。此结构用于包含关于字体的信息,并传递给处理字体选择和文本绘制的多个函数。

11.2 Loading A Font

作为绘制文本的第一步,我们使用字体装载函数,例如XLoadQueryFont()。该函数要求X服务器装载给定名字的字体。如果字体被发现了,服务器装载那个字体,返回一个XFontStruct结构的指针。如果字体没有被发现,或者是装载失败了,返回一个值NULL。每个字体也许会有两个名字。一个是长字符串,指明了字体的全部属性(字体族,字体尺寸,斜体/黑体/是否有下划线等等)。另一个是短的别名,为各自的服务器所配置。作为一个例子,我们尝试装载”-helvetica--12-*“字体:

/* this pointer will hold the returned font structure. */
XFontStruct* font_info;
 
/* try to load the given font. */
char* font_name = "*-helvetica-*-12-*";
font_info = XLoadQueryFont(display, fond_name);
if (!font_info) {
    fprintf(stderr, "XLoadQueryFont: failed loading font '%s'/n", font_name);
}

linux输入 xlsfonts 查询x11可用的字体

xlsfonts

11.3 Assigning A Font To A Graphics Context

在我们装载了字体后,我们需要把它分配给一个GC。假设一个叫”gc”的GC已经存在了,下面是我们如何做:

XSetFont(display, gc, font_info->fid);

“fid”领域是一个XFontStruct结构用来为各种请求识别各种装载的字体。

11.4 Drawing Text In A Window

我们一旦为我们的GC装载了字体,我们就可以使用例如函数XDrawString(),在我们的窗口里绘制文本。该函数可以在窗口里的一个给定位置里绘制文本。给定的位置将是从被绘制的文本的左下算起,下面是它的例子:

/* assume that win_width contains the width of our window, win_height        */
/* contains the height of our window, and 'win' is the handle of our window. */
 
/* some temporary variables used for the drawing. */
int x, y;
 
/* draw a "hello world" string on the top-left side of our window. */
x = 0;
y = 0;
XDrawString(display, win, gc, x, y, "hello world", strlen("hello world"));
 
/* draw a "middle of the road" string in the middle of our window. */
char* text_string = "middle of the road";
/* find the width, in pixels, of the text that will be drawn using */
/* the given font.                                                 */
int string_width = XTextWidth(font_info, text_string, strlen(text_string));
/* find the height of the characters drawn using this font.        */
int fond_height = font_info->ascent + font_info->descent;
x = (win_width - string_width) / 2;
y = (win_width - font_height) / 2;
XDrawString(display, win, gc, x, y, "hello world", strlen("hello world"));

以下的说明应该可以使程序更清楚:

  • 函数XTextWidth()被用来预测字符串的长度,当它使用指定字体进行绘制时。它被用来检查那里是开始那里是结束使它看起来占据着窗口的中央

  • 一个字体的两个名字为”ascent”和”descent”的属性用来指定字体的高。基本上,一个字体的字符是画在一条假象的横线上的。一些字符被画在横线上面,一些画在下面。最高的字符是被画在”font_info->ascent”线上的,最低的部分则在”font_info->descent”线下面。因此,这两个值得和指明了字体的高度。

上面的源程序可以参考文件 04_text_and_fonts.c

参考

https://osiris.df.unipi.it/~moruzzi/xlib-programming.html#text