font: SharedGrid.getIndex

This commit is contained in:
Mitchell Hashimoto
2024-04-05 19:00:41 -07:00
parent 329697779a
commit c99b27d364

View File

@ -143,6 +143,39 @@ pub fn cellSize(self: *SharedGrid) renderer.CellSize {
}; };
} }
/// Get the font index for a given codepoint. This is cached.
pub fn getIndex(
self: *SharedGrid,
alloc: Allocator,
cp: u32,
style: Style,
p: ?Presentation,
) !?Collection.Index {
const key: CodepointKey = .{ .style = style, .codepoint = cp, .presentation = p };
// Fast path: the cache has the value. This is almost always true and
// only requires a read lock.
{
self.lock.lockShared();
defer self.lock.unlockShared();
if (self.codepoints.get(key)) |v| return v;
}
// Slow path: we need to search this codepoint
self.lock.lock();
defer self.lock.unlock();
// Try to get it, if it is now in the cache another thread beat us to it.
const gop = try self.codepoints.getOrPut(alloc, key);
if (gop.found_existing) return gop.value_ptr.*;
errdefer self.codepoints.removeByPtr(gop.key_ptr);
// Load a value and cache it. This even caches negative matches.
const value = self.resolver.getIndex(alloc, cp, style, p);
gop.value_ptr.* = value;
return value;
}
const CodepointKey = struct { const CodepointKey = struct {
style: Style, style: Style,
codepoint: u32, codepoint: u32,
@ -179,7 +212,7 @@ fn testGrid(mode: TestMode, alloc: Allocator, lib: Library) !SharedGrid {
return try init(alloc, r, false); return try init(alloc, r, false);
} }
test "SharedGrid inits metrics" { test getIndex {
const testing = std.testing; const testing = std.testing;
const alloc = testing.allocator; const alloc = testing.allocator;
// const testEmoji = @import("test.zig").fontEmoji; // const testEmoji = @import("test.zig").fontEmoji;
@ -190,21 +223,20 @@ test "SharedGrid inits metrics" {
var grid = try testGrid(.normal, alloc, lib); var grid = try testGrid(.normal, alloc, lib);
defer grid.deinit(alloc); defer grid.deinit(alloc);
// Visible ASCII. Do it twice to verify cache is used. // Visible ASCII.
// var i: u32 = 32; for (32..127) |i| {
// while (i < 127) : (i += 1) { const idx = (try grid.getIndex(alloc, @intCast(i), .regular, null)).?;
// const idx = (try cache.indexForCodepoint(alloc, i, .regular, null)).?; try testing.expectEqual(Style.regular, idx.style);
// try testing.expectEqual(Style.regular, idx.style); try testing.expectEqual(@as(Collection.Index.IndexInt, 0), idx.idx);
// try testing.expectEqual(@as(Group.FontIndex.IndexInt, 0), idx.idx); }
//
// // Render // Do it again without a resolver set to ensure we only hit the cache
// const face = try cache.group.faceFromIndex(idx); const old_resolver = grid.resolver;
// const glyph_index = face.glyphIndex(i).?; grid.resolver = undefined;
// _ = try cache.renderGlyph( defer grid.resolver = old_resolver;
// alloc, for (32..127) |i| {
// idx, const idx = (try grid.getIndex(alloc, @intCast(i), .regular, null)).?;
// glyph_index, try testing.expectEqual(Style.regular, idx.style);
// .{}, try testing.expectEqual(@as(Collection.Index.IndexInt, 0), idx.idx);
// ); }
// }
} }