vtgl

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

Commit: 6a78f908852974118c8ac9e644da87bfbaccf866
Parent: d538eba43dab4578427d7ada3db0542b50e54e22
Author: Randy Palamar
Date:   Wed, 13 Nov 2024 07:18:42 -0700

font: compress width/height calculations

Diffstat:
Mconfig.def.h | 2+-
Mfont.c | 51+++++++++++++++++++++++++--------------------------
Mutil.h | 14+++++++-------
3 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -1,5 +1,5 @@ /* See LICENSE for copyright details */ -static FontDesc g_fonts[][FS_LAST] = { +static FontDesc g_fonts[][FS_COUNT] = { { [FS_NORMAL] = {.path = "/usr/share/fonts/gofont/Go-Mono.ttf", .height = 24}, [FS_BOLD] = {.path = "/usr/share/fonts/gofont/Go-Mono-Bold.ttf", .height = 24}, diff --git a/font.c b/font.c @@ -48,7 +48,6 @@ cached_glyph_to_uv(FontAtlas *fa, CachedGlyph *cg, v2 *start, v2 *end, v2 scale) { v2 cs = {.w = fa->info.w, .h = fa->info.h}; uv2 tile_coord = unpack_gpu_tile_coord(cg->gpu_tile_index); - f32 min_x = tile_coord.x * cs.w + cg->x0; f32 max_x = min_x + cg->width; f32 min_y = tile_coord.y * cs.h + fa->info.h + cg->y0 - fa->info.baseline; @@ -278,12 +277,13 @@ render_glyph(Arena *a, FontAtlas *fa, u32 cp, u32 font_id, enum face_style style for (u32 i = 0; i < cg->tile_count; i++) gc->occupied_tiles[tile_index + i] = 1; + i32 out_y = (fa->info.h + y0 - fa->info.baseline) * out_width; + ASSERT(out_y >= 0); ASSERT(x0 + FONT_H_PADDING >= 0); rgba_bitmap = alloc(a, u32, out_size); - u32 out_y = (fa->info.h + y0 - fa->info.baseline) * out_width; for (i32 i = 0; i < height; i++) { - u32 out_x = x0 + FONT_H_PADDING; + i32 out_x = x0 + FONT_H_PADDING; for (i32 j = 0; j < width; j++) { /* TODO: handled coloured glyphs */ u32 pixel = 0; @@ -303,6 +303,21 @@ end: return rgba_bitmap; } +static FontInfo +compute_font_info(Font *font, f32 scale) +{ + FontInfo result; + + i32 x0, x1, y0, y1; + stbtt_GetFontBoundingBox(&font->font_info, &x0, &y0, &x1, &y1); + + result.h = (u32)(scale * (y1 - y0)) + 1; + result.w = (u32)(scale * (x1 - x0)) + 1 + FONT_H_PADDING; + result.baseline = (u32)(-scale * y0) + 1 + FONT_BASELINE_EXTRA; + + return result; +} + static void font_atlas_update(FontAtlas *fa, iv2 glyph_bitmap_dim) { @@ -317,20 +332,7 @@ font_atlas_update(FontAtlas *fa, iv2 glyph_bitmap_dim) Font *font = &fa->fonts[0][FS_BOLD]; if (!font) font = &fa->fonts[0][FS_NORMAL]; - i32 x0, x1, y0, y1; - stbtt_GetFontBoundingBox(&font->font_info, &x0, &y0, &x1, &y1); - f32 scale = font->stbtt_scale; - fa->info.h = (u32)(scale * (y1 - y0)) + 1; - fa->info.w = (u32)(scale * (x1 - x0)) + 1 + FONT_H_PADDING; - fa->info.baseline = (u32)(-scale * y0) + 1 + FONT_BASELINE_EXTRA; - - ASSERT(FONT_H_PADDING >= (i32)ABS(x0 * scale)); - - /* NOTE: sometimes the reported width is wrong; try '_' which is often the widest char */ - i32 glyph_idx = stbtt_FindGlyphIndex(&font->font_info, '_'); - stbtt_GetGlyphBitmapBoxSubpixel(&font->font_info, glyph_idx, scale, scale, 0, 0, - &x0, &y0, &x1, &y1); - if (x1 - x0 > fa->info.w) fa->info.w = x1 - x0; + fa->info = compute_font_info(font, font->stbtt_scale); gc->tiles_in_x = (glyph_bitmap_dim.x - 1) / fa->info.w - 1; gc->tiles_in_y = (glyph_bitmap_dim.y - 1) / fa->info.h - 1; @@ -346,7 +348,7 @@ static void shift_font_sizes(FontAtlas *fa, i32 size_delta) { for (u32 i = 0; i < fa->nfonts; i++) { - for (u32 j = 0; j < FS_LAST; j++) { + for (u32 j = 0; j < FS_COUNT; j++) { Font *f = &fa->fonts[i][j]; if (!f->buf) continue; @@ -365,7 +367,7 @@ init_fonts(FontAtlas *fa, Arena *a, iv2 glyph_bitmap_dim) fa->fonts = alloc(a, typeof(*fa->fonts), ARRAY_COUNT(g_fonts)); for (u32 j = 0; j < ARRAY_COUNT(g_fonts); j++) { b32 result = 0; - for (u32 i = 0; i < FS_LAST; i++) { + for (u32 i = 0; i < FS_COUNT; i++) { if (!g_fonts[j][i].path) continue; if (init_font(&fa->fonts[fa->nfonts][i], &g_fonts[j][i])) { @@ -383,13 +385,10 @@ init_fonts(FontAtlas *fa, Arena *a, iv2 glyph_bitmap_dim) 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); - stbtt_GetFontBoundingBox(&f->font_info, &x0, &y0, &x1, &y1); - f32 h = (u32)(scale * (y1 - y0)) + 1; - f32 w = (u32)(scale * (x1 - x0)) + 1 + FONT_H_PADDING; - i32 max_tiles_x = glyph_bitmap_dim.x / w; - i32 max_tiles_y = glyph_bitmap_dim.y / h; + FontInfo info = compute_font_info(f, stbtt_ScaleForPixelHeight(&f->font_info, + MIN_FONT_SIZE)); + i32 max_tiles_x = glyph_bitmap_dim.x / info.w; + i32 max_tiles_y = glyph_bitmap_dim.y / info.h; GlyphCache *gc = &fa->glyph_cache; gc->cache_len = round_down_power_of_2(max_tiles_x * max_tiles_y); diff --git a/util.h b/util.h @@ -340,7 +340,7 @@ enum face_style { FS_BOLD = ATTR_BOLD, FS_ITALIC = ATTR_ITALIC, FS_BOLD_ITALIC = ATTR_BOLD|ATTR_ITALIC, - FS_LAST, + FS_COUNT, FS_MASK = FS_BOLD_ITALIC, }; @@ -350,6 +350,11 @@ typedef struct { } FontDesc; typedef struct { + u32 h, w; + i32 baseline; +} FontInfo; + +typedef struct { stbtt_fontinfo font_info; u8 *buf; i32 bufsize; @@ -357,12 +362,7 @@ typedef struct { f32 stbtt_scale; } Font; -typedef Font FontFamily[FS_LAST]; - -typedef struct { - u32 h, w; - i32 baseline; -} FontInfo; +typedef Font FontFamily[FS_COUNT]; typedef struct { u32 cp;