ghostty/pkg/macos/text/font.zig
Mitchell Hashimoto 12c9482d48 Mac Font Discovery with CoreText (#17)
This implements font discovery so the `--font-family` flag works for macOS. Fonts are looked up using the Core Text API so any installed font on the Mac system can be used. 

We still use FreeType for rendering, and CoreText doesn't _quite_ give us all the information we need to build the exact face in FreeType. So a TODO after this is to now implement glyph _rendering_ using Core Text and Core Graphics. Until then, a couple fonts don't quite work (i.e. Monaco, a big one!) but many do!
2022-10-01 22:21:30 -07:00

68 lines
2.0 KiB
Zig

const std = @import("std");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const foundation = @import("../foundation.zig");
const graphics = @import("../graphics.zig");
const text = @import("../text.zig");
const c = @import("c.zig");
pub const Font = opaque {
pub fn createWithFontDescriptor(desc: *text.FontDescriptor, size: f32) Allocator.Error!*Font {
return @intToPtr(
?*Font,
@ptrToInt(c.CTFontCreateWithFontDescriptor(
@ptrCast(c.CTFontDescriptorRef, desc),
size,
null,
)),
) orelse Allocator.Error.OutOfMemory;
}
pub fn release(self: *Font) void {
c.CFRelease(self);
}
pub fn getGlyphsForCharacters(self: *Font, chars: []const u16, glyphs: []graphics.Glyph) bool {
assert(chars.len == glyphs.len);
return c.CTFontGetGlyphsForCharacters(
@ptrCast(c.CTFontRef, self),
chars.ptr,
glyphs.ptr,
@intCast(c_long, chars.len),
);
}
pub fn copyAttribute(self: *Font, comptime attr: text.FontAttribute) attr.Value() {
return @intToPtr(attr.Value(), @ptrToInt(c.CTFontCopyAttribute(
@ptrCast(c.CTFontRef, self),
@ptrCast(c.CFStringRef, attr.key()),
)));
}
pub fn copyDisplayName(self: *Font) *foundation.String {
return @intToPtr(
*foundation.String,
@ptrToInt(c.CTFontCopyDisplayName(@ptrCast(c.CTFontRef, self))),
);
}
};
test {
const testing = std.testing;
const name = try foundation.String.createWithBytes("Monaco", .utf8, false);
defer name.release();
const desc = try text.FontDescriptor.createWithNameAndSize(name, 12);
defer desc.release();
const font = try Font.createWithFontDescriptor(desc, 12);
defer font.release();
var glyphs = [1]graphics.Glyph{0};
try testing.expect(font.getGlyphsForCharacters(
&[_]u16{'A'},
&glyphs,
));
try testing.expect(glyphs[0] > 0);
}