106 lines
2.6 KiB
Plaintext
106 lines
2.6 KiB
Plaintext
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";
|