In the previous sections, I demonstrated the creation of Windows using XCB, drawing in Windows, and capturing and handling events. In this article, I'll show you how to draw text in a window. Drawing text is of course inseparable from fonts, so I'll simply explore the core font system of X server. The usual, first on the code and run, the code is as follows:
1#include <stdlib.h>2#include <stdio.h>3#include <string.h>4#include <inttypes.h>5#include <xcb/xcb.h>6 7 8 #defineWIDTH 6009 #defineHEIGHT 400Ten #defineTest_cookie (Fn,errmessage) OneCookie=fn; AError=Xcb_request_check (Connection,cookie); - if(Error) { -fprintf (stderr,"Error:%s:%"PRIu8"\ n", Errmessage, error->Error_code); the } - - Static voidDrawText (xcb_connection_t *connection, xcb_screen_t *Screen , xcb_window_t window, -int16_t x, int16_t y,Const Char*font_name,Const Char*string){ + /*Cookie and error, for Test_cookie*/ - xcb_void_cookie_t cookies; +xcb_generic_error_t *error; A atxcb_font_t Font =xcb_generate_id (connection); -Test_cookie (xcb_open_font_checked (connection, Font, strlen (font_name), Font_name),"Can ' t open font"); -xcb_gcontext_t GC =xcb_generate_id (connection); -uint32_t mask = Xcb_gc_foreground | Xcb_gc_background |Xcb_gc_font; -uint32_t values[3] = {Screen->black_pixel, screen->white_pixel, font}; -Test_cookie (xcb_create_gc_checked (Connection, GC, window, mask, values),"Can ' t create GC") in /*Draw the text*/ -Test_cookie (xcb_image_text_8_checked (Connection, strlen (string), window, GC, X, Y,string),"Can ' t draw text"); to /*Close the font*/ + Xcb_close_font (connection, font); - XCB_FREE_GC (Connection, GC); the } * $ intMain ()Panax Notoginseng { -xcb_connection_t *connection =xcb_connect (null, NULL); thexcb_screen_t *screen =Xcb_setup_roots_iterator (Xcb_get_setup (connection)). Data; + A /*Create the window*/ thexcb_window_t window =xcb_generate_id (connection); +uint32_t mask = Xcb_cw_back_pixel |Xcb_cw_event_mask; -uint32_t values[2]; $values[0] = screen->White_pixel; $values[1] = Xcb_event_mask_key_release | xcb_event_mask_button_press | -Xcb_event_mask_exposure |xcb_event_mask_pointer_motion; -Xcb_create_window (Connection, screen->Root_depth, thewindow, Screen->root, -, $, - WIDTH, HEIGHT,Wuyi 0, Xcb_window_class_input_output, theScreen->Root_visual, - mask, values); Wu Xcb_map_window (Connection, window); - Xcb_flush (connection); About $ /*Event Loop*/ -xcb_generic_event_t *Event; - while((Event=xcb_wait_for_event (connection))) { - Switch(Event->response_type & ~0x80){ A CaseXcb_expose: + { theDrawText (Connection, screen, window,Ten, -,"fixed","Press ESC key to exit."); -DrawText (Connection, screen, window,Ten, +,"Dejavu Sans Mono","Press ESC key to exit."); $DrawText (Connection, screen, window,Ten, -,"Wenquanyi Zen Hei is black","Press the ESC key to exit. "); the Break; the } the Casexcb_key_release: the { -xcb_key_release_event_t *kr = (xcb_key_release_event_t*)Event; in Switch(kr->detail) { the Case 9:/*ESC*/ the { AboutFreeEvent); the Xcb_disconnect (connection); the return 0; the } + } - } the }BayiFreeEvent); the } the return 0; -}
Operating effects such as:
I admit, this code is a bit confusing, but it's enough to show how the text is drawn in the window. You only need to use the following function to draw the text in the window:
1. Use xcb_generate_id () to generate an ID to represent a font;
2. Use Xcb_open_font () or xcb_open_font_checked () function to open a font;
3. Create a GC with the previously opened font, and create a GC before, just call the xcb_generate_id () and xcb_create_gc () or xcb_create_gc_checked () functions, but here, Be aware of the mask and values when creating a GC, Mask requires Xcb_gc_foreground | Xcb_gc_background | Xcb_gc_font, which represent the foreground color, background color and font, and set the corresponding value in values;
4. Use the Xcb_image_text_8 () or xcb_image_text_8_checked () function to draw text on the window.
Now look back to the code, do you feel enlightened? Just a few APIs. And it can be seen that in the XCB, every possible error function has another _checked version, with _checked version will return a cookie, through the Xcb_request_check () function can check the cookie, This determines whether the function call succeeds. Using the C language API is a hassle, often to check the success of a function call, so the use of C language writing program is often written like this:
int= some_function (...); if (Error) { printf ("... some message ... " ); = another_function (...); if (Error) { printf ("..... another message ... " ); ...}
This is really too painful. Fortunately, there is a macro in the C language, so I defined a macro Test_cookie at the beginning of the program, specifically to do it. The macro is not well defined and there is room for improvement, but it has made my code much more comfortable to write and read.
In the program, I used three DrawText, requiring the program to draw three lines of text in fixed font, Dejavu San mono font, and Wenquanyi Zen Hei positive black font, but the final result is only the fixed row is successfully drawn, the remaining two lines are displayed in the console error message, All indicate that the font cannot be opened, the GC cannot be created, so the text is certainly not drawn. This occurs because the font chosen here is the only font installed in the X Server Core font system. I wrote in the "Linux Lakes and 05:linux Desktop system font Configuration" (below), in xorg there are two font systems, one is the x Server Core font system, the other is xft. Although the X Server Core font system has evolved over the years, features are well-established and can be perfectly supported for TrueType fonts, however, xorg officials repeatedly recommend that you do not use the core font system, but rather recommend that you use XFT. It may be that the X Server Core font system is more difficult to install and manage fonts. Use the xlsfonts command to list which fonts are installed in X server, such as:
Can see the information of each font is smelly and long, only the last three lines shorter, so I chose the shortest fixed font in the program as an example. Also, the X Server Core font system installs fonts with extremely cumbersome commands such as Mkfontdir, Mkfontscale, and so on.
One last thing that makes sense is, why is there a 8 behind the xcb_image_text_8 () function? Is there a function such as xcb_image_text_16 () and xcb_image_text_32 ()? No problem, use CTRL +] to jump to XCB's header file and look inside. Such as:
The notes inside are still very detailed. In particular, the last sentence:
The last sentence again emphasizes that X core fonts is outdated and deprecated, and it is recommended that you use xft again. As I wrote this series of XCB articles, I said that using XCB is only for learning, learning the underlying knowledge of the X protocol, and learning the construction principles of the GUI system. When it comes to writing applications, there is no one who uses xcb such a bottom-level library. and high-level libraries need to draw text, it is estimated that long ago is xft eminence, so do not need us to pay too much of the heart.
(Jingshan Ranger in 2014-07-15 published in the blog Park, reproduced please indicate the source. )