mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
font: set "backend" enum vs booleans
This commit is contained in:
@ -19,10 +19,12 @@ const Presentation = @import("main.zig").Presentation;
|
||||
face: ?Face = null,
|
||||
|
||||
/// Fontconfig
|
||||
fc: if (options.fontconfig) ?Fontconfig else void = if (options.fontconfig) null else {},
|
||||
fc: if (options.backend == .fontconfig_freetype) ?Fontconfig else void =
|
||||
if (options.backend == .fontconfig_freetype) null else {},
|
||||
|
||||
/// CoreText
|
||||
ct: if (options.coretext) ?CoreText else void = if (options.coretext) null else {},
|
||||
ct: if (options.backend == .coretext) ?CoreText else void =
|
||||
if (options.backend == .coretext) null else {},
|
||||
|
||||
/// Fontconfig specific data. This is only present if building with fontconfig.
|
||||
pub const Fontconfig = struct {
|
||||
@ -61,8 +63,11 @@ pub fn initLoaded(face: Face) DeferredFace {
|
||||
|
||||
pub fn deinit(self: *DeferredFace) void {
|
||||
if (self.face) |*face| face.deinit();
|
||||
if (options.fontconfig) if (self.fc) |*fc| fc.deinit();
|
||||
if (options.coretext) if (self.ct) |*ct| ct.deinit();
|
||||
switch (options.backend) {
|
||||
.fontconfig_freetype => if (self.fc) |*fc| fc.deinit(),
|
||||
.coretext => if (self.ct) |*ct| ct.deinit(),
|
||||
.freetype => {},
|
||||
}
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
@ -74,16 +79,16 @@ pub inline fn loaded(self: DeferredFace) bool {
|
||||
/// Returns the name of this face. The memory is always owned by the
|
||||
/// face so it doesn't have to be freed.
|
||||
pub fn name(self: DeferredFace) ![:0]const u8 {
|
||||
if (options.fontconfig) {
|
||||
if (self.fc) |fc|
|
||||
return (try fc.pattern.get(.fullname, 0)).string;
|
||||
}
|
||||
switch (options.backend) {
|
||||
.fontconfig_freetype => if (self.fc) |fc|
|
||||
return (try fc.pattern.get(.fullname, 0)).string,
|
||||
|
||||
if (options.coretext) {
|
||||
if (self.ct) |ct| {
|
||||
.coretext => if (self.ct) |ct| {
|
||||
const display_name = ct.font.copyDisplayName();
|
||||
return display_name.cstringPtr(.utf8) orelse "<unsupported internal encoding>";
|
||||
}
|
||||
},
|
||||
|
||||
.freetype => {},
|
||||
}
|
||||
|
||||
return "TODO: built-in font names";
|
||||
@ -98,19 +103,21 @@ pub fn load(
|
||||
// No-op if we already loaded
|
||||
if (self.face != null) return;
|
||||
|
||||
if (options.fontconfig) {
|
||||
switch (options.backend) {
|
||||
.fontconfig_freetype => {
|
||||
try self.loadFontconfig(lib, size);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
if (options.coretext) {
|
||||
.coretext => {
|
||||
try self.loadCoreText(lib, size);
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
||||
// Unreachable because we must be already loaded or have the
|
||||
// proper configuration for one of the other deferred mechanisms.
|
||||
unreachable;
|
||||
.freetype => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn loadFontconfig(
|
||||
@ -181,9 +188,10 @@ pub fn hasCodepoint(self: DeferredFace, cp: u32, p: ?Presentation) bool {
|
||||
return face.glyphIndex(cp) != null;
|
||||
}
|
||||
|
||||
switch (options.backend) {
|
||||
.fontconfig_freetype => {
|
||||
// If we are using fontconfig, use the fontconfig metadata to
|
||||
// avoid loading the face.
|
||||
if (options.fontconfig) {
|
||||
if (self.fc) |fc| {
|
||||
// Check if char exists
|
||||
if (!fc.charset.hasChar(cp)) return false;
|
||||
@ -201,10 +209,10 @@ pub fn hasCodepoint(self: DeferredFace, cp: u32, p: ?Presentation) bool {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
.coretext => {
|
||||
// If we are using coretext, we check the loaded CT font.
|
||||
if (options.coretext) {
|
||||
if (self.ct) |ct| {
|
||||
// Turn UTF-32 into UTF-16 for CT API
|
||||
var unichars: [2]u16 = undefined;
|
||||
@ -215,6 +223,9 @@ pub fn hasCodepoint(self: DeferredFace, cp: u32, p: ?Presentation) bool {
|
||||
var glyphs = [2]macos.graphics.Glyph{ 0, 0 };
|
||||
return ct.font.getGlyphsForCharacters(unichars[0..len], glyphs[0..len]);
|
||||
}
|
||||
},
|
||||
|
||||
.freetype => {},
|
||||
}
|
||||
|
||||
// This is unreachable because discovery mechanisms terminate, and
|
||||
@ -239,7 +250,7 @@ test "preloaded" {
|
||||
}
|
||||
|
||||
test "fontconfig" {
|
||||
if (!options.fontconfig) return error.SkipZigTest;
|
||||
if (options.backend != .fontconfig_freetype) return error.SkipZigTest;
|
||||
|
||||
const discovery = @import("main.zig").discovery;
|
||||
const testing = std.testing;
|
||||
@ -269,7 +280,7 @@ test "fontconfig" {
|
||||
}
|
||||
|
||||
test "coretext" {
|
||||
if (!options.coretext) return error.SkipZigTest;
|
||||
if (options.backend != .coretext) return error.SkipZigTest;
|
||||
|
||||
const discovery = @import("main.zig").discovery;
|
||||
const testing = std.testing;
|
||||
|
@ -224,7 +224,7 @@ test {
|
||||
}
|
||||
|
||||
test {
|
||||
if (!options.fontconfig) return error.SkipZigTest;
|
||||
if (options.backend != .fontconfig_freetype) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
@ -9,12 +9,11 @@ const DeferredFace = @import("main.zig").DeferredFace;
|
||||
const log = std.log.named(.discovery);
|
||||
|
||||
/// Discover implementation for the compile options.
|
||||
pub const Discover = if (options.fontconfig)
|
||||
Fontconfig
|
||||
else if (options.coretext)
|
||||
CoreText
|
||||
else
|
||||
void;
|
||||
pub const Discover = switch (options.backend) {
|
||||
.fontconfig_freetype => Fontconfig,
|
||||
.coretext => CoreText,
|
||||
else => void,
|
||||
};
|
||||
|
||||
/// Descriptor is used to search for fonts. The only required field
|
||||
/// is "family". The rest are ignored unless they're set to a non-zero
|
||||
@ -273,7 +272,7 @@ pub const CoreText = struct {
|
||||
};
|
||||
|
||||
test "fontconfig" {
|
||||
if (!options.fontconfig) return error.SkipZigTest;
|
||||
if (options.backend != .fontconfig_freetype) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
@ -286,7 +285,7 @@ test "fontconfig" {
|
||||
}
|
||||
|
||||
test "core text" {
|
||||
if (!options.coretext) return error.SkipZigTest;
|
||||
if (options.backend != .coretext) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
|
@ -14,11 +14,25 @@ pub const Discover = discovery.Discover;
|
||||
|
||||
/// Build options
|
||||
pub const options: struct {
|
||||
coretext: bool = false,
|
||||
fontconfig: bool = false,
|
||||
backend: Backend,
|
||||
} = .{
|
||||
.coretext = build_options.coretext,
|
||||
.fontconfig = build_options.fontconfig,
|
||||
.backend = if (build_options.coretext)
|
||||
.coretext
|
||||
else if (build_options.fontconfig)
|
||||
.fontconfig_freetype
|
||||
else
|
||||
.freetype,
|
||||
};
|
||||
|
||||
pub const Backend = enum {
|
||||
/// FreeType for font rendering with no font discovery enabled.
|
||||
freetype,
|
||||
|
||||
/// Fontconfig for font discovery and FreeType for font rendering.
|
||||
fontconfig_freetype,
|
||||
|
||||
/// CoreText for both font discovery and rendering (macOS).
|
||||
coretext,
|
||||
};
|
||||
|
||||
/// The styles that a family can take.
|
||||
|
Reference in New Issue
Block a user