mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
font atlas creates glyph records
This commit is contained in:
@ -103,17 +103,25 @@ pub fn loadFaceFromMemory(self: *FontAtlas, source: [:0]const u8, size: u32) !vo
|
|||||||
return error.FaceLoadFailed;
|
return error.FaceLoadFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the glyph for the given codepoint.
|
||||||
|
pub fn getGlyph(self: *FontAtlas, v: anytype) ?*Glyph {
|
||||||
|
const utf32 = codepoint(v);
|
||||||
|
const entry = self.glyphs.getEntry(utf32) orelse return null;
|
||||||
|
return entry.value_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a glyph to the font atlas. The codepoint can be either a u8 or
|
/// Add a glyph to the font atlas. The codepoint can be either a u8 or
|
||||||
/// []const u8 depending on if you know it is ASCII or must be UTF-8 decoded.
|
/// []const u8 depending on if you know it is ASCII or must be UTF-8 decoded.
|
||||||
pub fn addGlyph(self: *FontAtlas, alloc: Allocator, codepoint: anytype) !void {
|
pub fn addGlyph(self: *FontAtlas, alloc: Allocator, v: anytype) !void {
|
||||||
assert(self.ft_face != null);
|
assert(self.ft_face != null);
|
||||||
|
|
||||||
// We need a UTF32 codepoint for freetype
|
// We need a UTF32 codepoint for freetype
|
||||||
const utf32 = switch (@TypeOf(codepoint)) {
|
const utf32 = codepoint(v);
|
||||||
comptime_int, u8 => @intCast(u32, codepoint),
|
|
||||||
[]const u8 => @intCast(u32, try std.unicode.utfDecode(codepoint)),
|
// If we have this glyph loaded already then we're done.
|
||||||
else => @compileError("invalid codepoint type"),
|
const gop = try self.glyphs.getOrPut(alloc, utf32);
|
||||||
};
|
if (gop.found_existing) return;
|
||||||
|
errdefer _ = self.glyphs.remove(utf32);
|
||||||
|
|
||||||
const glyph_index = ftc.FT_Get_Char_Index(self.ft_face, utf32);
|
const glyph_index = ftc.FT_Get_Char_Index(self.ft_face, utf32);
|
||||||
|
|
||||||
@ -153,7 +161,6 @@ pub fn addGlyph(self: *FontAtlas, alloc: Allocator, codepoint: anytype) !void {
|
|||||||
assert(region.height == tgt_h);
|
assert(region.height == tgt_h);
|
||||||
self.atlas.set(region, buffer);
|
self.atlas.set(region, buffer);
|
||||||
|
|
||||||
const gop = try self.glyphs.getOrPut(alloc, utf32);
|
|
||||||
gop.value_ptr.* = .{
|
gop.value_ptr.* = .{
|
||||||
.width = tgt_w,
|
.width = tgt_w,
|
||||||
.height = tgt_h,
|
.height = tgt_h,
|
||||||
@ -167,6 +174,16 @@ pub fn addGlyph(self: *FontAtlas, alloc: Allocator, codepoint: anytype) !void {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the UTF-32 codepoint for the given value.
|
||||||
|
fn codepoint(v: anytype) u32 {
|
||||||
|
// We need a UTF32 codepoint for freetype
|
||||||
|
return switch (@TypeOf(v)) {
|
||||||
|
comptime_int, u8 => @intCast(u32, v),
|
||||||
|
[]const u8 => @intCast(u32, try std.unicode.utfDecode(v)),
|
||||||
|
else => @compileError("invalid codepoint type"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
var font = try init(try Atlas.init(alloc, 512));
|
var font = try init(try Atlas.init(alloc, 512));
|
||||||
@ -180,6 +197,11 @@ test {
|
|||||||
while (i < 127) : (i += 1) {
|
while (i < 127) : (i += 1) {
|
||||||
try font.addGlyph(alloc, i);
|
try font.addGlyph(alloc, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = 32;
|
||||||
|
while (i < 127) : (i += 1) {
|
||||||
|
try testing.expect(font.getGlyph(i) != null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const testFont = @embedFile("../fonts/Inconsolata-Regular.ttf");
|
const testFont = @embedFile("../fonts/Inconsolata-Regular.ttf");
|
||||||
|
Reference in New Issue
Block a user