Files
filmcraft/crates/render/tests/underline_direction.rs
Vikram Bhaskaran 66c2e63092 Draw underlines for vertical graphic text.
The vertical layout path never emitted underline rectangles, so layer and
run underlines were a no-op. Place a tall strip to the right of each
underlined cell (vertical-rl) and compare horizontal vs vertical "A" at 60px.
2026-10-11 22:49:08 +11:00

60 lines
2.1 KiB
Rust

//! Horizontal vs vertical graphic text with underline (letter A, 60 px).
use filmcraft_geom::{Affine, Vec2};
use filmcraft_project::graphic::{new_text_layer, new_vertical_text_layer};
use filmcraft_project::{EffectInstance, ParamValue};
use filmcraft_render::graphic_clip::render_graphic_layers;
use filmcraft_render::image::Image;
use filmcraft_time::Tick;
fn set(e: &mut EffectInstance, k: &str, v: ParamValue) {
e.params.get_mut(k).unwrap_or_else(|| panic!("{k}")).value = v;
}
fn draw(layer: EffectInstance) -> Image {
let mut img = Image::new(320, 200);
render_graphic_layers(&[layer], Tick::ZERO, (320, 200), &Affine::IDENTITY, &mut img);
img
}
fn ink_box(img: &Image) -> [usize; 4] {
let mut b: Option<[usize; 4]> = None;
for y in 0..img.h {
for x in 0..img.w {
if img.get(x, y)[3] > 0.4 {
b = Some(match b {
Some(a) => [a[0].min(x), a[1].min(y), a[2].max(x), a[3].max(y)],
None => [x, y, x, y],
});
}
}
}
b.expect("ink")
}
fn count(img: &Image) -> usize {
(0..img.h).flat_map(|y| (0..img.w).map(move |x| (x, y))).filter(|&(x, y)| img.get(x, y)[3] > 0.4).count()
}
#[test]
fn underline_horizontal_vs_vertical_letter_a() {
let pos = Vec2::new(80.0, 100.0);
let mut h = new_text_layer("A", pos, 60.0);
let h_plain = draw(h.clone());
set(&mut h, "underline", ParamValue::Bool(true));
let h_ul = draw(h);
let mut v = new_vertical_text_layer("A", Vec2::new(200.0, 100.0), 60.0);
let v_plain = draw(v.clone());
set(&mut v, "underline", ParamValue::Bool(true));
let v_ul = draw(v);
assert!(count(&h_ul) > count(&h_plain) + 20, "horizontal underline adds ink");
assert!(count(&v_ul) > count(&v_plain) + 20, "vertical underline adds ink");
let hb = ink_box(&h_ul);
let hp = ink_box(&h_plain);
let vb = ink_box(&v_ul);
let vp = ink_box(&v_plain);
assert!(hb[3] > hp[3] + 1, "horizontal underline sits below the letter: plain {hp:?} ul {hb:?}");
assert!(vb[2] > vp[2] + 1, "vertical underline sits to the right of the letter: plain {vp:?} ul {vb:?}");
}