From 997328ddc66d2f97702cf8c354ad52e04caa7246 Mon Sep 17 00:00:00 2001 From: Ali Chraghi Date: Sat, 18 Jun 2022 02:26:30 +0430 Subject: [PATCH] freetype/harfbuzz: shape_plan binding --- freetype/src/harfbuzz/font.zig | 1 - freetype/src/harfbuzz/shape.zig | 2 +- freetype/src/harfbuzz/shape_plan.zig | 79 +++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/freetype/src/harfbuzz/font.zig b/freetype/src/harfbuzz/font.zig index 3f8bbfd7..e9f4c974 100644 --- a/freetype/src/harfbuzz/font.zig +++ b/freetype/src/harfbuzz/font.zig @@ -3,7 +3,6 @@ const Face = @import("face.zig").Face; const Buffer = @import("buffer.zig").Buffer; const Feature = @import("common.zig").Feature; const SegmentProps = @import("buffer.zig").SegmentProps; -const ShapePlan = @import("shape_plan.zig").ShapePlan; pub const Font = struct { handle: *c.hb_font_t, diff --git a/freetype/src/harfbuzz/shape.zig b/freetype/src/harfbuzz/shape.zig index e57ce0c8..b3af4fbf 100644 --- a/freetype/src/harfbuzz/shape.zig +++ b/freetype/src/harfbuzz/shape.zig @@ -9,7 +9,7 @@ pub const ListShapers = struct { return .{ .index = 0, .list = c.hb_shape_list_shapers() }; } - pub fn next(self: *ListShapers) ?[]const u8 { + pub fn next(self: *ListShapers) ?[:0]const u8 { self.index += 1; return std.mem.span( self.list[self.index - 1] orelse return null, diff --git a/freetype/src/harfbuzz/shape_plan.zig b/freetype/src/harfbuzz/shape_plan.zig index e9c5d116..ad6789b2 100644 --- a/freetype/src/harfbuzz/shape_plan.zig +++ b/freetype/src/harfbuzz/shape_plan.zig @@ -1,2 +1,79 @@ +const std = @import("std"); const c = @import("c.zig"); -pub const ShapePlan = *c.hb_shape_plan_t; +const Buffer = @import("buffer.zig").Buffer; +const Font = @import("font.zig").Font; +const Face = @import("face.zig").Face; +const SegmentProps = @import("buffer.zig").SegmentProps; +const Feature = @import("common.zig").Feature; + +pub const ShapePlan = struct { + handle: *c.hb_shape_plan_t, + + pub fn init(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: []const []const u8) ShapePlan { + return .{ .handle = hb_shape_plan_create( + face.handle, + &props.cast(), + if (features) |f| f.ptr else null, + if (features) |f| @intCast(c_uint, f.len) else 0, + @ptrCast([*c]const [*c]const u8, shapers), + ).? }; + } + + pub fn initCached(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: []const []const u8) ShapePlan { + return .{ .handle = hb_shape_plan_create_cached( + face.handle, + &props.cast(), + if (features) |f| f.ptr else null, + if (features) |f| @intCast(c_uint, f.len) else 0, + @ptrCast([*c]const [*c]const u8, shapers), + ).? }; + } + + pub fn init2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: []const []const u8) ShapePlan { + return .{ .handle = hb_shape_plan_create2( + face.handle, + &props.cast(), + if (features) |f| f.ptr else null, + if (features) |f| @intCast(c_uint, f.len) else 0, + cords.ptr, + @intCast(c_uint, cords.len), + @ptrCast([*c]const [*c]const u8, shapers), + ).? }; + } + + pub fn initCached2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: []const []const u8) ShapePlan { + return .{ .handle = hb_shape_plan_create_cached2( + face.handle, + &props.cast(), + if (features) |f| f.ptr else null, + if (features) |f| @intCast(c_uint, f.len) else 0, + cords.ptr, + @intCast(c_uint, cords.len), + @ptrCast([*c]const [*c]const u8, shapers), + ).? }; + } + + pub fn deinit(self: ShapePlan) void { + c.hb_shape_plan_destroy(self.handle); + } + + pub fn execute(self: ShapePlan, font: Font, buffer: Buffer, features: ?[]Feature) error{ShapingFailed}!void { + if (hb_shape_plan_execute( + self.handle, + font.handle, + buffer.handle, + if (features) |f| f.ptr else null, + if (features) |f| @intCast(c_uint, f.len) else 0, + ) < 1) return error.ShapingFailed; + } + + pub fn getShaper(self: ShapePlan) [:0]const u8 { + return std.mem.span(c.hb_shape_plan_get_shaper(self.handle)); + } +}; + +pub extern fn hb_shape_plan_create(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t; +pub extern fn hb_shape_plan_create_cached(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t; +pub extern fn hb_shape_plan_create2(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, coords: [*c]const c_int, num_coords: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t; +pub extern fn hb_shape_plan_create_cached2(face: ?*c.hb_face_t, props: [*c]const c.hb_segment_properties_t, user_features: [*c]const Feature, num_user_features: c_uint, coords: [*c]const c_int, num_coords: c_uint, shaper_list: [*c]const [*c]const u8) ?*c.hb_shape_plan_t; +pub extern fn hb_shape_plan_execute(shape_plan: ?*c.hb_shape_plan_t, font: ?*c.hb_font_t, buffer: ?*c.hb_buffer_t, features: [*c]const Feature, num_features: c_uint) u8;