Commit: 6a78f908852974118c8ac9e644da87bfbaccf866
Parent: d538eba43dab4578427d7ada3db0542b50e54e22
Author: Randy Palamar
Date: Wed, 13 Nov 2024 07:18:42 -0700
font: compress width/height calculations
Diffstat:
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;