Skip to content

Commit

Permalink
font: add sprites for the separated block quadrants (#2975)
Browse files Browse the repository at this point in the history
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:

![Screenshot From 2024-12-15
13-15-31](https://github.com/user-attachments/assets/fcf825e1-c824-4f56-8c7d-b4e126401c2b)

cc @qwerasd205 @rockorager
  • Loading branch information
mitchellh authored Dec 22, 2024
2 parents bef2852 + d89db99 commit eb7b056
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ test/ghostty
test/cases/**/*.actual.png

glad.zip
/Box_test.ppm
/Box_test_diff.ppm
113 changes: 113 additions & 0 deletions src/font/sprite/Box.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,37 @@ fn draw(self: Box, alloc: Allocator, canvas: *font.sprite.Canvas, cp: u32) !void
.right = true,
}, .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,
}
}
Expand Down Expand Up @@ -2865,6 +2896,74 @@ fn rect(
} }).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" {
const testing = std.testing;
const alloc = testing.allocator;
Expand Down Expand Up @@ -2994,6 +3093,20 @@ fn testRenderAll(self: Box, alloc: Allocator, atlas: *font.Atlas) !void {
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" {
Expand Down
5 changes: 4 additions & 1 deletion src/font/sprite/Face.zig
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ pub fn renderGlyph(

break :cursor g;
},

};
}

Expand Down Expand Up @@ -263,6 +262,10 @@ const Kind = enum {
//            
0xF5D0...0xF60D => .box,

// Separated Block Quadrants from Symbols for Legacy Computing Supplement
// 𜰡 𜰢 𜰣 𜰤 𜰥 𜰦 𜰧 𜰨 𜰩 𜰪 𜰫 𜰬 𜰭 𜰮 𜰯
0x1CC21...0x1CC2F => .box,

// Powerline fonts
0xE0B0,
0xE0B1,
Expand Down
Binary file modified src/font/sprite/testdata/Box.ppm
Binary file not shown.

0 comments on commit eb7b056

Please sign in to comment.