font: add codepoint map and descriptor cache to Group, not used yet

This commit is contained in:
Mitchell Hashimoto
2023-09-24 11:50:03 -07:00
parent 3915d9ee3a
commit 9e2e3acecf

View File

@ -33,6 +33,32 @@ const log = std.log.scoped(.font_group);
// to the user so we can change this later. // to the user so we can change this later.
const StyleArray = std.EnumArray(Style, std.ArrayListUnmanaged(GroupFace)); const StyleArray = std.EnumArray(Style, std.ArrayListUnmanaged(GroupFace));
/// Map of descriptors to faces. This is used with manual codepoint maps
/// to ensure that we don't load the same font multiple times.
///
/// Note that the current implementation will load the same font multiple
/// times if the font used for a codepoint map is identical to a font used
/// for a regular style. That's just an inefficient choice made now because
/// the implementation is simpler and codepoint maps matching a regular
/// font is a rare case.
const DescriptorCache = std.HashMapUnmanaged(
font.discovery.Descriptor,
FontIndex,
struct {
const KeyType = font.discovery.Descriptor;
pub fn hash(ctx: @This(), k: KeyType) u64 {
_ = ctx;
return k.hash();
}
pub fn eql(ctx: @This(), a: KeyType, b: KeyType) bool {
return ctx.hash(a) == ctx.hash(b);
}
},
std.hash_map.default_max_load_percentage,
);
/// The allocator for this group /// The allocator for this group
alloc: Allocator, alloc: Allocator,
@ -50,6 +76,15 @@ faces: StyleArray,
/// the codepoint. This can be set after initialization. /// the codepoint. This can be set after initialization.
discover: ?*font.Discover = null, discover: ?*font.Discover = null,
/// A map of codepoints to font requests for codepoint-level overrides.
/// The memory associated with the map is owned by the caller and is not
/// modified or freed by Group.
codepoint_map: ?font.CodepointMap = null,
/// The descriptor cache is used to cache the descriptor to font face
/// mapping for codepoint maps.
descriptor_cache: DescriptorCache = .{},
/// Set this to a non-null value to enable sprite glyph drawing. If this /// Set this to a non-null value to enable sprite glyph drawing. If this
/// isn't enabled we'll just fall through to trying to use regular fonts /// isn't enabled we'll just fall through to trying to use regular fonts
/// to render sprite glyphs. But more than likely, if this isn't set then /// to render sprite glyphs. But more than likely, if this isn't set then
@ -87,6 +122,7 @@ pub fn init(
} }
pub fn deinit(self: *Group) void { pub fn deinit(self: *Group) void {
{
var it = self.faces.iterator(); var it = self.faces.iterator();
while (it.next()) |entry| { while (it.next()) |entry| {
for (entry.value.items) |*item| item.deinit(); for (entry.value.items) |*item| item.deinit();
@ -94,6 +130,9 @@ pub fn deinit(self: *Group) void {
} }
} }
self.descriptor_cache.deinit(self.alloc);
}
/// Add a face to the list for the given style. This face will be added as /// Add a face to the list for the given style. This face will be added as
/// next in priority if others exist already, i.e. it'll be the _last_ to be /// next in priority if others exist already, i.e. it'll be the _last_ to be
/// searched for a glyph in that list. /// searched for a glyph in that list.
@ -173,9 +212,12 @@ pub fn setSize(self: *Group, size: font.face.DesiredSize) !void {
} }
/// This represents a specific font in the group. /// This represents a specific font in the group.
pub const FontIndex = packed struct(u8) { pub const FontIndex = packed struct(FontIndex.Backing) {
const Backing = u8;
const backing_bits = @typeInfo(Backing).Int.bits;
/// The number of bits we use for the index. /// The number of bits we use for the index.
const idx_bits = 8 - @typeInfo(@typeInfo(Style).Enum.tag_type).Int.bits; const idx_bits = backing_bits - @typeInfo(@typeInfo(Style).Enum.tag_type).Int.bits;
pub const IndexInt = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = idx_bits } }); pub const IndexInt = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = idx_bits } });
/// The special-case fonts that we support. /// The special-case fonts that we support.
@ -196,7 +238,7 @@ pub const FontIndex = packed struct(u8) {
} }
/// Convert to int /// Convert to int
pub fn int(self: FontIndex) u8 { pub fn int(self: FontIndex) Backing {
return @bitCast(self); return @bitCast(self);
} }
@ -212,7 +254,7 @@ pub const FontIndex = packed struct(u8) {
// We never want to take up more than a byte since font indexes are // We never want to take up more than a byte since font indexes are
// everywhere so if we increase the size of this we'll dramatically // everywhere so if we increase the size of this we'll dramatically
// increase our memory usage. // increase our memory usage.
try std.testing.expectEqual(@sizeOf(u8), @sizeOf(FontIndex)); try std.testing.expectEqual(@sizeOf(Backing), @sizeOf(FontIndex));
} }
}; };