mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
WIP
This commit is contained in:
@ -41,6 +41,11 @@
|
|||||||
.hash = "ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf",
|
.hash = "ziglyph-0.11.2-AAAAAHPtHwB4Mbzn1KvOV7Wpjo82NYEc_v0WC8oCLrkf",
|
||||||
.lazy = true,
|
.lazy = true,
|
||||||
},
|
},
|
||||||
|
.zg = .{
|
||||||
|
.url = "https://codeberg.org/jacobsandlund/zg/archive/21be4c72f2aff537d7630a7aeb641befc935db89.tar.gz",
|
||||||
|
.hash = "zg-0.14.0-oGqU3IkvswJcetRSabEnsUe_jsWz48WkZebbVS-pJ5jB",
|
||||||
|
.lazy = true,
|
||||||
|
},
|
||||||
.zig_wayland = .{
|
.zig_wayland = .{
|
||||||
// codeberg ifreund/zig-wayland
|
// codeberg ifreund/zig-wayland
|
||||||
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
|
.url = "https://codeberg.org/ifreund/zig-wayland/archive/f3c5d503e540ada8cbcb056420de240af0c094f7.tar.gz",
|
||||||
|
@ -27,6 +27,8 @@ hyperfine \
|
|||||||
"./zig-out/bin/bench-grapheme-break --mode=noop${ARGS} </tmp/ghostty_bench_data" \
|
"./zig-out/bin/bench-grapheme-break --mode=noop${ARGS} </tmp/ghostty_bench_data" \
|
||||||
-n ziglyph \
|
-n ziglyph \
|
||||||
"./zig-out/bin/bench-grapheme-break --mode=ziglyph${ARGS} </tmp/ghostty_bench_data" \
|
"./zig-out/bin/bench-grapheme-break --mode=ziglyph${ARGS} </tmp/ghostty_bench_data" \
|
||||||
|
-n zg \
|
||||||
|
"./zig-out/bin/bench-grapheme-break --mode=zg${ARGS} </tmp/ghostty_bench_data" \
|
||||||
-n table \
|
-n table \
|
||||||
"./zig-out/bin/bench-grapheme-break --mode=table${ARGS} </tmp/ghostty_bench_data"
|
"./zig-out/bin/bench-grapheme-break --mode=table${ARGS} </tmp/ghostty_bench_data"
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ const assert = std.debug.assert;
|
|||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
const ziglyph = @import("ziglyph");
|
const ziglyph = @import("ziglyph");
|
||||||
|
const Graphemes = @import("Graphemes");
|
||||||
const cli = @import("../cli.zig");
|
const cli = @import("../cli.zig");
|
||||||
const simd = @import("../simd/main.zig");
|
const simd = @import("../simd/main.zig");
|
||||||
const unicode = @import("../unicode/main.zig");
|
const unicode = @import("../unicode/main.zig");
|
||||||
@ -44,6 +45,9 @@ const Mode = enum {
|
|||||||
/// Use ziglyph library to calculate the display width of each codepoint.
|
/// Use ziglyph library to calculate the display width of each codepoint.
|
||||||
ziglyph,
|
ziglyph,
|
||||||
|
|
||||||
|
/// Use zg library to calculate the display width of each codepoint.
|
||||||
|
zg,
|
||||||
|
|
||||||
/// Ghostty's table-based approach.
|
/// Ghostty's table-based approach.
|
||||||
table,
|
table,
|
||||||
};
|
};
|
||||||
@ -56,6 +60,10 @@ pub fn main() !void {
|
|||||||
// We want to use the c allocator because it is much faster than GPA.
|
// We want to use the c allocator because it is much faster than GPA.
|
||||||
const alloc = std.heap.c_allocator;
|
const alloc = std.heap.c_allocator;
|
||||||
|
|
||||||
|
// Initialize Graphemes for zg
|
||||||
|
const graphemes = try Graphemes.init(alloc);
|
||||||
|
graphemes.deinit(alloc);
|
||||||
|
|
||||||
// Parse our args
|
// Parse our args
|
||||||
var args: Args = .{};
|
var args: Args = .{};
|
||||||
defer args.deinit();
|
defer args.deinit();
|
||||||
@ -72,6 +80,7 @@ pub fn main() !void {
|
|||||||
switch (args.mode) {
|
switch (args.mode) {
|
||||||
.noop => try benchNoop(reader, buf),
|
.noop => try benchNoop(reader, buf),
|
||||||
.ziglyph => try benchZiglyph(reader, buf),
|
.ziglyph => try benchZiglyph(reader, buf),
|
||||||
|
.zg => try benchZg(&graphemes, reader, buf),
|
||||||
.table => try benchTable(reader, buf),
|
.table => try benchTable(reader, buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -118,6 +127,32 @@ noinline fn benchTable(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
noinline fn benchZg(
|
||||||
|
graphemes: *const Graphemes,
|
||||||
|
reader: anytype,
|
||||||
|
buf: []u8,
|
||||||
|
) !void {
|
||||||
|
var d: UTF8Decoder = .{};
|
||||||
|
var state: Graphemes.State = .{};
|
||||||
|
var cp1: u21 = 0;
|
||||||
|
while (true) {
|
||||||
|
const n = try reader.read(buf);
|
||||||
|
if (n == 0) break;
|
||||||
|
|
||||||
|
// Using stream.next directly with a for loop applies a naive
|
||||||
|
// scalar approach.
|
||||||
|
for (buf[0..n]) |c| {
|
||||||
|
const cp_, const consumed = d.next(c);
|
||||||
|
assert(consumed);
|
||||||
|
if (cp_) |cp2| {
|
||||||
|
const v = Graphemes.graphemeBreak(cp1, @intCast(cp2), graphemes, &state);
|
||||||
|
buf[0] = @intCast(@intFromBool(v));
|
||||||
|
cp1 = cp2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
noinline fn benchZiglyph(
|
noinline fn benchZiglyph(
|
||||||
reader: anytype,
|
reader: anytype,
|
||||||
buf: []u8,
|
buf: []u8,
|
||||||
|
@ -417,6 +417,18 @@ pub fn add(
|
|||||||
})) |dep| {
|
})) |dep| {
|
||||||
step.root_module.addImport("ziglyph", dep.module("ziglyph"));
|
step.root_module.addImport("ziglyph", dep.module("ziglyph"));
|
||||||
}
|
}
|
||||||
|
if (b.lazyDependency("zg", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
})) |dep| {
|
||||||
|
step.root_module.addImport("CaseFolding", dep.module("CaseFolding"));
|
||||||
|
// Only needed for table gen, but still include to have build succeeed
|
||||||
|
step.root_module.addImport("DisplayWidth", dep.module("DisplayWidth"));
|
||||||
|
step.root_module.addImport("Emoji", dep.module("Emoji"));
|
||||||
|
step.root_module.addImport("GeneralCategories", dep.module("GeneralCategories"));
|
||||||
|
step.root_module.addImport("Graphemes", dep.module("Graphemes"));
|
||||||
|
step.root_module.addImport("LetterCasing", dep.module("LetterCasing"));
|
||||||
|
}
|
||||||
if (b.lazyDependency("zf", .{
|
if (b.lazyDependency("zf", .{
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
|
@ -21,13 +21,11 @@ pub fn init(b: *std.Build) !UnicodeTables {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (b.lazyDependency("ziglyph", .{
|
if (b.lazyDependency("zg", .{
|
||||||
.target = b.graph.host,
|
.target = b.graph.host,
|
||||||
})) |ziglyph_dep| {
|
})) |dep| {
|
||||||
exe.root_module.addImport(
|
exe.root_module.addImport("Graphemes", dep.module("Graphemes"));
|
||||||
"ziglyph",
|
exe.root_module.addImport("DisplayWidth", dep.module("DisplayWidth"));
|
||||||
ziglyph_dep.module("ziglyph"),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const run = b.addRunArtifact(exe);
|
const run = b.addRunArtifact(exe);
|
||||||
|
@ -16,7 +16,6 @@ const build_config = @import("../build_config.zig");
|
|||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||||
const global_state = &@import("../global.zig").state;
|
|
||||||
const fontpkg = @import("../font/main.zig");
|
const fontpkg = @import("../font/main.zig");
|
||||||
const inputpkg = @import("../input.zig");
|
const inputpkg = @import("../input.zig");
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
@ -5765,6 +5764,8 @@ pub const Keybinds = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var set: Keybinds = .{};
|
var set: Keybinds = .{};
|
||||||
try set.parseCLI(alloc, "shift+a=copy_to_clipboard");
|
try set.parseCLI(alloc, "shift+a=copy_to_clipboard");
|
||||||
@ -5779,6 +5780,8 @@ pub const Keybinds = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: Keybinds = .{};
|
var list: Keybinds = .{};
|
||||||
try list.parseCLI(alloc, "shift+a=csi:hello");
|
try list.parseCLI(alloc, "shift+a=csi:hello");
|
||||||
@ -5795,6 +5798,8 @@ pub const Keybinds = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: Keybinds = .{};
|
var list: Keybinds = .{};
|
||||||
try list.parseCLI(alloc, "ctrl+z>1=goto_tab:1");
|
try list.parseCLI(alloc, "ctrl+z>1=goto_tab:1");
|
||||||
@ -5819,6 +5824,8 @@ pub const Keybinds = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: Keybinds = .{};
|
var list: Keybinds = .{};
|
||||||
try list.parseCLI(alloc, "ctrl+a>ctrl+b>n=new_window");
|
try list.parseCLI(alloc, "ctrl+a>ctrl+b>n=new_window");
|
||||||
@ -6030,6 +6037,8 @@ pub const RepeatableCodepointMap = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: Self = .{};
|
var list: Self = .{};
|
||||||
try list.parseCLI(alloc, "U+ABCD=Comic Sans");
|
try list.parseCLI(alloc, "U+ABCD=Comic Sans");
|
||||||
@ -6067,6 +6076,8 @@ pub const RepeatableCodepointMap = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: Self = .{};
|
var list: Self = .{};
|
||||||
try list.parseCLI(alloc, "U+ABCD=Comic Sans");
|
try list.parseCLI(alloc, "U+ABCD=Comic Sans");
|
||||||
@ -6082,6 +6093,8 @@ pub const RepeatableCodepointMap = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: Self = .{};
|
var list: Self = .{};
|
||||||
try list.parseCLI(alloc, "U+0001 - U+0005=Verdana");
|
try list.parseCLI(alloc, "U+0001 - U+0005=Verdana");
|
||||||
@ -6097,6 +6110,8 @@ pub const RepeatableCodepointMap = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: Self = .{};
|
var list: Self = .{};
|
||||||
try list.parseCLI(alloc, "U+0006-U+0009, U+ABCD=Courier");
|
try list.parseCLI(alloc, "U+0006-U+0009, U+ABCD=Courier");
|
||||||
@ -6175,6 +6190,8 @@ pub const FontStyle = union(enum) {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var p: Self = .{ .default = {} };
|
var p: Self = .{ .default = {} };
|
||||||
try p.parseCLI(alloc, "default");
|
try p.parseCLI(alloc, "default");
|
||||||
@ -6195,6 +6212,8 @@ pub const FontStyle = union(enum) {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var p: Self = .{ .default = {} };
|
var p: Self = .{ .default = {} };
|
||||||
try p.parseCLI(alloc, "default");
|
try p.parseCLI(alloc, "default");
|
||||||
@ -6210,6 +6229,8 @@ pub const FontStyle = union(enum) {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var p: Self = .{ .default = {} };
|
var p: Self = .{ .default = {} };
|
||||||
try p.parseCLI(alloc, "false");
|
try p.parseCLI(alloc, "false");
|
||||||
@ -6225,6 +6246,8 @@ pub const FontStyle = union(enum) {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var p: Self = .{ .default = {} };
|
var p: Self = .{ .default = {} };
|
||||||
try p.parseCLI(alloc, "bold");
|
try p.parseCLI(alloc, "bold");
|
||||||
@ -6402,6 +6425,8 @@ pub const RepeatableCommand = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: RepeatableCommand = .{};
|
var list: RepeatableCommand = .{};
|
||||||
try list.parseCLI(alloc, "title:Foo,action:ignore");
|
try list.parseCLI(alloc, "title:Foo,action:ignore");
|
||||||
@ -6447,6 +6472,8 @@ pub const RepeatableCommand = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: RepeatableCommand = .{};
|
var list: RepeatableCommand = .{};
|
||||||
try list.parseCLI(alloc, "title:Bobr, action:text:Bober");
|
try list.parseCLI(alloc, "title:Bobr, action:text:Bober");
|
||||||
@ -6462,6 +6489,8 @@ pub const RepeatableCommand = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var list: RepeatableCommand = .{};
|
var list: RepeatableCommand = .{};
|
||||||
try list.parseCLI(alloc, "title:Bobr, action:text:kurwa");
|
try list.parseCLI(alloc, "title:Bobr, action:text:kurwa");
|
||||||
@ -7180,6 +7209,8 @@ pub const Theme = struct {
|
|||||||
var arena = ArenaAllocator.init(testing.allocator);
|
var arena = ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
// Single
|
// Single
|
||||||
{
|
{
|
||||||
@ -7597,6 +7628,8 @@ const TestIterator = struct {
|
|||||||
|
|
||||||
test "parse hook: invalid command" {
|
test "parse hook: invalid command" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(testing.allocator);
|
var cfg = try Config.default(testing.allocator);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
const alloc = cfg._arena.?.allocator();
|
const alloc = cfg._arena.?.allocator();
|
||||||
@ -7608,6 +7641,8 @@ test "parse hook: invalid command" {
|
|||||||
|
|
||||||
test "parse e: command only" {
|
test "parse e: command only" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(testing.allocator);
|
var cfg = try Config.default(testing.allocator);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
const alloc = cfg._arena.?.allocator();
|
const alloc = cfg._arena.?.allocator();
|
||||||
@ -7623,6 +7658,8 @@ test "parse e: command only" {
|
|||||||
|
|
||||||
test "parse e: command and args" {
|
test "parse e: command and args" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(testing.allocator);
|
var cfg = try Config.default(testing.allocator);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
const alloc = cfg._arena.?.allocator();
|
const alloc = cfg._arena.?.allocator();
|
||||||
@ -7641,6 +7678,8 @@ test "parse e: command and args" {
|
|||||||
test "clone default" {
|
test "clone default" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var source = try Config.default(alloc);
|
var source = try Config.default(alloc);
|
||||||
defer source.deinit();
|
defer source.deinit();
|
||||||
@ -7658,6 +7697,8 @@ test "clone default" {
|
|||||||
test "clone preserves conditional state" {
|
test "clone preserves conditional state" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var a = try Config.default(alloc);
|
var a = try Config.default(alloc);
|
||||||
defer a.deinit();
|
defer a.deinit();
|
||||||
@ -7686,6 +7727,8 @@ test "clone can then change conditional state" {
|
|||||||
var arena = ArenaAllocator.init(alloc);
|
var arena = ArenaAllocator.init(alloc);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc_arena = arena.allocator();
|
const alloc_arena = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
// Setup our test theme
|
// Setup our test theme
|
||||||
var td = try internal_os.TempDir.init();
|
var td = try internal_os.TempDir.init();
|
||||||
@ -7746,6 +7789,8 @@ test "clone can then change conditional state" {
|
|||||||
test "clone preserves conditional set" {
|
test "clone preserves conditional set" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
@ -7765,6 +7810,8 @@ test "clone preserves conditional set" {
|
|||||||
test "changed" {
|
test "changed" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var source = try Config.default(alloc);
|
var source = try Config.default(alloc);
|
||||||
defer source.deinit();
|
defer source.deinit();
|
||||||
@ -7779,6 +7826,8 @@ test "changed" {
|
|||||||
test "changeConditionalState ignores irrelevant changes" {
|
test "changeConditionalState ignores irrelevant changes" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
{
|
{
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
@ -7798,6 +7847,8 @@ test "changeConditionalState ignores irrelevant changes" {
|
|||||||
test "changeConditionalState applies relevant changes" {
|
test "changeConditionalState applies relevant changes" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
{
|
{
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
@ -7820,6 +7871,8 @@ test "theme loading" {
|
|||||||
var arena = ArenaAllocator.init(alloc);
|
var arena = ArenaAllocator.init(alloc);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc_arena = arena.allocator();
|
const alloc_arena = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
// Setup our test theme
|
// Setup our test theme
|
||||||
var td = try internal_os.TempDir.init();
|
var td = try internal_os.TempDir.init();
|
||||||
@ -7856,6 +7909,8 @@ test "theme loading preserves conditional state" {
|
|||||||
var arena = ArenaAllocator.init(alloc);
|
var arena = ArenaAllocator.init(alloc);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc_arena = arena.allocator();
|
const alloc_arena = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
// Setup our test theme
|
// Setup our test theme
|
||||||
var td = try internal_os.TempDir.init();
|
var td = try internal_os.TempDir.init();
|
||||||
@ -7886,6 +7941,8 @@ test "theme priority is lower than config" {
|
|||||||
var arena = ArenaAllocator.init(alloc);
|
var arena = ArenaAllocator.init(alloc);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc_arena = arena.allocator();
|
const alloc_arena = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
// Setup our test theme
|
// Setup our test theme
|
||||||
var td = try internal_os.TempDir.init();
|
var td = try internal_os.TempDir.init();
|
||||||
@ -7920,6 +7977,8 @@ test "theme loading correct light/dark" {
|
|||||||
var arena = ArenaAllocator.init(alloc);
|
var arena = ArenaAllocator.init(alloc);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc_arena = arena.allocator();
|
const alloc_arena = arena.allocator();
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
// Setup our test theme
|
// Setup our test theme
|
||||||
var td = try internal_os.TempDir.init();
|
var td = try internal_os.TempDir.init();
|
||||||
@ -8009,6 +8068,8 @@ test "theme loading correct light/dark" {
|
|||||||
test "theme specifying light/dark changes window-theme from auto" {
|
test "theme specifying light/dark changes window-theme from auto" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
{
|
{
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
@ -8027,6 +8088,8 @@ test "theme specifying light/dark changes window-theme from auto" {
|
|||||||
test "theme specifying light/dark sets theme usage in conditional state" {
|
test "theme specifying light/dark sets theme usage in conditional state" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
{
|
{
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
|
@ -121,6 +121,8 @@ fn fieldByKey(self: *const Config, comptime k: Key) Value(k) {
|
|||||||
test "c_get: u8" {
|
test "c_get: u8" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var c = try Config.default(alloc);
|
var c = try Config.default(alloc);
|
||||||
defer c.deinit();
|
defer c.deinit();
|
||||||
@ -134,6 +136,8 @@ test "c_get: u8" {
|
|||||||
test "c_get: enum" {
|
test "c_get: enum" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var c = try Config.default(alloc);
|
var c = try Config.default(alloc);
|
||||||
defer c.deinit();
|
defer c.deinit();
|
||||||
@ -149,6 +153,8 @@ test "c_get: enum" {
|
|||||||
test "c_get: color" {
|
test "c_get: color" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var c = try Config.default(alloc);
|
var c = try Config.default(alloc);
|
||||||
defer c.deinit();
|
defer c.deinit();
|
||||||
@ -164,6 +170,8 @@ test "c_get: color" {
|
|||||||
test "c_get: optional" {
|
test "c_get: optional" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var c = try Config.default(alloc);
|
var c = try Config.default(alloc);
|
||||||
defer c.deinit();
|
defer c.deinit();
|
||||||
@ -187,6 +195,8 @@ test "c_get: optional" {
|
|||||||
test "c_get: background-blur" {
|
test "c_get: background-blur" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var c = try Config.default(alloc);
|
var c = try Config.default(alloc);
|
||||||
defer c.deinit();
|
defer c.deinit();
|
||||||
|
@ -193,6 +193,8 @@ pub const FileFormatter = struct {
|
|||||||
test "format default config" {
|
test "format default config" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
|
|
||||||
@ -212,6 +214,8 @@ test "format default config" {
|
|||||||
test "format default config changed" {
|
test "format default config changed" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
cfg.@"font-size" = 42;
|
cfg.@"font-size" = 42;
|
||||||
|
@ -13,8 +13,9 @@ const CodepointResolver = @This();
|
|||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ziglyph = @import("ziglyph");
|
const Emoji = @import("Emoji");
|
||||||
const font = @import("main.zig");
|
const font = @import("main.zig");
|
||||||
|
const zg = &@import("../global.zig").state.zg;
|
||||||
const Atlas = font.Atlas;
|
const Atlas = font.Atlas;
|
||||||
const CodepointMap = font.CodepointMap;
|
const CodepointMap = font.CodepointMap;
|
||||||
const Collection = font.Collection;
|
const Collection = font.Collection;
|
||||||
@ -150,7 +151,7 @@ pub fn getIndex(
|
|||||||
// we'll do this multiple times if we recurse, but this is a cached function
|
// we'll do this multiple times if we recurse, but this is a cached function
|
||||||
// call higher up (GroupCache) so this should be rare.
|
// call higher up (GroupCache) so this should be rare.
|
||||||
const p_mode: Collection.PresentationMode = if (p) |v| .{ .explicit = v } else .{
|
const p_mode: Collection.PresentationMode = if (p) |v| .{ .explicit = v } else .{
|
||||||
.default = if (ziglyph.emoji.isEmojiPresentation(@intCast(cp)))
|
.default = if (Emoji.isEmojiPresentation(zg.emoji, @intCast(cp)))
|
||||||
.emoji
|
.emoji
|
||||||
else
|
else
|
||||||
.text,
|
.text,
|
||||||
@ -379,6 +380,8 @@ test getIndex {
|
|||||||
const testFont = font.embedded.regular;
|
const testFont = font.embedded.regular;
|
||||||
const testEmoji = font.embedded.emoji;
|
const testEmoji = font.embedded.emoji;
|
||||||
const testEmojiText = font.embedded.emoji_text;
|
const testEmojiText = font.embedded.emoji_text;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var lib = try Library.init(alloc);
|
var lib = try Library.init(alloc);
|
||||||
defer lib.deinit();
|
defer lib.deinit();
|
||||||
@ -457,6 +460,8 @@ test "getIndex disabled font style" {
|
|||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
const testFont = font.embedded.regular;
|
const testFont = font.embedded.regular;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var atlas_grayscale = try font.Atlas.init(alloc, 512, .grayscale);
|
var atlas_grayscale = try font.Atlas.init(alloc, 512, .grayscale);
|
||||||
defer atlas_grayscale.deinit(alloc);
|
defer atlas_grayscale.deinit(alloc);
|
||||||
@ -512,6 +517,8 @@ test "getIndex disabled font style" {
|
|||||||
test "getIndex box glyph" {
|
test "getIndex box glyph" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var lib = try Library.init(alloc);
|
var lib = try Library.init(alloc);
|
||||||
defer lib.deinit();
|
defer lib.deinit();
|
||||||
|
@ -369,6 +369,8 @@ fn testGrid(mode: TestMode, alloc: Allocator, lib: Library) !SharedGrid {
|
|||||||
test getIndex {
|
test getIndex {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
// const testEmoji = @import("test.zig").fontEmoji;
|
// const testEmoji = @import("test.zig").fontEmoji;
|
||||||
|
|
||||||
var lib = try Library.init(alloc);
|
var lib = try Library.init(alloc);
|
||||||
|
@ -694,6 +694,8 @@ pub const Key = struct {
|
|||||||
test "Key" {
|
test "Key" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
|
|
||||||
@ -713,6 +715,8 @@ test "Key" {
|
|||||||
test "Key different font points" {
|
test "Key different font points" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
|
|
||||||
@ -731,6 +735,8 @@ test "Key different font points" {
|
|||||||
test "Key different font DPI" {
|
test "Key different font DPI" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
var cfg = try Config.default(alloc);
|
var cfg = try Config.default(alloc);
|
||||||
defer cfg.deinit();
|
defer cfg.deinit();
|
||||||
|
|
||||||
@ -749,6 +755,8 @@ test "Key different font DPI" {
|
|||||||
test SharedGridSet {
|
test SharedGridSet {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var set = try SharedGridSet.init(alloc);
|
var set = try SharedGridSet.init(alloc);
|
||||||
defer set.deinit();
|
defer set.deinit();
|
||||||
|
@ -576,6 +576,8 @@ pub const Shaper = struct {
|
|||||||
test "run iterator" {
|
test "run iterator" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -656,6 +658,8 @@ test "run iterator" {
|
|||||||
test "run iterator: empty cells with background set" {
|
test "run iterator: empty cells with background set" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -704,6 +708,8 @@ test "run iterator: empty cells with background set" {
|
|||||||
test "shape" {
|
test "shape" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -737,6 +743,8 @@ test "shape" {
|
|||||||
test "shape nerd fonts" {
|
test "shape nerd fonts" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaperWithFont(alloc, .nerd_font);
|
var testdata = try testShaperWithFont(alloc, .nerd_font);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -770,6 +778,8 @@ test "shape nerd fonts" {
|
|||||||
test "shape inconsolata ligs" {
|
test "shape inconsolata ligs" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -824,6 +834,8 @@ test "shape inconsolata ligs" {
|
|||||||
test "shape monaspace ligs" {
|
test "shape monaspace ligs" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaperWithFont(alloc, .monaspace_neon);
|
var testdata = try testShaperWithFont(alloc, .monaspace_neon);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -856,6 +868,8 @@ test "shape monaspace ligs" {
|
|||||||
test "shape left-replaced lig in last run" {
|
test "shape left-replaced lig in last run" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaperWithFont(alloc, .geist_mono);
|
var testdata = try testShaperWithFont(alloc, .geist_mono);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -888,6 +902,8 @@ test "shape left-replaced lig in last run" {
|
|||||||
test "shape left-replaced lig in early run" {
|
test "shape left-replaced lig in early run" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaperWithFont(alloc, .geist_mono);
|
var testdata = try testShaperWithFont(alloc, .geist_mono);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -917,6 +933,8 @@ test "shape left-replaced lig in early run" {
|
|||||||
test "shape U+3C9 with JB Mono" {
|
test "shape U+3C9 with JB Mono" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaperWithFont(alloc, .jetbrains_mono);
|
var testdata = try testShaperWithFont(alloc, .jetbrains_mono);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -948,6 +966,8 @@ test "shape U+3C9 with JB Mono" {
|
|||||||
test "shape emoji width" {
|
test "shape emoji width" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -977,6 +997,8 @@ test "shape emoji width" {
|
|||||||
test "shape emoji width long" {
|
test "shape emoji width long" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1024,6 +1046,8 @@ test "shape emoji width long" {
|
|||||||
test "shape variation selector VS15" {
|
test "shape variation selector VS15" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1057,6 +1081,8 @@ test "shape variation selector VS15" {
|
|||||||
test "shape variation selector VS16" {
|
test "shape variation selector VS16" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1090,6 +1116,8 @@ test "shape variation selector VS16" {
|
|||||||
test "shape with empty cells in between" {
|
test "shape with empty cells in between" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1121,6 +1149,8 @@ test "shape with empty cells in between" {
|
|||||||
test "shape Chinese characters" {
|
test "shape Chinese characters" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1161,6 +1191,8 @@ test "shape Chinese characters" {
|
|||||||
test "shape box glyphs" {
|
test "shape box glyphs" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1198,6 +1230,8 @@ test "shape box glyphs" {
|
|||||||
test "shape selection boundary" {
|
test "shape selection boundary" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1321,6 +1355,8 @@ test "shape selection boundary" {
|
|||||||
test "shape cursor boundary" {
|
test "shape cursor boundary" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1458,6 +1494,8 @@ test "shape cursor boundary" {
|
|||||||
test "shape cursor boundary and colored emoji" {
|
test "shape cursor boundary and colored emoji" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1552,6 +1590,8 @@ test "shape cursor boundary and colored emoji" {
|
|||||||
test "shape cell attribute change" {
|
test "shape cell attribute change" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
@ -1680,6 +1720,8 @@ test "shape high plane sprite font codepoint" {
|
|||||||
|
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var testdata = try testShaper(alloc);
|
var testdata = try testShaper(alloc);
|
||||||
defer testdata.deinit();
|
defer testdata.deinit();
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const ziglyph = @import("ziglyph");
|
const Graphemes = @import("Graphemes");
|
||||||
const font = @import("../main.zig");
|
const font = @import("../main.zig");
|
||||||
const terminal = @import("../../terminal/main.zig");
|
const terminal = @import("../../terminal/main.zig");
|
||||||
|
const zg = &@import("../../global.zig").state.zg;
|
||||||
|
|
||||||
const log = std.log.scoped(.font_shaper);
|
const log = std.log.scoped(.font_shaper);
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ pub const Shaper = struct {
|
|||||||
// font ligatures. However, we do support grapheme clustering.
|
// font ligatures. However, we do support grapheme clustering.
|
||||||
// This means we can render things like skin tone emoji but
|
// This means we can render things like skin tone emoji but
|
||||||
// we can't render things like single glyph "=>".
|
// we can't render things like single glyph "=>".
|
||||||
var break_state: u3 = 0;
|
var break_state: Graphemes.State = .{};
|
||||||
var cp1: u21 = @intCast(codepoints[0]);
|
var cp1: u21 = @intCast(codepoints[0]);
|
||||||
|
|
||||||
var start: usize = 0;
|
var start: usize = 0;
|
||||||
@ -126,9 +127,10 @@ pub const Shaper = struct {
|
|||||||
const cp2: u21 = @intCast(codepoints[i]);
|
const cp2: u21 = @intCast(codepoints[i]);
|
||||||
defer cp1 = cp2;
|
defer cp1 = cp2;
|
||||||
|
|
||||||
break :blk ziglyph.graphemeBreak(
|
break :blk Graphemes.graphemeBreak(
|
||||||
cp1,
|
cp1,
|
||||||
cp2,
|
cp2,
|
||||||
|
zg.graphemes,
|
||||||
&break_state,
|
&break_state,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -10,6 +10,12 @@ const oni = @import("oniguruma");
|
|||||||
const crash = @import("crash/main.zig");
|
const crash = @import("crash/main.zig");
|
||||||
const renderer = @import("renderer.zig");
|
const renderer = @import("renderer.zig");
|
||||||
const apprt = @import("apprt.zig");
|
const apprt = @import("apprt.zig");
|
||||||
|
const CaseFolding = @import("CaseFolding");
|
||||||
|
const Emoji = @import("Emoji");
|
||||||
|
const GeneralCategories = @import("GeneralCategories");
|
||||||
|
const Graphemes = @import("Graphemes");
|
||||||
|
const LetterCasing = @import("LetterCasing");
|
||||||
|
const unicode = @import("unicode/main.zig");
|
||||||
|
|
||||||
/// We export the xev backend we want to use so that the rest of
|
/// We export the xev backend we want to use so that the rest of
|
||||||
/// Ghostty can import this once and have access to the proper
|
/// Ghostty can import this once and have access to the proper
|
||||||
@ -33,6 +39,7 @@ pub const GlobalState = struct {
|
|||||||
action: ?cli.Action,
|
action: ?cli.Action,
|
||||||
logging: Logging,
|
logging: Logging,
|
||||||
rlimits: ResourceLimits = .{},
|
rlimits: ResourceLimits = .{},
|
||||||
|
zg: Zg,
|
||||||
|
|
||||||
/// The app resources directory, equivalent to zig-out/share when we build
|
/// The app resources directory, equivalent to zig-out/share when we build
|
||||||
/// from source. This is null if we can't detect it.
|
/// from source. This is null if we can't detect it.
|
||||||
@ -64,6 +71,7 @@ pub const GlobalState = struct {
|
|||||||
.logging = .{ .stderr = {} },
|
.logging = .{ .stderr = {} },
|
||||||
.rlimits = .{},
|
.rlimits = .{},
|
||||||
.resources_dir = .{},
|
.resources_dir = .{},
|
||||||
|
.zg = undefined,
|
||||||
};
|
};
|
||||||
errdefer self.deinit();
|
errdefer self.deinit();
|
||||||
|
|
||||||
@ -150,6 +158,8 @@ pub const GlobalState = struct {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.zg = try Zg.init(self.alloc);
|
||||||
|
|
||||||
// const sentrylib = @import("sentry");
|
// const sentrylib = @import("sentry");
|
||||||
// if (sentrylib.captureEvent(sentrylib.Value.initMessageEvent(
|
// if (sentrylib.captureEvent(sentrylib.Value.initMessageEvent(
|
||||||
// .info,
|
// .info,
|
||||||
@ -188,6 +198,8 @@ pub const GlobalState = struct {
|
|||||||
// Flush our crash logs
|
// Flush our crash logs
|
||||||
crash.deinit();
|
crash.deinit();
|
||||||
|
|
||||||
|
self.zg.deinit(self.alloc);
|
||||||
|
|
||||||
if (self.gpa) |*value| {
|
if (self.gpa) |*value| {
|
||||||
// We want to ensure that we deinit the GPA because this is
|
// We want to ensure that we deinit the GPA because this is
|
||||||
// the point at which it will output if there were safety violations.
|
// the point at which it will output if there were safety violations.
|
||||||
@ -216,6 +228,42 @@ pub const GlobalState = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const Zg = struct {
|
||||||
|
case_folding: CaseFolding,
|
||||||
|
emoji: Emoji,
|
||||||
|
general_categories: GeneralCategories,
|
||||||
|
graphemes: Graphemes,
|
||||||
|
letter_casing: LetterCasing,
|
||||||
|
|
||||||
|
pub fn init(alloc: std.mem.Allocator) !Zg {
|
||||||
|
return .{
|
||||||
|
.case_folding = try CaseFolding.init(alloc),
|
||||||
|
.emoji = try Emoji.init(alloc),
|
||||||
|
.general_categories = try GeneralCategories.init(alloc),
|
||||||
|
.graphemes = try Graphemes.init(alloc),
|
||||||
|
.letter_casing = try LetterCasing.init(alloc),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Zg, alloc: std.mem.Allocator) void {
|
||||||
|
self.case_folding.deinit(alloc);
|
||||||
|
self.emoji.deinit(alloc);
|
||||||
|
self.general_categories.deinit(alloc);
|
||||||
|
self.graphemes.deinit(alloc);
|
||||||
|
self.letter_casing.deinit(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initForTesting() !*Zg {
|
||||||
|
const zg = &state.zg;
|
||||||
|
zg.* = try Zg.init(std.testing.allocator);
|
||||||
|
return zg;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinitForTesting(self: *Zg) void {
|
||||||
|
self.deinit(std.testing.allocator);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// Maintains the Unix resource limits that we set for our process. This
|
/// Maintains the Unix resource limits that we set for our process. This
|
||||||
/// can be used to restore the limits to their original values.
|
/// can be used to restore the limits to their original values.
|
||||||
pub const ResourceLimits = struct {
|
pub const ResourceLimits = struct {
|
||||||
|
@ -5,9 +5,11 @@ const Binding = @This();
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const ziglyph = @import("ziglyph");
|
const LetterCasing = @import("LetterCasing");
|
||||||
|
const CaseFolding = @import("CaseFolding");
|
||||||
const key = @import("key.zig");
|
const key = @import("key.zig");
|
||||||
const KeyEvent = key.KeyEvent;
|
const KeyEvent = key.KeyEvent;
|
||||||
|
const zg = &@import("../global.zig").state.zg;
|
||||||
|
|
||||||
/// The trigger that needs to be performed to execute the action.
|
/// The trigger that needs to be performed to execute the action.
|
||||||
trigger: Trigger,
|
trigger: Trigger,
|
||||||
@ -1551,15 +1553,17 @@ pub const Trigger = struct {
|
|||||||
/// in more codepoints so we need to use a 3 element array.
|
/// in more codepoints so we need to use a 3 element array.
|
||||||
fn foldedCodepoint(cp: u21) [3]u21 {
|
fn foldedCodepoint(cp: u21) [3]u21 {
|
||||||
// ASCII fast path
|
// ASCII fast path
|
||||||
if (ziglyph.letter.isAsciiLetter(cp)) {
|
if (('A' <= cp and cp <= 'Z') or ('a' <= cp and cp <= 'z')) {
|
||||||
return .{ ziglyph.letter.toLower(cp), 0, 0 };
|
return .{ LetterCasing.toLower(zg.letter_casing, cp), 0, 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unicode slow path. Case folding can resultin more codepoints.
|
// Unicode slow path. Case folding can result in more codepoints.
|
||||||
// If more codepoints are produced then we return the codepoint
|
// If more codepoints are produced then we return the codepoint
|
||||||
// as-is which isn't correct but until we have a failing test
|
// as-is which isn't correct but until we have a failing test
|
||||||
// then I don't want to handle this.
|
// then I don't want to handle this.
|
||||||
return ziglyph.letter.toCaseFold(cp);
|
var buf: [3]u21 = .{ 0, 0, 0 };
|
||||||
|
_ = CaseFolding.caseFold(&zg.case_folding, cp, &buf);
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert the trigger to a C API compatible trigger.
|
/// Convert the trigger to a C API compatible trigger.
|
||||||
@ -2612,6 +2616,8 @@ test "parse: sequences" {
|
|||||||
test "set: parseAndPut typical binding" {
|
test "set: parseAndPut typical binding" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2635,6 +2641,8 @@ test "set: parseAndPut typical binding" {
|
|||||||
test "set: parseAndPut unconsumed binding" {
|
test "set: parseAndPut unconsumed binding" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2659,6 +2667,8 @@ test "set: parseAndPut unconsumed binding" {
|
|||||||
test "set: parseAndPut removed binding" {
|
test "set: parseAndPut removed binding" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2677,6 +2687,8 @@ test "set: parseAndPut removed binding" {
|
|||||||
test "set: parseAndPut sequence" {
|
test "set: parseAndPut sequence" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2701,6 +2713,8 @@ test "set: parseAndPut sequence" {
|
|||||||
test "set: parseAndPut sequence with two actions" {
|
test "set: parseAndPut sequence with two actions" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2733,6 +2747,8 @@ test "set: parseAndPut sequence with two actions" {
|
|||||||
test "set: parseAndPut overwrite sequence" {
|
test "set: parseAndPut overwrite sequence" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2758,6 +2774,8 @@ test "set: parseAndPut overwrite sequence" {
|
|||||||
test "set: parseAndPut overwrite leader" {
|
test "set: parseAndPut overwrite leader" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2783,6 +2801,8 @@ test "set: parseAndPut overwrite leader" {
|
|||||||
test "set: parseAndPut unbind sequence unbinds leader" {
|
test "set: parseAndPut unbind sequence unbinds leader" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2799,6 +2819,8 @@ test "set: parseAndPut unbind sequence unbinds leader" {
|
|||||||
test "set: parseAndPut unbind sequence unbinds leader if not set" {
|
test "set: parseAndPut unbind sequence unbinds leader if not set" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2814,6 +2836,8 @@ test "set: parseAndPut unbind sequence unbinds leader if not set" {
|
|||||||
test "set: parseAndPut sequence preserves reverse mapping" {
|
test "set: parseAndPut sequence preserves reverse mapping" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2831,6 +2855,8 @@ test "set: parseAndPut sequence preserves reverse mapping" {
|
|||||||
test "set: put overwrites sequence" {
|
test "set: put overwrites sequence" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2851,6 +2877,8 @@ test "set: put overwrites sequence" {
|
|||||||
test "set: maintains reverse mapping" {
|
test "set: maintains reverse mapping" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2879,6 +2907,8 @@ test "set: maintains reverse mapping" {
|
|||||||
test "set: performable is not part of reverse mappings" {
|
test "set: performable is not part of reverse mappings" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2912,6 +2942,8 @@ test "set: performable is not part of reverse mappings" {
|
|||||||
test "set: overriding a mapping updates reverse" {
|
test "set: overriding a mapping updates reverse" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2933,6 +2965,8 @@ test "set: overriding a mapping updates reverse" {
|
|||||||
test "set: consumed state" {
|
test "set: consumed state" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2958,6 +2992,8 @@ test "set: consumed state" {
|
|||||||
test "set: getEvent physical" {
|
test "set: getEvent physical" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -2988,6 +3024,8 @@ test "set: getEvent physical" {
|
|||||||
test "set: getEvent codepoint" {
|
test "set: getEvent codepoint" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -3028,6 +3066,8 @@ test "set: getEvent codepoint" {
|
|||||||
test "set: getEvent codepoint case folding" {
|
test "set: getEvent codepoint case folding" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
var s: Set = .{};
|
var s: Set = .{};
|
||||||
defer s.deinit(alloc);
|
defer s.deinit(alloc);
|
||||||
@ -3070,6 +3110,8 @@ test "Action: clone" {
|
|||||||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const alloc = arena.allocator();
|
const alloc = arena.allocator();
|
||||||
|
_ = try @import("../global.zig").Zg.initForTesting();
|
||||||
|
defer zg.deinitForTesting();
|
||||||
|
|
||||||
{
|
{
|
||||||
var a: Action = .ignore;
|
var a: Action = .ignore;
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const ziglyph = @import("ziglyph");
|
|
||||||
const font = @import("../font/main.zig");
|
const font = @import("../font/main.zig");
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
const renderer = @import("../renderer.zig");
|
const renderer = @import("../renderer.zig");
|
||||||
const shaderpkg = renderer.Renderer.API.shaders;
|
const shaderpkg = renderer.Renderer.API.shaders;
|
||||||
const ArrayListCollection = @import("../datastruct/array_list_collection.zig").ArrayListCollection;
|
const ArrayListCollection = @import("../datastruct/array_list_collection.zig").ArrayListCollection;
|
||||||
|
const GeneralCategories = @import("GeneralCategories");
|
||||||
|
const zg = &@import("../global.zig").state.zg;
|
||||||
|
|
||||||
/// The possible cell content keys that exist.
|
/// The possible cell content keys that exist.
|
||||||
pub const Key = enum {
|
pub const Key = enum {
|
||||||
@ -246,8 +247,10 @@ pub fn fgMode(
|
|||||||
const cell = cell_pin.rowAndCell().cell;
|
const cell = cell_pin.rowAndCell().cell;
|
||||||
const cp = cell.codepoint();
|
const cp = cell.codepoint();
|
||||||
|
|
||||||
if (!ziglyph.general_category.isPrivateUse(cp) and
|
// If it's not Private Use (Co) or Dingbats (0x2700-0x27bf), use
|
||||||
!ziglyph.blocks.isDingbats(cp))
|
// normal mode.
|
||||||
|
if (GeneralCategories.gc(zg.general_categories, cp) != .Co and
|
||||||
|
!(cp >= 0x2700 and cp <= 0x27bf))
|
||||||
{
|
{
|
||||||
break :text .normal;
|
break :text .normal;
|
||||||
}
|
}
|
||||||
@ -278,7 +281,8 @@ pub fn fgMode(
|
|||||||
// Powerline is whitespace
|
// Powerline is whitespace
|
||||||
if (isPowerline(prev_cp)) break :prev;
|
if (isPowerline(prev_cp)) break :prev;
|
||||||
|
|
||||||
if (ziglyph.general_category.isPrivateUse(prev_cp)) {
|
// If it's Private Use (Co), then we use constrained mode.
|
||||||
|
if (GeneralCategories.gc(zg.general_categories, cp) == .Co) {
|
||||||
break :text .constrained;
|
break :text .constrained;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@ const std = @import("std");
|
|||||||
extern "c" fn ghostty_simd_codepoint_width(u32) i8;
|
extern "c" fn ghostty_simd_codepoint_width(u32) i8;
|
||||||
|
|
||||||
pub fn codepointWidth(cp: u32) i8 {
|
pub fn codepointWidth(cp: u32) i8 {
|
||||||
//return @import("ziglyph").display_width.codePointWidth(@intCast(cp), .half);
|
// const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
// defer zg.deinitForTesting();
|
||||||
|
// try testing.expectEqual(@as(i8, 1), @import("DisplayWidth").codePointWidth(zg.display_width, @intCast(cp)));
|
||||||
return ghostty_simd_codepoint_width(cp);
|
return ghostty_simd_codepoint_width(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,27 +21,41 @@ test "codepointWidth basic" {
|
|||||||
try testing.expectEqual(@as(i8, 2), codepointWidth(0xF900)); // 豈
|
try testing.expectEqual(@as(i8, 2), codepointWidth(0xF900)); // 豈
|
||||||
try testing.expectEqual(@as(i8, 2), codepointWidth(0x20000)); // 𠀀
|
try testing.expectEqual(@as(i8, 2), codepointWidth(0x20000)); // 𠀀
|
||||||
try testing.expectEqual(@as(i8, 2), codepointWidth(0x30000)); // 𠀀
|
try testing.expectEqual(@as(i8, 2), codepointWidth(0x30000)); // 𠀀
|
||||||
// try testing.expectEqual(@as(i8, 1), @import("ziglyph").display_width.codePointWidth(0x100, .half));
|
// const zg = try @import("../../global.zig").Zg.initForTesting();
|
||||||
|
// defer zg.deinitForTesting();
|
||||||
|
// try testing.expectEqual(@as(i8, 1), @import("DisplayWidth").codePointWidth(zg.display_width, 0x100));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is not very fast in debug modes, so its commented by default.
|
// This is not very fast in debug modes, so its commented by default.
|
||||||
// IMPORTANT: UNCOMMENT THIS WHENEVER MAKING CODEPOINTWIDTH CHANGES.
|
// IMPORTANT: UNCOMMENT THIS WHENEVER MAKING CODEPOINTWIDTH CHANGES.
|
||||||
// test "codepointWidth matches ziglyph" {
|
//test "codepointWidth matches zg" {
|
||||||
// const testing = std.testing;
|
// const testing = std.testing;
|
||||||
// const ziglyph = @import("ziglyph");
|
// const DisplayWidth = @import("DisplayWidth");
|
||||||
|
// const display_width = try DisplayWidth.init(std.testing.allocator);
|
||||||
|
// defer display_width.deinit(std.testing.allocator);
|
||||||
|
// var success: bool = true;
|
||||||
//
|
//
|
||||||
// const min = 0xFF + 1; // start outside ascii
|
// const min = 0xFF + 1; // start outside ascii
|
||||||
// for (min..std.math.maxInt(u21)) |cp| {
|
// for (min..0x110000) |cp| {
|
||||||
// const simd = codepointWidth(@intCast(cp));
|
// const simd = codepointWidth(@intCast(cp));
|
||||||
// const zg = ziglyph.display_width.codePointWidth(@intCast(cp), .half);
|
// const zg_width = DisplayWidth.codePointWidth(display_width, @intCast(cp));
|
||||||
// if (simd != zg) mismatch: {
|
// if (simd != zg_width) mismatch: {
|
||||||
// if (cp == 0x2E3B) {
|
// if (cp == 0x2E3B) {
|
||||||
// try testing.expectEqual(@as(i8, 2), simd);
|
// try testing.expectEqual(@as(i8, 2), simd);
|
||||||
|
// std.log.warn("mismatch for 0x2e3b cp=U+{x} simd={} zg={}", .{ cp, simd, zg_width });
|
||||||
// break :mismatch;
|
// break :mismatch;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// std.log.warn("mismatch cp=U+{x} simd={} zg={}", .{ cp, simd, zg });
|
// if (cp == 0x890) {
|
||||||
// try testing.expect(false);
|
// try testing.expectEqual(@as(i8, 0), simd);
|
||||||
// }
|
// try testing.expectEqual(@as(i8, 1), zg_width);
|
||||||
|
// break :mismatch;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// std.log.warn("mismatch cp=U+{x} simd={} zg={}", .{ cp, simd, zg_width });
|
||||||
|
// success = false;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
|
// try testing.expect(success);
|
||||||
|
//}
|
||||||
|
@ -344,7 +344,7 @@ pub fn print(self: *Terminal, c: u21) !void {
|
|||||||
// VS15 makes it narrow.
|
// VS15 makes it narrow.
|
||||||
if (c == 0xFE0F or c == 0xFE0E) {
|
if (c == 0xFE0F or c == 0xFE0E) {
|
||||||
// This only applies to emoji
|
// This only applies to emoji
|
||||||
const prev_props = unicode.getProperties(prev.cell.content.codepoint);
|
const prev_props = unicode.table.get(prev.cell.content.codepoint);
|
||||||
const emoji = prev_props.grapheme_boundary_class.isExtendedPictographic();
|
const emoji = prev_props.grapheme_boundary_class.isExtendedPictographic();
|
||||||
if (!emoji) return;
|
if (!emoji) return;
|
||||||
|
|
||||||
@ -416,7 +416,7 @@ pub fn print(self: *Terminal, c: u21) !void {
|
|||||||
const width: usize = if (c <= 0xFF) 1 else @intCast(unicode.table.get(c).width);
|
const width: usize = if (c <= 0xFF) 1 else @intCast(unicode.table.get(c).width);
|
||||||
|
|
||||||
// Note: it is possible to have a width of "3" and a width of "-1"
|
// Note: it is possible to have a width of "3" and a width of "-1"
|
||||||
// from ziglyph. We should look into those cases and handle them
|
// from zg. We should look into those cases and handle them
|
||||||
// appropriately.
|
// appropriately.
|
||||||
assert(width <= 2);
|
assert(width <= 2);
|
||||||
// log.debug("c={x} width={}", .{ c, width });
|
// log.debug("c={x} width={}", .{ c, width });
|
||||||
@ -452,7 +452,7 @@ pub fn print(self: *Terminal, c: u21) !void {
|
|||||||
|
|
||||||
// If this is a emoji variation selector, prev must be an emoji
|
// If this is a emoji variation selector, prev must be an emoji
|
||||||
if (c == 0xFE0F or c == 0xFE0E) {
|
if (c == 0xFE0F or c == 0xFE0E) {
|
||||||
const prev_props = unicode.getProperties(prev.content.codepoint);
|
const prev_props = unicode.table.get(prev.content.codepoint);
|
||||||
const emoji = prev_props.grapheme_boundary_class == .extended_pictographic;
|
const emoji = prev_props.grapheme_boundary_class == .extended_pictographic;
|
||||||
if (!emoji) return;
|
if (!emoji) return;
|
||||||
}
|
}
|
||||||
|
@ -149,21 +149,19 @@ fn graphemeBreakClass(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If you build this file as a binary, we will verify the grapheme break
|
// This test will verify the grapheme break implementation. This iterates over billions of codepoints so it is SLOW.
|
||||||
/// implementation. This iterates over billions of codepoints so it is
|
// It's not meant to be run in CI, but it's useful for debugging.
|
||||||
/// SLOW. It's not meant to be run in CI, but it's useful for debugging.
|
test "grapheme break check against ziglyph" {
|
||||||
pub fn main() !void {
|
|
||||||
const ziglyph = @import("ziglyph");
|
const ziglyph = @import("ziglyph");
|
||||||
|
|
||||||
// Set the min and max to control the test range.
|
// Set the min and max to control the test range.
|
||||||
const min = 0;
|
const min = 0;
|
||||||
const max = std.math.maxInt(u21) + 1;
|
const max = std.math.maxInt(u21) + 1;
|
||||||
|
var success: bool = true;
|
||||||
|
|
||||||
var state: BreakState = .{};
|
var state: BreakState = .{};
|
||||||
var zg_state: u3 = 0;
|
var zg_state: u3 = 0;
|
||||||
for (min..max) |cp1| {
|
for (min..max) |cp1| {
|
||||||
if (cp1 % 1000 == 0) std.log.warn("progress cp1={}", .{cp1});
|
|
||||||
|
|
||||||
if (cp1 == '\r' or cp1 == '\n' or
|
if (cp1 == '\r' or cp1 == '\n' or
|
||||||
ziglyph.grapheme_break.isControl(@intCast(cp1))) continue;
|
ziglyph.grapheme_break.isControl(@intCast(cp1))) continue;
|
||||||
|
|
||||||
@ -174,6 +172,7 @@ pub fn main() !void {
|
|||||||
const gb = graphemeBreak(@intCast(cp1), @intCast(cp2), &state);
|
const gb = graphemeBreak(@intCast(cp1), @intCast(cp2), &state);
|
||||||
const zg_gb = ziglyph.graphemeBreak(@intCast(cp1), @intCast(cp2), &zg_state);
|
const zg_gb = ziglyph.graphemeBreak(@intCast(cp1), @intCast(cp2), &zg_state);
|
||||||
if (gb != zg_gb) {
|
if (gb != zg_gb) {
|
||||||
|
success = false;
|
||||||
std.log.warn("cp1={x} cp2={x} gb={} state={} zg_gb={} zg_state={}", .{
|
std.log.warn("cp1={x} cp2={x} gb={} state={} zg_gb={} zg_state={}", .{
|
||||||
cp1,
|
cp1,
|
||||||
cp2,
|
cp2,
|
||||||
@ -185,6 +184,8 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try std.testing.expect(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const std_options = struct {
|
pub const std_options = struct {
|
||||||
|
@ -11,7 +11,7 @@ const Allocator = std.mem.Allocator;
|
|||||||
/// can in theory be generated at runtime.
|
/// can in theory be generated at runtime.
|
||||||
///
|
///
|
||||||
/// Context must have two functions:
|
/// Context must have two functions:
|
||||||
/// - `get(Context, u21) Elem`: returns the mapping for a given codepoint
|
/// - `get(Context, u21) !Elem`: returns the mapping for a given codepoint
|
||||||
/// - `eql(Context, Elem, Elem) bool`: returns true if two mappings are equal
|
/// - `eql(Context, Elem, Elem) bool`: returns true if two mappings are equal
|
||||||
///
|
///
|
||||||
pub fn Generator(
|
pub fn Generator(
|
||||||
|
@ -4,7 +4,6 @@ const grapheme = @import("grapheme.zig");
|
|||||||
const props = @import("props.zig");
|
const props = @import("props.zig");
|
||||||
pub const table = props.table;
|
pub const table = props.table;
|
||||||
pub const Properties = props.Properties;
|
pub const Properties = props.Properties;
|
||||||
pub const getProperties = props.get;
|
|
||||||
pub const graphemeBreak = grapheme.graphemeBreak;
|
pub const graphemeBreak = grapheme.graphemeBreak;
|
||||||
pub const GraphemeBreakState = grapheme.BreakState;
|
pub const GraphemeBreakState = grapheme.BreakState;
|
||||||
|
|
||||||
|
@ -1,9 +1,26 @@
|
|||||||
const props = @This();
|
const props = @This();
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const ziglyph = @import("ziglyph");
|
const Graphemes = @import("Graphemes");
|
||||||
|
const DisplayWidth = @import("DisplayWidth");
|
||||||
const lut = @import("lut.zig");
|
const lut = @import("lut.zig");
|
||||||
|
|
||||||
|
graphemes: Graphemes,
|
||||||
|
display_width: DisplayWidth,
|
||||||
|
|
||||||
|
fn init(alloc: std.mem.Allocator) !props {
|
||||||
|
const graphemes = try Graphemes.init(alloc);
|
||||||
|
return .{
|
||||||
|
.graphemes = graphemes,
|
||||||
|
.display_width = try DisplayWidth.initWithGraphemes(alloc, graphemes),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deinit(self: *props, alloc: std.mem.Allocator) void {
|
||||||
|
self.graphemes.deinit(alloc);
|
||||||
|
self.display_width.deinit(alloc);
|
||||||
|
}
|
||||||
|
|
||||||
/// The lookup tables for Ghostty.
|
/// The lookup tables for Ghostty.
|
||||||
pub const table = table: {
|
pub const table = table: {
|
||||||
// This is only available after running main() below as part of the Ghostty
|
// This is only available after running main() below as part of the Ghostty
|
||||||
@ -79,31 +96,26 @@ pub const GraphemeBoundaryClass = enum(u4) {
|
|||||||
|
|
||||||
/// Gets the grapheme boundary class for a codepoint. This is VERY
|
/// Gets the grapheme boundary class for a codepoint. This is VERY
|
||||||
/// SLOW. The use case for this is only in generating lookup tables.
|
/// SLOW. The use case for this is only in generating lookup tables.
|
||||||
pub fn init(cp: u21) GraphemeBoundaryClass {
|
pub fn init(ctx: props, cp: u21) GraphemeBoundaryClass {
|
||||||
// We special-case modifier bases because we should not break
|
return switch (Graphemes.gbp(ctx.graphemes, cp)) {
|
||||||
// if a modifier isn't next to a base.
|
.Emoji_Modifier_Base => .extended_pictographic_base,
|
||||||
if (ziglyph.emoji.isEmojiModifierBase(cp)) {
|
.Emoji_Modifier => .emoji_modifier,
|
||||||
assert(ziglyph.emoji.isExtendedPictographic(cp));
|
.Extended_Pictographic => .extended_pictographic,
|
||||||
return .extended_pictographic_base;
|
.L => .L,
|
||||||
}
|
.V => .V,
|
||||||
|
.T => .T,
|
||||||
if (ziglyph.emoji.isEmojiModifier(cp)) return .emoji_modifier;
|
.LV => .LV,
|
||||||
if (ziglyph.emoji.isExtendedPictographic(cp)) return .extended_pictographic;
|
.LVT => .LVT,
|
||||||
if (ziglyph.grapheme_break.isL(cp)) return .L;
|
.Prepend => .prepend,
|
||||||
if (ziglyph.grapheme_break.isV(cp)) return .V;
|
.Extend => .extend,
|
||||||
if (ziglyph.grapheme_break.isT(cp)) return .T;
|
.ZWJ => .zwj,
|
||||||
if (ziglyph.grapheme_break.isLv(cp)) return .LV;
|
.SpacingMark => .spacing_mark,
|
||||||
if (ziglyph.grapheme_break.isLvt(cp)) return .LVT;
|
.Regional_Indicator => .regional_indicator,
|
||||||
if (ziglyph.grapheme_break.isPrepend(cp)) return .prepend;
|
|
||||||
if (ziglyph.grapheme_break.isExtend(cp)) return .extend;
|
|
||||||
if (ziglyph.grapheme_break.isZwj(cp)) return .zwj;
|
|
||||||
if (ziglyph.grapheme_break.isSpacingmark(cp)) return .spacing_mark;
|
|
||||||
if (ziglyph.grapheme_break.isRegionalIndicator(cp)) return .regional_indicator;
|
|
||||||
|
|
||||||
// This is obviously not INVALID invalid, there is SOME grapheme
|
// This is obviously not INVALID invalid, there is SOME grapheme
|
||||||
// boundary class for every codepoint. But we don't care about
|
// boundary class for every codepoint. But we don't care about
|
||||||
// anything that doesn't fit into the above categories.
|
// anything that doesn't fit into the above categories.
|
||||||
return .invalid;
|
.none, .Control, .CR, .LF => .invalid,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this is an extended pictographic type. This
|
/// Returns true if this is an extended pictographic type. This
|
||||||
@ -120,13 +132,25 @@ pub const GraphemeBoundaryClass = enum(u4) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn get(cp: u21) Properties {
|
pub fn get(ctx: props, cp: u21) !Properties {
|
||||||
const zg_width = ziglyph.display_width.codePointWidth(cp, .half);
|
if (cp > 0x10FFFF) {
|
||||||
|
return .{
|
||||||
|
.width = 0,
|
||||||
|
.grapheme_boundary_class = .invalid,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const zg_width = DisplayWidth.codePointWidth(ctx.display_width, cp);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.width = @intCast(@min(2, @max(0, zg_width))),
|
.width = @intCast(@min(2, @max(0, zg_width))),
|
||||||
.grapheme_boundary_class = .init(cp),
|
.grapheme_boundary_class = .init(ctx, cp),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eql(ctx: props, a: Properties, b: Properties) bool {
|
||||||
|
_ = ctx;
|
||||||
|
return a.eql(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runnable binary to generate the lookup tables and output to stdout.
|
/// Runnable binary to generate the lookup tables and output to stdout.
|
||||||
@ -135,20 +159,13 @@ pub fn main() !void {
|
|||||||
defer arena_state.deinit();
|
defer arena_state.deinit();
|
||||||
const alloc = arena_state.allocator();
|
const alloc = arena_state.allocator();
|
||||||
|
|
||||||
|
var self = try init(alloc);
|
||||||
|
defer self.deinit(alloc);
|
||||||
|
|
||||||
const gen: lut.Generator(
|
const gen: lut.Generator(
|
||||||
Properties,
|
Properties,
|
||||||
struct {
|
props,
|
||||||
pub fn get(ctx: @This(), cp: u21) !Properties {
|
) = .{ .ctx = self };
|
||||||
_ = ctx;
|
|
||||||
return props.get(cp);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn eql(ctx: @This(), a: Properties, b: Properties) bool {
|
|
||||||
_ = ctx;
|
|
||||||
return a.eql(b);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
) = .{};
|
|
||||||
|
|
||||||
const t = try gen.generate(alloc);
|
const t = try gen.generate(alloc);
|
||||||
defer alloc.free(t.stage1);
|
defer alloc.free(t.stage1);
|
||||||
@ -166,16 +183,19 @@ pub fn main() !void {
|
|||||||
|
|
||||||
// This is not very fast in debug modes, so its commented by default.
|
// This is not very fast in debug modes, so its commented by default.
|
||||||
// IMPORTANT: UNCOMMENT THIS WHENEVER MAKING CODEPOINTWIDTH CHANGES.
|
// IMPORTANT: UNCOMMENT THIS WHENEVER MAKING CODEPOINTWIDTH CHANGES.
|
||||||
// test "tables match ziglyph" {
|
//test "tables match zg" {
|
||||||
// const testing = std.testing;
|
// const testing = std.testing;
|
||||||
//
|
//
|
||||||
|
// const display_width = try DisplayWidth.init(std.testing.allocator);
|
||||||
|
// defer display_width.deinit(std.testing.allocator);
|
||||||
|
//
|
||||||
// const min = 0xFF + 1; // start outside ascii
|
// const min = 0xFF + 1; // start outside ascii
|
||||||
// for (min..std.math.maxInt(u21)) |cp| {
|
// for (min..0x110000) |cp| {
|
||||||
// const t = table.get(@intCast(cp));
|
// const t = table.get(@intCast(cp));
|
||||||
// const zg = @min(2, @max(0, ziglyph.display_width.codePointWidth(@intCast(cp), .half)));
|
// const zg = @min(2, @max(0, DisplayWidth.codePointWidth(display_width, @intCast(cp))));
|
||||||
// if (t.width != zg) {
|
// if (t.width != zg) {
|
||||||
// std.log.warn("mismatch cp=U+{x} t={} zg={}", .{ cp, t, zg });
|
// std.log.warn("mismatch cp=U+{x} t={} zg={}", .{ cp, t, zg });
|
||||||
// try testing.expect(false);
|
// try testing.expect(false);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
//}
|
||||||
|
Reference in New Issue
Block a user