font/coretext: can read font tables

This commit is contained in:
Mitchell Hashimoto
2024-05-27 20:23:10 -07:00
parent 83dbcaad7a
commit 1a7cde9e3e
4 changed files with 72 additions and 1 deletions

View File

@ -16,3 +16,20 @@ pub const Range = extern struct {
return @bitCast(c.CFRangeMake(@intCast(loc), @intCast(len)));
}
};
pub const FourCharCode = packed struct(u32) {
d: u8,
c: u8,
b: u8,
a: u8,
pub fn init(v: *const [4]u8) FourCharCode {
return .{ .a = v[0], .b = v[1], .c = v[2], .d = v[3] };
}
/// Converts the ID to a string. The return value is only valid
/// for the lifetime of the self pointer.
pub fn str(self: FourCharCode) [4]u8 {
return .{ self.a, self.b, self.c, self.d };
}
};

View File

@ -20,9 +20,13 @@ pub const Data = opaque {
foundation.CFRelease(self);
}
pub fn getPointer(self: *Data) *const anyopaque {
pub fn getPointer(self: *Data) [*]const u8 {
return @ptrCast(c.CFDataGetBytePtr(@ptrCast(self)));
}
pub fn getLength(self: *Data) usize {
return @intCast(c.CFDataGetLength(@ptrCast(self)));
}
};
test {

View File

@ -67,6 +67,14 @@ pub const Font = opaque {
return @ptrCast(@constCast(c.CTFontCopyDefaultCascadeListForLanguages(@ptrCast(self), null)));
}
pub fn copyTable(self: *Font, tag: FontTableTag) ?*foundation.Data {
return @constCast(@ptrCast(c.CTFontCopyTable(
@ptrCast(self),
@intFromEnum(tag),
c.kCTFontTableOptionNoOptions,
)));
}
pub fn getGlyphCount(self: *Font) usize {
return @intCast(c.CTFontGetGlyphCount(@ptrCast(self)));
}
@ -195,6 +203,16 @@ pub const FontOrientation = enum(c_uint) {
vertical = c.kCTFontOrientationVertical,
};
pub const FontTableTag = enum(u32) {
svg = c.kCTFontTableSVG,
_,
pub fn init(v: *const [4]u8) FontTableTag {
const raw: u32 = @bitCast(foundation.FourCharCode.init(v));
return @enumFromInt(raw);
}
};
test {
const testing = std.testing;

View File

@ -570,6 +570,21 @@ pub const Face = struct {
return result;
}
/// Copy the font table data for the given tag.
pub fn copyTable(self: Face, alloc: Allocator, tag: *const [4]u8) !?[]u8 {
const data = self.font.copyTable(macos.text.FontTableTag.init(tag)) orelse
return null;
defer data.release();
const buf = try alloc.alloc(u8, data.getLength());
errdefer alloc.free(buf);
const ptr = data.getPointer();
@memcpy(buf, ptr[0..buf.len]);
return buf;
}
};
test {
@ -727,3 +742,20 @@ test "mixed color/non-color font treated as text" {
try testing.expect(face.presentation == .text);
}
test "svg font table" {
const testing = std.testing;
const alloc = testing.allocator;
const testFont = @import("../test.zig").fontJuliaMono;
var lib = try font.Library.init();
defer lib.deinit();
var face = try Face.init(lib, testFont, .{ .size = .{ .points = 12 } });
defer face.deinit();
const table = (try face.copyTable(alloc, "SVG ")).?;
defer alloc.free(table);
try testing.expect(table.len > 0);
}