╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Title.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
123 "#....#", 124 "#....#", 125 "#....#", 126 "#....#", 127 "#....#", 128 "#....#", 129 "#####.", 130 }, 131 'E' => .{ 132 "######", 133 "#.....", 134 "#.....", 135 "#.....", 136 "#####.", 137 "#.....", 138 "#.....", 139 "#.....", 140 "######", 141 }, 142 'F' => .{ 143 "######", 144 "#.....", 145 "#.....", 146 "#.....", 147 "#####.", 148 "#.....", 149 "#.....", 150 "#.....", 151 "#.....", 152 }, 153 'G' => .{ 154 ".####.", 155 "#....#", 156 "#.....", 157 "#.....", 158 "#..###", 159 "#....#", 160 "#....#", 161 "#....#", 162 ".####.", 163 }, 164 'H' => .{ 165 "#....#", 166 "#....#", 167 "#....#", 168 "#....#", 169 "######", 170 "#....#", 171 "#....#", 172 "#....#", 173 "#....#", 174 }, 175 'I' => .{ 176 "######", 177 "..##..", 178 "..##..", 179 "..##..", 180 "..##..", 181 "..##..", 182 "..##..", 183 "..##..", 184 "######", 185 }, 186 'J' => .{ 187 "....##", 188 "....##", 189 "....##", 190 "....##", 191 "....##", 192 "....##", 193 "#...##", 194 "#..##.", 195 ".##...", 196 }, 197 'K' => .{ 198 "#....#", 199 "#...#.", 200 "#..#..", 201 "#.#...", 202 "##....", 203 "#.#...", 204 "#..#..", 205 "#...#.", 206 "#....#", 207 }, 208 'L' => .{ 209 "#.....", 210 "#.....", 211 "#.....", 212 "#.....", 213 "#.....", 214 "#.....", 215 "#.....", 216 "#.....", 217 "######", 218 }, 219 'M' => .{ 220 "#....#", 221 "##..##", 222 "#.##.#", 223 "#.##.#", 224 "#....#", 225 "#....#", 226 "#....#", 227 "#....#", 228 "#....#", 229 }, 230 'N' => .{ 231 "#....#", 232 "##...#", 233 "##...#", 234 "#.#..#", 235 "#..#.#", 236 "#...##", 237 "#...##", 238 "#....#", 239 "#....#", 240 }, 241 'O' => .{ 242 ".####.", 243 "#....#", 244 "#....#", 245 "#....#", 246 "#....#", 247 "#....#", 248 "#....#", 249 "#....#", 250 ".####.", 251 }, 252 'P' => .{ 253 "#####.", 254 "#....#", 255 "#....#", 256 "#....#", 257 "#####.", 258 "#.....", 259 "#.....", 260 "#.....", 261 "#.....", 262 }, 263 'Q' => .{ 264 ".####.", 265 "#....#", 266 "#....#", 267 "#....#", 268 "#....#", 269 "#....#", 270 "#..#.#", 271 ".####.", 272 ".....#", 273 }, 274 'R' => .{ 275 "#####.", 276 "#....#", 277 "#....#", 278 "#....#", 279 "#####.", 280 "#.#...", 281 "#..#..", 282 "#...#.", 283 "#....#", 284 }, 285 'S' => .{ 286 ".####.", 287 "#....#", 288 "#.....", 289 "#.....", 290 ".####.", 291 ".....#", 292 ".....#", 293 "#....#", 294 ".####.", 295 }, 296 'T' => .{ 297 "######", 298 "..##..", 299 "..##..", 300 "..##..", 301 "..##..", 302 "..##..", 303 "..##..", 304 "..##..", 305 "..##..", 306 }, 307 'U' => .{ 308 "#....#", 309 "#....#", 310 "#....#", 311 "#....#", 312 "#....#", 313 "#....#", 314 "#....#", 315 "#....#", 316 ".####.", 317 }, 318 'V' => .{ 319 "#....#", 320 "#....#", 321 "#....#", 322 ".#..#.", 323 ".#..#.", 324 ".#..#.", 325 ".#..#.", 326 ".#..#.", 327 "..##..", 328 }, 329 'W' => .{ 330 "#....#", 331 "#....#", 332 "#....#", 333 "#....#", 334 "#....#", 335 "#.##.#", 336 "#.##.#", 337 "##..##", 338 ".#..#.", 339 }, 340 'X' => .{ 341 "#....#", 342 ".#..#.", 343 ".#..#.", 344 "..##..", 345 "..##..", 346 "..##..", 347 ".#..#.", 348 ".#..#.", 349 "#....#", 350 }, 351 'Y' => .{ 352 "#....#", 353 ".#..#.", 354 ".#..#.", 355 "..##..", 356 "..##..", 357 "..##..", 358 "..##..", 359 "..##..", 360 "..##..", 361 }, 362 'Z' => .{ 363 "######", 364 "....#.", 365 "....#.", 366 "...#..", 367 "..##..", 368 "..#...", 369 ".#....", 370 ".#....", 371 "######", 372 }, 373 '0' => .{ 374 ".####.", 375 "#...##", 376 "#..#.#", 377 "#..#.#", 378 "#.#..#", 379 "#.#..#", 380 "##...#", 381 "#....#", 382 ".####.", 383 }, 384 '1' => .{ 385 "..##..", 386 ".###..", 387 "..##..", 388 "..##..", 389 "..##..", 390 "..##..", 391 "..##..", 392 "..##..", 393 "######", 394 }, 395 '2' => .{ 396 ".####.", 397 "#....#", 398 ".....#", 399 "....#.", 400 "...#..", 401 "..#...", 402 ".#....", 403 "#.....", 404 "######", 405 }, 406 '3' => .{ 407 ".####.", 408 "#....#", 409 ".....#", 410 ".....#", 411 ".####.", 412 ".....#", 413 ".....#", 414 "#....#", 415 ".####.", 416 }, 417 '4' => .{ 418 "....#.", 419 "...##.", 420 "..#.#.", 421 ".#..#.", 422 "#...#.", 423 "######", 424 "....#.", 425 "....#.", 426 "....#.", 427 }, 428 '5' => .{ 429 "######", 430 "#.....", 431 "#.....", 432 "#.....", 433 "#####.", 434 ".....#", 435 ".....#", 436 "#....#", 437 ".####.", 438 }, 439 '6' => .{ 440 ".####.", 441 "#....#", 442 "#.....", 443 "#.....", 444 "#####.", 445 "#....#", 446 "#....#", 447 "#....#", 448 ".####.", 449 }, 450 '7' => .{ 451 "######", 452 ".....#", 453 "....#.", 454 "....#.", 455 "...#..", 456 "...#..", 457 "..#...", 458 "..#...", 459 ".#....", 460 }, 461 '8' => .{ 462 ".####.", 463 "#....#", 464 "#....#", 465 "#....#", 466 ".####.", 467 "#....#", 468 "#....#", 469 "#....#", 470 ".####.", 471 }, 472 '9' => .{ 473 ".####.", 474 "#....#", 475 "#....#", 476 "#....#", 477 ".#####", 478 ".....#", 479 ".....#", 480 "#....#", 481 ".####.", 482 }, 483 '-' => .{ 484 "......", 485 "......", 486 "......", 487 "......", 488 ".####.", 489 "......", 490 "......", 491 "......", 492 "......", 493 }, 494 '.' => .{ 495 "......", 496 "......", 497 "......", 498 "......", 499 "......", 500 "......", 501 "......", 502 "..##..", 503 "..##..", 504 }, 505 '?' => .{ 506 ".####.", 507 "#....#", 508 ".....#", 509 "....#.", 510 "..##..", 511 "..##..", 512 "......", 513 "..##..", 514 "..##..", 515 }, 516 '!' => .{ 517 "..##..", 518 "..##..", 519 "..##..", 520 "..##..", 521 "..##..", 522 "..##..", 523 "......", 524 "..##..", 525 "..##..", 526 }, 527 '\'' => .{ 528 "..##..", 529 "..##..", 530 "...#..", 531 "......", 532 "......", 533 "......", 534 "......", 535 "......", 536 "......", 537 }, 538 ',' => .{ 539 "......", 540 "......", 541 "......", 542 "......", 543 "......", 544 "......", 545 "..##..", 546 "..##..", 547 "..#...", 548 }, 549 ':' => .{ 550 "......", 551 "......", 552 "..##..", 553 "..##..", 554 "......", 555 "......", 556 "......", 557 "..##..", 558 "..##..", 559 }, 560 '/' => .{ 561 ".....#", 562 "....#.", 563 "....#.", 564 "...#..", 565 "...#..", 566 "..#...", 567 "..#...", 568 ".#....", 569 "#.....", 570 }, 571 else => null, 572 }; 573 } 574 575 // whether every char of `text` has a glyph 576 pub fn covers(text: []const u8) bool { 577 for (text) |c| { 578 if (glyphFor(c) == null) return false; 579 } 580 return true; 581 } 582 583 // map a 2x3 sub-pixel pattern to its corresponding sextant codepoint 584 fn sextantCodepoint(pattern: u6) u21 { 585 return switch (pattern) { 586 0b000000 => ' ', 587 0b010101 => 0x258C, // ▌ left half block 588 0b101010 => 0x2590, // ▐ right half block 589 0b111111 => 0x2588, // █ full block 590 else => blk: { 591 var offset: u21 = @as(u21, pattern) - 1; 592 if (pattern > 0b010101) offset -= 1; 593 if (pattern > 0b101010) offset -= 1; 594 break :blk 0x1FB00 + offset; 595 }, 596 }; 597 } 598 599 fn renderTitle(allocator: std.mem.Allocator, input: []const u8, style: Style) ![]const u8 { 600 var rows: [3]std.ArrayList(u8) = .{ .empty, .empty, .empty }; 601 defer for (&rows) |*r| r.deinit(allocator); 602 603 var first = true; 604 for (input) |c| { 605 const glyph = glyphFor(c) orelse continue; 606 607 // scanlines: keep on-pixels only at even bitmap rows. 608 var kept: [9][6]bool = std.mem.zeroes([9][6]bool); 609 for (0..9) |r| { 610 if (style == .scanlines and r % 2 != 0) continue; 611 for (0..6) |col| { 612 kept[r][col] = glyph[r][col] == '#'; 613 } 614 } 615 616 if (!first) { 617 for (&rows) |*r| try r.append(allocator, ' '); 618 } 619 first = false; 620 621 for (0..3) |text_row| { 622 for (0..3) |text_col| { 623 var pattern: u6 = 0; 624 for (0..3) |sub_row| { 625 for (0..2) |sub_col| { 626 const row_idx = text_row * 3 + sub_row; 627 const col_idx = text_col * 2 + sub_col; 628 if (kept[row_idx][col_idx]) { 629 pattern |= @as(u6, 1) << @intCast(sub_row * 2 + sub_col); 630 } 631 } 632 } 633 const cp = sextantCodepoint(pattern); 634 var utf8_buf: [4]u8 = undefined; 635 const len = try std.unicode.utf8Encode(cp, &utf8_buf); 636 try rows[text_row].appendSlice(allocator, utf8_buf[0..len]); 637 } 638 } 639 } 640 641 var out: std.ArrayList(u8) = .empty; 642 errdefer out.deinit(allocator); 643 try out.appendSlice(allocator, rows[0].items); 644 try out.append(allocator, '\n'); 645 try out.appendSlice(allocator, rows[1].items); 646 try out.append(allocator, '\n'); 647 try out.appendSlice(allocator, rows[2].items); 648 return out.toOwnedSlice(allocator); 649 } 650