aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/pkg/macos/text/font_descriptor.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/pkg/macos/text/font_descriptor.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/pkg/macos/text/font_descriptor.zig')
-rw-r--r--vendor/libghostty-vt/pkg/macos/text/font_descriptor.zig287
1 files changed, 287 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/pkg/macos/text/font_descriptor.zig b/vendor/libghostty-vt/pkg/macos/text/font_descriptor.zig
new file mode 100644
index 00000000..563165bc
--- /dev/null
+++ b/vendor/libghostty-vt/pkg/macos/text/font_descriptor.zig
@@ -0,0 +1,287 @@
+const std = @import("std");
+const Allocator = std.mem.Allocator;
+const foundation = @import("../foundation.zig");
+const c = @import("c.zig").c;
+
+pub const FontDescriptor = opaque {
+ pub fn createWithNameAndSize(name: *foundation.String, size: f64) Allocator.Error!*FontDescriptor {
+ return @as(
+ ?*FontDescriptor,
+ @ptrFromInt(@intFromPtr(c.CTFontDescriptorCreateWithNameAndSize(@ptrCast(name), size))),
+ ) orelse Allocator.Error.OutOfMemory;
+ }
+
+ pub fn createWithAttributes(dict: *foundation.Dictionary) Allocator.Error!*FontDescriptor {
+ return @as(
+ ?*FontDescriptor,
+ @ptrFromInt(@intFromPtr(c.CTFontDescriptorCreateWithAttributes(@ptrCast(dict)))),
+ ) orelse Allocator.Error.OutOfMemory;
+ }
+
+ pub fn createCopyWithAttributes(
+ original: *FontDescriptor,
+ dict: *foundation.Dictionary,
+ ) Allocator.Error!*FontDescriptor {
+ return @as(
+ ?*FontDescriptor,
+ @ptrFromInt(@intFromPtr(c.CTFontDescriptorCreateCopyWithAttributes(
+ @ptrCast(original),
+ @ptrCast(dict),
+ ))),
+ ) orelse Allocator.Error.OutOfMemory;
+ }
+
+ pub fn createCopyWithVariation(
+ original: *FontDescriptor,
+ id: *foundation.Number,
+ value: f64,
+ ) Allocator.Error!*FontDescriptor {
+ return @as(
+ ?*FontDescriptor,
+ @ptrCast(@constCast(c.CTFontDescriptorCreateCopyWithVariation(
+ @ptrCast(original),
+ @ptrCast(id),
+ value,
+ ))),
+ ) orelse Allocator.Error.OutOfMemory;
+ }
+
+ pub fn retain(self: *FontDescriptor) void {
+ _ = c.CFRetain(self);
+ }
+
+ pub fn release(self: *FontDescriptor) void {
+ c.CFRelease(self);
+ }
+
+ pub fn copyAttribute(self: *const FontDescriptor, comptime attr: FontAttribute) ?attr.Value() {
+ return @ptrFromInt(@intFromPtr(c.CTFontDescriptorCopyAttribute(
+ @ptrCast(self),
+ @ptrCast(attr.key()),
+ )));
+ }
+
+ pub fn copyAttributes(self: *const FontDescriptor) *foundation.Dictionary {
+ return @ptrFromInt(@intFromPtr(c.CTFontDescriptorCopyAttributes(
+ @ptrCast(self),
+ )));
+ }
+};
+
+pub const FontAttribute = enum {
+ url,
+ name,
+ display_name,
+ family_name,
+ style_name,
+ traits,
+ variation,
+ size,
+ matrix,
+ cascade_list,
+ character_set,
+ languages,
+ baseline_adjust,
+ macintosh_encodings,
+ features,
+ feature_settings,
+ fixed_advance,
+ orientation,
+ format,
+ registration_scope,
+ priority,
+ enabled,
+ downloadable,
+ downloaded,
+
+ // https://developer.apple.com/documentation/coretext/core_text_constants?language=objc
+ variation_axes,
+
+ pub fn key(self: FontAttribute) *foundation.String {
+ return @as(*foundation.String, @ptrFromInt(@intFromPtr(switch (self) {
+ .url => c.kCTFontURLAttribute,
+ .name => c.kCTFontNameAttribute,
+ .display_name => c.kCTFontDisplayNameAttribute,
+ .family_name => c.kCTFontFamilyNameAttribute,
+ .style_name => c.kCTFontStyleNameAttribute,
+ .traits => c.kCTFontTraitsAttribute,
+ .variation => c.kCTFontVariationAttribute,
+ .size => c.kCTFontSizeAttribute,
+ .matrix => c.kCTFontMatrixAttribute,
+ .cascade_list => c.kCTFontCascadeListAttribute,
+ .character_set => c.kCTFontCharacterSetAttribute,
+ .languages => c.kCTFontLanguagesAttribute,
+ .baseline_adjust => c.kCTFontBaselineAdjustAttribute,
+ .macintosh_encodings => c.kCTFontMacintoshEncodingsAttribute,
+ .features => c.kCTFontFeaturesAttribute,
+ .feature_settings => c.kCTFontFeatureSettingsAttribute,
+ .fixed_advance => c.kCTFontFixedAdvanceAttribute,
+ .orientation => c.kCTFontOrientationAttribute,
+ .format => c.kCTFontFormatAttribute,
+ .registration_scope => c.kCTFontRegistrationScopeAttribute,
+ .priority => c.kCTFontPriorityAttribute,
+ .enabled => c.kCTFontEnabledAttribute,
+ .downloadable => c.kCTFontDownloadableAttribute,
+ .downloaded => c.kCTFontDownloadedAttribute,
+ .variation_axes => c.kCTFontVariationAxesAttribute,
+ })));
+ }
+
+ pub fn Value(comptime self: FontAttribute) type {
+ return switch (self) {
+ .url => *foundation.URL,
+ .name => *foundation.String,
+ .display_name => *foundation.String,
+ .family_name => *foundation.String,
+ .style_name => *foundation.String,
+ .traits => *foundation.Dictionary,
+ .variation => *foundation.Dictionary,
+ .size => *foundation.Number,
+ .matrix => *anyopaque, // CFDataRef
+ .cascade_list => *foundation.Array,
+ .character_set => *anyopaque, // CFCharacterSetRef
+ .languages => *foundation.Array,
+ .baseline_adjust => *foundation.Number,
+ .macintosh_encodings => *foundation.Number,
+ .features => *foundation.Array,
+ .feature_settings => *foundation.Array,
+ .fixed_advance => *foundation.Number,
+ .orientation => *foundation.Number,
+ .format => *foundation.Number,
+ .registration_scope => *foundation.Number,
+ .priority => *foundation.Number,
+ .enabled => *foundation.Number,
+ .downloadable => *anyopaque, // CFBoolean
+ .downloaded => *anyopaque, // CFBoolean
+ .variation_axes => *foundation.Array,
+ };
+ }
+};
+
+pub const FontTraitKey = enum {
+ symbolic,
+ weight,
+ width,
+ slant,
+
+ pub fn key(self: FontTraitKey) *foundation.String {
+ return @as(*foundation.String, @ptrFromInt(@intFromPtr(switch (self) {
+ .symbolic => c.kCTFontSymbolicTrait,
+ .weight => c.kCTFontWeightTrait,
+ .width => c.kCTFontWidthTrait,
+ .slant => c.kCTFontSlantTrait,
+ })));
+ }
+
+ pub fn Value(self: FontTraitKey) type {
+ return switch (self) {
+ .symbolic => *foundation.Number,
+ .weight => *foundation.Number,
+ .width => *foundation.Number,
+ .slant => *foundation.Number,
+ };
+ }
+};
+
+// https://developer.apple.com/documentation/coretext/ctfont/font_variation_axis_dictionary_keys?language=objc
+pub const FontVariationAxisKey = enum {
+ identifier,
+ minimum_value,
+ maximum_value,
+ default_value,
+ name,
+ hidden,
+
+ pub fn key(self: FontVariationAxisKey) *foundation.String {
+ return @as(*foundation.String, @ptrFromInt(@intFromPtr(switch (self) {
+ .identifier => c.kCTFontVariationAxisIdentifierKey,
+ .minimum_value => c.kCTFontVariationAxisMinimumValueKey,
+ .maximum_value => c.kCTFontVariationAxisMaximumValueKey,
+ .default_value => c.kCTFontVariationAxisDefaultValueKey,
+ .name => c.kCTFontVariationAxisNameKey,
+ .hidden => c.kCTFontVariationAxisHiddenKey,
+ })));
+ }
+
+ pub fn Value(comptime self: FontVariationAxisKey) type {
+ return switch (self) {
+ .identifier => foundation.Number,
+ .minimum_value => foundation.Number,
+ .maximum_value => foundation.Number,
+ .default_value => foundation.Number,
+ .name => foundation.String,
+ .hidden => foundation.Number,
+ };
+ }
+};
+
+pub const FontSymbolicTraits = packed struct(u32) {
+ italic: bool = false,
+ bold: bool = false,
+ _unused1: u3 = 0,
+ expanded: bool = false,
+ condensed: bool = false,
+ _unused2: u3 = 0,
+ monospace: bool = false,
+ vertical: bool = false,
+ ui_optimized: bool = false,
+ color_glyphs: bool = false,
+ composite: bool = false,
+ _padding: u17 = 0,
+
+ pub fn init(num: *foundation.Number) FontSymbolicTraits {
+ var raw: i32 = undefined;
+ _ = num.getValue(.sint32, &raw);
+ return @as(FontSymbolicTraits, @bitCast(raw));
+ }
+
+ test {
+ try std.testing.expectEqual(
+ @bitSizeOf(c.CTFontSymbolicTraits),
+ @bitSizeOf(FontSymbolicTraits),
+ );
+ }
+
+ test "bitcast" {
+ const actual: c.CTFontSymbolicTraits = c.kCTFontTraitMonoSpace | c.kCTFontTraitExpanded;
+ const expected: FontSymbolicTraits = .{
+ .monospace = true,
+ .expanded = true,
+ };
+
+ try std.testing.expectEqual(actual, @as(c.CTFontSymbolicTraits, @bitCast(expected)));
+ }
+
+ test "number" {
+ const raw: i32 = c.kCTFontTraitMonoSpace | c.kCTFontTraitExpanded;
+ const num = try foundation.Number.create(.sint32, &raw);
+ defer num.release();
+
+ const expected: FontSymbolicTraits = .{ .monospace = true, .expanded = true };
+ const actual = FontSymbolicTraits.init(num);
+ try std.testing.expect(std.meta.eql(expected, actual));
+ }
+};
+
+test {
+ @import("std").testing.refAllDecls(@This());
+}
+
+test "descriptor" {
+ const testing = std.testing;
+
+ const name = try foundation.String.createWithBytes("foo", .utf8, false);
+ defer name.release();
+
+ const v = try FontDescriptor.createWithNameAndSize(name, 12);
+ defer v.release();
+
+ const copy_name = v.copyAttribute(.name).?;
+ defer copy_name.release();
+
+ {
+ var buf: [128]u8 = undefined;
+ const cstr = copy_name.cstring(&buf, .utf8).?;
+ try testing.expectEqualStrings("foo", cstr);
+ }
+}