diff --git a/firmware/export/font.h b/firmware/export/font.h index 36c6e0a291..02476c17ff 100644 --- a/firmware/export/font.h +++ b/firmware/export/font.h @@ -100,6 +100,8 @@ struct font { /* file, buffer and cache management */ int fd; /* fd for the font file. >= 0 if cached */ + int fd_width; /* fd for the font file. >= 0 if cached */ + int fd_offset; /* fd for the font file. >= 0 if cached */ unsigned char *buffer_start; /* buffer to store the font in */ unsigned char *buffer_position; /* position in the buffer */ unsigned char *buffer_end; /* end of the buffer */ diff --git a/firmware/font.c b/firmware/font.c index 8b70a7dcb9..943f2e2d06 100644 --- a/firmware/font.c +++ b/firmware/font.c @@ -394,7 +394,22 @@ static bool internal_load_font(int font_id, const char *path, char *buf, return false; } + /* Cheat to get sector cache for different parts of font * + * file while preloading glyphs. Without this the disk head * + * thrashes between the width, offset, and bitmap data * + * in glyph_cache_load(). */ + pf->fd_width = open(path, O_RDONLY|O_BINARY); + pf->fd_offset = open(path, O_RDONLY|O_BINARY); + glyph_cache_load(font_id); + + if(pf->fd_width >= 0) + close(pf->fd_width); + pf->fd_width = -1; + + if(pf->fd_offset >= 0) + close(pf->fd_offset); + pf->fd_offset = -1; } else { @@ -402,6 +417,8 @@ static bool internal_load_font(int font_id, const char *path, char *buf, pf->buffer_end = pf->buffer_position + size; close(pf->fd); pf->fd = -1; + pf->fd_width = -1; + pf->fd_offset = -1; if (!font_load_header(pf)) { @@ -451,6 +468,8 @@ static int alloc_and_init(int font_idx, const char* name, size_t size) pdata->refcount = 1; pf->buffer_position = pf->buffer_start = buffer_from_handle(handle); pf->buffer_size = size; + pf->fd_width = -1; + pf->fd_offset = -1; return handle; } @@ -639,14 +658,20 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data) int handle = pf_to_handle(pf); unsigned short char_code = p->_char_code; unsigned char tmp[2]; + int fd; if (handle > 0) lock_font_handle(handle, true); if (pf->file_width_offset) { int width_offset = pf->file_width_offset + char_code; - lseek(pf->fd, width_offset, SEEK_SET); - read(pf->fd, &(p->width), 1); + /* load via different fd to get this file section cached */ + if(pf->fd_width >=0 ) + fd = pf->fd_width; + else + fd = pf->fd; + lseek(fd, width_offset, SEEK_SET); + read(fd, &(p->width), 1); } else { @@ -658,11 +683,16 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data) if (pf->file_offset_offset) { int32_t offset = pf->file_offset_offset + char_code * (pf->long_offset ? sizeof(int32_t) : sizeof(int16_t)); - lseek(pf->fd, offset, SEEK_SET); - read (pf->fd, tmp, 2); + /* load via different fd to get this file section cached */ + if(pf->fd_offset >=0 ) + fd = pf->fd_offset; + else + fd = pf->fd; + lseek(fd, offset, SEEK_SET); + read (fd, tmp, 2); bitmap_offset = tmp[0] | (tmp[1] << 8); if (pf->long_offset) { - read (pf->fd, tmp, 2); + read (fd, tmp, 2); bitmap_offset |= (tmp[0] << 16) | (tmp[1] << 24); } } diff --git a/tools/convbdf.c b/tools/convbdf.c index d562365ed5..d4f7c3cb9a 100644 --- a/tools/convbdf.c +++ b/tools/convbdf.c @@ -1401,6 +1401,8 @@ int gen_c_source(struct font* pf, char *path) " %d, /* defaultchar */\n" " %d, /* bits_size */\n" " -1, /* font fd */\n" + " -1, /* font fd width */\n" + " -1, /* font fd offset */\n" " 0, /* buffer start */\n" " 0, /* ^ position */\n" " 0, /* ^ end */\n"