mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
Merge pull request #2583 from ghostty-org/push-qvypslzouwzx
font/harfbuzz: force LTR font shaping
This commit is contained in:
@ -14,6 +14,7 @@ pub const emoji = @embedFile("res/NotoColorEmoji.ttf");
|
||||
pub const emoji_text = @embedFile("res/NotoEmoji-Regular.ttf");
|
||||
|
||||
/// Fonts with general properties
|
||||
pub const arabic = @embedFile("res/KawkabMono-Regular.ttf");
|
||||
pub const variable = @embedFile("res/Lilex-VF.ttf");
|
||||
|
||||
/// Font with nerd fonts embedded.
|
||||
|
BIN
src/font/res/KawkabMono-Regular.ttf
Normal file
BIN
src/font/res/KawkabMono-Regular.ttf
Normal file
Binary file not shown.
@ -190,6 +190,11 @@ pub const Shaper = struct {
|
||||
// Reset the buffer for our current run
|
||||
self.shaper.hb_buf.reset();
|
||||
self.shaper.hb_buf.setContentType(.unicode);
|
||||
|
||||
// We don't support RTL text because RTL in terminals is messy.
|
||||
// Its something we want to improve. For now, we force LTR because
|
||||
// our renderers assume a strictly increasing X value.
|
||||
self.shaper.hb_buf.setDirection(.ltr);
|
||||
}
|
||||
|
||||
pub fn addCodepoint(self: RunIteratorHook, cp: u32, cluster: u32) !void {
|
||||
@ -453,6 +458,46 @@ test "shape monaspace ligs" {
|
||||
}
|
||||
}
|
||||
|
||||
// Ghostty doesn't currently support RTL and our renderers assume
|
||||
// that cells are in strict LTR order. This means that we need to
|
||||
// force RTL text to be LTR for rendering. This test ensures that
|
||||
// we are correctly forcing RTL text to be LTR.
|
||||
test "shape arabic forced LTR" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var testdata = try testShaperWithFont(alloc, .arabic);
|
||||
defer testdata.deinit();
|
||||
|
||||
var screen = try terminal.Screen.init(alloc, 120, 30, 0);
|
||||
defer screen.deinit();
|
||||
try screen.testWriteString(@embedFile("testdata/arabic.txt"));
|
||||
|
||||
var shaper = &testdata.shaper;
|
||||
var it = shaper.runIterator(
|
||||
testdata.grid,
|
||||
&screen,
|
||||
screen.pages.pin(.{ .screen = .{ .y = 0 } }).?,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
var count: usize = 0;
|
||||
while (try it.next(alloc)) |run| {
|
||||
count += 1;
|
||||
try testing.expectEqual(@as(usize, 25), run.cells);
|
||||
|
||||
const cells = try shaper.shape(run);
|
||||
try testing.expectEqual(@as(usize, 25), cells.len);
|
||||
|
||||
var x: u16 = cells[0].x;
|
||||
for (cells[1..]) |cell| {
|
||||
try testing.expectEqual(x + 1, cell.x);
|
||||
x = cell.x;
|
||||
}
|
||||
}
|
||||
try testing.expectEqual(@as(usize, 1), count);
|
||||
}
|
||||
|
||||
test "shape emoji width" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
@ -1146,6 +1191,7 @@ const TestShaper = struct {
|
||||
const TestFont = enum {
|
||||
inconsolata,
|
||||
monaspace_neon,
|
||||
arabic,
|
||||
};
|
||||
|
||||
/// Helper to return a fully initialized shaper.
|
||||
@ -1159,6 +1205,7 @@ fn testShaperWithFont(alloc: Allocator, font_req: TestFont) !TestShaper {
|
||||
const testFont = switch (font_req) {
|
||||
.inconsolata => font.embedded.inconsolata,
|
||||
.monaspace_neon => font.embedded.monaspace_neon,
|
||||
.arabic => font.embedded.arabic,
|
||||
};
|
||||
|
||||
var lib = try Library.init();
|
||||
|
3
src/font/shaper/testdata/arabic.txt
vendored
Normal file
3
src/font/shaper/testdata/arabic.txt
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
غريبه لاني عربي أبا عن جد
|
||||
واتكلم الانجليزية بطلاقة اكثر من ٢٥ سنه
|
||||
ومع هذا اجد العربيه افضل لان فيها الكثير من المفردات الاكثر دقه بالوصف
|
Reference in New Issue
Block a user