[Xcb-commit] tutorial
XCB site
xcb at freedesktop.org
Mon Nov 12 00:09:25 PST 2007
tutorial/fonts.mdwn | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 292 insertions(+), 1 deletion(-)
New commits:
commit 29653e49bc76b5b9cdcad73c42122062f0c8e60d
Author: brian.thomas.will <brian.thomas.will at gmail.com>
Date: Mon Nov 12 00:09:24 2007 -0800
seriously refactored long example (which was section 11.5 of the original tutorial)
diff --git a/tutorial/fonts.mdwn b/tutorial/fonts.mdwn
index 30d74d2..dd8f7b3 100644
--- a/tutorial/fonts.mdwn
+++ b/tutorial/fonts.mdwn
@@ -1 +1,292 @@
-test
\ No newline at end of file
+# Handling text and fonts
+
+Besides drawing graphics on a window, we often want to draw text. Text strings have two major properties: the characters to be drawn and the font with which they are drawn. In order to draw text, we need to first request the X server to load a font. We then assign a font to a Graphic Context, and finally, we draw the text in a window using the Graphic Context.
+
+### 1. The Font structure
+
+In order to support flexible fonts, a font type is defined, and guess what, it's an Id:
+
+ typedef uint32_t xcb_font_t;
+
+A font id is passed to several functions that handle fonts selection and text drawing. We ask the X server to attribute an Id to our font with the function:
+
+ xcb_font_t xcb_generate_id (xcb_connection_t *c);
+
+
+### 2. Opening a Font
+
+To open a font, we use the following function:
+
+ xcb_void_cookie_t xcb_open_font (xcb_connection_t *c,
+ xcb_font_t fid,
+ uint16_t name_len,
+ const char *name);
+
+The fid parameter is the font Id defined by xcb_generate_id() (see above). The name parameter is the name of the font you want to open. Use the command xlsfonts in a terminal to know which are the fonts available on your computer. The parameter name_len is the length of the name of the font (given by strlen()).
+
+### 3. Assigning a Font to a Graphic Context
+
+Once a font is opened, you have to create a Graphic Context that will contain the informations about the color of the foreground and the background used when you draw a text in a Drawable. Here is an exemple of a Graphic Context that will allow us to draw an opened font with a black foreground and a white background:
+
+ /*
+ * c is the connection
+ * screen is the screen where the window is displayed
+ * window is the window in which we will draw the text
+ * font is the opened font
+ */
+
+ uint32_t value_list[3];
+ xcb_gcontext_t gc;
+ uint32_t mask;
+
+ gc = xcb_generate_id (c);
+ mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
+ value_list[0] = screen->black_pixel;
+ value_list[1] = screen->white_pixel;
+ value_list[2] = font;
+ xcb_create_gc (c, gc, window, mask, value_list);
+
+ /* The font is not needed anymore, so we close it */
+ xcb_close_font (c, font);
+
+### 4. Drawing text in a drawable
+
+To draw a text in a drawable, we use the following function:
+
+ xcb_void_cookie_t xcb_image_text_8 (xcb_connection_t *c,
+ uint8_t string_len,
+ xcb_drawable_t drawable,
+ xcb_gcontext_t gc,
+ int16_t x,
+ int16_t y,
+ const char *string);
+
+The string parameter is the text to draw. The location of the drawing is given by the parameters x and y. The base line of the text is exactly the parameter y.
+
+### 5. Complete example
+
+This example draw a text at 10 pixels (for the base line) of the bottom of a window. Pressing the Esc key exits the program.
+
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+
+ #include <xcb/xcb.h>
+
+ #define WIDTH 300
+ #define HEIGHT 100
+
+
+ static xcb_gc_t getFontGC (xcb_connection_t *c,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ const char *font_name );
+
+
+ static void drawText (xcb_connection_t *c,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ int16_t x1,
+ int16_t y1,
+ const char *label );
+
+
+ static void
+ testCookie (xcb_void_cookie_t cookie,
+ xcb_connection_t *connection,
+ char *errMessage )
+ {
+ xcb_generic_error_t *error = xcb_request_check (connection, cookie);
+ if (error) {
+ fprintf (stderr, "ERROR: %s : %d\n", errMessage , error->error_code);
+ xcb_disconnect (connection);
+ exit (-1);
+ }
+ }
+
+
+
+ /*
+ */
+ static void
+ drawText (xcb_connection_t *connection,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ int16_t x1,
+ int16_t y1,
+ const char *label )
+ {
+ xcb_generic_error_t *error; // used by TEST_SUCCESS();
+
+
+ /* get graphics context */
+
+ xcb_gcontext_t gc = getFontGC (connection, screen, window, "7x13");
+
+
+ /* draw the text */
+
+ xcb_void_cookie_t textCookie = xcb_image_text_8_checked (connection,
+ strlen (label),
+ window,
+ gc,
+ x1, y1,
+ label );
+
+ testCookie(textCookie, connection, "can't paste text");
+
+
+ /* free the gc */
+
+ xcb_void_cookie_t gcCookie = xcb_free_gc (connection, gc);
+
+ testCookie(gcCookie, connection, "can't free gc");
+ }
+
+
+ /*
+ */
+ static xcb_gc_t
+ getFontGC (xcb_connection_t *connection,
+ xcb_screen_t *screen,
+ xcb_window_t window,
+ const char *font_name )
+ {
+ /* get font */
+
+ xcb_font_t font = xcb_generate_id (connection);
+ xcb_void_cookie_t fontCookie = xcb_open_font_checked (connection,
+ font,
+ strlen (font_name),
+ font_name );
+
+ testCookie(fontCookie, connection, "can't open font");
+
+
+ /* create graphics context */
+
+ xcb_gcontext_t gc = xcb_generate_id (connection);
+ uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
+ uint32_t value_list[3] = { screen->black_pixel,
+ screen->white_pixel,
+ font };
+
+ xcb_void_cookie_t gcCookie = xcb_create_gc_checked (connection,
+ gc,
+ window,
+ mask,
+ value_list );
+
+ testCookie(gcCookie, connection, "can't create gc");
+
+
+ /* close font */
+
+ fontCookie = xcb_close_font_checked (connection, font);
+
+ testCookie(fontCookie, connection, "can't close font");
+
+ return gc;
+ }
+
+
+ /*
+ */
+ int
+ main ()
+ {
+ /* get the connection */
+
+ int screenNum;
+ xcb_connection_t *connection = xcb_connect (NULL, &screenNum);
+ if (!connection) {
+ fprintf (stderr, "ERROR: can't connect to an X server\n");
+ return -1;
+ }
+
+
+ /* get the current screen */
+
+
+ xcb_screen_iterator_t iter = xcb_setup_roots_iterator (xcb_get_setup (connection));
+
+ // we want the screen at index screenNum of the iterator
+ for (int i = 0; i < screenNum; ++i) {
+ xcb_screen_next (&iter);
+ }
+
+ xcb_screen_t *screen = iter.data;
+
+ if (!screen) {
+ fprintf (stderr, "ERROR: can't get the current screen\n");
+ xcb_disconnect (connection);
+ return -1;
+ }
+
+
+ /* create the window */
+
+ xcb_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_void_cookie_t windowCookie = xcb_create_window_checked (connection,
+ screen->root_depth,
+ window, screen->root,
+ 20, 200,
+ WIDTH, HEIGHT,
+ 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ screen->root_visual,
+ mask, values);
+
+ testCookie(windowCookie, connection, "can't create window");
+
+ xcb_void_cookie_t mapCookie = xcb_map_window_checked (connection, window);
+
+ testCookie(mapCookie, connection, "can't map window");
+
+ xcb_flush(connection); // make sure window is drawn
+
+
+ /* event loop */
+
+ xcb_generic_event_t *event;
+
+ while (1) { ;
+ if (event = xcb_poll_for_event(connection)) {
+ switch (event->response_type & ~0x80) {
+ case XCB_EXPOSE: {
+ drawText (connection,
+ screen,
+ window,
+ 10, HEIGHT - 10,
+ "Press ESC key to exit..." );
+ break;
+ }
+ case XCB_KEY_RELEASE: {
+ xcb_key_release_event_t *kr;
+
+ kr = (xcb_key_release_event_t *)event;
+
+ switch (kr->detail) {
+ /* ESC */
+ case 9: {
+ free (event);
+ xcb_disconnect (connection);
+ return 0;
+ {
+ }
+ }
+ }
+ free (event);
+ }
+ }
+
+ return 0;
+ }
More information about the xcb-commit
mailing list