use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
use super::Buffer;
use crate::render::Style;
const WIDE_CLIP_PLACEHOLDER: &str = "…";
impl Buffer {
pub fn set_symbol(&mut self, x: u16, y: u16, symbol: &str, style: Style) {
if let Some(c) = self.cell_mut(x, y) {
c.set_symbol(symbol);
c.apply_style(style);
}
}
pub fn set_char(&mut self, x: u16, y: u16, ch: char, style: Style) {
let mut buf = [0u8; 4];
let s: &str = ch.encode_utf8(&mut buf);
self.set_symbol(x, y, s, style);
}
pub fn set_style(&mut self, x: u16, y: u16, style: Style) {
if let Some(c) = self.cell_mut(x, y) {
c.apply_style(style);
}
}
pub fn set_link_range(&mut self, x: u16, y: u16, width: u16, link: Option<&str>) {
for dx in 0..width {
let cx = x.saturating_add(dx);
if let Some(cell) = self.cell_mut(cx, y) {
cell.set_link(link);
}
}
}
pub fn set_string(&mut self, x: u16, y: u16, s: &str, style: Style) -> (u16, u16) {
self.set_stringn(x, y, s, self.area.width, style)
}
pub fn set_stringn(
&mut self,
x: u16,
y: u16,
s: &str,
max_width: u16,
style: Style,
) -> (u16, u16) {
if y < self.area.y || y >= self.area.bottom() {
return (x, y);
}
if x >= self.area.right() {
return (x, y);
}
let buffer_room = self.area.right().saturating_sub(x);
let budget = max_width.min(buffer_room);
if budget == 0 {
return (x, y);
}
let mut cursor_x = x;
let mut cells_written: u16 = 0;
for grapheme in s.graphemes(true) {
let first = grapheme.chars().next().unwrap_or(' ');
if first.is_control() {
continue;
}
let w = UnicodeWidthStr::width(grapheme) as u16;
if w == 0 {
continue;
}
if cells_written + w > budget {
if w == 2 && budget - cells_written == 1 {
if let Some(c) = self.cell_mut(cursor_x, y) {
c.set_symbol(WIDE_CLIP_PLACEHOLDER);
c.apply_style(style);
}
cursor_x = cursor_x.saturating_add(1);
}
break;
}
if let Some(c) = self.cell_mut(cursor_x, y) {
c.set_symbol(grapheme);
c.apply_style(style);
}
if w == 2 {
let spacer_x = cursor_x.saturating_add(1);
if let Some(c) = self.cell_mut(spacer_x, y) {
c.set_spacer();
c.apply_style(style);
}
}
cursor_x = cursor_x.saturating_add(w);
cells_written += w;
}
(cursor_x, y)
}
}