diff --git a/src/font/SharedGrid.zig b/src/font/SharedGrid.zig index c24ac08f5..3f4d3599a 100644 --- a/src/font/SharedGrid.zig +++ b/src/font/SharedGrid.zig @@ -199,7 +199,38 @@ pub const Render = struct { presentation: Presentation, }; -/// Render a glyph. This automatically determines the correct texture +/// Render a codepoint. This uses the first font index that has the codepoint +/// and matches the presentation requested. If the codepoint cannot be found +/// in any font, an null render is returned. +pub fn renderCodepoint( + self: *SharedGrid, + alloc: Allocator, + cp: u32, + style: Style, + p: ?Presentation, + opts: RenderOptions, +) !?Render { + // Note: we could optimize the below to use way less locking, but + // at the time of writing this codepath is only called for preedit + // text which is relatively rare and almost non-existent in multiple + // surfaces at the same time. + + // Get the font that has the codepoint + const index = try self.getIndex(alloc, cp, style, p) orelse return null; + + // Get the glyph for the font + const glyph_index = glyph_index: { + self.lock.lockShared(); + defer self.lock.unlockShared(); + const face = try self.resolver.collection.getFace(index); + break :glyph_index face.glyphIndex(cp) orelse return null; + }; + + // Render + return try self.renderGlyph(alloc, index, glyph_index, opts); +} + +/// Render a glyph index. This automatically determines the correct texture /// atlas to use and caches the result. pub fn renderGlyph( self: *SharedGrid, diff --git a/src/renderer/Metal.zig b/src/renderer/Metal.zig index 998decb10..ea94a796d 100644 --- a/src/renderer/Metal.zig +++ b/src/renderer/Metal.zig @@ -2033,39 +2033,25 @@ fn addPreeditCell( x: usize, y: usize, ) !void { - if (true) @panic("TODO"); // TODO(fontmem) - // Preedit is rendered inverted const bg = self.foreground_color; const fg = self.background_color; - // Get the font for this codepoint. - const font_index = if (self.font_group.indexForCodepoint( + // Render the glyph for our preedit text + const render_ = self.font_grid.renderCodepoint( self.alloc, @intCast(cp.codepoint), .regular, .text, - )) |index| index orelse return else |_| return; - - // Get the font face so we can get the glyph - const face = self.font_group.group.faceFromIndex(font_index) catch |err| { - log.warn("error getting face for font_index={} err={}", .{ font_index, err }); - return; - }; - - // Use the face to now get the glyph index - const glyph_index = face.glyphIndex(@intCast(cp.codepoint)) orelse return; - - // Render the glyph for our preedit text - const glyph = self.font_group.renderGlyph( - self.alloc, - font_index, - glyph_index, .{ .grid_metrics = self.grid_metrics }, ) catch |err| { log.warn("error rendering preedit glyph err={}", .{err}); return; }; + const render = render_ orelse { + log.warn("failed to find font for preedit codepoint={X}", .{cp.codepoint}); + return; + }; // Add our opaque background cell self.cells_bg.appendAssumeCapacity(.{ @@ -2083,9 +2069,9 @@ fn addPreeditCell( .cell_width = if (cp.wide) 2 else 1, .color = .{ fg.r, fg.g, fg.b, 255 }, .bg_color = .{ bg.r, bg.g, bg.b, 255 }, - .glyph_pos = .{ glyph.atlas_x, glyph.atlas_y }, - .glyph_size = .{ glyph.width, glyph.height }, - .glyph_offset = .{ glyph.offset_x, glyph.offset_y }, + .glyph_pos = .{ render.glyph.atlas_x, render.glyph.atlas_y }, + .glyph_size = .{ render.glyph.width, render.glyph.height }, + .glyph_offset = .{ render.glyph.offset_x, render.glyph.offset_y }, }); }