Skip to content

Commit

Permalink
font/coretext: force LTR shaping
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed May 8, 2024
1 parent eeb7f7a commit 1cb70d6
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
9 changes: 6 additions & 3 deletions pkg/macos/text/paragraph_style.zig
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ pub const ParagraphStyleSpecifier = enum(c_uint) {
base_writing_direction = 13,
};

pub const WritingDirection = enum(i8) {
/// https://developer.apple.com/documentation/uikit/nswritingdirectionattributename?language=objc
pub const WritingDirection = enum(c_int) {
natural = -1,
left_to_right = 0,
right_to_left = 1,
ltr = 0,
rtl = 1,
lro = 2,
rlo = 3,
};

test ParagraphStyle {
Expand Down
2 changes: 2 additions & 0 deletions pkg/macos/text/stylized_strings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ const c = @import("c.zig");
pub const StringAttribute = enum {
font,
paragraph_style,
writing_direction,

pub fn key(self: StringAttribute) *foundation.String {
return @ptrFromInt(@intFromPtr(switch (self) {
.font => c.kCTFontAttributeName,
.paragraph_style => c.kCTParagraphStyleAttributeName,
.writing_direction => c.kCTWritingDirectionAttributeName,
}));
}
};
43 changes: 39 additions & 4 deletions src/font/shaper/coretext.zig
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ pub const Shaper = struct {
/// The shared memory used for shaping results.
cell_buf: CellBuf,

/// The cached writing direction value for shaping. This isn't
/// configurable we just use this as a cache to avoid creating
/// and releasing many objects when shaping.
writing_direction: *macos.foundation.Array,

const CellBuf = std.ArrayListUnmanaged(font.shape.Cell);
const CodepointList = std.ArrayListUnmanaged(Codepoint);
const Codepoint = struct {
Expand Down Expand Up @@ -172,21 +177,45 @@ pub const Shaper = struct {
for (hardcoded_features) |name| try feats.append(name);
for (opts.features) |name| try feats.append(name);

const run_state = try RunState.init();
errdefer run_state.deinit();
var run_state = try RunState.init();
errdefer run_state.deinit(alloc);

// For now we only support LTR text. If we shape RTL text then
// rendering will be very wrong so we need to explicitly force
// LTR no matter what.
//
// See: https://github.com/mitchellh/ghostty/issues/1737
// See: https://github.com/mitchellh/ghostty/issues/1442
const writing_direction = array: {
const dir: macos.text.WritingDirection = .lro;
const num = try macos.foundation.Number.create(
.int,
&@intFromEnum(dir),
);
defer num.release();

var arr_init = [_]*const macos.foundation.Number{num};
break :array try macos.foundation.Array.create(
macos.foundation.Number,
&arr_init,
);
};
errdefer writing_direction.release();

return Shaper{
.alloc = alloc,
.cell_buf = .{},
.run_state = run_state,
.features = feats,
.writing_direction = writing_direction,
};
}

pub fn deinit(self: *Shaper) void {
self.cell_buf.deinit(self.alloc);
self.run_state.deinit(self.alloc);
self.features.deinit();
self.writing_direction.release();
}

pub fn runIterator(
Expand Down Expand Up @@ -276,8 +305,14 @@ pub const Shaper = struct {
// Get our font and use that get the attributes to set for the
// attributed string so the whole string uses the same font.
const attr_dict = dict: {
var keys = [_]?*const anyopaque{macos.text.StringAttribute.font.key()};
var values = [_]?*const anyopaque{run_font};
var keys = [_]?*const anyopaque{
macos.text.StringAttribute.font.key(),
macos.text.StringAttribute.writing_direction.key(),
};
var values = [_]?*const anyopaque{
run_font,
self.writing_direction,
};
break :dict try macos.foundation.Dictionary.create(&keys, &values);
};
defer attr_dict.release();
Expand Down

0 comments on commit 1cb70d6

Please sign in to comment.