diff --git a/fonts.d b/fonts.d index ba60a91..64c3b8b 100644 --- a/fonts.d +++ b/fonts.d @@ -5,31 +5,15 @@ import dlib.aliases; import dlib.util; import dlib.alloc; -enum AtlasType -{ - None = 0, - SoftMask, -} - -enum YOrigin -{ - None = 0, - Bottom, -} - struct FontAtlas { - AtlasType type; - f32 size; - u32 width; - u32 height; - YOrigin y_origin; - f32 em_size; - f32 line_height; - f32 ascender; - f32 descender; - f32 underline_y; - f32 underline_thickness; + f32 size; + f32 units_per_em; + f32 ascent; + f32 descent; + f32 line_gap; + u32 width; + u32 height; 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"); - FontAtlasBuf atlas = { + FontAtlasBuf abuf = { data: Alloc!(u8)(arena, dimension * dimension * 4), atlas: { - size: size, - width: dimension, + size: size, + width: dimension, height: dimension, }, }; @@ -117,14 +101,17 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension) // TODO: proper packing algorithm if(font != null) { - i64 f_ascent = cast(i64)(font.size.metrics.ascender >> 6); - i64 f_descent = cast(i64)(font.size.metrics.descender >> 6); - i64 f_height = cast(i64)(font.size.metrics.height >> 6); + abuf.atlas.units_per_em = cast(f32)font.units_per_EM; + abuf.atlas.ascent = cast(f32)font.ascender; + abuf.atlas.descent = cast(f32)font.descender; + abuf.atlas.line_gap = cast(f32)(font.height - font.ascender + font.descender); - u32 max_w = 0; - u32 max_h = 0; - u32 current_h = 0; - u32 count = 0; + Logf("%f %f %f", font.height, font.ascender, font.descender); + + u32 max_w; + u32 max_h; + u32 current_h; + u32 count; i32 font_size = Float26(size); @@ -142,7 +129,7 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension) if(max_w + bmp_w > dimension) { max_h += current_h; - max_w = 0; + max_w = 0; } 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_Bitmap* bmp = &font.glyph.bitmap; - i32 top = font.glyph.bitmap_top; - i32 left = font.glyph.bitmap_left; + FT_Bitmap* bmp = &font.glyph.bitmap; 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_a = bmp.buffer[offset+3]; - atlas.data[offset+0] = DeMultiply(p_r, p_a); - atlas.data[offset+1] = DeMultiply(p_b, p_a); - atlas.data[offset+2] = DeMultiply(p_g, p_a); - atlas.data[offset+3] = p_a; + abuf.data[offset+0] = DeMultiply(p_r, p_a); + abuf.data[offset+1] = DeMultiply(p_b, p_a); + abuf.data[offset+2] = DeMultiply(p_g, p_a); + abuf.data[offset+3] = p_a; } } } break; @@ -225,10 +210,10 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension) x = max_w + c; u64 offset = (y*dimension + x) * 4; - atlas.data[offset+0] = 255; - atlas.data[offset+1] = 255; - atlas.data[offset+2] = 255; - atlas.data[offset+3] = (bits & 0x80) ? 255 : 0; + abuf.data[offset+0] = 255; + abuf.data[offset+1] = 255; + abuf.data[offset+2] = 255; + abuf.data[offset+3] = (bits & 0x80) ? 255 : 0; bits <<= 1; } @@ -247,10 +232,10 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension) x = max_w + c; u64 offset = (y*dimension + x) * 4; - atlas.data[offset+0] = 255; - atlas.data[offset+1] = 255; - atlas.data[offset+2] = 255; - atlas.data[offset+3] = bmp.buffer[r*bmp.pitch + c]; + abuf.data[offset+0] = 255; + abuf.data[offset+1] = 255; + abuf.data[offset+2] = 255; + abuf.data[offset+3] = bmp.buffer[r*bmp.pitch + c]; } } } break; @@ -259,28 +244,32 @@ CreateAtlas(Arena* arena, FontFace font, f32 size, u32 dimension) break; } - Glyph* g = atlas.atlas.glyphs.ptr + char_code; + Glyph* g = abuf.atlas.glyphs.ptr + char_code; - g.ch = cast(dchar)char_code; - g.advance = cast(f32)(glyph.advance.x >> 6); - g.plane_left = cast(f32)left; - g.plane_right = g.plane_left + bmp.width; - g.plane_top = cast(f32)top; - g.plane_bottom = g.plane_top + bmp.rows; + f32 height = glyph.metrics.height >> 6; + f32 width = glyph.metrics.width >> 6; + f32 top = -font.glyph.bitmap_top; + f32 left = font.glyph.bitmap_left; - g.atlas_top = max_h; - g.atlas_left = max_w; + g.ch = cast(dchar)char_code; + 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_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; count += 1; } } - return atlas; + return abuf; } -