font: coretext face presentation

This commit is contained in:
Mitchell Hashimoto
2022-10-08 09:55:22 -07:00
parent 90f3b9391c
commit 723db8be2f
4 changed files with 49 additions and 4 deletions

View File

@ -89,6 +89,12 @@ pub const Font = opaque {
@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) {
@ -108,6 +114,12 @@ test {
const font = try Font.createWithFontDescriptor(desc, 12);
defer font.release();
// Traits
{
const traits = font.getSymbolicTraits();
try testing.expect(!traits.color_glyphs);
}
var glyphs = [1]graphics.Glyph{0};
try testing.expect(font.getGlyphsForCharacters(
&[_]u16{'A'},

View File

@ -111,7 +111,13 @@ pub fn load(
},
.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;
},
@ -136,7 +142,7 @@ fn loadFontconfig(
self.face = try Face.initFile(lib, filename, face_index, size);
}
fn loadCoreText(
fn loadCoreTextFreetype(
self: *DeferredFace,
lib: Library,
size: font.face.DesiredSize,

View File

@ -1,7 +1,7 @@
const builtin = @import("builtin");
const options = @import("main.zig").options;
const freetype = @import("face/freetype.zig");
const coretext = @import("face/coretext.zig");
pub const freetype = @import("face/freetype.zig");
pub const coretext = @import("face/coretext.zig");
/// Face implementation for the compile options.
pub const Face = switch (options.backend) {

View File

@ -1,3 +1,4 @@
const std = @import("std");
const macos = @import("macos");
const harfbuzz = @import("harfbuzz");
const font = @import("../main.zig");
@ -9,6 +10,9 @@ pub const Face = struct {
/// Harfbuzz font corresponding to this face.
hb_font: harfbuzz.Font,
/// The presentation for this font.
presentation: font.Presentation,
/// Initialize a CoreText-based face from another initialized font face
/// 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
@ -21,9 +25,12 @@ pub const Face = struct {
const hb_font = try harfbuzz.coretext.createFont(ct_font);
errdefer hb_font.destroy();
const traits = ct_font.getSymbolicTraits();
return Face{
.font = ct_font,
.hb_font = hb_font,
.presentation = if (traits.color_glyphs) .emoji else .text,
};
}
@ -35,6 +42,8 @@ pub const Face = struct {
};
test {
const testing = std.testing;
const name = try macos.foundation.String.createWithBytes("Monaco", .utf8, false);
defer name.release();
const desc = try macos.text.FontDescriptor.createWithNameAndSize(name, 12);
@ -44,4 +53,22 @@ test {
var face = try Face.initFontCopy(ct_font, .{ .points = 18 });
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);
}