1use crossterm::style::{Attribute, Color as CtColor, ContentStyle};
4use emux_term::grid::{Cell, UnderlineStyle};
5use emux_term::Color;
6
7pub fn color_to_crossterm(color: &Color) -> CtColor {
9 match color {
10 Color::Default => CtColor::Reset,
11 Color::Indexed(idx) => CtColor::AnsiValue(*idx),
12 Color::Rgb(r, g, b) => CtColor::Rgb { r: *r, g: *g, b: *b },
13 }
14}
15
16pub fn cell_style(cell: &Cell) -> ContentStyle {
18 let mut style = ContentStyle::new();
19 style.foreground_color = Some(color_to_crossterm(&cell.fg));
20 style.background_color = Some(color_to_crossterm(&cell.bg));
21
22 if cell.attrs.bold {
23 style.attributes.set(Attribute::Bold);
24 }
25 if cell.attrs.italic {
26 style.attributes.set(Attribute::Italic);
27 }
28 match cell.attrs.underline {
29 UnderlineStyle::None => {}
30 UnderlineStyle::Single => {
31 style.attributes.set(Attribute::Underlined);
32 }
33 UnderlineStyle::Double => {
34 style.attributes.set(Attribute::DoubleUnderlined);
35 }
36 UnderlineStyle::Curly => {
37 style.attributes.set(Attribute::Undercurled);
38 }
39 }
40 if cell.attrs.blink {
41 style.attributes.set(Attribute::SlowBlink);
42 }
43 if cell.attrs.reverse {
44 style.attributes.set(Attribute::Reverse);
45 }
46 if cell.attrs.invisible {
47 style.attributes.set(Attribute::Hidden);
48 }
49 if cell.attrs.strikethrough {
50 style.attributes.set(Attribute::CrossedOut);
51 }
52
53 style
54}
55
56pub fn render_row(cells: &[Cell], width: usize) -> Vec<(ContentStyle, String)> {
62 let mut spans: Vec<(ContentStyle, String)> = Vec::new();
63 let mut col = 0;
64
65 for cell in cells.iter().take(width) {
66 if cell.width == 0 {
68 col += 1;
69 continue;
70 }
71
72 let style = cell_style(cell);
73 let ch = if cell.c < ' ' { ' ' } else { cell.c };
74
75 if let Some(last) = spans.last_mut() {
76 if last.0 == style {
77 last.1.push(ch);
78 } else {
79 spans.push((style, ch.to_string()));
80 }
81 } else {
82 spans.push((style, ch.to_string()));
83 }
84
85 col += cell.width as usize;
86 }
87
88 while col < width {
90 let style = ContentStyle::new();
91 if let Some(last) = spans.last_mut() {
92 if last.0 == style {
93 last.1.push(' ');
94 } else {
95 spans.push((style, " ".to_string()));
96 }
97 } else {
98 spans.push((style, " ".to_string()));
99 }
100 col += 1;
101 }
102
103 spans
104}