From: Michael Stapelberg Date: Thu, 10 Mar 2011 22:20:17 +0000 (+0100) Subject: refactor font caching to just save the ID instead of mainting a cache with pattern... X-Git-Tag: tree-pr3~139 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=f162e7efaa4817c327d84c79854a5c3102a60105;p=i3%2Fi3 refactor font caching to just save the ID instead of mainting a cache with pattern→id-mapping --- diff --git a/include/config.h b/include/config.h index 986f7aa2..32212e3d 100644 --- a/include/config.h +++ b/include/config.h @@ -86,7 +86,7 @@ struct Mode { */ struct Config { const char *terminal; - const char *font; + i3Font font; const char *ipc_socket_path; const char *restart_state_path; diff --git a/include/data.h b/include/data.h index 71347364..e10b8680 100644 --- a/include/data.h +++ b/include/data.h @@ -173,10 +173,6 @@ struct Autostart { * */ struct Font { - /** The name of the font, that is what the pattern resolves to */ - char *name; - /** A copy of the pattern to build a cache */ - char *pattern; /** The height of the font, built from font_ascent + font_descent */ int height; /** The xcb-id for the font */ diff --git a/include/xcb.h b/include/xcb.h index 1dc141e6..2d3f9cc1 100644 --- a/include/xcb.h +++ b/include/xcb.h @@ -71,11 +71,12 @@ enum { _NET_SUPPORTED = 0, extern unsigned int xcb_numlock_mask; /** - * Loads a font for usage, getting its height. This function is used very - * often, so it maintains a cache. + * Loads a font for usage, also getting its height. If fallback is true, + * i3 loads 'fixed' or '-misc-*' if the font cannot be found instead of + * exiting. * */ -i3Font *load_font(xcb_connection_t *conn, const char *pattern); +i3Font load_font(const char *pattern, bool fallback); /** * Returns the colorpixel to use for the given hex color (think of HTML). @@ -162,8 +163,7 @@ void cached_pixmap_prepare(xcb_connection_t *conn, struct Cached_Pixmap *pixmap) * real length (amount of glyphs) using the given font. * */ -int predict_text_width(xcb_connection_t *conn, const char *font_pattern, char *text, - int length); +int predict_text_width(char *text, int length); /** * Configures the given window to have the size/position specified by given rect diff --git a/src/cfgparse.y b/src/cfgparse.y index adb02122..5ee6dfd4 100644 --- a/src/cfgparse.y +++ b/src/cfgparse.y @@ -597,8 +597,8 @@ terminal: font: TOKFONT WHITESPACE STR { - config.font = $3; - printf("font %s\n", config.font); + config.font = load_font($3, true); + printf("font %s\n", $3); } ; diff --git a/src/config.c b/src/config.c index 8a394c1f..e7f4617b 100644 --- a/src/config.c +++ b/src/config.c @@ -332,7 +332,10 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath, grab_all_keys(conn, false); } - REQUIRED_OPTION(font); + if (config.font.id == 0) { + ELOG("You did not specify required configuration option \"font\"\n"); + config.font = load_font("fixed", true); + } #if 0 /* Set an empty name for every workspace which got no name */ diff --git a/src/floating.c b/src/floating.c index 6aea7a91..fe878f75 100644 --- a/src/floating.c +++ b/src/floating.c @@ -94,8 +94,7 @@ void floating_enable(Con *con, bool automatic) { free(name); /* find the height for the decorations */ - i3Font *font = load_font(conn, config.font); - int deco_height = font->height + 5; + int deco_height = config.font.height + 5; DLOG("Original rect: (%d, %d) with %d x %d\n", con->rect.x, con->rect.y, con->rect.width, con->rect.height); Rect zero = { 0, 0, 0, 0 }; diff --git a/src/handlers.c b/src/handlers.c index e8506843..9c584b8b 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -336,8 +336,7 @@ int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure DLOG("Configure request!\n"); if (con_is_floating(con) && con_is_leaf(con)) { /* find the height for the decorations */ - i3Font *font = load_font(conn, config.font); - int deco_height = font->height + 5; + int deco_height = config.font.height + 5; /* we actually need to apply the size/position changes to the *parent* * container */ Rect bsr = con_border_style_rect(con); diff --git a/src/render.c b/src/render.c index 37ee6e47..5bdc2e21 100644 --- a/src/render.c +++ b/src/render.c @@ -194,8 +194,7 @@ void render_con(Con *con, bool render_fullscreen) { } /* find the height for the decorations */ - i3Font *font = load_font(conn, config.font); - int deco_height = font->height + 5; + int deco_height = config.font.height + 5; /* precalculate the sizes to be able to correct rounding errors */ int sizes[children]; diff --git a/src/sighandler.c b/src/sighandler.c index 4b5fb103..d6128b5b 100644 --- a/src/sighandler.c +++ b/src/sighandler.c @@ -165,16 +165,14 @@ void handle_signal(int sig, siginfo_t *info, void *data) { xcb_event_handlers_init(conn, &sig_evenths); xcb_event_set_key_press_handler(&sig_evenths, sig_handle_key_press, NULL); - i3Font *font = load_font(conn, config.font); - /* width and height of the popup window, so that the text fits in */ int crash_text_num = sizeof(crash_text) / sizeof(char*); - int height = 13 + (crash_text_num * font->height); + int height = 13 + (crash_text_num * config.font.height); /* calculate width for longest text */ int text_len = strlen(crash_text[crash_text_longest]); char *longest_text = convert_utf8_to_ucs2(crash_text[crash_text_longest], &text_len); - int font_width = predict_text_width(conn, config.font, longest_text, text_len); + int font_width = predict_text_width(longest_text, text_len); int width = font_width + 20; /* Open a popup window on each virtual screen */ @@ -192,7 +190,7 @@ void handle_signal(int sig, siginfo_t *info, void *data) { xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0); /* Create graphics context */ - xcb_change_gc_single(conn, pixmap_gc, XCB_GC_FONT, font->id); + xcb_change_gc_single(conn, pixmap_gc, XCB_GC_FONT, config.font.id); /* Grab the keyboard to get all input */ xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); @@ -201,7 +199,7 @@ void handle_signal(int sig, siginfo_t *info, void *data) { xcb_grab_pointer(conn, false, win, XCB_NONE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, win, XCB_NONE, XCB_CURRENT_TIME); - sig_draw_window(win, width, height, font->height); + sig_draw_window(win, width, height, config.font.height); xcb_flush(conn); } diff --git a/src/x.c b/src/x.c index d4b95315..c055f649 100644 --- a/src/x.c +++ b/src/x.c @@ -311,11 +311,10 @@ void x_draw_decoration(Con *con) { con->deco_rect.y + con->deco_rect.height - 1); /* to_y */ /* 5: draw the title */ - i3Font *font = load_font(conn, config.font); uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; - uint32_t values[] = { color->text, color->background, font->id }; + uint32_t values[] = { color->text, color->background, config.font.id }; xcb_change_gc(conn, parent->gc, mask, values); - int text_offset_y = font->height + (con->deco_rect.height - font->height) / 2 - 1; + int text_offset_y = config.font.height + (con->deco_rect.height - config.font.height) / 2 - 1; struct Window *win = con->window; if (win == NULL || win->name_x == NULL) { diff --git a/src/xcb.c b/src/xcb.c index 9ec0df9c..aaad590d 100644 --- a/src/xcb.c +++ b/src/xcb.c @@ -17,24 +17,19 @@ TAILQ_HEAD(cached_fonts_head, Font) cached_fonts = TAILQ_HEAD_INITIALIZER(cached unsigned int xcb_numlock_mask; /* - * Loads a font for usage, getting its height. This function is used very often, so it - * maintains a cache. + * Loads a font for usage, also getting its height. If fallback is true, + * i3 loads 'fixed' or '-misc-*' if the font cannot be found instead of + * exiting. * */ -i3Font *load_font(xcb_connection_t *conn, const char *pattern) { - /* Check if we got the font cached */ - i3Font *font; - TAILQ_FOREACH(font, &cached_fonts, fonts) - if (strcmp(font->pattern, pattern) == 0) - return font; - - i3Font *new = smalloc(sizeof(i3Font)); +i3Font load_font(const char *pattern, bool fallback) { + i3Font new; xcb_void_cookie_t font_cookie; xcb_list_fonts_with_info_cookie_t info_cookie; /* Send all our requests first */ - new->id = xcb_generate_id(conn); - font_cookie = xcb_open_font_checked(conn, new->id, strlen(pattern), pattern); + new.id = xcb_generate_id(conn); + font_cookie = xcb_open_font_checked(conn, new.id, strlen(pattern), pattern); info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); /* Check for errors. If errors, fall back to default font. */ @@ -44,7 +39,7 @@ i3Font *load_font(xcb_connection_t *conn, const char *pattern) { if (error != NULL) { ELOG("Could not open font %s (X error %d). Reverting to backup font.\n", pattern, error->error_code); pattern = "fixed"; - font_cookie = xcb_open_font_checked(conn, new->id, strlen(pattern), pattern); + font_cookie = xcb_open_font_checked(conn, new.id, strlen(pattern), pattern); info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); /* Check if we managed to open 'fixed' */ @@ -54,7 +49,7 @@ i3Font *load_font(xcb_connection_t *conn, const char *pattern) { if (error != NULL) { ELOG("Could not open fallback font '%s', trying with '-misc-*'\n",pattern); pattern = "-misc-*"; - font_cookie = xcb_open_font_checked(conn, new->id, strlen(pattern), pattern); + font_cookie = xcb_open_font_checked(conn, new.id, strlen(pattern), pattern); info_cookie = xcb_list_fonts_with_info(conn, 1, strlen(pattern), pattern); check_error(conn, font_cookie, "Could open neither requested font nor fallback (fixed or -misc-*"); @@ -65,14 +60,7 @@ i3Font *load_font(xcb_connection_t *conn, const char *pattern) { xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(conn, info_cookie, NULL); exit_if_null(reply, "Could not load font \"%s\"\n", pattern); - if (asprintf(&(new->name), "%.*s", xcb_list_fonts_with_info_name_length(reply), - xcb_list_fonts_with_info_name(reply)) == -1) - die("asprintf() failed\n"); - new->pattern = sstrdup(pattern); - new->height = reply->font_ascent + reply->font_descent; - - /* Insert into cache */ - TAILQ_INSERT_TAIL(&cached_fonts, new, fonts); + new.height = reply->font_ascent + reply->font_descent; return new; } @@ -127,9 +115,9 @@ xcb_window_t create_window(xcb_connection_t *conn, Rect dims, uint16_t window_cl values[0] = xcursor_get_cursor(cursor); xcb_change_window_attributes(conn, result, mask, values); } else { - i3Font *cursor_font = load_font(conn, "cursor"); + i3Font cursor_font = load_font("cursor", false); int xcb_cursor = xcursor_get_xcb_cursor(cursor); - xcb_create_glyph_cursor(conn, cursor_id, cursor_font->id, cursor_font->id, + xcb_create_glyph_cursor(conn, cursor_id, cursor_font.id, cursor_font.id, xcb_cursor, xcb_cursor + 1, 0, 0, 0, 65535, 65535, 65535); xcb_change_window_attributes(conn, result, XCB_CW_CURSOR, &cursor_id); xcb_free_cursor(conn, cursor_id); @@ -318,15 +306,13 @@ void cached_pixmap_prepare(xcb_connection_t *conn, struct Cached_Pixmap *pixmap) * length (amount of glyphs) using the given font. * */ -int predict_text_width(xcb_connection_t *conn, const char *font_pattern, char *text, int length) { - i3Font *font = load_font(conn, font_pattern); - +int predict_text_width(char *text, int length) { xcb_query_text_extents_cookie_t cookie; xcb_query_text_extents_reply_t *reply; xcb_generic_error_t *error; int width; - cookie = xcb_query_text_extents(conn, font->id, length, (xcb_char2b_t*)text); + cookie = xcb_query_text_extents(conn, config.font.id, length, (xcb_char2b_t*)text); if ((reply = xcb_query_text_extents_reply(conn, cookie, &error)) == NULL) { ELOG("Could not get text extents (X error code %d)\n", error->error_code);