font: SharedGrid setup test infra

This commit is contained in:
Mitchell Hashimoto
2024-04-05 14:39:31 -07:00
parent 9fb883666a
commit b9471f3791

View File

@ -9,6 +9,13 @@
//! reads well. Going even further, the font subsystem should be very rarely
//! read at all since it should only be necessary when the grid actively
//! changes.
//!
//! SharedGrid does NOT support resizing, font-family changes, font removals
//! in collections, etc. Because the Grid is shared this would cause a
//! major disruption in the rendering of multiple surfaces (i.e. increasing
//! the font size in one would increase it in all). In many cases this isn't
//! desirable so to implement configuration changes the grid should be
//! reinitialized and all surfaces should switch over to using that one.
const SharedGrid = @This();
// TODO(fontmem):
@ -21,7 +28,9 @@ const font = @import("main.zig");
const Atlas = font.Atlas;
const CodepointResolver = font.CodepointResolver;
const Collection = font.Collection;
const Face = font.Face;
const Glyph = font.Glyph;
const Library = font.Library;
const Metrics = font.face.Metrics;
const Presentation = font.Presentation;
const Style = font.Style;
@ -48,6 +57,18 @@ resolver: CodepointResolver,
/// This is calculated based on the resolver and current fonts.
metrics: Metrics,
/// The RwLock used to protect the shared grid.
lock: std.Thread.RwLock,
/// Initialize the grid.
///
/// The resolver must have a collection that supports deferred loading
/// (collection.load_options != null). This is because we need the load
/// options data to determine grid metrics and setup our sprite font.
///
/// SharedGrid always configures the sprite font. This struct is expected to be
/// used with a terminal grid and therefore the sprite font is always
/// necessary for correct rendering.
pub fn init(
alloc: Allocator,
resolver: CodepointResolver,
@ -65,6 +86,8 @@ pub fn init(
.resolver = resolver,
.atlas_greyscale = atlas_greyscale,
.atlas_color = atlas_color,
.lock = .{},
.metrics = undefined, // Loaded below
};
// We set an initial capacity that can fit a good number of characters.
@ -78,6 +101,7 @@ pub fn init(
return result;
}
/// Deinit. Assumes no concurrent access so no lock is taken.
pub fn deinit(self: *SharedGrid, alloc: Allocator) void {
self.codepoints.deinit(alloc);
self.glyphs.deinit(alloc);
@ -118,3 +142,57 @@ const GlyphKey = struct {
glyph: u32,
opts: RenderOptions,
};
const TestMode = enum { normal };
fn testGrid(mode: TestMode, alloc: Allocator, lib: Library) !SharedGrid {
const testFont = @import("test.zig").fontRegular;
var c = try Collection.init(alloc);
c.load_options = .{ .library = lib };
switch (mode) {
.normal => {
_ = try c.add(alloc, .regular, .{ .loaded = try Face.init(
lib,
testFont,
.{ .size = .{ .points = 12, .xdpi = 96, .ydpi = 96 } },
) });
},
}
var r: CodepointResolver = .{ .collection = c };
errdefer r.deinit(alloc);
return try init(alloc, r, false);
}
test "SharedGrid inits metrics" {
const testing = std.testing;
const alloc = testing.allocator;
// const testEmoji = @import("test.zig").fontEmoji;
var lib = try Library.init();
defer lib.deinit();
var grid = try testGrid(.normal, alloc, lib);
defer grid.deinit(alloc);
// Visible ASCII. Do it twice to verify cache is used.
// var i: u32 = 32;
// while (i < 127) : (i += 1) {
// const idx = (try cache.indexForCodepoint(alloc, i, .regular, null)).?;
// try testing.expectEqual(Style.regular, idx.style);
// try testing.expectEqual(@as(Group.FontIndex.IndexInt, 0), idx.idx);
//
// // Render
// const face = try cache.group.faceFromIndex(idx);
// const glyph_index = face.glyphIndex(i).?;
// _ = try cache.renderGlyph(
// alloc,
// idx,
// glyph_index,
// .{},
// );
// }
}