╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ SubTitle.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
382 ".##.", 383 ".##.", 384 }, 385 else => null, 386 }; 387 } 388 389 // map a 2x3 sub-pixel pattern to its corresponding sextant codepoint 390 fn sextantCodepoint(pattern: u6) u21 { 391 return switch (pattern) { 392 0b000000 => ' ', 393 0b010101 => 0x258C, // ▌ left half block 394 0b101010 => 0x2590, // ▐ right half block 395 0b111111 => 0x2588, // █ full block 396 else => blk: { 397 var offset: u21 = @as(u21, pattern) - 1; 398 if (pattern > 0b010101) offset -= 1; 399 if (pattern > 0b101010) offset -= 1; 400 break :blk 0x1FB00 + offset; 401 }, 402 }; 403 } 404 405 fn renderSubTitle(allocator: std.mem.Allocator, input: []const u8) ![]const u8 { 406 var rows: [2]std.ArrayList(u8) = .{ .empty, .empty }; 407 defer for (&rows) |*r| r.deinit(allocator); 408 409 var first = true; 410 for (input) |c| { 411 const glyph = glyphFor(c) orelse continue; 412 413 var on: [6][4]bool = std.mem.zeroes([6][4]bool); 414 for (0..6) |r| { 415 for (0..4) |col| { 416 on[r][col] = glyph[r][col] == '#'; 417 } 418 } 419 420 if (!first) { 421 for (&rows) |*r| try r.append(allocator, ' '); 422 } 423 first = false; 424 425 for (0..2) |text_row| { 426 for (0..2) |text_col| { 427 var pattern: u6 = 0; 428 for (0..3) |sub_row| { 429 for (0..2) |sub_col| { 430 const row_idx = text_row * 3 + sub_row; 431 const col_idx = text_col * 2 + sub_col; 432 if (on[row_idx][col_idx]) { 433 pattern |= @as(u6, 1) << @intCast(sub_row * 2 + sub_col); 434 } 435 } 436 } 437 const cp = sextantCodepoint(pattern); 438 var utf8_buf: [4]u8 = undefined; 439 const len = try std.unicode.utf8Encode(cp, &utf8_buf); 440 try rows[text_row].appendSlice(allocator, utf8_buf[0..len]); 441 } 442 } 443 } 444 445 var out: std.ArrayList(u8) = .empty; 446 errdefer out.deinit(allocator); 447 try out.appendSlice(allocator, rows[0].items); 448 try out.append(allocator, '\n'); 449 try out.appendSlice(allocator, rows[1].items); 450 return out.toOwnedSlice(allocator); 451 } 452