]> git.sur5r.net Git - i3/i3/commitdiff
Cleanup load_font(), make it caching
authorMichael Stapelberg <michael+git@stapelberg.de>
Sun, 15 Feb 2009 01:40:03 +0000 (02:40 +0100)
committerMichael Stapelberg <michael+git@stapelberg.de>
Sun, 15 Feb 2009 01:40:03 +0000 (02:40 +0100)
include/data.h
src/font.c

index 6171f8b20ce2449483388468bca689de621b5ec2..b4dcd178f66f6a371c95b8871cef7bd8ed0da897 100644 (file)
@@ -106,6 +106,8 @@ struct Font {
         int height;
         /* The xcb-id for the font */
         xcb_font_t id;
+
+        TAILQ_ENTRY(Font) fonts;
 };
 
 /*
index 6ab7110b0e0e15d97e4320d324cf44dfc081a040..ec65eda7269baf8cfd1eef78a618244841aec21c 100644 (file)
 #include "data.h"
 #include "util.h"
 
+TAILQ_HEAD(cached_fonts_head, Font) cached_fonts = TAILQ_HEAD_INITIALIZER(cached_fonts);
+
+/*
+ * Loads a font for usage, getting its height. This function is used very often, so it
+ * maintains a cache.
+ *
+ */
 i3Font *load_font(xcb_connection_t *c, const char *pattern) {
-        /* TODO: this function should be caching */
+        /* 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 = malloc(sizeof(i3Font));
 
+        /* Send all our requests first */
+        new->id = xcb_generate_id(c);
+        xcb_void_cookie_t font_cookie = xcb_open_font_checked(c, new->id, strlen(pattern), pattern);
         xcb_list_fonts_with_info_cookie_t cookie = xcb_list_fonts_with_info(c, 1, strlen(pattern), pattern);
+
+        check_error(c, font_cookie, "Could not open font");
+
+        /* Get information (height/name) for this font */
         xcb_list_fonts_with_info_reply_t *reply = xcb_list_fonts_with_info_reply(c, cookie, NULL);
-        if (!reply) {
+        if (reply == NULL) {
                 printf("Could not load font\n");
                 exit(1);
         }
 
-        /* Oh my, this is so ugly :-(. Why can’t they just return a null-terminated
-         * string? That’s what abstraction layers are for. */
-        char buffer[xcb_list_fonts_with_info_name_length(reply)+1];
-        memset(buffer, 0, sizeof(buffer));
-        memcpy(buffer, xcb_list_fonts_with_info_name(reply), sizeof(buffer)-1);
-        new->name = strdup(buffer);
+        asprintf(&(new->name), "%.*s", xcb_list_fonts_with_info_name_length(reply),
+                        xcb_list_fonts_with_info_name(reply));
         new->pattern = strdup(pattern);
         new->height = reply->font_ascent + reply->font_descent;
 
-        /* Actually load the font */
-        new->id = xcb_generate_id(c);
-        xcb_void_cookie_t font_cookie = xcb_open_font_checked(c, new->id, strlen(pattern), pattern);
-        check_error(c, font_cookie, "Could not open font");
+        /* Insert into cache */
+        TAILQ_INSERT_TAIL(&cached_fonts, new, fonts);
 
         return new;
 }