update font code

This commit is contained in:
Matthew 2025-12-26 17:05:55 +11:00
parent bda9abf8b9
commit 5b6a36f845

113
fonts.d
View File

@ -5,31 +5,15 @@ import dlib.aliases;
import dlib.util; import dlib.util;
import dlib.alloc; import dlib.alloc;
enum AtlasType
{
None = 0,
SoftMask,
}
enum YOrigin
{
None = 0,
Bottom,
}
struct FontAtlas struct FontAtlas
{ {
AtlasType type; f32 size;
f32 size; f32 units_per_em;
u32 width; f32 ascent;
u32 height; f32 descent;
YOrigin y_origin; f32 line_gap;
f32 em_size; u32 width;
f32 line_height; u32 height;
f32 ascender;
f32 descender;
f32 underline_y;
f32 underline_thickness;
Glyph[128] glyphs; Glyph[128] glyphs;
} }
@ -105,11 +89,11 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
{ {
assert(dimension >= 128, "Dimension must be at least 128"); assert(dimension >= 128, "Dimension must be at least 128");
FontAtlasBuf atlas = { FontAtlasBuf abuf = {
data: Alloc!(u8)(arena, dimension * dimension * 4), data: Alloc!(u8)(arena, dimension * dimension * 4),
atlas: { atlas: {
size: size, size: size,
width: dimension, width: dimension,
height: dimension, height: dimension,
}, },
}; };
@ -117,14 +101,17 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
// TODO: proper packing algorithm // TODO: proper packing algorithm
if(font != null) if(font != null)
{ {
i64 f_ascent = cast(i64)(font.size.metrics.ascender >> 6); abuf.atlas.units_per_em = cast(f32)font.units_per_EM;
i64 f_descent = cast(i64)(font.size.metrics.descender >> 6); abuf.atlas.ascent = cast(f32)font.ascender;
i64 f_height = cast(i64)(font.size.metrics.height >> 6); abuf.atlas.descent = cast(f32)font.descender;
abuf.atlas.line_gap = cast(f32)(font.height - font.ascender + font.descender);
u32 max_w = 0; Logf("%f %f %f", font.height, font.ascender, font.descender);
u32 max_h = 0;
u32 current_h = 0; u32 max_w;
u32 count = 0; u32 max_h;
u32 current_h;
u32 count;
i32 font_size = Float26(size); i32 font_size = Float26(size);
@ -142,7 +129,7 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
if(max_w + bmp_w > dimension) if(max_w + bmp_w > dimension)
{ {
max_h += current_h; max_h += current_h;
max_w = 0; max_w = 0;
} }
assert(max_h < dimension, "Unable to pack atlas within dimensions"); assert(max_h < dimension, "Unable to pack atlas within dimensions");
@ -169,9 +156,7 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
} }
FT_GlyphSlot glyph = font.glyph; FT_GlyphSlot glyph = font.glyph;
FT_Bitmap* bmp = &font.glyph.bitmap; FT_Bitmap* bmp = &font.glyph.bitmap;
i32 top = font.glyph.bitmap_top;
i32 left = font.glyph.bitmap_left;
if(max_w + bmp.rows > dimension) if(max_w + bmp.rows > dimension)
{ {
@ -197,10 +182,10 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
u8 p_r = bmp.buffer[offset+2]; u8 p_r = bmp.buffer[offset+2];
u8 p_a = bmp.buffer[offset+3]; u8 p_a = bmp.buffer[offset+3];
atlas.data[offset+0] = DeMultiply(p_r, p_a); abuf.data[offset+0] = DeMultiply(p_r, p_a);
atlas.data[offset+1] = DeMultiply(p_b, p_a); abuf.data[offset+1] = DeMultiply(p_b, p_a);
atlas.data[offset+2] = DeMultiply(p_g, p_a); abuf.data[offset+2] = DeMultiply(p_g, p_a);
atlas.data[offset+3] = p_a; abuf.data[offset+3] = p_a;
} }
} }
} break; } break;
@ -225,10 +210,10 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
x = max_w + c; x = max_w + c;
u64 offset = (y*dimension + x) * 4; u64 offset = (y*dimension + x) * 4;
atlas.data[offset+0] = 255; abuf.data[offset+0] = 255;
atlas.data[offset+1] = 255; abuf.data[offset+1] = 255;
atlas.data[offset+2] = 255; abuf.data[offset+2] = 255;
atlas.data[offset+3] = (bits & 0x80) ? 255 : 0; abuf.data[offset+3] = (bits & 0x80) ? 255 : 0;
bits <<= 1; bits <<= 1;
} }
@ -247,10 +232,10 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
x = max_w + c; x = max_w + c;
u64 offset = (y*dimension + x) * 4; u64 offset = (y*dimension + x) * 4;
atlas.data[offset+0] = 255; abuf.data[offset+0] = 255;
atlas.data[offset+1] = 255; abuf.data[offset+1] = 255;
atlas.data[offset+2] = 255; abuf.data[offset+2] = 255;
atlas.data[offset+3] = bmp.buffer[r*bmp.pitch + c]; abuf.data[offset+3] = bmp.buffer[r*bmp.pitch + c];
} }
} }
} break; } break;
@ -259,28 +244,32 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension)
break; break;
} }
Glyph* g = atlas.atlas.glyphs.ptr + char_code; Glyph* g = abuf.atlas.glyphs.ptr + char_code;
g.ch = cast(dchar)char_code; f32 height = glyph.metrics.height >> 6;
g.advance = cast(f32)(glyph.advance.x >> 6); f32 width = glyph.metrics.width >> 6;
g.plane_left = cast(f32)left; f32 top = -font.glyph.bitmap_top;
g.plane_right = g.plane_left + bmp.width; f32 left = font.glyph.bitmap_left;
g.plane_top = cast(f32)top;
g.plane_bottom = g.plane_top + bmp.rows;
g.atlas_top = max_h; g.ch = cast(dchar)char_code;
g.atlas_left = max_w; g.advance = cast(f32)(glyph.advance.x >> 6);
g.plane_left = left;
g.plane_right = g.plane_left + width;
g.plane_top = top;
g.plane_bottom = g.plane_top + height;
g.atlas_top = max_h;
g.atlas_left = max_w;
g.atlas_bottom = max_h + bmp.rows; g.atlas_bottom = max_h + bmp.rows;
g.atlas_right = max_w + bmp.width; g.atlas_right = max_w + bmp.width;
max_w += bmp.width + PADDING; max_w += bmp.width + PADDING;
current_h = bmp.rows > current_h ? bmp.rows : current_h; current_h = bmp.rows > current_h ? bmp.rows : current_h;
count += 1; count += 1;
} }
} }
return atlas; return abuf;
} }