ghostty/src/renderer/State.zig
2023-11-15 09:53:51 -08:00

60 lines
2.1 KiB
Zig

//! This is the render state that is given to a renderer.
const std = @import("std");
const Allocator = std.mem.Allocator;
const Inspector = @import("../inspector/main.zig").Inspector;
const terminal = @import("../terminal/main.zig");
const renderer = @import("../renderer.zig");
/// The mutex that must be held while reading any of the data in the
/// members of this state. Note that the state itself is NOT protected
/// by the mutex and is NOT thread-safe, only the members values of the
/// state (i.e. the terminal, devmode, etc. values).
mutex: *std.Thread.Mutex,
/// The terminal data.
terminal: *terminal.Terminal,
/// The terminal inspector, if any. This will be null while the inspector
/// is not active and will be set when it is active.
inspector: ?*Inspector = null,
/// Dead key state. This will render the current dead key preedit text
/// over the cursor. This currently only ever renders a single codepoint.
/// Preedit can in theory be multiple codepoints long but that is left as
/// a future exercise.
preedit: ?Preedit = null,
/// The pre-edit state. See Surface.preeditCallback for more information.
pub const Preedit = struct {
/// The codepoints to render as preedit text. We allow up to 16 codepoints
/// as a sort of arbitrary limit. If we experience a realisitic use case
/// where we need more please open an issue.
codepoints: [16]Codepoint = undefined,
len: u8 = 0,
/// A single codepoint to render as preedit text.
pub const Codepoint = struct {
codepoint: u21,
wide: bool = false,
};
/// The width in cells of all codepoints in the preedit.
pub fn width(self: *const Preedit) usize {
var result: usize = 0;
for (self.codepoints[0..self.len]) |cp| {
result += if (cp.wide) 2 else 1;
}
return result;
}
pub fn range(self: *const Preedit, start: usize, max: usize) [2]usize {
// If our preedit goes off the end of the screen, we adjust it so
// that it shifts left.
const end = start + self.width();
const offset = if (end > max) end - max else 0;
return .{ start -| offset, end -| offset };
}
};