Initial commit
This commit is contained in:
105
renderer/font.jai
Normal file
105
renderer/font.jai
Normal file
@@ -0,0 +1,105 @@
|
||||
Font_Handle :: #type, distinct u32;
|
||||
|
||||
Glyph :: struct {
|
||||
ax: float; // advance.x
|
||||
ay: float; // advance.y
|
||||
bw: float; // bitmap.width;
|
||||
bh: float; // bitmap.rows;
|
||||
bl: float; // bitmap_left;
|
||||
bt: float; // bitmap_top;
|
||||
tx: float; // x offset of glyph in texture coordinates
|
||||
}
|
||||
|
||||
Point :: struct {
|
||||
x: float;
|
||||
y: float;
|
||||
s: float;
|
||||
t: float;
|
||||
|
||||
color: Vector4;
|
||||
};
|
||||
|
||||
Font :: struct {
|
||||
glyphs: [..] Glyph;
|
||||
face: FT_Face;
|
||||
pixel_size: u32;
|
||||
atlas_width: u32;
|
||||
atlas_height: u32;
|
||||
texture: Texture_Handle;
|
||||
}
|
||||
|
||||
ft : FT_Library;
|
||||
|
||||
init_freetype :: () {
|
||||
if FT_Init_FreeType(*ft) {
|
||||
log("Couldn't init Freetype\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
create_font :: (renderer: *Renderer, path: string, pixel_size: u32) -> Font_Handle {
|
||||
font: Font;
|
||||
font.pixel_size = pixel_size;
|
||||
array_resize(*font.glyphs, 128);
|
||||
|
||||
if FT_New_Face(ft, path.data, 0, *font.face) {
|
||||
log("Couldn't create new face\n");
|
||||
assert(false);
|
||||
} else {
|
||||
FT_Set_Pixel_Sizes(font.face, 0, pixel_size);
|
||||
|
||||
g := font.face.glyph;
|
||||
w : u32 = 0;
|
||||
h : u32 = 0;
|
||||
|
||||
index := 0;
|
||||
for 32..128-1 {
|
||||
if FT_Load_Char(font.face, xx it, FT_LOAD_RENDER) {
|
||||
continue;
|
||||
}
|
||||
|
||||
w += g.bitmap.width + 1;
|
||||
h = max(h, g.bitmap.rows);
|
||||
}
|
||||
|
||||
atlas_width := w;
|
||||
|
||||
bytes : [..] u8;
|
||||
bytes.allocator = temp;
|
||||
array_resize(*bytes, w * h);
|
||||
|
||||
texture := create_texture(renderer, bytes.data, w, h, 1, generate_mips=false, format=.R8_UNORM);
|
||||
|
||||
font.atlas_width = w;
|
||||
font.atlas_height = h;
|
||||
|
||||
font.texture = texture;
|
||||
|
||||
x : u32 = 0;
|
||||
|
||||
pixel_width := 1.0 / cast(float)atlas_width;
|
||||
|
||||
for 32..128-1 {
|
||||
if FT_Load_Char(font.face, xx it, FT_LOAD_RENDER) continue;
|
||||
|
||||
// @Speed: We should put this buffer data into an array and upload everything once after this loop
|
||||
update_texture_region(renderer, texture, x, 0, g.bitmap.width, g.bitmap.rows, 1, g.bitmap.buffer);
|
||||
|
||||
font.glyphs[it].ax = cast(float)(g.advance.x >> 6);
|
||||
font.glyphs[it].ay = cast(float)(g.advance.y >> 6);
|
||||
font.glyphs[it].bw = cast(float)g.bitmap.width;
|
||||
font.glyphs[it].bh = cast(float)g.bitmap.rows;
|
||||
font.glyphs[it].bl = cast(float)g.bitmap_left;
|
||||
font.glyphs[it].bt = cast(float)g.bitmap_top;
|
||||
font.glyphs[it].tx = cast(float)x / cast(float)w;
|
||||
x += g.bitmap.width + 1;
|
||||
}
|
||||
|
||||
array_add(*renderer.fonts, font);
|
||||
return xx renderer.fonts.count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#import "freetype-2.12.1";
|
||||
Reference in New Issue
Block a user