renderer/metal: port

This commit is contained in:
Mitchell Hashimoto
2024-03-08 21:33:10 -08:00
parent d966e74f45
commit c61de49082
5 changed files with 181 additions and 139 deletions

View File

@@ -21,11 +21,8 @@ pub const FgMode = enum {
/// renderer.
pub fn fgMode(
group: *font.Group,
screen: *terminal.Screen,
cell: terminal.Screen.Cell,
cell_pin: terminal.Pin,
shaper_run: font.shape.TextRun,
x: usize,
y: usize,
) !FgMode {
const presentation = try group.presentationFromIndex(shaper_run.font_index);
return switch (presentation) {
@@ -41,42 +38,55 @@ pub fn fgMode(
// the subsequent character is empty, then we allow it to use
// the full glyph size. See #1071.
.text => text: {
if (!ziglyph.general_category.isPrivateUse(@intCast(cell.char)) and
!ziglyph.blocks.isDingbats(@intCast(cell.char)))
const cell = cell_pin.rowAndCell().cell;
const cp = cell.codepoint();
if (!ziglyph.general_category.isPrivateUse(cp) and
!ziglyph.blocks.isDingbats(cp))
{
break :text .normal;
}
// We exempt the Powerline range from this since they exhibit
// box-drawing behavior and should not be constrained.
if (isPowerline(cell.char)) {
if (isPowerline(cp)) {
break :text .normal;
}
// If we are at the end of the screen its definitely constrained
if (x == screen.cols - 1) break :text .constrained;
if (cell_pin.x == cell_pin.page.data.size.cols - 1) break :text .constrained;
// If we have a previous cell and it was PUA then we need to
// also constrain. This is so that multiple PUA glyphs align.
// As an exception, we ignore powerline glyphs since they are
// used for box drawing and we consider them whitespace.
if (x > 0) prev: {
const prev_cell = screen.getCell(.active, y, x - 1);
if (cell_pin.x > 0) prev: {
const prev_cp = prev_cp: {
var copy = cell_pin;
copy.x -= 1;
const prev_cell = copy.rowAndCell().cell;
break :prev_cp prev_cell.codepoint();
};
// Powerline is whitespace
if (isPowerline(prev_cell.char)) break :prev;
if (isPowerline(prev_cp)) break :prev;
if (ziglyph.general_category.isPrivateUse(@intCast(prev_cell.char))) {
if (ziglyph.general_category.isPrivateUse(prev_cp)) {
break :text .constrained;
}
}
// If the next cell is empty, then we allow it to use the
// full glyph size.
const next_cell = screen.getCell(.active, y, x + 1);
if (next_cell.char == 0 or
next_cell.char == ' ' or
isPowerline(next_cell.char))
const next_cp = next_cp: {
var copy = cell_pin;
copy.x += 1;
const next_cell = copy.rowAndCell().cell;
break :next_cp next_cell.codepoint();
};
if (next_cp == 0 or
next_cp == ' ' or
isPowerline(next_cp))
{
break :text .normal;
}
@@ -88,7 +98,7 @@ pub fn fgMode(
}
// Returns true if the codepoint is a part of the Powerline range.
fn isPowerline(char: u32) bool {
fn isPowerline(char: u21) bool {
return switch (char) {
0xE0B0...0xE0C8, 0xE0CA, 0xE0CC...0xE0D2, 0xE0D4 => true,
else => false,