small software-rendered rust tty
Diffstat (limited to 'src/render.rs')
| -rw-r--r-- | src/render.rs | 101 |
1 files changed, 69 insertions, 32 deletions
diff --git a/src/render.rs b/src/render.rs index b52ce56..64a2f2a 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,18 +1,22 @@ use std::sync::LazyLock; +use atools::Join; +use fimg::BlendingOverlayAt; use swash::FontRef; use swash::scale::{Render, ScaleContext, Source}; use swash::zeno::Format; +use crate::colors; + #[implicit_fn::implicit_fn] pub fn render( x: &super::Terminal, (w, h): (usize, usize), ppem: f32, -) -> Image<Vec<u8>, 3> { +) -> Image<Box<[u8]>, 3> { let m = FONT.metrics(&[]); let sz = ppem * (m.max_width / m.units_per_em as f32); - let mut i = Image::alloc(w as _, h as _); + let mut i = Image::build(w as _, h as _).fill(colors::BACKGROUND); for (col, k) in x.cells.chunks_exact(x.size.0 as _).zip(0..).skip(1) { for (cell, j) in col.iter().skip(2).zip(0..).filter(_.0.letter.is_some()) @@ -33,19 +37,34 @@ pub fn render( if x.placement.width == 0 { continue; } - i.as_mut().overlay_at( - &Image::<Box<[u8]>, 4>::from( - Image::<_, 1>::build( - x.placement.width, - x.placement.height, - ) - .buf(&*x.data), - ) - .as_ref(), + let item = Image::<_, 4>::build( + x.placement.width, + x.placement.height, + ) + .buf( + x.data + .iter() + .flat_map(|&x| cell.style.color.join(x)) + .collect::<Vec<u8>>(), + ); + // let mut o = + // Image::build(x.placement.width, x.placement.height) + // .fill(cell.style.bg); + // o.overlay_blended(&item); + + i.as_mut().overlay_blended_at( + &item.as_ref(), + // &Image::<Box<[u8]>, 4>::from( + // Image::<_, 1>::build( + // x.placement.width, + // x.placement.height, + // ) + // .buf(&*x.data), + // ) + // .as_ref(), 4 + ((j as f32 * sz) + x.placement.left as f32) as u32, ((k as f32 * (ppem * 1.25)) as u32) .saturating_sub(x.placement.top as u32), - // x.placement.height - x.placement.top as u32, ); } } @@ -63,38 +82,29 @@ pub static FONT: LazyLock<FontRef<'static>> = LazyLock::new(|| { .unwrap() }); -use fimg::{Image, OverlayAt}; +use fimg::{BlendingOverlay, Image, OverlayAt}; // let x = b"echo -e \"\x1b(0lqqqk\nx \x1b(Bx\nmqqqj"; // let x = String::from_utf8_lossy(&x); // println!("{}", x); #[test] fn t() { let f = - FontRef::from_index(&include_bytes!("../CascadiaCode.ttf")[..], 0) - .unwrap(); + FontRef::from_index(&include_bytes!("../cjk.ttc")[..], 0).unwrap(); dbg!(f.attributes()); - let m = f.metrics(&[]); - dbg!(m); + let m = f.metrics(&[f.charmap().map('行') as _]); + let ppem = 30.0; - let sz = ppem * (m.max_width / m.units_per_em as f32); - dbg!( - &mut ScaleContext::new() - .builder(f) - .size(15.0) - .build() - .scale_outline(f.charmap().map('a')) - .unwrap() - .len() - ); - let mut grid = Image::<_, 4>::alloc(2000, 150); + let d = dims(&FONT, ppem); + let sz = d.0; + let mut grid = Image::<_, 4>::alloc(2000, 500); unsafe { grid.chunked_mut().for_each(|x| *x = [0, 0, 0, 255]) }; - for (letter, i) in "the quick brown fox jumped over the lazy dog" + for (letter, i) in "素早い茶色のキツネは怠け者の犬を飛び越えた" .chars() .zip(0..) { + // grid.as_ref().show(); let id = f.charmap().map(letter); - let x = Render::new(&[Source::Outline]) .format(Format::Alpha) .render( @@ -115,9 +125,36 @@ fn t() { .buf(&*x.data), ) .as_ref(), - ((i * sz as i32) + x.placement.left) as _, + ((i as f32 * sz * 2.0) as i32 + x.placement.left) as _, ppem as u32 - x.placement.top as u32, - // x.placement.height - x.placement.top as u32, + ); + } + } + for (letter, i) in "#".repeat(21 * 2).chars().zip(0..) { + // grid.as_ref().show(); + let id = FONT.charmap().map(letter); + let x = Render::new(&[Source::Outline]) + .format(Format::Alpha) + .render( + &mut ScaleContext::new().builder(*FONT).size(ppem).build(), + id, + ) + .unwrap(); + unsafe { + if x.placement.width == 0 { + continue; + } + grid.as_mut().overlay_at( + &Image::<Box<[u8]>, 4>::from( + Image::<_, 1>::build( + x.placement.width, + x.placement.height, + ) + .buf(&*x.data), + ) + .as_ref(), + ((i as f32 * sz) as i32 + x.placement.left) as _, + 30 + ppem as u32 - x.placement.top as u32, ); } } |