╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ ui.zig ───────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
2997 const dst = &out.cells.items[idx]; 2998 // composite the dimmed art behind every cell so it shows 2999 // through the whole UI: a blank cell becomes the art, while a 3000 // cell with a glyph keeps the glyph but takes the dimmed art as 3001 // its background (replacing whatever background it had, which 3002 // would otherwise obscure the art). 3003 if (cellIsBlank(dst.*)) { 3004 dst.* = src; 3005 dst.style.fg = sgrSafe(dimColor(dst.style.fg)); 3006 dst.style.bg = sgrSafe(dimColor(dst.style.bg)); 3007 } else { 3008 const background_maybe = sgrSafe(dimColor(src.style.bg orelse src.style.fg)); 3009 dst.style.bg = background_maybe; 3010 // change the color of text overlaying ANSI art to ensure 3011 // it is readable. don't do this in the web UI, since we 3012 // have direct control of the theme there (also, inner 3013 // scroll panes allow text to move without a re-render 3014 // by the TUI, which would break this). also don't do this 3015 // if the text is explicitly styled. 3016 if (is_terminal and dst.style.fg == null) { 3017 if (background_maybe) |background| { 3018 // use near-black and near-white, which is easier on the eyes 3019 // while retaining high contrast 3020 const luminance = (@as(u32, background.r) * 299 + 3021 @as(u32, background.g) * 587 + 3022 @as(u32, background.b) * 114) / 1000; 3023 dst.style.fg = if (luminance >= 128) 3024 .{ .r = 16, .g = 16, .b = 16 } 3025 else 3026 .{ .r = 240, .g = 240, .b = 240 }; 3027 } 3028 } 3029 } 3030 } 3031 } 3032 } 3033 return out; 3034 } 3035 }; 3036