bendn 7 months ago
parent 9c5cd14 · commit 77efeb2
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml7
-rw-r--r--src/lib.rs88
-rw-r--r--tests/test.rs44
4 files changed, 104 insertions, 37 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 02b5076..fc09bba 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -89,8 +89,6 @@ checksum = "6a02dba6a60cd31533cf16561ced53239686d18f1464bff49579dd320fcea081"
[[package]]
name = "fimg"
version = "0.4.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6739c38489a0264e04537f68b822f4cb7abb732b41eca5229a91685fcc998939"
dependencies = [
"atools",
"clipline",
diff --git a/Cargo.toml b/Cargo.toml
index 3c70a4d..a5abfc6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,6 +5,11 @@ edition = "2024"
[dependencies]
atools = "0.1.6"
-fimg = "0.4.45"
+fimg = { path = "../fimg" }
+# fimg = { git = "https://github.com/bend-n/fimg" }
implicit-fn = "0.1.0"
swash = "0.2.5"
+
+[[test]]
+name = "test"
+harness = false
diff --git a/src/lib.rs b/src/lib.rs
index db47456..4c51e49 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,3 +1,5 @@
+// |jlfJKlBM
+// |||||||||||||||||||||||||||||||||||||
#![allow(incomplete_features)]
#![feature(
super_let,
@@ -12,7 +14,7 @@
import_trait_associated_functions
)]
use std::iter::zip;
-mod cell;
+pub mod cell;
use atools::Join;
use swash::FontRef;
use swash::scale::{Render, ScaleContext, Source};
@@ -46,36 +48,42 @@ impl<'a, 'b, 'c, 'd> Fonts<'a, 'b, 'c, 'd> {
#[implicit_fn::implicit_fn]
pub unsafe fn render(
cells: &[Cell],
- (w, h): (usize, usize),
+ (c, r): (usize, usize),
ppem: f32,
bgcolor: [u8; 3],
fonts: Fonts,
+ line_spacing: f32,
) -> Image<Box<[u8]>, 3> {
- let m = fonts.regular.metrics(&[]);
- let sz = ppem * (m.max_width / m.units_per_em as f32);
+ assert_eq!(c * r, cells.len(), "cells too short.");
+
+ let (fw, h) = dims(&fonts.regular, ppem, line_spacing);
+ let fh = h - line_spacing;
+ let (w, h) = ((fw * c as f32).ceil() as u32, (h * r as f32).ceil() as u32);
let mut i = Image::build(w as _, h as _).fill(bgcolor);
if w < 60 || h < 60 {
return i;
}
- for (col, k) in cells.chunks_exact(w as _).zip(0..) {
+ for (col, k) in cells.chunks_exact(c as _).zip(0..) {
for (&cell, j) in zip(col, 0..) {
if cell.style.bg != bgcolor {
- let cell = Image::<_, 4>::build(sz.ceil() as u32, (ppem * 1.25).ceil() as u32)
- .fill(cell.style.bg.join(255));
+ let cell =
+ Image::<_, 4>::build(fw.ceil() as u32, (fh + line_spacing).round() as u32)
+ .fill(cell.style.bg.join(255));
+
unsafe {
i.as_mut().overlay_at(
&cell,
- 4 + (j as f32 * sz) as u32,
- (k as f32 * (ppem * 1.25)) as u32 - 20,
+ (j as f32 * fw).round() as u32,
+ (((k) as f32 * fh) + ((k as f32) * line_spacing as f32)).round() as u32,
)
};
}
}
}
- let mut characters: Vec<Glyph> = vec![Glyph::default(); w];
+ let mut characters: Vec<Glyph> = vec![Glyph::default(); c];
- for (col, k) in cells.chunks_exact(w as _).zip(0..) {
+ for (col, k) in cells.chunks_exact(c as _).zip(0..) {
let tokenized = col.iter().enumerate().map(|(i, cell)| {
let ch = cell.letter.unwrap_or(' ');
(
@@ -130,24 +138,24 @@ pub unsafe fn render(
if (cell.style.flags & Style::DIM) != 0 {
color = color.map(|x| x / 2);
}
- if (cell.style.flags & Style::UNDERLINE) != 0 {
- unsafe {
- i.as_mut().overlay_at(
- &Image::<_, 4>::build(sz.ceil() as u32, 2).fill(color.join(255)),
- 4 + (j as f32 * sz) as u32,
- (k as f32 * (ppem * 1.25)) as u32 + 5,
- )
- };
- }
- if (cell.style.flags & Style::STRIKETHROUGH) != 0 {
- unsafe {
- i.as_mut().overlay_at(
- &Image::<_, 4>::build(sz.ceil() as u32, 2).fill(color.join(255)),
- 4 + (j as f32 * sz) as u32,
- (k as f32 * (ppem * 1.25)) as u32 - 5,
- )
- };
- }
+ // if (cell.style.flags & Style::UNDERLINE) != 0 {
+ // unsafe {
+ // i.as_mut().overlay_at(
+ // &Image::<_, 4>::build(fw.ceil() as u32, 2).fill(color.join(255)),
+ // 4 + (j as f32 * fw as u32,
+ // (k as f32 * (ppem * 1.25)) as u32 + 5,
+ // )
+ // };
+ // }
+ // if (cell.style.flags & Style::STRIKETHROUGH) != 0 {
+ // unsafe {
+ // i.as_mut().overlay_at(
+ // &Image::<_, 4>::build(fw.ceil() as u32, 2).fill(color.join(255)),
+ // 4 + (j as f32 * fw) as u32,
+ // (k as f32 * (ppem * 1.25)) as u32 - 5,
+ // )
+ // };
+ // }
if let Some(_) = cell.letter {
let f = match cell.style.flags {
f if f & (Style::BOLD | Style::ITALIC) != 0 => fonts.bold_italic,
@@ -173,8 +181,12 @@ pub unsafe fn render(
i.as_mut().blend_alpha_and_color_at(
&item.as_ref(),
color,
- 4 + ((j as f32 * sz + glyph.x) + x.placement.left as f32).round() as u32,
- ((k as f32 * (ppem * 1.25)) as u32).saturating_sub(x.placement.top as u32),
+ ((j as f32 * fw + glyph.x) + x.placement.left as f32).round() as u32,
+ (
+ dbg!(((k + 1) as f32 * fh) - (x.placement.top as f32))
+ // + ((k as f32) * line_spacing as f32)
+ )
+ .round() as u32,
);
}
}
@@ -195,9 +207,17 @@ pub unsafe fn render(
i
}
-pub fn dims(font: &FontRef, ppem: f32) -> (f32, f32) {
+pub fn dims(font: &FontRef, ppem: f32, line_spacing: f32) -> (f32, f32) {
+ // ppem * (m.max_width / m.units_per_em as f32),
+ // m.max_width * (ppem / m.units_per_em as f32);
let m = font.metrics(&[]);
- (ppem * (m.max_width / m.units_per_em as f32), ppem * 1.25)
+ let f = ppem / m.units_per_em as f32;
+ (
+ m.max_width * f,
+ m.ascent * f + line_spacing,
+ // ((ppem + line_spacing) * (m.ascent / m.units_per_em as f32)),
+ )
}
-use crate::cell::{Cell, Style};
+pub use crate::cell::Cell;
+use crate::cell::Style;
use fimg::{Image, OverlayAt};
diff --git a/tests/test.rs b/tests/test.rs
new file mode 100644
index 0000000..f8d6aa2
--- /dev/null
+++ b/tests/test.rs
@@ -0,0 +1,44 @@
+use std::sync::LazyLock;
+
+use dsb::{Fonts, cell::Style};
+use swash::FontRef;
+
+fn main() {
+ let ppem = 300.0;
+ let lh = 0.0;
+ let (fw, fh) = dsb::dims(&FONT, ppem, lh);
+ let (w, h) = (2000, 2000);
+
+ let cols = (w as f32 / fw).floor() as usize;
+ let rows = (h as f32 / fh).floor() as usize;
+
+ dbg!(cols, rows);
+
+ let cells = include_str!("../src/lib.rs")
+ .chars()
+ .filter(|x| !x.is_whitespace())
+ .take(cols * rows)
+ .map(|x: char| dsb::Cell {
+ style: Style {
+ bg: [0; 3],
+ color: [255; 3],
+ flags: 0,
+ },
+ letter: Some(x),
+ })
+ .collect::<Vec<_>>();
+ unsafe {
+ dsb::render(
+ &cells,
+ (cols, rows),
+ ppem,
+ [1; 3],
+ Fonts::new(*FONT, *FONT, *FONT, *FONT),
+ lh,
+ )
+ }
+ .show();
+}
+pub static FONT: LazyLock<FontRef<'static>> = LazyLock::new(|| {
+ FontRef::from_index(&include_bytes!("/home/os/CascadiaCodeNF.ttf")[..], 0).unwrap()
+});