1
0
Fork 0
codesnap.nvim/generator/src/text.rs

105 lines
2.8 KiB
Rust

use cosmic_text::{
Align, Attrs, AttrsList, Buffer, BufferLine, Color, FontSystem, Metrics, Shaping, SwashCache,
};
use tiny_skia::{Paint, Pixmap, Rect, Transform};
pub struct FontRenderer {
font_system: FontSystem,
scale_factor: f32,
metrics: Metrics,
}
impl FontRenderer {
pub fn new(
font_size: f32,
line_height: f32,
scale_factor: f32,
fonts_folder: &str,
) -> FontRenderer {
let mut font_system = FontSystem::new();
font_system.db_mut().load_fonts_dir(fonts_folder);
let metrics = Metrics::new(font_size, line_height).scale(scale_factor.clone());
FontRenderer {
metrics,
font_system,
scale_factor,
}
}
pub fn draw_text(
&mut self,
x: f32,
y: f32,
w: f32,
h: f32,
spans: Vec<(&str, Attrs)>,
pixmap: &mut Pixmap,
) {
let mut buffer = Buffer::new(&mut self.font_system, self.metrics);
buffer.set_size(
&mut self.font_system,
w * self.scale_factor,
h * self.scale_factor,
);
buffer.set_rich_text(
&mut self.font_system,
spans,
Attrs::new(),
Shaping::Advanced,
);
self.draw(x, y, &mut buffer, pixmap);
}
pub fn draw_line(
&mut self,
x: f32,
y: f32,
w: f32,
h: f32,
line: &str,
attrs: Attrs,
align: Option<Align>,
pixmap: &mut Pixmap,
) {
let mut buffer = Buffer::new(&mut self.font_system, self.metrics);
let mut line = BufferLine::new(line, AttrsList::new(attrs), Shaping::Advanced);
line.set_align(align);
buffer.lines = vec![line];
buffer.set_size(&mut self.font_system, w, h);
self.draw(x, y, &mut buffer, pixmap);
}
fn draw<'a>(&mut self, x: f32, y: f32, buffer: &mut Buffer, pixmap: &mut Pixmap) {
let mut swash_cache = SwashCache::new();
let default_font_color = Color::rgb(255, 255, 255);
buffer.draw(
&mut self.font_system,
&mut swash_cache,
default_font_color,
|font_x, font_y, w, h, color| {
let mut paint = Paint {
anti_alias: true,
..Default::default()
};
paint.set_color_rgba8(color.r(), color.g(), color.b(), color.a());
let rect = Rect::from_xywh(
font_x as f32 + x * self.scale_factor,
font_y as f32 + y * self.scale_factor,
w as f32,
h as f32,
)
.expect("Cannot draw text on pixmap");
pixmap.fill_rect(rect, &paint, Transform::identity(), None);
},
);
}
}