mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
font: add sprites for the separated block quadrants (#2975)
Unicode 16 added "Separated Block Quadrants" from CP 0x0x1CC21 through 0x1CC2F: To test, use the following command: ``` printf "\U0001CC21\U0001CC22\U0001CC23\U0001CC24\U0001CC25\U0001CC26\U0001CC27\U0001CC28\U0001CC29\U0001CC2A\U0001CC2B\U0001CC2C\U0001CC2D\U0001CC2E\U0001CC2F\n" ``` Which should look like this:  cc @qwerasd205 @rockorager
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,3 +15,5 @@ test/ghostty
|
|||||||
test/cases/**/*.actual.png
|
test/cases/**/*.actual.png
|
||||||
|
|
||||||
glad.zip
|
glad.zip
|
||||||
|
/Box_test.ppm
|
||||||
|
/Box_test_diff.ppm
|
||||||
|
@ -1624,6 +1624,37 @@ fn draw(self: Box, alloc: Allocator, canvas: *font.sprite.Canvas, cp: u32) !void
|
|||||||
.right = true,
|
.right = true,
|
||||||
}, .light),
|
}, .light),
|
||||||
|
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-1
|
||||||
|
0x1cc21 => try self.draw_separated_block_quadrant(canvas, "1"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-2
|
||||||
|
0x1cc22 => try self.draw_separated_block_quadrant(canvas, "2"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-12
|
||||||
|
0x1cc23 => try self.draw_separated_block_quadrant(canvas, "12"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-3
|
||||||
|
0x1cc24 => try self.draw_separated_block_quadrant(canvas, "3"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-13
|
||||||
|
0x1cc25 => try self.draw_separated_block_quadrant(canvas, "13"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-23
|
||||||
|
0x1cc26 => try self.draw_separated_block_quadrant(canvas, "23"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-123
|
||||||
|
0x1cc27 => try self.draw_separated_block_quadrant(canvas, "123"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-4
|
||||||
|
0x1cc28 => try self.draw_separated_block_quadrant(canvas, "4"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-14
|
||||||
|
0x1cc29 => try self.draw_separated_block_quadrant(canvas, "14"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-24
|
||||||
|
0x1cc2a => try self.draw_separated_block_quadrant(canvas, "24"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-124
|
||||||
|
0x1cc2b => try self.draw_separated_block_quadrant(canvas, "124"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-34
|
||||||
|
0x1cc2c => try self.draw_separated_block_quadrant(canvas, "34"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-134
|
||||||
|
0x1cc2d => try self.draw_separated_block_quadrant(canvas, "134"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-234
|
||||||
|
0x1cc2e => try self.draw_separated_block_quadrant(canvas, "234"),
|
||||||
|
// '' - SEPARATED BLOCK QUADRANT-1234
|
||||||
|
0x1cc2f => try self.draw_separated_block_quadrant(canvas, "1234"),
|
||||||
|
|
||||||
else => return error.InvalidCodepoint,
|
else => return error.InvalidCodepoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2865,6 +2896,74 @@ fn rect(
|
|||||||
} }).rect(), .on);
|
} }).rect(), .on);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Separated Block Quadrants from Symbols for Legacy Computing Supplement
|
||||||
|
//
|
||||||
|
fn draw_separated_block_quadrant(self: Box, canvas: *font.sprite.Canvas, comptime fmt: []const u8) !void {
|
||||||
|
comptime {
|
||||||
|
if (fmt.len > 4) @compileError("cannot have more than four quadrants");
|
||||||
|
var seen = [_]bool{false} ** (std.math.maxInt(u8) + 1);
|
||||||
|
for (fmt) |c| {
|
||||||
|
if (seen[c]) @compileError("repeated quadrants not allowed");
|
||||||
|
seen[c] = true;
|
||||||
|
switch (c) {
|
||||||
|
'1'...'4' => {},
|
||||||
|
else => @compileError("invalid quadrant"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ctx: z2d.Context = .{
|
||||||
|
.surface = canvas.sfc,
|
||||||
|
.pattern = .{
|
||||||
|
.opaque_pattern = .{
|
||||||
|
.pixel = .{ .alpha8 = .{ .a = @intFromEnum(Shade.on) } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const gap: f64 = @max(1.0, @as(f64, @floatFromInt(self.metrics.cell_width)) * 0.10) / 2.0;
|
||||||
|
const left: f64 = gap;
|
||||||
|
const right = @as(f64, @floatFromInt(self.metrics.cell_width)) - gap;
|
||||||
|
const top: f64 = gap;
|
||||||
|
const bottom = @as(f64, @floatFromInt(self.metrics.cell_height)) - gap;
|
||||||
|
const center_x = @as(f64, @floatFromInt(self.metrics.cell_width)) / 2.0;
|
||||||
|
const center_left = center_x - gap;
|
||||||
|
const center_right = center_x + gap;
|
||||||
|
const center_y = @as(f64, @floatFromInt(self.metrics.cell_height)) / 2.0;
|
||||||
|
const center_top = center_y - gap;
|
||||||
|
const center_bottom = center_y + gap;
|
||||||
|
|
||||||
|
inline for (fmt) |c| {
|
||||||
|
const x1, const y1, const x2, const y2 = switch (c) {
|
||||||
|
'1' => .{
|
||||||
|
left, top,
|
||||||
|
center_left, center_top,
|
||||||
|
},
|
||||||
|
'2' => .{
|
||||||
|
center_right, top,
|
||||||
|
right, center_top,
|
||||||
|
},
|
||||||
|
'3' => .{
|
||||||
|
left, center_bottom,
|
||||||
|
center_left, bottom,
|
||||||
|
},
|
||||||
|
'4' => .{
|
||||||
|
center_right, center_bottom,
|
||||||
|
right, bottom,
|
||||||
|
},
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
var path = z2d.Path.init(canvas.alloc);
|
||||||
|
defer path.deinit();
|
||||||
|
try path.moveTo(x1, y1);
|
||||||
|
try path.lineTo(x2, y1);
|
||||||
|
try path.lineTo(x2, y2);
|
||||||
|
try path.lineTo(x1, y2);
|
||||||
|
try path.close();
|
||||||
|
try ctx.fill(canvas.alloc, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
test "all" {
|
test "all" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
@ -2994,6 +3093,20 @@ fn testRenderAll(self: Box, alloc: Allocator, atlas: *font.Atlas) !void {
|
|||||||
cp,
|
cp,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Symbols for Legacy Computing Supplement.
|
||||||
|
//
|
||||||
|
cp = 0x1cc21;
|
||||||
|
while (cp <= 0x1cc2f) : (cp += 1) {
|
||||||
|
switch (cp) {
|
||||||
|
0x1cc21...0x1cc2f => _ = try self.renderGlyph(
|
||||||
|
alloc,
|
||||||
|
atlas,
|
||||||
|
cp,
|
||||||
|
),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "render all sprites" {
|
test "render all sprites" {
|
||||||
|
@ -152,7 +152,6 @@ pub fn renderGlyph(
|
|||||||
|
|
||||||
break :cursor g;
|
break :cursor g;
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +262,10 @@ const Kind = enum {
|
|||||||
//
|
//
|
||||||
0xF5D0...0xF60D => .box,
|
0xF5D0...0xF60D => .box,
|
||||||
|
|
||||||
|
// Separated Block Quadrants from Symbols for Legacy Computing Supplement
|
||||||
|
//
|
||||||
|
0x1CC21...0x1CC2F => .box,
|
||||||
|
|
||||||
// Powerline fonts
|
// Powerline fonts
|
||||||
0xE0B0,
|
0xE0B0,
|
||||||
0xE0B1,
|
0xE0B1,
|
||||||
|
BIN
src/font/sprite/testdata/Box.ppm
vendored
BIN
src/font/sprite/testdata/Box.ppm
vendored
Binary file not shown.
Reference in New Issue
Block a user