freetype:harfbuzz: fix type for shapers args

Non zero-terminated slices of the previous type caused runtime errors.
This commit is contained in:
Erik Arvstedt 2023-04-05 16:37:52 +02:00 committed by Stephen Gutekanst
parent 762a2074ee
commit b4685feb37
4 changed files with 17 additions and 14 deletions

View file

@ -276,6 +276,8 @@ pub const Tag = struct {
} }
}; };
pub const Shapers = ?[*:null]const ?[*:0]const u8;
pub extern fn hb_feature_from_string(str: [*c]const u8, len: c_int, feature: [*c]Feature) u8; pub extern fn hb_feature_from_string(str: [*c]const u8, len: c_int, feature: [*c]Feature) u8;
pub extern fn hb_feature_to_string(feature: [*c]Feature, buf: [*c]u8, size: c_uint) void; pub extern fn hb_feature_to_string(feature: [*c]Feature, buf: [*c]u8, size: c_uint) void;
pub extern fn hb_variation_from_string(str: [*c]const u8, len: c_int, variation: [*c]Variation) u8; pub extern fn hb_variation_from_string(str: [*c]const u8, len: c_int, variation: [*c]Variation) u8;

View file

@ -5,6 +5,7 @@ const Face = @import("face.zig").Face;
const Buffer = @import("buffer.zig").Buffer; const Buffer = @import("buffer.zig").Buffer;
const Feature = @import("common.zig").Feature; const Feature = @import("common.zig").Feature;
const SegmentProps = @import("buffer.zig").SegmentProps; const SegmentProps = @import("buffer.zig").SegmentProps;
const Shapers = @import("common.zig").Shapers;
pub const Font = struct { pub const Font = struct {
handle: *c.hb_font_t, handle: *c.hb_font_t,
@ -86,13 +87,13 @@ pub const Font = struct {
); );
} }
pub fn shapeFull(self: Font, buf: Buffer, features: ?[]const Feature, shapers: []const []const u8) error{ShapingFailed}!void { pub fn shapeFull(self: Font, buf: Buffer, features: ?[]const Feature, shapers: Shapers) error{ShapingFailed}!void {
if (hb_shape_full( if (hb_shape_full(
self.handle, self.handle,
buf.handle, buf.handle,
if (features) |f| f.ptr else null, if (features) |f| f.ptr else null,
if (features) |f| @intCast(c_uint, f.len) else 0, if (features) |f| @intCast(c_uint, f.len) else 0,
@ptrCast([*c]const [*c]const u8, shapers), shapers,
) < 1) return error.ShapingFailed; ) < 1) return error.ShapingFailed;
} }
}; };

View file

@ -3,7 +3,7 @@ const c = @import("c.zig");
pub const ListShapers = struct { pub const ListShapers = struct {
index: usize, index: usize,
list: [*c][*c]const u8, list: [*:null]const ?[*:0]const u8,
pub fn init() ListShapers { pub fn init() ListShapers {
return .{ .index = 0, .list = c.hb_shape_list_shapers() }; return .{ .index = 0, .list = c.hb_shape_list_shapers() };
@ -11,9 +11,8 @@ pub const ListShapers = struct {
pub fn next(self: *ListShapers) ?[:0]const u8 { pub fn next(self: *ListShapers) ?[:0]const u8 {
self.index += 1; self.index += 1;
return std.mem.span(@ptrCast( return std.mem.span(
?[*:0]const u8,
self.list[self.index - 1] orelse return null, self.list[self.index - 1] orelse return null,
)); );
} }
}; };

View file

@ -5,31 +5,32 @@ const Font = @import("font.zig").Font;
const Face = @import("face.zig").Face; const Face = @import("face.zig").Face;
const SegmentProps = @import("buffer.zig").SegmentProps; const SegmentProps = @import("buffer.zig").SegmentProps;
const Feature = @import("common.zig").Feature; const Feature = @import("common.zig").Feature;
const Shapers = @import("common.zig").Shapers;
pub const ShapePlan = struct { pub const ShapePlan = struct {
handle: *c.hb_shape_plan_t, handle: *c.hb_shape_plan_t,
pub fn init(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: []const []const u8) ShapePlan { pub fn init(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: Shapers) ShapePlan {
return .{ .handle = hb_shape_plan_create( return .{ .handle = hb_shape_plan_create(
face.handle, face.handle,
&props.cast(), &props.cast(),
if (features) |f| f.ptr else null, if (features) |f| f.ptr else null,
if (features) |f| @intCast(c_uint, f.len) else 0, if (features) |f| @intCast(c_uint, f.len) else 0,
@ptrCast([*c]const [*c]const u8, shapers), shapers,
).? }; ).? };
} }
pub fn initCached(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: []const []const u8) ShapePlan { pub fn initCached(face: Face, props: SegmentProps, features: ?[]const Feature, shapers: Shapers) ShapePlan {
return .{ .handle = hb_shape_plan_create_cached( return .{ .handle = hb_shape_plan_create_cached(
face.handle, face.handle,
&props.cast(), &props.cast(),
if (features) |f| f.ptr else null, if (features) |f| f.ptr else null,
if (features) |f| @intCast(c_uint, f.len) else 0, if (features) |f| @intCast(c_uint, f.len) else 0,
@ptrCast([*c]const [*c]const u8, shapers), shapers,
).? }; ).? };
} }
pub fn init2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: []const []const u8) ShapePlan { pub fn init2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: Shapers) ShapePlan {
return .{ .handle = hb_shape_plan_create2( return .{ .handle = hb_shape_plan_create2(
face.handle, face.handle,
&props.cast(), &props.cast(),
@ -37,11 +38,11 @@ pub const ShapePlan = struct {
if (features) |f| @intCast(c_uint, f.len) else 0, if (features) |f| @intCast(c_uint, f.len) else 0,
cords.ptr, cords.ptr,
@intCast(c_uint, cords.len), @intCast(c_uint, cords.len),
@ptrCast([*c]const [*c]const u8, shapers), shapers,
).? }; ).? };
} }
pub fn initCached2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: []const []const u8) ShapePlan { pub fn initCached2(face: Face, props: SegmentProps, features: ?[]const Feature, cords: []const i32, shapers: Shapers) ShapePlan {
return .{ .handle = hb_shape_plan_create_cached2( return .{ .handle = hb_shape_plan_create_cached2(
face.handle, face.handle,
&props.cast(), &props.cast(),
@ -49,7 +50,7 @@ pub const ShapePlan = struct {
if (features) |f| @intCast(c_uint, f.len) else 0, if (features) |f| @intCast(c_uint, f.len) else 0,
cords.ptr, cords.ptr,
@intCast(c_uint, cords.len), @intCast(c_uint, cords.len),
@ptrCast([*c]const [*c]const u8, shapers), shapers,
).? }; ).? };
} }