Merge pull request #1653 from mitchellh/coretext

Enable CoreText font shaper for macOS by default
This commit is contained in:
Mitchell Hashimoto
2024-04-04 21:44:14 -07:00
committed by GitHub
12 changed files with 826 additions and 220 deletions

View File

@@ -13,8 +13,9 @@ pub const Face = struct {
/// Our font face
font: *macos.text.Font,
/// Harfbuzz font corresponding to this face.
hb_font: harfbuzz.Font,
/// Harfbuzz font corresponding to this face. We only use this
/// if we're using Harfbuzz.
hb_font: if (harfbuzz_shaper) harfbuzz.Font else void,
/// The presentation for this font.
presentation: font.Presentation,
@@ -25,6 +26,10 @@ pub const Face = struct {
/// Set quirks.disableDefaultFontFeatures
quirks_disable_default_font_features: bool = false,
/// True if our build is using Harfbuzz. If we're not, we can avoid
/// some Harfbuzz-specific code paths.
const harfbuzz_shaper = font.options.backend.hasHarfbuzz();
/// The matrix applied to a regular font to auto-italicize it.
pub const italic_skew = macos.graphics.AffineTransform{
.a = 1,
@@ -75,10 +80,6 @@ pub const Face = struct {
/// Initialize a face with a CTFont. This will take ownership over
/// the CTFont. This does NOT copy or retain the CTFont.
pub fn initFont(ct_font: *macos.text.Font, opts: font.face.Options) !Face {
var hb_font = try harfbuzz.coretext.createFont(ct_font);
errdefer hb_font.destroy();
hb_font.setScale(opts.size.pixels(), opts.size.pixels());
const traits = ct_font.getSymbolicTraits();
const metrics = metrics: {
var metrics = try calcMetrics(ct_font);
@@ -86,6 +87,13 @@ pub const Face = struct {
break :metrics metrics;
};
var hb_font = if (comptime harfbuzz_shaper) font: {
var hb_font = try harfbuzz.coretext.createFont(ct_font);
hb_font.setScale(opts.size.pixels(), opts.size.pixels());
break :font hb_font;
} else {};
errdefer if (comptime harfbuzz_shaper) hb_font.destroy();
var result: Face = .{
.font = ct_font,
.hb_font = hb_font,
@@ -144,7 +152,7 @@ pub const Face = struct {
pub fn deinit(self: *Face) void {
self.font.release();
self.hb_font.destroy();
if (comptime harfbuzz_shaper) self.hb_font.destroy();
self.* = undefined;
}

View File

@@ -115,6 +115,19 @@ pub const Backend = enum {
=> false,
};
}
pub fn hasHarfbuzz(self: Backend) bool {
return switch (self) {
.freetype,
.fontconfig_freetype,
.coretext_freetype,
=> true,
.coretext,
.web_canvas,
=> false,
};
}
};
/// The styles that a family can take.

Binary file not shown.

View File

@@ -1,7 +1,7 @@
const builtin = @import("builtin");
const options = @import("main.zig").options;
const harfbuzz = @import("shaper/harfbuzz.zig");
const coretext = @import("shaper/coretext.zig");
pub const harfbuzz = @import("shaper/harfbuzz.zig");
pub const coretext = @import("shaper/coretext.zig");
pub const web_canvas = @import("shaper/web_canvas.zig");
pub usingnamespace @import("shaper/run.zig");
@@ -10,12 +10,12 @@ pub const Shaper = switch (options.backend) {
.freetype,
.fontconfig_freetype,
.coretext_freetype,
.coretext,
=> harfbuzz.Shaper,
// Has missing features, can't be used yet. See the comments in
// the coretext.zig file for more details.
//.coretext => coretext.Shaper,
// Note that coretext_freetype cannot use the coretext
// shaper because the coretext shaper requests CoreText
// font faces.
.coretext => coretext.Shaper,
.web_canvas => web_canvas.Shaper,
};

File diff suppressed because it is too large Load Diff

View File

@@ -12,6 +12,9 @@ pub const fontEmoji = @embedFile("res/NotoColorEmoji.ttf");
pub const fontEmojiText = @embedFile("res/NotoEmoji-Regular.ttf");
pub const fontVariable = @embedFile("res/Lilex-VF.ttf");
/// Font with nerd fonts embedded.
pub const fontNerdFont = @embedFile("res/JetBrainsMonoNerdFont-Regular.ttf");
/// Cozette is a unique font because it embeds some emoji characters
/// but has a text presentation.
pub const fontCozette = @embedFile("res/CozetteVector.ttf");

View File

@@ -256,7 +256,9 @@ pub const GlobalState = struct {
std.log.info("ghostty build optimize={s}", .{build_config.mode_string});
std.log.info("runtime={}", .{build_config.app_runtime});
std.log.info("font_backend={}", .{build_config.font_backend});
std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()});
if (comptime build_config.font_backend.hasHarfbuzz()) {
std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()});
}
if (comptime build_config.font_backend.hasFontconfig()) {
std.log.info("dependency fontconfig={d}", .{fontconfig.version()});
}