vtgl

terminal emulator implemented in OpenGL
git clone anongit@rnpnr.xyz:vtgl.git
Log | Files | Refs | Feed | LICENSE

Commit: 8bb1ff95114b49c230f15310f6ffac5fcc1d709e
Parent: 5572b929a2a39dc33cf93724a1d0ba26688039bd
Author: Randy Palamar
Date:   Thu, 24 Oct 2024 21:02:46 -0600

don't segfault on failed font load

Diffstat:
Mfont.c | 44+++++++++++++++++++++++++++++++++-----------
Mos_unix.c | 20++++++++++++++------
Mutil.c | 8++++++++
3 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/font.c b/font.c @@ -1,16 +1,26 @@ /* See LICENSE for copyright details */ -static void +static b32 init_font(Font *f, FontDesc *fdesc) { + b32 result = 0; os_mapped_file map = os_map_file(fdesc->path, OS_MAP_READ, OS_MAP_PRIVATE); - f->bufsize = map.len; - f->buf = map.data; + if (map.len) { + result = stbtt_InitFont(&f->font_info, map.data, 0); + if (result) { + f->bufsize = map.len; + f->buf = map.data; + f->fontsize = fdesc->height; + f->stbtt_scale = stbtt_ScaleForPixelHeight(&f->font_info, f->fontsize); + } else { + /* TODO: leak */ + os_write_err_msg(s8("stbtt_InitFont: failed on ")); + os_write_err_msg(c_str_to_s8(fdesc->path)); + os_write_err_msg(s8("\n")); + } + } - if (!stbtt_InitFont(&f->font_info, f->buf, 0)) - os_die("stbtt_InitFont: failed on %s\n", fdesc->path); - f->fontsize = fdesc->height; - f->stbtt_scale = stbtt_ScaleForPixelHeight(&f->font_info, f->fontsize); + return result; } static u32 @@ -345,15 +355,27 @@ init_fonts(FontAtlas *fa, Arena *a, iv2 glyph_bitmap_dim) { u32 n_fonts = ARRAY_COUNT(g_fonts); - fa->fonts = alloc(a, typeof(*fa->fonts), n_fonts); - for (fa->nfonts = 0; fa->nfonts < n_fonts; fa->nfonts++) { + fa->nfonts = 0; + fa->fonts = alloc(a, typeof(*fa->fonts), n_fonts); + for (u32 j = 0; j < n_fonts; j++) { + b32 result = 0; for (u32 i = 0; i < FS_LAST; i++) { - if (!g_fonts[fa->nfonts][i].path) + if (!g_fonts[j][i].path) continue; - init_font(&fa->fonts[fa->nfonts][i], &g_fonts[fa->nfonts][i]); + if (init_font(&fa->fonts[fa->nfonts][i], &g_fonts[j][i])) { + result = 1; + } else { + os_write_err_msg(s8("failed to load font: ")); + os_write_err_msg(c_str_to_s8(g_fonts[j][i].path)); + os_write_err_msg(s8("\n")); + } } + fa->nfonts += result; } + if (!fa->nfonts) + os_fatal(s8("failed to load any fonts!\n")); + Font *f = &fa->fonts[0][FS_NORMAL]; i32 x0, x1, y0, y1; f32 scale = stbtt_ScaleForPixelHeight(&f->font_info, MIN_FONT_SIZE); diff --git a/os_unix.c b/os_unix.c @@ -55,6 +55,14 @@ os_die(char *fmt, ...) _exit(1); } +__attribute__((noreturn)) +static void +os_fatal(s8 msg) +{ + os_write_err_msg(msg); + _exit(1); +} + static Arena os_new_arena(size cap) { @@ -116,12 +124,12 @@ os_map_file(char *path, i32 mode, i32 perm) i32 fd = open(path, open_mode); os_file_stats fs = os_get_file_stats(path); - ASSERT(fd > 0 && fs.filesize > 0); - - res.len = fs.filesize; - res.data = mmap(NULL, res.len, mode, perm, fd, 0); - ASSERT(res.data != MAP_FAILED); - close(fd); + if (fd != -1) { + res.data = mmap(NULL, fs.filesize, mode, perm, fd, 0); + if (res.data != MAP_FAILED) + res.len = fs.filesize; + close(fd); + } return res; } diff --git a/util.c b/util.c @@ -134,6 +134,14 @@ s8alloc(Arena *a, size len) return (s8){.len = len, .data = alloc(a, u8, len)}; } +static s8 +c_str_to_s8(char *s) +{ + s8 result = {.data = (u8 *)s}; + while (*s) { result.len++; s++; } + return result; +} + static char * s8_to_cstr(Arena *a, s8 s) {