Commit: 8bb1ff95114b49c230f15310f6ffac5fcc1d709e
Parent: 5572b929a2a39dc33cf93724a1d0ba26688039bd
Author: Randy Palamar
Date: Thu, 24 Oct 2024 21:02:46 -0600
don't segfault on failed font load
Diffstat:
M | font.c | | | 44 | +++++++++++++++++++++++++++++++++----------- |
M | os_unix.c | | | 20 | ++++++++++++++------ |
M | util.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)
{