summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-08-28 11:21:35 -0700
committerMitchell Hashimoto <mitchell.hashimoto@gmail.com>2022-08-28 11:21:35 -0700
commit5d42e2711f328bb295c07d7d97a680409e9c50c5 (patch)
tree6ee9afa5b21ab700521d3ef1f58b9e5bdb4d9bcf /pkg
parent3d68c72912c81bb82da1199bfaf3f378001f2b7c (diff)
pkg/harfbuzz: face, font, freetype
Diffstat (limited to 'pkg')
-rw-r--r--pkg/harfbuzz/face.zig17
-rw-r--r--pkg/harfbuzz/font.zig20
-rw-r--r--pkg/harfbuzz/freetype.zig73
-rw-r--r--pkg/harfbuzz/main.zig3
-rwxr-xr-xpkg/harfbuzz/res/FiraCode.ttfbin0 -> 289624 bytes
-rw-r--r--pkg/harfbuzz/test.zig1
6 files changed, 114 insertions, 0 deletions
diff --git a/pkg/harfbuzz/face.zig b/pkg/harfbuzz/face.zig
new file mode 100644
index 000000000..2fd3605e8
--- /dev/null
+++ b/pkg/harfbuzz/face.zig
@@ -0,0 +1,17 @@
+const std = @import("std");
+const c = @import("c.zig");
+
+/// A font face is an object that represents a single face from within a font family.
+///
+/// More precisely, a font face represents a single face in a binary font file.
+/// Font faces are typically built from a binary blob and a face index.
+/// Font faces are used to create fonts.
+pub const Face = struct {
+ handle: *c.hb_face_t,
+
+ /// Decreases the reference count on a face object. When the reference
+ /// count reaches zero, the face is destroyed, freeing all memory.
+ pub fn destroy(self: *Face) void {
+ c.hb_face_destroy(self.handle);
+ }
+};
diff --git a/pkg/harfbuzz/font.zig b/pkg/harfbuzz/font.zig
new file mode 100644
index 000000000..259274446
--- /dev/null
+++ b/pkg/harfbuzz/font.zig
@@ -0,0 +1,20 @@
+const std = @import("std");
+const c = @import("c.zig");
+const Face = @import("face.zig").Face;
+const Error = @import("errors.zig").Error;
+
+pub const Font = struct {
+ handle: *c.hb_font_t,
+
+ /// Constructs a new font object from the specified face.
+ pub fn create(face: Face) Error!Font {
+ const handle = c.hb_font_create(face.handle) orelse return Error.HarfbuzzFailed;
+ return Font{ .handle = handle };
+ }
+
+ /// Decreases the reference count on the given font object. When the
+ /// reference count reaches zero, the font is destroyed, freeing all memory.
+ pub fn destroy(self: *Font) void {
+ c.hb_font_destroy(self.handle);
+ }
+};
diff --git a/pkg/harfbuzz/freetype.zig b/pkg/harfbuzz/freetype.zig
new file mode 100644
index 000000000..da33107ab
--- /dev/null
+++ b/pkg/harfbuzz/freetype.zig
@@ -0,0 +1,73 @@
+const freetype = @import("freetype");
+const std = @import("std");
+const c = @import("c.zig");
+const Face = @import("face.zig").Face;
+const Font = @import("font.zig").Font;
+const Error = @import("errors.zig").Error;
+
+/// Creates an hb_face_t face object from the specified FT_Face.
+///
+/// This is the preferred variant of the hb_ft_face_create* function
+/// family, because it calls FT_Reference_Face() on ft_face , ensuring
+/// that ft_face remains alive as long as the resulting hb_face_t face
+/// object remains alive. Also calls FT_Done_Face() when the hb_face_t
+/// face object is destroyed.
+///
+/// Use this version unless you know you have good reasons not to.
+pub fn createFace(face: freetype.c.FT_Face) Error!Face {
+ const handle = c.hb_ft_face_create_referenced(
+ @ptrCast(c.FT_Face, face),
+ ) orelse return Error.HarfbuzzFailed;
+ return Face{ .handle = handle };
+}
+
+/// Creates an hb_font_t font object from the specified FT_Face.
+pub fn createFont(face: freetype.c.FT_Face) Error!Font {
+ const handle = c.hb_ft_font_create_referenced(
+ @ptrCast(c.FT_Face, face),
+ ) orelse return Error.HarfbuzzFailed;
+ return Font{ .handle = handle };
+}
+
+/// Configures the font-functions structure of the specified hb_font_t font
+/// object to use FreeType font functions.
+///
+/// In particular, you can use this function to configure an existing
+/// hb_face_t face object for use with FreeType font functions even if that
+/// hb_face_t face object was initially created with hb_face_create(), and
+/// therefore was not initially configured to use FreeType font functions.
+///
+/// An hb_face_t face object created with hb_ft_face_create() is preconfigured
+/// for FreeType font functions and does not require this function to be used.
+pub fn setFontFuncs(font: Font) void {
+ c.hb_ft_font_set_funcs(font.handle);
+}
+
+test {
+ const testing = std.testing;
+ const testFont = @import("test.zig").fontRegular;
+ const ftc = freetype.c;
+ const ftok = ftc.FT_Err_Ok;
+
+ var ft_lib: ftc.FT_Library = undefined;
+ if (ftc.FT_Init_FreeType(&ft_lib) != ftok)
+ return error.FreeTypeInitFailed;
+ defer _ = ftc.FT_Done_FreeType(ft_lib);
+
+ var ft_face: ftc.FT_Face = undefined;
+ try testing.expect(ftc.FT_New_Memory_Face(
+ ft_lib,
+ testFont,
+ @intCast(c_long, testFont.len),
+ 0,
+ &ft_face,
+ ) == ftok);
+ defer _ = ftc.FT_Done_Face(ft_face);
+
+ var face = try createFace(ft_face);
+ defer face.destroy();
+
+ var font = try createFont(ft_face);
+ defer font.destroy();
+ setFontFuncs(font);
+}
diff --git a/pkg/harfbuzz/main.zig b/pkg/harfbuzz/main.zig
index 6959edc2f..12894b16d 100644
--- a/pkg/harfbuzz/main.zig
+++ b/pkg/harfbuzz/main.zig
@@ -1,7 +1,10 @@
pub const c = @import("c.zig");
pub usingnamespace @import("blob.zig");
pub usingnamespace @import("errors.zig");
+pub usingnamespace @import("face.zig");
+pub usingnamespace @import("font.zig");
pub usingnamespace @import("version.zig");
+pub const Freetype = @import("freetype.zig");
test {
@import("std").testing.refAllDecls(@This());
diff --git a/pkg/harfbuzz/res/FiraCode.ttf b/pkg/harfbuzz/res/FiraCode.ttf
new file mode 100755
index 000000000..bd7368519
--- /dev/null
+++ b/pkg/harfbuzz/res/FiraCode.ttf
Binary files differ
diff --git a/pkg/harfbuzz/test.zig b/pkg/harfbuzz/test.zig
new file mode 100644
index 000000000..64837a1e1
--- /dev/null
+++ b/pkg/harfbuzz/test.zig
@@ -0,0 +1 @@
+pub const fontRegular = @embedFile("res/FiraCode.ttf");