From d0677928af54eb3fea5d11db9b593dbc189e854c Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Sun, 15 Dec 2024 14:33:09 -0600 Subject: [PATCH] font: add sprites for the separated block quadrants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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" ``` --- src/font/sprite/Box.zig | 128 +++++++++++++++++++++++++++++++ src/font/sprite/Face.zig | 5 +- src/font/sprite/testdata/Box.ppm | Bin 1048593 -> 1048593 bytes 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/src/font/sprite/Box.zig b/src/font/sprite/Box.zig index cf929eb67..438af2c4c 100644 --- a/src/font/sprite/Box.zig +++ b/src/font/sprite/Box.zig @@ -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, } } @@ -2865,6 +2896,89 @@ 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 left: f64 = 0.5; + const right = @as(f64, @floatFromInt(self.metrics.cell_width)) - 0.5; + const top: f64 = 0.5; + const bottom = @as(f64, @floatFromInt(self.metrics.cell_height)) - 0.5; + const center_x = @as(f64, @floatFromInt(self.metrics.cell_width)) / 2.0; + const center_left = center_x - 0.5; + const center_right = center_x + 0.5; + const center_y = @as(f64, @floatFromInt(self.metrics.cell_height)) / 2.0; + const center_top = center_y - 0.5; + const center_bottom = center_y + 0.5; + + inline for (fmt) |c| { + switch (c) { + '1' => { + var path = z2d.Path.init(canvas.alloc); + defer path.deinit(); + try path.moveTo(left, top); + try path.lineTo(center_left, top); + try path.lineTo(center_left, center_top); + try path.lineTo(left, center_top); + try path.close(); + try ctx.fill(canvas.alloc, path); + }, + '2' => { + var path = z2d.Path.init(canvas.alloc); + defer path.deinit(); + try path.moveTo(center_right, top); + try path.lineTo(right, top); + try path.lineTo(right, center_top); + try path.lineTo(center_right, center_top); + try path.close(); + try ctx.fill(canvas.alloc, path); + }, + '3' => { + var path = z2d.Path.init(canvas.alloc); + defer path.deinit(); + try path.moveTo(left, center_bottom); + try path.lineTo(center_left, center_bottom); + try path.lineTo(center_left, bottom); + try path.lineTo(left, bottom); + try path.close(); + try ctx.fill(canvas.alloc, path); + }, + '4' => { + var path = z2d.Path.init(canvas.alloc); + defer path.deinit(); + try path.moveTo(center_right, center_bottom); + try path.lineTo(right, center_bottom); + try path.lineTo(right, bottom); + try path.lineTo(center_right, bottom); + try path.close(); + try ctx.fill(canvas.alloc, path); + }, + else => unreachable, + } + } +} + test "all" { const testing = std.testing; const alloc = testing.allocator; @@ -2994,6 +3108,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" { diff --git a/src/font/sprite/Face.zig b/src/font/sprite/Face.zig index ede67d00d..83dfffefa 100644 --- a/src/font/sprite/Face.zig +++ b/src/font/sprite/Face.zig @@ -152,7 +152,6 @@ pub fn renderGlyph( break :cursor g; }, - }; } @@ -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, diff --git a/src/font/sprite/testdata/Box.ppm b/src/font/sprite/testdata/Box.ppm index 1301a4299816fec222672eb24f327db221007b21..331d19502bc75a7ac691d782779325c26ca41b59 100644 GIT binary patch delta 19727 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