mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
font: coretext face presentation
This commit is contained in:
@ -89,6 +89,12 @@ pub const Font = opaque {
|
|||||||
@ptrToInt(c.CTFontCopyDisplayName(@ptrCast(c.CTFontRef, self))),
|
@ptrToInt(c.CTFontCopyDisplayName(@ptrCast(c.CTFontRef, self))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getSymbolicTraits(self: *Font) text.FontSymbolicTraits {
|
||||||
|
return @bitCast(text.FontSymbolicTraits, c.CTFontGetSymbolicTraits(
|
||||||
|
@ptrCast(c.CTFontRef, self),
|
||||||
|
));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const FontOrientation = enum(c_uint) {
|
pub const FontOrientation = enum(c_uint) {
|
||||||
@ -108,6 +114,12 @@ test {
|
|||||||
const font = try Font.createWithFontDescriptor(desc, 12);
|
const font = try Font.createWithFontDescriptor(desc, 12);
|
||||||
defer font.release();
|
defer font.release();
|
||||||
|
|
||||||
|
// Traits
|
||||||
|
{
|
||||||
|
const traits = font.getSymbolicTraits();
|
||||||
|
try testing.expect(!traits.color_glyphs);
|
||||||
|
}
|
||||||
|
|
||||||
var glyphs = [1]graphics.Glyph{0};
|
var glyphs = [1]graphics.Glyph{0};
|
||||||
try testing.expect(font.getGlyphsForCharacters(
|
try testing.expect(font.getGlyphsForCharacters(
|
||||||
&[_]u16{'A'},
|
&[_]u16{'A'},
|
||||||
|
@ -111,7 +111,13 @@ pub fn load(
|
|||||||
},
|
},
|
||||||
|
|
||||||
.coretext => {
|
.coretext => {
|
||||||
try self.loadCoreText(lib, size);
|
// It is possible to use CoreText with Freetype so we support
|
||||||
|
// both here.
|
||||||
|
switch (font.Face) {
|
||||||
|
font.face.freetype.Face => try self.loadCoreTextFreetype(lib, size),
|
||||||
|
else => unreachable,
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -136,7 +142,7 @@ fn loadFontconfig(
|
|||||||
self.face = try Face.initFile(lib, filename, face_index, size);
|
self.face = try Face.initFile(lib, filename, face_index, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loadCoreText(
|
fn loadCoreTextFreetype(
|
||||||
self: *DeferredFace,
|
self: *DeferredFace,
|
||||||
lib: Library,
|
lib: Library,
|
||||||
size: font.face.DesiredSize,
|
size: font.face.DesiredSize,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const options = @import("main.zig").options;
|
const options = @import("main.zig").options;
|
||||||
const freetype = @import("face/freetype.zig");
|
pub const freetype = @import("face/freetype.zig");
|
||||||
const coretext = @import("face/coretext.zig");
|
pub const coretext = @import("face/coretext.zig");
|
||||||
|
|
||||||
/// Face implementation for the compile options.
|
/// Face implementation for the compile options.
|
||||||
pub const Face = switch (options.backend) {
|
pub const Face = switch (options.backend) {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
const std = @import("std");
|
||||||
const macos = @import("macos");
|
const macos = @import("macos");
|
||||||
const harfbuzz = @import("harfbuzz");
|
const harfbuzz = @import("harfbuzz");
|
||||||
const font = @import("../main.zig");
|
const font = @import("../main.zig");
|
||||||
@ -9,6 +10,9 @@ pub const Face = struct {
|
|||||||
/// Harfbuzz font corresponding to this face.
|
/// Harfbuzz font corresponding to this face.
|
||||||
hb_font: harfbuzz.Font,
|
hb_font: harfbuzz.Font,
|
||||||
|
|
||||||
|
/// The presentation for this font.
|
||||||
|
presentation: font.Presentation,
|
||||||
|
|
||||||
/// Initialize a CoreText-based face from another initialized font face
|
/// Initialize a CoreText-based face from another initialized font face
|
||||||
/// but with a new size. This is often how CoreText fonts are initialized
|
/// but with a new size. This is often how CoreText fonts are initialized
|
||||||
/// because the font is loaded at a default size during discovery, and then
|
/// because the font is loaded at a default size during discovery, and then
|
||||||
@ -21,9 +25,12 @@ pub const Face = struct {
|
|||||||
const hb_font = try harfbuzz.coretext.createFont(ct_font);
|
const hb_font = try harfbuzz.coretext.createFont(ct_font);
|
||||||
errdefer hb_font.destroy();
|
errdefer hb_font.destroy();
|
||||||
|
|
||||||
|
const traits = ct_font.getSymbolicTraits();
|
||||||
|
|
||||||
return Face{
|
return Face{
|
||||||
.font = ct_font,
|
.font = ct_font,
|
||||||
.hb_font = hb_font,
|
.hb_font = hb_font,
|
||||||
|
.presentation = if (traits.color_glyphs) .emoji else .text,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +42,8 @@ pub const Face = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
const name = try macos.foundation.String.createWithBytes("Monaco", .utf8, false);
|
const name = try macos.foundation.String.createWithBytes("Monaco", .utf8, false);
|
||||||
defer name.release();
|
defer name.release();
|
||||||
const desc = try macos.text.FontDescriptor.createWithNameAndSize(name, 12);
|
const desc = try macos.text.FontDescriptor.createWithNameAndSize(name, 12);
|
||||||
@ -44,4 +53,22 @@ test {
|
|||||||
|
|
||||||
var face = try Face.initFontCopy(ct_font, .{ .points = 18 });
|
var face = try Face.initFontCopy(ct_font, .{ .points = 18 });
|
||||||
defer face.deinit();
|
defer face.deinit();
|
||||||
|
|
||||||
|
try testing.expectEqual(font.Presentation.text, face.presentation);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "emoji" {
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
const name = try macos.foundation.String.createWithBytes("Apple Color Emoji", .utf8, false);
|
||||||
|
defer name.release();
|
||||||
|
const desc = try macos.text.FontDescriptor.createWithNameAndSize(name, 12);
|
||||||
|
defer desc.release();
|
||||||
|
const ct_font = try macos.text.Font.createWithFontDescriptor(desc, 12);
|
||||||
|
defer ct_font.release();
|
||||||
|
|
||||||
|
var face = try Face.initFontCopy(ct_font, .{ .points = 18 });
|
||||||
|
defer face.deinit();
|
||||||
|
|
||||||
|
try testing.expectEqual(font.Presentation.emoji, face.presentation);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user