From decbaafc6a6b771c8a6405fd221488c2b6a68b76 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 1 Oct 2022 20:50:51 -0700 Subject: [PATCH] pkg/macos: add mutable dictionaries, flesh out font descriptor --- pkg/macos/foundation/dictionary.zig | 42 +++++++++++++++++++++++++++++ pkg/macos/text/c.zig | 3 +++ pkg/macos/text/font_descriptor.zig | 7 +++++ 3 files changed, 52 insertions(+) create mode 100644 pkg/macos/text/c.zig diff --git a/pkg/macos/foundation/dictionary.zig b/pkg/macos/foundation/dictionary.zig index 8d74a90f1..d467cb9ed 100644 --- a/pkg/macos/foundation/dictionary.zig +++ b/pkg/macos/foundation/dictionary.zig @@ -41,6 +41,29 @@ pub const Dictionary = opaque { } }; +pub const MutableDictionary = opaque { + pub fn create(cap: usize) Allocator.Error!*MutableDictionary { + return @intToPtr(?*MutableDictionary, @ptrToInt(c.CFDictionaryCreateMutable( + null, + @intCast(c.CFIndex, cap), + &c.kCFTypeDictionaryKeyCallBacks, + &c.kCFTypeDictionaryValueCallBacks, + ))) orelse Allocator.Error.OutOfMemory; + } + + pub fn release(self: *MutableDictionary) void { + foundation.CFRelease(self); + } + + pub fn setValue(self: *MutableDictionary, key: ?*const anyopaque, value: ?*const anyopaque) void { + c.CFDictionarySetValue( + @ptrCast(c.CFMutableDictionaryRef, self), + key, + value, + ); + } +}; + test "dictionary" { const testing = std.testing; @@ -56,3 +79,22 @@ test "dictionary" { try testing.expect(dict.getValue(foundation.String, c.kCFURLIsPurgeableKey) != null); try testing.expect(dict.getValue(foundation.String, c.kCFURLIsVolumeKey) == null); } + +test "mutable dictionary" { + const testing = std.testing; + + const dict = try MutableDictionary.create(0); + defer dict.release(); + + const str = try foundation.String.createWithBytes("hello", .unicode, false); + defer str.release(); + + dict.setValue(c.kCFURLIsPurgeableKey, str); + + { + const imm = @ptrCast(*Dictionary, dict); + try testing.expectEqual(@as(usize, 1), imm.getCount()); + try testing.expect(imm.getValue(foundation.String, c.kCFURLIsPurgeableKey) != null); + try testing.expect(imm.getValue(foundation.String, c.kCFURLIsVolumeKey) == null); + } +} diff --git a/pkg/macos/text/c.zig b/pkg/macos/text/c.zig new file mode 100644 index 000000000..1f9652583 --- /dev/null +++ b/pkg/macos/text/c.zig @@ -0,0 +1,3 @@ +pub usingnamespace @cImport({ + @cInclude("CoreText/CoreText.h"); +}); diff --git a/pkg/macos/text/font_descriptor.zig b/pkg/macos/text/font_descriptor.zig index 4de03a259..8370af20c 100644 --- a/pkg/macos/text/font_descriptor.zig +++ b/pkg/macos/text/font_descriptor.zig @@ -11,6 +11,13 @@ pub const FontDescriptor = opaque { ) orelse Allocator.Error.OutOfMemory; } + pub fn createWithAttributes(dict: *foundation.Dictionary) Allocator.Error!*FontDescriptor { + return @intToPtr( + ?*FontDescriptor, + @ptrToInt(c.CTFontDescriptorCreateWithAttributes(@ptrCast(c.CFDictionaryRef, dict))), + ) orelse Allocator.Error.OutOfMemory; + } + pub fn release(self: *FontDescriptor) void { c.CFRelease(self); }