╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ ui.zig ───────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
2571 var out = try Grid.initFromGrid(allocator, foreground, foreground.size, 0, 0); 2572 errdefer out.deinit(); 2573 2574 if (art.getGrid()) |art_grid| { 2575 const anchor_x = switch (anchor) { 2576 .top_left => 0, 2577 .top_right => foreground.size.width -| art_grid.size.width, 2578 }; 2579 for (0..art_grid.size.height) |y| { 2580 for (0..art_grid.size.width) |x| { 2581 const src = art_grid.cells.items[try art_grid.cells.at(.{ y, x })]; 2582 if (src.rune == null) continue; 2583 const idx = out.cells.at(.{ y, anchor_x + x }) catch continue; 2584 const dst = &out.cells.items[idx]; 2585 // composite the dimmed art behind every cell so it shows 2586 // through the whole UI: a blank cell becomes the art, while a 2587 // cell with a glyph keeps the glyph but takes the dimmed art as 2588 // its background (replacing whatever background it had, which 2589 // would otherwise obscure the art). 2590 if (cellIsBlank(dst.*)) { 2591 dst.* = src; 2592 dst.style.fg = sgrSafe(dimColor(dst.style.fg)); 2593 dst.style.bg = sgrSafe(dimColor(dst.style.bg)); 2594 } else { 2595 const background_maybe = sgrSafe(dimColor(src.style.bg orelse src.style.fg)); 2596 dst.style.bg = background_maybe; 2597 // change the color of text overlaying ANSI art to ensure 2598 // it is readable. don't do this in the web UI, since we 2599 // have direct control of the theme there (also, inner 2600 // scroll panes allow text to move without a re-render 2601 // by the TUI, which would break this). also don't do this 2602 // if the text is explicitly styled. 2603 if (is_terminal and dst.style.fg == null) { 2604 if (background_maybe) |background| { 2605 // use near-black and near-white, which is easier on the eyes 2606 // while retaining high contrast 2607 const luminance = (@as(u32, background.r) * 299 + 2608 @as(u32, background.g) * 587 + 2609 @as(u32, background.b) * 114) / 1000; 2610 dst.style.fg = if (luminance >= 128) 2611 .{ .r = 16, .g = 16, .b = 16 } 2612 else 2613 .{ .r = 240, .g = 240, .b = 240 }; 2614 } 2615 } 2616 } 2617 } 2618 } 2619 } 2620 return out; 2621 } 2622 }; 2623