diff --git a/CMakeLists.txt b/CMakeLists.txt index 752fa1a..4312377 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,8 @@ set(HB_HAVE_FREETYPE ON CACHE BOOL "" FORCE) set(HB_HAVE_GLIB OFF CACHE BOOL "" FORCE) set(HB_HAVE_ICU OFF CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(harfbuzz) + FetchContent_Declare( stb GIT_REPOSITORY https://github.com/nothings/stb.git @@ -58,7 +60,8 @@ endif() FetchContent_Declare( tracy GIT_REPOSITORY https://github.com/wolfpld/tracy.git - GIT_TAG 05cceee0df3b8d7c6fa87e9638af311dbabc63cb + GIT_TAG master + SYSTEM ) FetchContent_MakeAvailable(tracy) diff --git a/src/font.cpp b/src/font.cpp index 000e107..b444419 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -10,6 +10,9 @@ #include #include +#include "raymath.h" +#include "tracy/TracyC.h" + FT_Library ft_lib; Shader shader; @@ -22,11 +25,14 @@ MyFont::MyFont(const std::string& filename, int size) { if (!file.is_open()) throw std::runtime_error("Failed to open font file"); std::streamsize file_size = file.tellg(); - font_data.resize(file_size); + std::vector file_data(file_size); file.seekg(0, std::ios::beg); - file.read(reinterpret_cast(font_data.data()), file_size); + file.read(reinterpret_cast(file_data.data()), file_size); - if (FT_New_Memory_Face(ft_lib, font_data.data(), font_data.size(), 0, &face)) { + kb_file_data = file_data; + + face = {}; + if (FT_New_Memory_Face(ft_lib, file_data.data(), file_data.size(), 0, &face)) { throw std::runtime_error("Failed to create FreeType face"); } @@ -34,7 +40,6 @@ MyFont::MyFont(const std::string& filename, int size) { FT_Set_Char_Size(face, 0, size * 64, 0, (FT_UInt)(96 * dpi.y)); FT_Select_Charmap(face, FT_ENCODING_UNICODE); - // Rect packing setup std::vector rects; rects.reserve(face->num_glyphs); @@ -98,6 +103,12 @@ MyFont::MyFont(const std::string& filename, int size) { glyphs[g.index] = g; } + kbts = kbts_FontFromMemory(kb_file_data.data(), kb_file_data.size(), 0, nullptr, nullptr); + + if (kbts_FontIsValid(&kbts) == 0) { + std::println("[Error] [kb_text_shape] Failed to load the font."); + } + Image img = { .data = atlas_data.data(), .width = ATLAS_SIZE, @@ -110,26 +121,42 @@ MyFont::MyFont(const std::string& filename, int size) { } void MyFont::deinit() { + kbts_FreeFont(&kbts); if (face) FT_Done_Face(face); UnloadTexture(texture); glyphs.clear(); - font_data.clear(); + kb_file_data.clear(); } -void MyFont::render_text(const std::string_view text, const Vector2 pos, const Color color) { - if (text.size() == 0) +void MyFont::render_text(const std::string_view text, const Vector2 pos, const Color colour) +{ + if (text.empty()) return; + // if (nice_background) { + // self.render_text( + // text, + // pos.add(.{.x = 3.0, .y = -3.0}), + // window_space, + // rl.Color{ .r = 0, .g = 0, .b = 0, .a = 255 }, + // rl.Color{ .r = 0, .g = 0, .b = 0, .a = 0 }, + // false, + // false + // ); + // } + ZoneScoped + Vector2 render_pos = pos; + BeginShaderMode(shader); rlSetTexture(texture.id); rlBegin(RL_QUADS); - Vector2 dpi = GetWindowScaleDPI(); - const float font_ascent = (float)(face->size->metrics.ascender >> 6); - float cursor_x = pos.x; - float cursor_y = pos.y + (font_ascent / dpi.y); + const float font_ascent = face->size->metrics.ascender >> 6; + const float dpi_font_ascent = font_ascent / GetWindowScaleDPI().y; + + render_pos.y += dpi_font_ascent; kbts_shape_context *Context = kbts_CreateShapeContext(nullptr, nullptr); const kbts_font *kb_font = kbts_ShapePushFont(Context, &kbts); @@ -138,36 +165,77 @@ void MyFont::render_text(const std::string_view text, const Vector2 pos, const C return; } - // ZoneNamedC() - // const zone2 = ztracy.ZoneNC(@src(), "ShapeUtf8", 0x00_ff_00_00); - // kb.kbts_ShapeBegin(Context, kb.KBTS_DIRECTION_DONT_KNOW, kb.KBTS_LANGUAGE_DONT_KNOW); - // kb.kbts_ShapeUtf8(Context, text.ptr, @intCast(text.len), kb.KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX); - // kb.kbts_ShapeEnd(Context); - // zone2.End(); + { + ZoneScopedN("font") + kbts_ShapeBegin(Context, KBTS_DIRECTION_DONT_KNOW, KBTS_LANGUAGE_DONT_KNOW); + kbts_ShapeUtf8(Context, text.data(), text.size(), KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX); + kbts_ShapeEnd(Context); + } - // This is a simplified loop. - // In your Zig code, you used 'kb' to get shaped runs. - // Below is the logical equivalent for glyph placement: - for (char c : text) { - uint32_t glyph_index = FT_Get_Char_Index(face, c); - if (glyphs.count(glyph_index)) { - const Glyph& g = glyphs[glyph_index]; + float cursor_x = 0; + float cursor_y = 0; - float x0 = cursor_x + g.dpi_bearing_x; - float y0 = cursor_y - g.dpi_bearing_y; - float x1 = x0 + g.dpi_width; - float y1 = y0 + g.dpi_height; + kbts_run Run; + while (my_kbts_ShapeRun(Context, &Run) != 0) { + ZoneScopedN("shape run") + if ((Run.Flags & KBTS_BREAK_FLAG_LINE_HARD) != 0) { + const float font_linegap = face->size->metrics.height >> 6; + const float dpi_font_linegap = font_linegap / GetWindowScaleDPI().y; - rlColor4ub(color.r, color.g, color.b, color.a); + cursor_y += dpi_font_linegap; + cursor_x = 0; + } - rlTexCoord2f(g.st0.x, g.st0.y); rlVertex2f(x0, y0); - rlTexCoord2f(g.st0.x, g.st1.y); rlVertex2f(x0, y1); - rlTexCoord2f(g.st1.x, g.st1.y); rlVertex2f(x1, y1); - rlTexCoord2f(g.st1.x, g.st0.y); rlVertex2f(x1, y0); + kbts_glyph *RunGlyph; + while (kbts_GlyphIteratorNext(&Run.Glyphs, &RunGlyph) != 0) { + ZoneScopedN("glyph iterator") + const int32_t CodepointIndex = RunGlyph->UserIdOrCodepointIndex; + kbts_shape_codepoint ShapeCodepoint; + if (kbts_ShapeGetShapeCodepoint(Context, CodepointIndex, &ShapeCodepoint) == 0) { + std::println("aah it's wrong!! idk how to handle the error rn!!"); + } - // Advance (simplified, usually handled by HarfBuzz/kb) - FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT); - cursor_x += (float)(face->glyph->advance.x >> 6) / dpi.x; + const float advance_x = FT_MulFix(RunGlyph->AdvanceX, face->size->metrics.x_scale) >> 6; + const float advance_y = FT_MulFix(RunGlyph->AdvanceY, face->size->metrics.y_scale) >> 6; + const float dpi_advance_x = advance_x / GetWindowScaleDPI().x; + const float dpi_advance_y = advance_y / GetWindowScaleDPI().y; + + const float offset_x = FT_MulFix(RunGlyph->OffsetX, face->size->metrics.x_scale) >> 6; + const float offset_y = FT_MulFix(RunGlyph->OffsetY, face->size->metrics.y_scale) >> 6; + const float dpi_offset_x = offset_x / GetWindowScaleDPI().x; + const float dpi_offset_y = offset_y / GetWindowScaleDPI().y; + + if (auto it = glyphs.find(RunGlyph->Id); it != glyphs.end()) { + auto &glyph = it->second; + + const Vector2 v0 = Vector2Add(render_pos, { .x = cursor_x + glyph.dpi_bearing_x + dpi_offset_x, + .y = cursor_y - glyph.dpi_bearing_y - dpi_offset_y }); + + const Vector2 v1 = Vector2Add(v0, Vector2{ .x = glyph.dpi_width, .y = glyph.dpi_height }); + const Vector4 p0 = { .x = v0.x, .y = v0.y, .z = 0.0, .w = 1.0 }; + const Vector4 p1 = { .x = v1.x, .y = v1.y, .z = 0.0, .w = 1.0 }; + + cursor_x += dpi_advance_x; + cursor_y += dpi_advance_y; + + const Vector2 st0 = glyph.st0; + const Vector2 st1 = glyph.st1; + + rlColor4ub(colour.r, colour.g, colour.b, colour.a); + rlNormal3f(0.0, 0.0, 1.0); + + rlTexCoord2f(st0.x, st0.y); rlVertex2f(p0.x, p0.y); + rlTexCoord2f(st0.x, st1.y); rlVertex2f(p0.x, p1.y); + rlTexCoord2f(st1.x, st1.y); rlVertex2f(p1.x, p1.y); + rlTexCoord2f(st1.x, st0.y); rlVertex2f(p1.x, p0.y); + + } else { + std::println("kb_text_shape found the glyph, but we didn't load it from the font. index {}", + RunGlyph->Id); + std::println("advance_x {}", advance_x); + cursor_x += dpi_advance_x; + cursor_y += dpi_advance_y; + } } } @@ -233,350 +301,3 @@ int32_t my_kbts_ShapeRun(kbts_shape_context *Context, kbts_run *Run) { return kbts_ShapeRun(Context, Run); } - -// pub const Font = struct { -// face : ft.Face, -// glyphs : std.AutoHashMap(u32, Glyph), -// kbts_font : kb.kbts_font, -// // texture : c.Texture2D, -// texture : rl.Texture2D, -// kb_file_data : []u8, -// -// pub fn init(filename : [:0]const u8, size : i32, allocator: std.mem.Allocator) !Font { -// -// const file_data = try std.fs.cwd().readFileAlloc( -// allocator, -// filename, -// 10 * 1024 * 1024 -// ); -// defer allocator.free(file_data); -// -// const kb_file_data = try allocator.dupe(u8, file_data); -// errdefer allocator.free(kb_file_data); -// -// var face = try ft_lib.createFaceMemory(file_data, 0); -// var glyphs = std.AutoHashMap(u32, Glyph).init(allocator); -// try face.setCharSize(0, size * 64, 0, 96 * @as(u16, @intFromFloat(rl.getWindowScaleDPI().y))); -// try face.selectCharmap(.unicode); -// -// var rects = try std.ArrayList(rp.stbrp_rect).initCapacity(allocator, 1024); -// defer rects.deinit(allocator); -// -// var nodes : [ATLAS_SIZE]rp.stbrp_node = std.mem.zeroes([ATLAS_SIZE]rp.stbrp_node); -// -// var stbrpcontext : rp.stbrp_context = .{}; -// rp.stbrp_init_target(&stbrpcontext, ATLAS_SIZE, ATLAS_SIZE, &nodes, nodes.len); -// -// const _atlas : []u8 = try allocator.alloc(u8, ATLAS_SIZE * ATLAS_SIZE); -// defer allocator.free(_atlas); -// @memset(_atlas, 0); -// -// const atlas : rl.Image = .{ -// .data = _atlas.ptr, -// .width = ATLAS_SIZE, -// .height = ATLAS_SIZE, -// .mipmaps = 1, -// .format = rl.PixelFormat.uncompressed_grayscale, -// }; -// -// for (0..face.numGlyphs()) |index| { -// try face.loadGlyph(@intCast(index), .{}); -// const bmp = face.glyph().bitmap(); -// -// try rects.append(allocator, .{ -// .id = @intCast(index),//@intCast(face.glyph().glyphIndex()), -// .w = @max(1, @as(c_int, @intCast(bmp.width()))), -// .h = @max(1, @as(c_int, @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| { -// const index : u32 = @intCast(rect.id); -// if (rect.was_packed == 0) continue; -// try face.loadGlyph(index, .{ .render = true }); -// -// const bmp = face.glyph().bitmap(); -// -// 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); -// -// if (bmp.buffer()) |buf| { -// 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 : i32 = @intCast(bmp.width()); -// const height : i32 = @intCast(bmp.rows()); -// const dpi_width : f32 = @as(f32, @floatFromInt(width)) / rl.getWindowScaleDPI().x; -// const dpi_height : f32 = @as(f32, @floatFromInt(height)) / rl.getWindowScaleDPI().y; -// const bearing_x : i32 = face.glyph().bitmapLeft(); -// const bearing_y : i32 = face.glyph().bitmapTop(); -// const dpi_bearing_x : f32 = @as(f32, @floatFromInt(bearing_x)) / rl.getWindowScaleDPI().x; -// const dpi_bearing_y : f32 = @as(f32, @floatFromInt(bearing_y)) / rl.getWindowScaleDPI().y; -// const descent : i32 = height - bearing_y; -// const ascent : i32 = height - descent; -// const dpi_descent : f32 = dpi_height - dpi_bearing_y; -// const dpi_ascent : f32 = dpi_height - dpi_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 = x, -// .y = y, -// .index = index, -// .bearing_x = bearing_x, -// .bearing_y = bearing_y, -// .dpi_bearing_x = dpi_bearing_x, -// .dpi_bearing_y = dpi_bearing_y, -// .width = width, -// .height = height, -// .dpi_width = dpi_width, -// .dpi_height = dpi_height, -// .descent = descent, -// .ascent = ascent, -// .dpi_descent = dpi_descent, -// .dpi_ascent = dpi_ascent, -// .st0 = .{.x = (fx + 0.5) / fs, .y = (fy - fh + 0.5) / fs}, -// .st1 = .{.x = (fx + fw - 0.5) / fs, .y = (fy - 0.5) / fs}, -// }; -// -// try glyphs.put(glyph.index, glyph); -// } -// -// const texture = try rl.loadTextureFromImage(atlas); -// -// var kbts_font = kb.kbts_FontFromMemory(kb_file_data.ptr, @intCast(kb_file_data.len), 0, null, null); -// -// if (kb.kbts_FontIsValid(&kbts_font) == 0) { -// std.log.info("[Error] [kb_text_shape] Failed to load the font.", .{}); -// } -// -// const hb_blob = hb.Blob.initFromFile(filename); -// _ = hb_blob; -// -// return .{ -// .face = face, -// .glyphs = glyphs, -// .kbts_font = kbts_font, -// .texture = texture, -// .kb_file_data = kb_file_data, -// }; -// } -// -// pub fn deinit(self: *Font, allocator : std.mem.Allocator) void { -// self.glyphs.deinit(); -// self.face.deinit(); -// kb.kbts_FreeFont(&self.kbts_font); -// self.texture.unload(); -// allocator.free(self.kb_file_data); -// } -// -// pub fn render_text( -// self: *Font, -// text: []const u8, -// pos: rl.Vector2, -// window_space: bool, -// colour: rl.Color, -// background: rl.Color, -// nice_background: bool, -// count_descent: bool -// ) void { -// if (text.len == 0) -// return; -// -// const zone = ztracy.ZoneNC(@src(), "render_text", 0x00_ff_00_00); -// defer zone.End(); -// -// rl.beginShaderMode(shader); -// rl.gl.rlSetTexture(self.texture.id); -// rl.gl.rlBegin(rl.gl.rl_quads); -// -// if (nice_background) { -// self.render_text( -// text, -// pos.add(.{.x = 3.0, .y = -3.0}), -// window_space, -// rl.Color{ .r = 0, .g = 0, .b = 0, .a = 255 }, -// rl.Color{ .r = 0, .g = 0, .b = 0, .a = 0 }, -// false, -// false -// ); -// } -// -// var render_pos = pos; -// _ = count_descent; -// _ = background; -// -// const font_ascent : f32 = @floatFromInt(self.face.size().metrics().ascender >> 6); -// const dpi_font_ascent = font_ascent / rl.getWindowScaleDPI().y; -// -// render_pos.y += dpi_font_ascent; -// -// const Context = kb.kbts_CreateShapeContext(null, null); -// defer kb.kbts_DestroyShapeContext(Context); -// const kb_font = kb.kbts_ShapePushFont(Context, &self.kbts_font); -// if (kb_font == null) { -// std.log.info("Could not open font!", .{}); -// return; -// } -// -// const zone2 = ztracy.ZoneNC(@src(), "ShapeUtf8", 0x00_ff_00_00); -// kb.kbts_ShapeBegin(Context, kb.KBTS_DIRECTION_DONT_KNOW, kb.KBTS_LANGUAGE_DONT_KNOW); -// kb.kbts_ShapeUtf8(Context, text.ptr, @intCast(text.len), kb.KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX); -// kb.kbts_ShapeEnd(Context); -// zone2.End(); -// -// var cursor_x : f32 = 0; -// var cursor_y : f32 = 0; -// -// var Run = kb.kbts_run{}; -// while (my_kbts_ShapeRun(Context, &Run) != 0) { -// const zone3 = ztracy.ZoneNC(@src(), "shape run", 0x00_ff_00_00); -// defer zone3.End(); -// if ((Run.Flags & kb.KBTS_BREAK_FLAG_LINE_HARD) != 0) { -// const font_linegap : f32 = @floatFromInt(self.face.size().metrics().height >> 6); -// const dpi_font_linegap = font_linegap / rl.getWindowScaleDPI().y; -// -// cursor_y += dpi_font_linegap; -// cursor_x = 0; -// } -// -// var g : [*c]kb.kbts_glyph = null; -// while (kb.kbts_GlyphIteratorNext(&Run.Glyphs, &g) != 0) { -// const zone4 = ztracy.ZoneNC(@src(), "glyph iterator", 0x00_ff_00_00); -// defer zone4.End(); -// const RunGlyph : *kb.kbts_glyph = g.?; -// const CodepointIndex : i32 = RunGlyph.UserIdOrCodepointIndex; -// var ShapeCodepoint : kb.kbts_shape_codepoint = undefined; -// if (kb.kbts_ShapeGetShapeCodepoint(Context, CodepointIndex, &ShapeCodepoint) == 0) { -// std.log.info("aah it's wrong!! idk how to handle the error rn!!", .{}); -// } -// -// const advance_x : f32 = @floatFromInt(ft.mulFix(RunGlyph.AdvanceX, @intCast(self.face.size().metrics().x_scale)) >> 6); -// const advance_y : f32 = @floatFromInt(ft.mulFix(RunGlyph.AdvanceY, @intCast(self.face.size().metrics().y_scale)) >> 6); -// const dpi_advance_x = advance_x / rl.getWindowScaleDPI().x; -// const dpi_advance_y = advance_y / rl.getWindowScaleDPI().y; -// -// const offset_x : f32 = @floatFromInt(ft.mulFix(RunGlyph.OffsetX, @intCast(self.face.size().metrics().x_scale)) >> 6); -// const offset_y : f32 = @floatFromInt(ft.mulFix(RunGlyph.OffsetY, @intCast(self.face.size().metrics().y_scale)) >> 6); -// const dpi_offset_x = offset_x / rl.getWindowScaleDPI().x; -// const dpi_offset_y = offset_y / rl.getWindowScaleDPI().y; -// -// if (self.glyphs.getPtr(RunGlyph.Id)) |glyph| { -// if (RunGlyph.OffsetX != 0) { -// std.log.info("font bearing ({}, {}), kb offset ({}, {})", .{glyph.bearing_x, glyph.bearing_y, RunGlyph.OffsetX, RunGlyph.OffsetX}); -// } -// -// var v0 = rl.Vector2.zero(); -// var v1 = rl.Vector2.zero(); -// -// v0 = render_pos.add(.{ .x = cursor_x + glyph.dpi_bearing_x + dpi_offset_x, -// .y = cursor_y - glyph.dpi_bearing_y - dpi_offset_y }); -// -// v1 = v0.add(rl.Vector2{ .x = glyph.dpi_width, .y = glyph.dpi_height }); -// const p0 : rl.Vector4 = .{ .x = v0.x, .y = v0.y, .z = 0.0, .w = 1.0 }; -// const p1 : rl.Vector4 = .{ .x = v1.x, .y = v1.y, .z = 0.0, .w = 1.0 }; -// -// cursor_x += dpi_advance_x; -// cursor_y += dpi_advance_y; -// -// const st0 = glyph.st0; -// const st1 = glyph.st1; -// -// rl.gl.rlColor4ub(colour.r, colour.g, colour.b, colour.a); -// rl.gl.rlNormal3f(0.0, 0.0, 1.0); -// -// rl.gl.rlTexCoord2f(st0.x, st0.y); rl.gl.rlVertex2f(p0.x, p0.y); -// rl.gl.rlTexCoord2f(st0.x, st1.y); rl.gl.rlVertex2f(p0.x, p1.y); -// rl.gl.rlTexCoord2f(st1.x, st1.y); rl.gl.rlVertex2f(p1.x, p1.y); -// rl.gl.rlTexCoord2f(st1.x, st0.y); rl.gl.rlVertex2f(p1.x, p0.y); -// -// } else { -// std.log.warn("kb_text_shape found the glyph, but we didn't load it from the font. index {}", .{RunGlyph.Id}); -// std.log.warn("advance_x {}", .{advance_x}); -// cursor_x += dpi_advance_x; -// cursor_y += dpi_advance_y; -// } -// } -// } -// -// rl.gl.rlEnd(); -// rl.gl.rlSetTexture(0); -// rl.endShaderMode(); -// } -// -// pub fn size_row(self: *Font, str: []const u8, n: i32, max_width: f32) struct {rl.Vector2, f32, i32} { -// _ = max_width; -// _ = n; -// const Context = kb.kbts_CreateShapeContext(null, null); -// const kb_font = kb.kbts_ShapePushFont(Context, &self.kb); -// if (kb_font == null) { -// std.log.info("Could not open font!", .{}); -// return .{ rl.Vector2.zero(), 0, 0 }; -// } -// -// kb.kbts_ShapeBegin(Context, kb.KBTS_DIRECTION_DONT_KNOW, kb.KBTS_LANGUAGE_DONT_KNOW); -// kb.kbts_ShapeUtf8(Context, str.ptr, @intCast(str.len), kb.KBTS_USER_ID_GENERATION_MODE_CODEPOINT_INDEX); -// kb.kbts_ShapeEnd(Context); -// -// var size = rl.Vector2.zero(); -// var max_descent : f32 = 0; -// -// var Run = kb.kbts_run{}; -// while(kb.kbts_ShapeRun(Context, &Run) != 0) { -// if ((Run.Flags & kb.KBTS_BREAK_FLAG_LINE_HARD) != 0) { -// -// } -// -// var g : [*c]kb.kbts_glyph = null; -// while (kb.kbts_GlyphIteratorNext(&Run.Glyphs, &g) != 0) { -// const RunGlyph : *kb.kbts_glyph = g.?; -// const CodepointIndex : i32 = RunGlyph.UserIdOrCodepointIndex; -// var ShapeCodepoint : kb.kbts_shape_codepoint = undefined; -// if (kb.kbts_ShapeGetShapeCodepoint(Context, CodepointIndex, &ShapeCodepoint) == 0) { -// std.log.info("aah it's wrong!! idk how to handle the error rn!!", .{}); -// } -// -// if (self.glyphs.getPtr(@intCast(RunGlyph.Id))) |glyph| { -// const advance_x = @as(f32, @floatFromInt(ft.mulFix(RunGlyph.AdvanceX, @intCast(self.face.size().metrics().x_scale)) >> 6)); -// const dpi_advance_x = advance_x / rl.getWindowScaleDPI().x; -// -// size.y = @max(size.y, glyph.dpi_height); -// size.x += dpi_advance_x; -// max_descent = @max(max_descent, glyph.dpi_descent); -// } -// } -// } -// -// return .{ size, max_descent, 0}; -// } -// }; -// -// fn my_kbts_ShapeRun(Context: ?*kb.kbts_shape_context, Run: [*c]kb.kbts_run) c_int { -// const zone = ztracy.ZoneNC(@src(), "my_kbts_ShapeRun", 0x00_ff_00_00); -// defer zone.End(); -// return kb.kbts_ShapeRun(Context, Run); -// } - diff --git a/src/font.h b/src/font.h index 31d90d0..46cb5cb 100644 --- a/src/font.h +++ b/src/font.h @@ -35,13 +35,13 @@ struct MyFont { FT_Face face; std::unordered_map glyphs; Texture2D texture; - std::vector font_data; + std::vector kb_file_data; kbts_font kbts; MyFont(const std::string& filename, int size); void deinit(); - void render_text(const std::string_view text, const Vector2 pos, const Color color); + void render_text(std::string_view text, Vector2 pos, Color color); struct size_ret { Vector2 size; diff --git a/src/main.cpp b/src/main.cpp index 468b5b0..846fd8a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include "font.h" #include "misc.h" @@ -28,12 +28,13 @@ int main() { } - const int32_t screenwidth = 2560; - const int32_t screenheight = 1440; + const int32_t screenwidth = 1280; + const int32_t screenheight = 720; InitWindow(screenwidth, screenheight, "raylib"); MyFont vollkorn("assets/fonts/Vollkorn/static/Vollkorn-Regular.ttf", 42); + MyFont arabic("assets/fonts/Amiri/Amiri-Regular.ttf", 28); shader = LoadShader(nullptr, "assets/text.frag"); float old_time = GetTime(); @@ -59,18 +60,22 @@ int main() { } auto [x, y] = GetWindowScaleDPI(); - std::printf("(%f, %f)\n", x, y); BeginDrawing(); ClearBackground(SKYBLUE); //DrawText("Hello, Sailor!", 150, 150, 20, RAYWHITE); - vollkorn.render_text("The night is long and cold outside", {0 ,0}, WHITE); + // vollkorn.render_text("The night is long and cold outside", {0 ,0}, WHITE); + + arabic.render_text("الليل طويل وبارد في الخارج", Vector2{ .x = 0, .y = 100}, WHITE); misc::drawFPS(0, 0, frame_time); EndDrawing(); - SwapScreenBuffer(); + { + ZoneScopedN("SwapScreenBuffer") + SwapScreenBuffer(); + } frame++;