╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Title.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
147 'G' => .{ 148 ".####.", 149 "#....#", 150 "#.....", 151 "#.....", 152 "#..###", 153 "#....#", 154 "#....#", 155 "#....#", 156 ".####.", 157 }, 158 'H' => .{ 159 "#....#", 160 "#....#", 161 "#....#", 162 "#....#", 163 "######", 164 "#....#", 165 "#....#", 166 "#....#", 167 "#....#", 168 }, 169 'I' => .{ 170 "######", 171 "..##..", 172 "..##..", 173 "..##..", 174 "..##..", 175 "..##..", 176 "..##..", 177 "..##..", 178 "######", 179 }, 180 'J' => .{ 181 "....##", 182 "....##", 183 "....##", 184 "....##", 185 "....##", 186 "....##", 187 "#...##", 188 "#..##.", 189 ".##...", 190 }, 191 'K' => .{ 192 "#....#", 193 "#...#.", 194 "#..#..", 195 "#.#...", 196 "##....", 197 "#.#...", 198 "#..#..", 199 "#...#.", 200 "#....#", 201 }, 202 'L' => .{ 203 "#.....", 204 "#.....", 205 "#.....", 206 "#.....", 207 "#.....", 208 "#.....", 209 "#.....", 210 "#.....", 211 "######", 212 }, 213 'M' => .{ 214 "#....#", 215 "##..##", 216 "#.##.#", 217 "#.##.#", 218 "#....#", 219 "#....#", 220 "#....#", 221 "#....#", 222 "#....#", 223 }, 224 'N' => .{ 225 "#....#", 226 "##...#", 227 "##...#", 228 "#.#..#", 229 "#..#.#", 230 "#...##", 231 "#...##", 232 "#....#", 233 "#....#", 234 }, 235 'O' => .{ 236 ".####.", 237 "#....#", 238 "#....#", 239 "#....#", 240 "#....#", 241 "#....#", 242 "#....#", 243 "#....#", 244 ".####.", 245 }, 246 'P' => .{ 247 "#####.", 248 "#....#", 249 "#....#", 250 "#....#", 251 "#####.", 252 "#.....", 253 "#.....", 254 "#.....", 255 "#.....", 256 }, 257 'Q' => .{ 258 ".####.", 259 "#....#", 260 "#....#", 261 "#....#", 262 "#....#", 263 "#....#", 264 "#..#.#", 265 ".####.", 266 ".....#", 267 }, 268 'R' => .{ 269 "#####.", 270 "#....#", 271 "#....#", 272 "#....#", 273 "#####.", 274 "#.#...", 275 "#..#..", 276 "#...#.", 277 "#....#", 278 }, 279 'S' => .{ 280 ".####.", 281 "#....#", 282 "#.....", 283 "#.....", 284 ".####.", 285 ".....#", 286 ".....#", 287 "#....#", 288 ".####.", 289 }, 290 'T' => .{ 291 "######", 292 "..##..", 293 "..##..", 294 "..##..", 295 "..##..", 296 "..##..", 297 "..##..", 298 "..##..", 299 "..##..", 300 }, 301 'U' => .{ 302 "#....#", 303 "#....#", 304 "#....#", 305 "#....#", 306 "#....#", 307 "#....#", 308 "#....#", 309 "#....#", 310 ".####.", 311 }, 312 'V' => .{ 313 "#....#", 314 "#....#", 315 "#....#", 316 ".#..#.", 317 ".#..#.", 318 ".#..#.", 319 ".#..#.", 320 ".#..#.", 321 "..##..", 322 }, 323 'W' => .{ 324 "#....#", 325 "#....#", 326 "#....#", 327 "#....#", 328 "#....#", 329 "#.##.#", 330 "#.##.#", 331 "##..##", 332 ".#..#.", 333 }, 334 'X' => .{ 335 "#....#", 336 ".#..#.", 337 ".#..#.", 338 "..##..", 339 "..##..", 340 "..##..", 341 ".#..#.", 342 ".#..#.", 343 "#....#", 344 }, 345 'Y' => .{ 346 "#....#", 347 ".#..#.", 348 ".#..#.", 349 "..##..", 350 "..##..", 351 "..##..", 352 "..##..", 353 "..##..", 354 "..##..", 355 }, 356 'Z' => .{ 357 "######", 358 "....#.", 359 "....#.", 360 "...#..", 361 "..##..", 362 "..#...", 363 ".#....", 364 ".#....", 365 "######", 366 }, 367 '0' => .{ 368 ".####.", 369 "#...##", 370 "#..#.#", 371 "#..#.#", 372 "#.#..#", 373 "#.#..#", 374 "##...#", 375 "#....#", 376 ".####.", 377 }, 378 '1' => .{ 379 "..##..", 380 ".###..", 381 "..##..", 382 "..##..", 383 "..##..", 384 "..##..", 385 "..##..", 386 "..##..", 387 "######", 388 }, 389 '2' => .{ 390 ".####.", 391 "#....#", 392 ".....#", 393 "....#.", 394 "...#..", 395 "..#...", 396 ".#....", 397 "#.....", 398 "######", 399 }, 400 '3' => .{ 401 ".####.", 402 "#....#", 403 ".....#", 404 ".....#", 405 ".####.", 406 ".....#", 407 ".....#", 408 "#....#", 409 ".####.", 410 }, 411 '4' => .{ 412 "....#.", 413 "...##.", 414 "..#.#.", 415 ".#..#.", 416 "#...#.", 417 "######", 418 "....#.", 419 "....#.", 420 "....#.", 421 }, 422 '5' => .{ 423 "######", 424 "#.....", 425 "#.....", 426 "#.....", 427 "#####.", 428 ".....#", 429 ".....#", 430 "#....#", 431 ".####.", 432 }, 433 '6' => .{ 434 ".####.", 435 "#....#", 436 "#.....", 437 "#.....", 438 "#####.", 439 "#....#", 440 "#....#", 441 "#....#", 442 ".####.", 443 }, 444 '7' => .{ 445 "######", 446 ".....#", 447 "....#.", 448 "....#.", 449 "...#..", 450 "...#..", 451 "..#...", 452 "..#...", 453 ".#....", 454 }, 455 '8' => .{ 456 ".####.", 457 "#....#", 458 "#....#", 459 "#....#", 460 ".####.", 461 "#....#", 462 "#....#", 463 "#....#", 464 ".####.", 465 }, 466 '9' => .{ 467 ".####.", 468 "#....#", 469 "#....#", 470 "#....#", 471 ".#####", 472 ".....#", 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 else => null, 500 }; 501 } 502 503 // map a 2x3 sub-pixel pattern to its corresponding sextant codepoint 504 fn sextantCodepoint(pattern: u6) u21 { 505 return switch (pattern) { 506 0b000000 => ' ', 507 0b010101 => 0x258C, // ▌ left half block 508 0b101010 => 0x2590, // ▐ right half block 509 0b111111 => 0x2588, // █ full block 510 else => blk: { 511 var offset: u21 = @as(u21, pattern) - 1; 512 if (pattern > 0b010101) offset -= 1; 513 if (pattern > 0b101010) offset -= 1; 514 break :blk 0x1FB00 + offset; 515 }, 516 }; 517 } 518 519 fn renderTitle(allocator: std.mem.Allocator, input: []const u8) ![]const u8 { 520 var rows: [3]std.ArrayList(u8) = .{ .empty, .empty, .empty }; 521 defer for (&rows) |*r| r.deinit(allocator); 522 523 var first = true; 524 for (input) |c| { 525 const glyph = glyphFor(c) orelse continue; 526 527 // row-aligned dither: keep on-pixels only at even bitmap rows. 528 var kept: [9][6]bool = std.mem.zeroes([9][6]bool); 529 for (0..9) |r| { 530 if (r % 2 != 0) continue; 531 for (0..6) |col| { 532 kept[r][col] = glyph[r][col] == '#'; 533 } 534 } 535 536 if (!first) { 537 for (&rows) |*r| try r.append(allocator, ' '); 538 } 539 first = false; 540 541 for (0..3) |text_row| { 542 for (0..3) |text_col| { 543 var pattern: u6 = 0; 544 for (0..3) |sub_row| { 545 for (0..2) |sub_col| { 546 const row_idx = text_row * 3 + sub_row; 547 const col_idx = text_col * 2 + sub_col; 548 if (kept[row_idx][col_idx]) { 549 pattern |= @as(u6, 1) << @intCast(sub_row * 2 + sub_col); 550 } 551 } 552 } 553 const cp = sextantCodepoint(pattern); 554 var utf8_buf: [4]u8 = undefined; 555 const len = try std.unicode.utf8Encode(cp, &utf8_buf); 556 try rows[text_row].appendSlice(allocator, utf8_buf[0..len]); 557 } 558 } 559 } 560 561 var out: std.ArrayList(u8) = .empty; 562 errdefer out.deinit(allocator); 563 try out.appendSlice(allocator, rows[0].items); 564 try out.append(allocator, '\n'); 565 try out.appendSlice(allocator, rows[1].items); 566 try out.append(allocator, '\n'); 567 try out.appendSlice(allocator, rows[2].items); 568 return out.toOwnedSlice(allocator); 569 } 570