font: load font glyphs into memory
authorAli Gholami Rudi <ali@rudi.ir>
Fri, 4 May 2012 05:46:00 +0000 (4 10:16 +0430)
committerAli Gholami Rudi <ali@rudi.ir>
Fri, 4 May 2012 05:46:00 +0000 (4 10:16 +0430)
Loading glyphs from disk can result in noticeable delays in fbpad,
specially when the disk is busy.  What's more, modifying loaded font
files when fbpad is running may result in strange characters in fbpad.
On the other hand, fonts files are relatively small compared to the size
of framebuffers and very little memory can be saved by not loading them.

This patch changes fbpad to load the whole font file into the memory
to solve the mentioned problems.

font.c

diff --git a/font.c b/font.c
index 6164134..6a0aa00 100644 (file)
--- a/font.c
+++ b/font.c
@@ -8,11 +8,11 @@
 #include "util.h"
 
 struct font {
-       int fd;
        int rows;
        int cols;
        int n;
        int *glyphs;
+       char *data;
 };
 
 /*
@@ -34,23 +34,35 @@ struct tinyfont {
        int rows, cols;
 };
 
+static void *xread(int fd, int len)
+{
+       void *buf = malloc(len);
+       if (buf && read(fd, buf, len) == len)
+               return buf;
+       free(buf);
+       return NULL;
+}
+
 struct font *font_open(char *path)
 {
        struct font *font;
        struct tinyfont head;
-       font = malloc(sizeof(*font));
-       font->fd = open(path, O_RDONLY);
-       if (font->fd == -1)
-               return NULL;
-       fcntl(font->fd, F_SETFD, fcntl(font->fd, F_GETFD) | FD_CLOEXEC);
-       if (read(font->fd, &head, sizeof(head)) != sizeof(head))
+       int fd = open(path, O_RDONLY);
+       if (fd < 0 || read(fd, &head, sizeof(head)) != sizeof(head)) {
+               close(fd);
                return NULL;
+       }
+       font = malloc(sizeof(*font));
        font->n = head.n;
        font->rows = head.rows;
        font->cols = head.cols;
-       font->glyphs = malloc(font->n * sizeof(int));
-       if (read(font->fd, font->glyphs, font->n * sizeof(int)) != font->n * sizeof(int))
+       font->glyphs = xread(fd, font->n * sizeof(int));
+       font->data = xread(fd, font->n * font->rows * font->cols);
+       close(fd);
+       if (!font->glyphs || !font->data) {
+               font_free(font);
                return NULL;
+       }
        return font;
 }
 
@@ -73,18 +85,19 @@ static int find_glyph(struct font *font, int c)
 int font_bitmap(struct font *font, void *dst, int c)
 {
        int i = find_glyph(font, c);
+       int len = font->rows * font->cols;
        if (i < 0)
                return 1;
-       lseek(font->fd, sizeof(struct tinyfont) + font->n * sizeof(int) +
-                                       i * font->rows * font->cols, 0);
-       read(font->fd, dst, font->rows * font->cols);
+       memcpy(dst, font->data + i * len, len);
        return 0;
 }
 
 void font_free(struct font *font)
 {
-       free(font->glyphs);
-       close(font->fd);
+       if (font->data)
+               free(font->data);
+       if (font->glyphs)
+               free(font->glyphs);
        free(font);
 }