Add Renderer trait for more flexible rendering of buffers and editors

This commit is contained in:
Jeremy Soller 2025-11-06 11:23:11 -07:00
parent 8a7bc790e5
commit 9339446cfa
No known key found for this signature in database
GPG key ID: 670FDFB5428E05CA
7 changed files with 135 additions and 79 deletions

View file

@ -1,15 +1,13 @@
use alloc::{collections::BTreeMap, string::String};
#[cfg(feature = "swash")]
use core::cmp;
use modit::{Event, Key, Parser, TextObject, WordIter};
use crate::{
Action, AttrsList, BorrowedWithFontSystem, BufferRef, Change, Color, Cursor, Edit, FontSystem,
Motion, Selection, SyntaxEditor, SyntaxTheme,
Motion, Renderer, Selection, SyntaxEditor, SyntaxTheme,
};
pub use modit::{ViMode, ViParser};
#[cfg(feature = "swash")]
use unicode_segmentation::UnicodeSegmentation;
fn undo_2_action<'buffer, E: Edit<'buffer>>(
@ -305,10 +303,19 @@ impl<'syntax_system, 'buffer> ViEditor<'syntax_system, 'buffer> {
}
#[cfg(feature = "swash")]
pub fn draw<F>(&self, font_system: &mut FontSystem, cache: &mut crate::SwashCache, mut f: F)
pub fn draw<F>(&self, font_system: &mut FontSystem, cache: &mut crate::SwashCache, callback: F)
where
F: FnMut(i32, i32, u32, u32, Color),
{
let mut renderer = crate::LegacyRenderer {
font_system,
cache,
callback,
};
self.render(&mut renderer);
}
pub fn render<R: Renderer>(&self, renderer: &mut R) {
let background_color = self.background_color();
let foreground_color = self.foreground_color();
let cursor_color = self.cursor_color();
@ -317,7 +324,7 @@ impl<'syntax_system, 'buffer> ViEditor<'syntax_system, 'buffer> {
let size = buffer.size();
if let Some(width) = size.0 {
if let Some(height) = size.1 {
f(0, 0, width as u32, height as u32, background_color);
renderer.rectangle(0, 0, width as u32, height as u32, background_color);
}
}
let font_size = buffer.metrics().font_size;
@ -388,7 +395,7 @@ impl<'syntax_system, 'buffer> ViEditor<'syntax_system, 'buffer> {
None => Some((c_x as i32, (c_x + c_w) as i32)),
};
} else if let Some((min, max)) = range_opt.take() {
f(
renderer.rectangle(
min,
line_top as i32,
cmp::max(0, max - min) as u32,
@ -414,7 +421,7 @@ impl<'syntax_system, 'buffer> ViEditor<'syntax_system, 'buffer> {
max = buffer.size().0.unwrap_or(0.0) as i32;
}
}
f(
renderer.rectangle(
min,
line_top as i32,
cmp::max(0, max - min) as u32,
@ -476,7 +483,7 @@ impl<'syntax_system, 'buffer> ViEditor<'syntax_system, 'buffer> {
if block_cursor {
let left_x = cmp::min(start_x, end_x);
let right_x = cmp::max(start_x, end_x);
f(
renderer.rectangle(
left_x,
line_top as i32,
(right_x - left_x) as u32,
@ -484,7 +491,7 @@ impl<'syntax_system, 'buffer> ViEditor<'syntax_system, 'buffer> {
selection_color,
);
} else {
f(
renderer.rectangle(
start_x,
line_top as i32,
1,
@ -495,27 +502,14 @@ impl<'syntax_system, 'buffer> ViEditor<'syntax_system, 'buffer> {
}
for glyph in run.glyphs.iter() {
let physical_glyph = glyph.physical((0., 0.), 1.0);
let physical_glyph = glyph.physical((0., line_y), 1.0);
let glyph_color = match glyph.color_opt {
Some(some) => some,
None => foreground_color,
};
cache.with_pixels(
font_system,
physical_glyph.cache_key,
glyph_color,
|x, y, color| {
f(
physical_glyph.x + x,
line_y as i32 + physical_glyph.y + y,
1,
1,
color,
);
},
);
renderer.glyph(physical_glyph, glyph_color);
}
}
});