当前位置:天才代写 > tutorial > C语言/C++ 教程 > 利用XCB编写X Window措施(四) 在窗口中绘制文字

利用XCB编写X Window措施(四) 在窗口中绘制文字

2017-11-02 08:00 星期四 所属: C语言/C++ 教程 浏览:1052

副标题#e#

在前面的几节中,我展示了利用XCB建设窗口、在窗口中绘图以及捕捉并处理惩罚事件。在这一篇中,我将展示在窗口中绘制文字。绘制文字虽然离不开字体,所以我还会简朴地探讨一下X Server的焦点字体系统。老端正,先上代码和运行结果图,代码如下:

1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <inttypes.h>
5 #include <xcb/xcb.h>
6
7
8 #define WIDTH 600
9 #define HEIGHT 400
10 #define TEST_COOKIE(fn,errMessage) \
11 cookie=fn; \
12 error=xcb_request_check(connection,cookie); \
13 if(error){ \
14 fprintf(stderr, "Error: %s : %"PRIu8"\n", errMessage, error->error_code); \
15 } \
16
17 static void drawText(xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window,
18 int16_t x, int16_t y, const char *font_name, const char *string){
19 /*cookie and error, for TEST_COOKIE */
20 xcb_void_cookie_t cookie;
21 xcb_generic_error_t *error;
22
23 xcb_font_t font = xcb_generate_id(connection);
24 TEST_COOKIE(xcb_open_font_checked(connection, font, strlen(font_name), font_name), "Can't open font");
25 xcb_gcontext_t gc = xcb_generate_id(connection);
26 uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
27 uint32_t values[3] = {screen->black_pixel, screen->white_pixel, font};
28 TEST_COOKIE(xcb_create_gc_checked(connection, gc, window, mask, values), "Can't create GC")
29 /*draw the text*/
30 TEST_COOKIE(xcb_image_text_8_checked(connection, strlen(string), window, gc, x, y, string), "Can't draw text");
31 /*close the font*/
32 xcb_close_font(connection, font);
33 xcb_free_gc(connection, gc);
34 }
35
36 int main()
37 {
38 xcb_connection_t *connection = xcb_connect(NULL, NULL);
39 xcb_screen_t *screen = xcb_setup_roots_iterator( xcb_get_setup(connection)).data;
40
41 /*Create the window*/
42 xcb_window_t window = xcb_generate_id(connection);
43 uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
44 uint32_t values[2];
45 values[0] = screen->white_pixel;
46 values[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS |
47 XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION;
48 xcb_create_window(connection, screen->root_depth,
49 window, screen->root, 20, 200,
50 WIDTH, HEIGHT,
51 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
52 screen->root_visual,
53 mask, values);
54 xcb_map_window(connection, window);
55 xcb_flush(connection);
56
57 /*event loop*/
58 xcb_generic_event_t *event;
59 while((event = xcb_wait_for_event(connection))){
60 switch(event->response_type & ~0x80){
61 case XCB_EXPOSE:
62 {
63 drawText(connection, screen, window, 10, 20,"fixed", "Press ESC key to exit.");
64 drawText(connection, screen, window, 10, 40, "Dejavu Sans Mono", "Press ESC key to exit.");
65 drawText(connection, screen, window, 10, 60, "文泉驿正黑", "按ESC键退出。");
66 break;
67 }
68 case XCB_KEY_RELEASE:
69 {
70 xcb_key_release_event_t *kr = (xcb_key_release_event_t*)event;
71 switch(kr->detail){
72 case 9: /* ESC */
73 {
74 free(event);
75 xcb_disconnect(connection);
76 return 0;
77 }
78 }
79 }
80 }
81 free(event);
82 }
83 return 0;
84 }


#p#副标题#e#

运行结果如下图:

操作XCB编写X Window法子(四) 在窗口中绘制文字

我认可,这段代码写得有点乱,不外说明怎么在窗口中绘制文字已经足够了。在窗口中绘制文字只需要用到如下函数:

1、利用xcb_generate_id()生成一个ID,用来暗示一个字体;

2、利用xcb_open_font()可能xcb_open_font_checked()函数打开一个字体;

3、利用前面打开的字体建设一个gc;建设gc前面已经讲过了,只需要挪用xcb_generate_id()和xcb_create_gc()可能xcb_create_gc_checked()函数即可,不外在这里,要留意建设gc时的mask和values值,mask需要XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT,别离代表前景致、配景致和字体,在values中配置相应的值;

4、利用xcb_image_text_8()可能xcb_image_text_8_checked()函数在窗口上绘制文字。

#p#副标题#e#

#p#分页标题#e#

此刻再回过甚来看代码,是不是以为豁然开朗?就这么几个API罢了。并且可以看出,在XCB中,每一个有大概堕落的函数都有别的一个加上了_checked的版本,带_checked的版本会返回一个cookie,通过xcb_request_check()函数可以查抄该cookie,从而判定该函数挪用是否乐成。利用C语言的API就是这一点很贫苦,常常要去查抄函数挪用是否乐成,所以利用C语言写措施常常会写成这样:

int error;
error = some_function(...);
if(error){
    printf("...some message...");
    ...
}
error = another_function(...);
if(error){
    printf("....another message...");
    ...
}

这实在是太疾苦了。亏得C语言中尚有宏这么一个对象,所以我就在措施的开头界说了一个宏TEST_COOKIE,专门用来干这个事。宏界说得欠好,尚有改造的余地,不外已经让我的代码写起来和读起来都舒服了不少。

在措施中,我利用了三个drawText,要求措施别离用fixed字体、Dejavu San Mono字体和文泉驿正黑字体绘制三行文字,可是最终的功效只有fixed那一行乐成绘制,剩下的两行都在节制台显示有错误信息,都暗示字体打不开、gc建设不了、所以文字虽然绘制不了。之所以呈现这种环境,就是因为这里选择的字体只能是X Server焦点字体系统里安装的字体。我在《Linux江湖05:Linux桌面系统字体设置要略(下)》内里写过,Xorg中有两种字体系统,一种是X Server焦点字体系统,另一种是Xft。固然X Server焦点字体系统颠末多年的成长,成果已经很完善了,能较量完美地支持TrueType字体,可是Xorg官方重复发起各人不要利用焦点字体系统,而是推荐各人利用Xft。大概是因为X Server焦点字体系统对字体的安装和打点都较量贫苦吧。利用xlsfonts呼吁可以列出X Server中安装有哪些字体,如下图:

操作XCB编写X Window法子(四) 在窗口中绘制文字

#p#副标题#e#

可以看到每一个字体的信息都又臭又长,只有最后三行短一点,所以我才在措施中选择了最短的fixed字体作为示例。并且X Server焦点字体系统安装字体时需要利用mkfontdir、mkfontscale等极其贫苦的呼吁。

最后有一点想不通的是,为什么xcb_image_text_8()函数后头有一个8呢?是不是尚有xcb_image_text_16()和xcb_image_text_32()这样的函数呢?不要紧,利用Ctrl+]跳到XCB的头文件内里看一下。如下图:

操作XCB编写X Window法子(四) 在窗口中绘制文字

内里的注释照旧很具体的。出格是下图的最后一句:

操作XCB编写X Window法子(四) 在窗口中绘制文字

最后一句再次强调X core fonts是过期的、不发起利用的,再次推荐各人利用Xft。我在写这一系列XCB文章的时候就说过,利用XCB只是为了进修,进修X协议的底层常识,进修GUI系统的构建道理等。真正写应用措施的时候,是没有谁利用XCB这么底层的库的。而高条理的库中需要绘制文字时,预计早就都是Xft一统天下了,所以并不需要我们费太多的心。

作者:cnblogs 京山游侠

 

    关键字:

天才代写-代写联系方式