rmux_core/screen/
capture.rs1use crate::grid::{Grid, GridCapture, GridRenderOptions, GridStringState};
2use crate::hyperlinks::Hyperlinks;
3use crate::transcript::{resolve_screen_capture_range, ScreenCaptureRange};
4
5use super::Screen;
6
7impl Screen {
8 #[cfg_attr(not(test), allow(dead_code))]
9 #[must_use]
10 pub(crate) fn capture_grid(&self, join_wrapped: bool) -> GridCapture {
11 self.grid.capture(join_wrapped)
12 }
13
14 #[must_use]
16 pub fn capture_transcript(
17 &self,
18 range: ScreenCaptureRange,
19 options: GridRenderOptions,
20 ) -> Vec<u8> {
21 capture_grid_bytes(&self.grid, &self.hyperlinks, range, options)
22 }
23
24 #[must_use]
30 pub fn capture_transcript_lines_independent(
31 &self,
32 range: ScreenCaptureRange,
33 options: GridRenderOptions,
34 ) -> Vec<Vec<u8>> {
35 capture_grid_lines_independent(&self.grid, &self.hyperlinks, range, options)
36 }
37
38 #[must_use]
40 pub fn capture_saved_transcript(
41 &self,
42 range: ScreenCaptureRange,
43 options: GridRenderOptions,
44 ) -> Option<Vec<u8>> {
45 self.saved_grid
46 .as_ref()
47 .map(|saved| capture_grid_bytes(&saved.grid, &self.hyperlinks, range, options))
48 }
49}
50
51fn capture_grid_lines_independent(
52 grid: &Grid,
53 hyperlinks: &Hyperlinks,
54 range: ScreenCaptureRange,
55 options: GridRenderOptions,
56) -> Vec<Vec<u8>> {
57 let total_lines = grid.hsize() + usize::try_from(grid.sy()).unwrap_or(usize::MAX);
58 let Some(range) = resolve_screen_capture_range(range, grid.hsize(), total_lines) else {
59 return Vec::new();
60 };
61
62 let mut output = Vec::new();
63 for absolute_y in range {
64 let mut state = GridStringState::default();
65 let Some(line) =
66 grid.render_absolute_line(absolute_y, options, &mut state, Some(hyperlinks))
67 else {
68 continue;
69 };
70 output.push(line.into_bytes());
71 }
72 output
73}
74
75fn capture_grid_bytes(
76 grid: &Grid,
77 hyperlinks: &Hyperlinks,
78 range: ScreenCaptureRange,
79 options: GridRenderOptions,
80) -> Vec<u8> {
81 let total_lines = grid.hsize() + usize::try_from(grid.sy()).unwrap_or(usize::MAX);
82 let Some(range) = resolve_screen_capture_range(range, grid.hsize(), total_lines) else {
83 return Vec::new();
84 };
85
86 let mut output = Vec::new();
87 let mut state = GridStringState::default();
88 for absolute_y in range {
89 let Some(line) =
90 grid.render_absolute_line(absolute_y, options, &mut state, Some(hyperlinks))
91 else {
92 continue;
93 };
94 output.extend_from_slice(line.as_bytes());
95 let wrapped = grid.absolute_line_wrapped(absolute_y).unwrap_or(false);
96 if !options.join_wrapped || !wrapped {
97 output.push(b'\n');
98 }
99 }
100 output
101}