diff options
| author | Qwerasd <qwerasd205@users.noreply.github.com> | 2025-10-02 15:01:44 -0600 |
|---|---|---|
| committer | Qwerasd <qwerasd205@users.noreply.github.com> | 2025-10-02 15:32:21 -0600 |
| commit | efc6e0d6738d3ff070422db1512eb1b9f91b278f (patch) | |
| tree | 881e0432a420bf3c383c51876e09450434c5a693 /pkg | |
| parent | d6063428bd9b58ca377b576eb0638be72afaa933 (diff) | |
fix(font/coretext): always prevent shaper from emitting rtl
The solution we had before worked in most cases but there were some
which caused problems still. This is what HarfBuzz's CoreText shaper
backend does, it uses a CTTypesetter with the forced embedding level
attribute. This fixes the failure case I found that was causing non-
monotonic outputs which can have all sorts of unexpected results, and
causes a crash in Debug modes because we assert the monotonicity while
rendering.
Diffstat (limited to 'pkg')
| -rw-r--r-- | pkg/macos/text.zig | 2 | ||||
| -rw-r--r-- | pkg/macos/text/typesetter.zig | 36 |
2 files changed, 38 insertions, 0 deletions
diff --git a/pkg/macos/text.zig b/pkg/macos/text.zig index 0589f8692..bfaa388b3 100644 --- a/pkg/macos/text.zig +++ b/pkg/macos/text.zig @@ -4,6 +4,7 @@ const font_descriptor = @import("text/font_descriptor.zig"); const font_manager = @import("text/font_manager.zig"); const frame = @import("text/frame.zig"); const framesetter = @import("text/framesetter.zig"); +const typesetter = @import("text/typesetter.zig"); const line = @import("text/line.zig"); const paragraph_style = @import("text/paragraph_style.zig"); const run = @import("text/run.zig"); @@ -23,6 +24,7 @@ pub const createFontDescriptorsFromData = font_manager.createFontDescriptorsFrom pub const createFontDescriptorFromData = font_manager.createFontDescriptorFromData; pub const Frame = frame.Frame; pub const Framesetter = framesetter.Framesetter; +pub const Typesetter = typesetter.Typesetter; pub const Line = line.Line; pub const ParagraphStyle = paragraph_style.ParagraphStyle; pub const ParagraphStyleSetting = paragraph_style.ParagraphStyleSetting; diff --git a/pkg/macos/text/typesetter.zig b/pkg/macos/text/typesetter.zig new file mode 100644 index 000000000..dc07df980 --- /dev/null +++ b/pkg/macos/text/typesetter.zig @@ -0,0 +1,36 @@ +const std = @import("std"); +const assert = std.debug.assert; +const Allocator = std.mem.Allocator; +const foundation = @import("../foundation.zig"); +const graphics = @import("../graphics.zig"); +const text = @import("../text.zig"); +const c = @import("c.zig").c; + +pub const Typesetter = opaque { + pub fn createWithAttributedStringAndOptions( + str: *foundation.AttributedString, + opts: *foundation.Dictionary, + ) Allocator.Error!*Typesetter { + return @as( + ?*Typesetter, + @ptrFromInt(@intFromPtr(c.CTTypesetterCreateWithAttributedStringAndOptions( + @ptrCast(str), + @ptrCast(opts), + ))), + ) orelse Allocator.Error.OutOfMemory; + } + + pub fn release(self: *Typesetter) void { + foundation.CFRelease(self); + } + + pub fn createLine( + self: *Typesetter, + range: foundation.c.CFRange, + ) *text.Line { + return @ptrFromInt(@intFromPtr(c.CTTypesetterCreateLine( + @ptrCast(self), + range, + ))); + } +}; |
