diff --git a/src/client/font.zig b/src/client/font.zig index dc45b34..68759c6 100644 --- a/src/client/font.zig +++ b/src/client/font.zig @@ -32,8 +32,6 @@ const Glyph = struct { st0 : rl.Vector2, st1 : rl.Vector2, - - bitmap : []u8, }; pub const Font = struct { @@ -49,25 +47,9 @@ pub const Font = struct { const font_data = try std.fs.cwd().readFileAlloc(allocator, filename, 10 * 1024 * 1024); - - // if !success { - // log("[Error] Could not read the font file."); - // return; - // } - var face = try ft_lib.createFaceMemory(font_data, 0); var glyphs = std.AutoHashMap(u32, Glyph).init(allocator); - // .FT_New_Memory_Face(ftlib, font_data.data, xx font_data.count, 0, *face); - // if error { - // log("[Error] %", to_string(FT_Error_String(error))); - // } - - //FT_Set_Pixel_Sizes(face, 0, size); try face.setCharSize(0, size * 64, 0, 96); - // error = FT_Set_Char_Size(face, 0, size * 64, 0, 96); - // if error { - // log("[Error] %", to_string(FT_Error_String(error))); - // } var rects = try std.ArrayList(rp.stbrp_rect).initCapacity(allocator, 1024); defer rects.deinit(allocator); @@ -79,8 +61,9 @@ pub const Font = struct { const _atlas : []u8 = try allocator.alloc(u8, ATLAS_SIZE * ATLAS_SIZE); defer allocator.free(_atlas); + @memset(_atlas, 0); - var atlas : rl.Image = .{ + const atlas : rl.Image = .{ .data = _atlas.ptr, .width = ATLAS_SIZE, .height = ATLAS_SIZE, @@ -88,35 +71,67 @@ pub const Font = struct { .format = .uncompressed_grayscale }; - std.log.info("We have {} glyphs", .{face.numGlyphs()}); - // for (0..1500) |i| { for (0..face.numGlyphs()) |i| { - //for 65..90 { + try face.loadGlyph(@intCast(i), .{}); + const bmp = face.glyph().bitmap(); + + std.log.info("got size {}, {}", .{bmp.width(), bmp.rows()}); + + try rects.append(allocator, .{ + .id = @intCast(face.glyph().glyphIndex()), + .w = @intCast(bmp.width()), + .h = @intCast(bmp.rows()), + .x = 0, + .y = 0, + .was_packed = 0, + }); + } + + _ = rp.stbrp_pack_rects(&stbrpcontext, rects.items.ptr, @intCast(rects.items.len)); + + for (rects.items) |rect| { + if (rect.was_packed == 0) continue; + const i : u32 = @intCast(rect.id); //index := FT_Get_Char_Index(face, xx it); - try face.loadGlyph(@intCast(i), .{ .render = true }); + try face.loadGlyph(i, .{ .render = true }); - // array_add(*rects, stbrp_rect.{cast(s32) face.glyph.glyph_index, cast(s32) face.glyph.bitmap.width, - // cast(s32) face.glyph.bitmap.rows, 0, 0, 0}); - try rects.append(allocator, - rp.stbrp_rect{ - .id = @intCast(face.glyph().glyphIndex()), - .w = @intCast(face.glyph().bitmap().width()), - .h = @intCast(face.glyph().bitmap().rows()), - .x = 0, - .y = 0, - .was_packed = 0, - } - ); + const bmp = face.glyph().bitmap(); + const buf = bmp.buffer() orelse continue; - const width = face.glyph().bitmap().width(); - const height = face.glyph().bitmap().rows(); + const pitch: usize = @intCast(bmp.pitch()); + const w: usize = @intCast(bmp.width()); + const h: usize = @intCast(bmp.rows()); + + const dst_x: usize = @intCast(rect.x); + const dst_y: usize = @intCast(rect.y); + + for (0..h) |y| { + const src = buf[y * pitch .. y * pitch + w]; + + const dst_index = (dst_y + y) * ATLAS_SIZE + dst_x; + const dst = _atlas[dst_index .. dst_index + w]; + + @memcpy(dst, src); + } + + const width = bmp.width(); + const height = bmp.rows(); const bearing_y = face.glyph().bitmapTop(); const descent = @as(i32, @intCast(height)) - bearing_y; const ascent = @as(i32, @intCast(height)) - descent; + const x : i16 = @intCast(rect.x); + const y : i16 = @as(i16, @intCast(rect.y)) + @as(i16, @intCast(height)); + + const fx = @as(f32, @floatFromInt(x)); + const fy = @as(f32, @floatFromInt(y)); + const fw = @as(f32, @floatFromInt(width)); + const fh = @as(f32, @floatFromInt(height)); + const fs = @as(f32, ATLAS_SIZE); + const glyph = Glyph{ - .x = 0, - .y = 0, + .x = x, + .y = y, .utf32 = @intCast(i), .index = face.glyph().glyphIndex(), .bearing_x = face.glyph().bitmapLeft(), @@ -128,77 +143,15 @@ pub const Font = struct { .descent = @as(i32, @intCast(face.glyph().bitmap().rows())) - face.glyph().bitmapTop(), .ascent = ascent, .advance = @intCast(face.glyph().advance().x >> 6), - .st0 = rl.Vector2.zero(), - .st1 = rl.Vector2.zero(), - .bitmap = try allocator.alloc(u8, width * height), + .st0 = rl.Vector2.init((fx + 0.5) / fs, (fy - 0.5) / fs), + .st1 = .{.x = (fx + fw) / fs, .y = (fy - fh) / fs}, }; - const s = glyph.height * glyph.width; - const buf = face.glyph().bitmap().buffer() orelse continue; - @memcpy(glyph.bitmap, buf[0..s]); - // table_set(*font.glyphs, glyph.index, glyph); try glyphs.put(glyph.index, glyph); - // if (try glyphs.fetchPut(glyph.index, glyph)) |old| { - // allocator.free(old.value.bitmap); - // } - } - - _ = rp.stbrp_pack_rects(&stbrpcontext, rects.items.ptr, @intCast(rects.items.len)); - // stbrp_pack_rects(*stbrpcontext, rects.data, cast(s32) rects.count); - - for (rects.items) |rect| { - // for rect : rects { - const glyph = glyphs.getPtr(@intCast(rect.id)) orelse continue; - if (glyph.bitmap.len != 0) { - glyph.x = @intCast(rect.x); - glyph.y = @as(i16, @intCast(rect.y)) + @as(i16, @intCast(glyph.height)); - - const fx = @as(f32, @floatFromInt(glyph.x)); - const fy = @as(f32, @floatFromInt(glyph.y)); - const fw = @as(f32, @floatFromInt(glyph.width)); - const fh = @as(f32, @floatFromInt(glyph.height)); - const fs = @as(f32, ATLAS_SIZE); - - glyph.st0 = rl.Vector2.init((fx + 0.5) / fs, (fy - 0.5) / fs); - - glyph.st1 = .{ - .x = (fx + fw) / fs, - .y = (fy - fh) / fs, - }; - - const g = rl.Image{ - .data = glyph.bitmap.ptr, - .width = @intCast(glyph.width), - .height = @intCast(glyph.height), - .mipmaps = 1, - .format = .uncompressed_grayscale - }; - - atlas.drawImage(g, - .{ .x = 0, .y = 0, .width = @floatFromInt(g.width), .height = @floatFromInt(g.height) }, - .{ .x = @floatFromInt(rect.x), .y = @floatFromInt(rect.y), .width = @floatFromInt(g.width), .height = @floatFromInt(g.height)}, - .white - ); - - // copyBitmapToAtlas(glyph.bitmap, glyph.width, glyph.height, atlas, @intCast(rect.x), @intCast(rect.y)); - } - // glyph : *Glyph = table_find_pointer(*font.glyphs, cast(u32) rect.id); - // if (glyph.bitmap) { - // glyph.x = cast,trunc(s16, rect.x); - // glyph.y = cast,trunc(s16, rect.y) + xx glyph.height; - // glyph.st0 = .{cast(float, glyph.x + 0.5) / ATLAS_SIZE, cast(float, glyph.y - 0.5) / ATLAS_SIZE}; - // //glyph.st1 = glyph.st0 + .{cast(float, glyph.width) / ATLAS_SIZE, -cast(float, glyph.height) / ATLAS_SIZE}; - // glyph.st1 = .{(cast(float, glyph.x + glyph.width )) / cast(float, ATLAS_SIZE), (cast(float, glyph.y - glyph.height )) / cast(float, ATLAS_SIZE)}; - // copyBitmapToAtlas(glyph.bitmap, cast(s32) glyph.width, cast(s32) glyph.height, atlas, cast(s32) rect.x, cast(s32) rect.y); - // } } const texture = try rl.Texture.fromImage(atlas); - // image.flipVertical(); - // texture = make_texture_from_data(atlas, ATLAS_SIZE, ATLAS_SIZE); - - // const kb = kbts_FontFromMemory(font_data.data, xx font_data.count, 0, null, null); var _kb = kb.kbts_FontFromMemory(font_data.ptr, @intCast(font_data.len), 0, null, null); if (kb.kbts_FontIsValid(&_kb) != 0) { @@ -215,10 +168,10 @@ pub const Font = struct { } pub fn deinit(self: *Font, allocator: std.mem.Allocator) void { - var it = self.glyphs.valueIterator(); - while (it.next()) |g| { - allocator.free(g.bitmap); - } + // var it = self.glyphs.valueIterator(); + // while (it.next()) |g| { + // allocator.free(g.bitmap); + // } self.glyphs.deinit(); self.face.deinit(); kb.kbts_FreeFont(&self.kb); @@ -314,9 +267,9 @@ pub const Font = struct { rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y); rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st0.x, st1.y); rl.gl.rlVertex2f(p0.x, p1.y); - rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st0.y); rl.gl.rlVertex2f(p1.x, p0.y); - rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y); - rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st0.x, st0.y); rl.gl.rlVertex2f(p0.x, p0.y); + // rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st0.y); rl.gl.rlVertex2f(p1.x, p0.y); + // rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y); + // rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); rl.gl.rlTexCoord2f(st0.x, st0.y); rl.gl.rlVertex2f(p0.x, p0.y); } else { continue; } diff --git a/src/client/main.zig b/src/client/main.zig index f138940..3b270ad 100644 --- a/src/client/main.zig +++ b/src/client/main.zig @@ -180,17 +180,22 @@ pub fn main() !void { rl.beginDrawing(); + f.texture.drawPro( + .{.x = 0, .y = 0, .width = 4096, .height = 4096}, + .{.x = 0, .y = 0, .width = 512, .height = 512 }, + .zero(), 0, .white); + rl.beginShaderMode(shader); - f.render_text( - "H", - rl.Vector2.init(400, 400), - true, - rl.Color.white, - rl.Color.blank, - true, - true - ); + // f.render_text( + // "H", + // rl.Vector2.init(400, 400), + // true, + // rl.Color.white, + // rl.Color.blank, + // true, + // true + // ); // rl.gl.rlBegin(rl.gl.rl_triangles);