foxygit / Hush Log in
commits tags

/src/fonts.c · 2.9 KB

raw
#include "fonts.h"
#include "paths.h"
#include <stdlib.h>
#include <stdio.h>

/* Point size TTF_OpenFont is called with -- irrelevant beyond needing to be a valid size, since
   every real measure/draw call re-sets the actual size via TTF_SetFontSize first (hittest.c's
   measure_width, render.c's measure_cb and hush_measure_text). Unlike raylib's LoadFontEx (bake
   one atlas at a large base size, then rely on GPU minification for smaller draws), SDL2_ttf
   re-rasterizes via FreeType at the exact requested size every time, so there's no
   baked-atlas/mipmap story here at all. */
#define FONT_OPEN_SIZE 16

static void load_one(SDL2_Font *font, int fontId, const char *overridePath, const char *defaultFileName) {
    char defaultPath[1024];
    snprintf(defaultPath, sizeof defaultPath, "%s/fonts/%s", paths_assets_dir(), defaultFileName);

    const char *path = (overridePath && overridePath[0]) ? overridePath : defaultPath;
    font->fontId = (uint32_t)fontId;
    font->font = TTF_OpenFont(path, FONT_OPEN_SIZE);
    if (!font->font && overridePath) {
        /* Bad override path (e.g. a typo) -- fall back to the bundled default rather than
           leaving this style slot with no usable font. */
        font->font = TTF_OpenFont(defaultPath, FONT_OPEN_SIZE);
    }
    if (!font->font) {
        /* Only realistically reachable if assets/fonts/ itself is missing or corrupt -- already
           an unrecoverable state today, just previously masked by raylib's built-in fallback
           font. SDL2_ttf has no bundled font to fall back to, so fail loudly instead of handing
           a NULL TTF_Font* to later TTF_SizeUTF8/TTF_RenderUTF8_Blended calls. */
        fprintf(stderr, "hush: fatal: could not load bundled default font \"%s\": %s\n", defaultPath, TTF_GetError());
        exit(1);
    }
}

void fonts_load(SDL2_Font *fonts, char *const *overridePaths) {
    char *none[FONT_COUNT] = {0};
    char *const *ov = overridePaths ? overridePaths : none;

    load_one(&fonts[FONT_SANS_REGULAR], FONT_SANS_REGULAR, ov[FONT_SANS_REGULAR], "DejaVuSans.ttf");
    load_one(&fonts[FONT_SANS_BOLD], FONT_SANS_BOLD, ov[FONT_SANS_BOLD], "DejaVuSans-Bold.ttf");
    load_one(&fonts[FONT_SANS_ITALIC], FONT_SANS_ITALIC, ov[FONT_SANS_ITALIC], "DejaVuSans-Oblique.ttf");
    load_one(&fonts[FONT_SANS_BOLD_ITALIC], FONT_SANS_BOLD_ITALIC, ov[FONT_SANS_BOLD_ITALIC], "DejaVuSans-BoldOblique.ttf");
    load_one(&fonts[FONT_MONO_REGULAR], FONT_MONO_REGULAR, ov[FONT_MONO_REGULAR], "DejaVuSansMono.ttf");
    load_one(&fonts[FONT_MONO_BOLD], FONT_MONO_BOLD, ov[FONT_MONO_BOLD], "DejaVuSansMono-Bold.ttf");
    load_one(&fonts[FONT_MONO_ITALIC], FONT_MONO_ITALIC, ov[FONT_MONO_ITALIC], "DejaVuSansMono-Oblique.ttf");
    load_one(&fonts[FONT_MONO_BOLD_ITALIC], FONT_MONO_BOLD_ITALIC, ov[FONT_MONO_BOLD_ITALIC], "DejaVuSansMono-BoldOblique.ttf");
}

void fonts_unload(SDL2_Font *fonts) {
    for (int i = 0; i < FONT_COUNT; i++) TTF_CloseFont(fonts[i].font);
}