aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/pkg/harfbuzz/blob.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/harfbuzz/blob.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/pkg/harfbuzz/blob.zig')
-rw-r--r--vendor/libghostty-vt/pkg/harfbuzz/blob.zig126
1 files changed, 126 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/pkg/harfbuzz/blob.zig b/vendor/libghostty-vt/pkg/harfbuzz/blob.zig
new file mode 100644
index 00000000..9472e4c7
--- /dev/null
+++ b/vendor/libghostty-vt/pkg/harfbuzz/blob.zig
@@ -0,0 +1,126 @@
+const std = @import("std");
+const c = @import("c.zig").c;
+const Error = @import("errors.zig").Error;
+
+/// Data type holding the memory modes available to client programs.
+///
+/// Regarding these various memory-modes:
+///
+/// - In no case shall the HarfBuzz client modify memory that is passed to
+/// HarfBuzz in a blob. If there is any such possibility,
+/// HB_MEMORY_MODE_DUPLICATE should be used such that HarfBuzz makes a
+/// copy immediately,
+///
+/// - Use HB_MEMORY_MODE_READONLY otherwise, unless you really really really
+/// know what you are doing,
+///
+/// - HB_MEMORY_MODE_WRITABLE is appropriate if you really made a copy of
+/// data solely for the purpose of passing to HarfBuzz and doing that
+/// just once (no reuse!),
+///
+/// - If the font is mmap()ed, it's okay to use
+/// HB_MEMORY_READONLY_MAY_MAKE_WRITABLE , however, using that mode
+/// correctly is very tricky. Use HB_MEMORY_MODE_READONLY instead.
+pub const MemoryMode = enum(u2) {
+ /// HarfBuzz immediately makes a copy of the data.
+ duplicate = c.HB_MEMORY_MODE_DUPLICATE,
+
+ /// HarfBuzz client will never modify the data, and HarfBuzz will never
+ /// modify the data.
+ readonly = c.HB_MEMORY_MODE_READONLY,
+
+ /// HarfBuzz client made a copy of the data solely for HarfBuzz, so
+ /// HarfBuzz may modify the data.
+ writable = c.HB_MEMORY_MODE_WRITABLE,
+
+ /// See above
+ readonly_may_make_writable = c.HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
+};
+
+/// Blobs wrap a chunk of binary data to handle lifecycle management of data
+/// while it is passed between client and HarfBuzz. Blobs are primarily
+/// used to create font faces, but also to access font face tables, as well as
+/// pass around other binary data.
+pub const Blob = struct {
+ handle: *c.hb_blob_t,
+
+ /// Creates a new "blob" object wrapping data . The mode parameter is used
+ /// to negotiate ownership and lifecycle of data .
+ ///
+ /// Note that this function returns a freshly-allocated empty blob even
+ /// if length is zero. This is in contrast to hb_blob_create(), which
+ /// returns the singleton empty blob (as returned by hb_blob_get_empty())
+ /// if length is zero.
+ pub fn create(data: []const u8, mode: MemoryMode) Error!Blob {
+ const handle = c.hb_blob_create_or_fail(
+ data.ptr,
+ @intCast(data.len),
+ @intFromEnum(mode),
+ null,
+ null,
+ ) orelse return Error.HarfbuzzFailed;
+
+ return Blob{ .handle = handle };
+ }
+
+ /// Decreases the reference count on blob , and if it reaches zero,
+ /// destroys blob , freeing all memory, possibly calling the
+ /// destroy-callback the blob was created for if it has not been
+ /// called already.
+ pub fn destroy(self: *Blob) void {
+ c.hb_blob_destroy(self.handle);
+ }
+
+ /// Attaches a user-data key/data pair to the specified blob.
+ pub fn setUserData(
+ self: Blob,
+ comptime T: type,
+ key: ?*anyopaque,
+ ptr: ?*T,
+ comptime destroycb: ?*const fn (?*T) callconv(.c) void,
+ replace: bool,
+ ) bool {
+ const Callback = struct {
+ pub fn callback(data: ?*anyopaque) callconv(.c) void {
+ @call(.{ .modifier = .always_inline }, destroycb, .{
+ @as(?*T, @ptrCast(@alignCast(data))),
+ });
+ }
+ };
+
+ return c.hb_blob_set_user_data(
+ self.handle,
+ @ptrCast(key),
+ ptr,
+ if (destroycb != null) Callback.callback else null,
+ if (replace) 1 else 0,
+ ) > 0;
+ }
+
+ /// Fetches the user data associated with the specified key, attached to
+ /// the specified font-functions structure.
+ pub fn getUserData(
+ self: Blob,
+ comptime T: type,
+ key: ?*anyopaque,
+ ) ?*T {
+ const opt = c.hb_blob_get_user_data(self.handle, @ptrCast(key));
+ if (opt) |ptr|
+ return @ptrCast(@alignCast(ptr))
+ else
+ return null;
+ }
+};
+
+test {
+ const testing = std.testing;
+
+ const data = "hello";
+ var blob = try Blob.create(data, .readonly);
+ defer blob.destroy();
+
+ var userdata: u8 = 127;
+ var key: u8 = 0;
+ try testing.expect(blob.setUserData(u8, &key, &userdata, null, false));
+ try testing.expect(blob.getUserData(u8, &key).?.* == 127);
+}