97 lines
3.1 KiB
Rust
97 lines
3.1 KiB
Rust
|
|
use hcie_composite::composite_layers;
|
|
use hcie_protocol::{BlendMode, Layer, LayerType};
|
|
|
|
fn make_layer(name: &str, w: u32, h: u32, rgba: [u8; 4]) -> Layer {
|
|
let mut l = Layer::from_rgba(name, w, h, vec![rgba; (w * h) as usize].into_iter().flatten().collect());
|
|
l.blend_mode = BlendMode::Normal;
|
|
l
|
|
}
|
|
|
|
fn make_group(name: &str, w: u32, h: u32, id: u64) -> Layer {
|
|
let mut l = Layer::new_transparent(name, w, h);
|
|
l.layer_type = LayerType::Group;
|
|
l.blend_mode = BlendMode::PassThrough;
|
|
l.id = id;
|
|
l
|
|
}
|
|
|
|
#[test]
|
|
fn test_pass_through_group_skipped_in_composite() {
|
|
let w = 2u32;
|
|
let h = 2u32;
|
|
|
|
// Background: opaque white
|
|
let bg = make_layer("bg", w, h, [255, 255, 255, 255]);
|
|
|
|
// Group: PassThrough (no pixels)
|
|
let group = make_group("group", w, h, 1);
|
|
|
|
// Child: Multiply on grey
|
|
let mut child = make_layer("child", w, h, [128, 128, 128, 255]);
|
|
child.blend_mode = BlendMode::Multiply;
|
|
child.parent_id = Some(1);
|
|
|
|
// Composite order: bg, group, child
|
|
let layers = vec![bg, group, child];
|
|
let out = composite_layers(&layers, w, h);
|
|
|
|
// PassThrough: child blends directly onto bg.
|
|
// Multiply: 255 * 128 / 255 = 128 for each channel.
|
|
// Expected: every pixel [128, 128, 128, 255]
|
|
let expected = vec![128u8, 128, 128, 255, 128, 128, 128, 255,
|
|
128, 128, 128, 255, 128, 128, 128, 255];
|
|
assert_eq!(out, expected, "PassThrough group should let child blend directly onto backdrop");
|
|
}
|
|
|
|
#[test]
|
|
fn test_pass_through_group_invisible_children() {
|
|
let w = 2u32;
|
|
let h = 2u32;
|
|
|
|
let bg = make_layer("bg", w, h, [255, 255, 255, 255]);
|
|
let group = make_group("group", w, h, 1);
|
|
let mut child = make_layer("child", w, h, [128, 128, 128, 255]);
|
|
child.blend_mode = BlendMode::Multiply;
|
|
child.parent_id = Some(1);
|
|
child.visible = false;
|
|
|
|
let layers = vec![bg, group, child];
|
|
let out = composite_layers(&layers, w, h);
|
|
|
|
// Child hidden → only bg visible
|
|
let expected = vec![255u8, 255, 255, 255, 255, 255, 255, 255,
|
|
255, 255, 255, 255, 255, 255, 255, 255];
|
|
assert_eq!(out, expected);
|
|
}
|
|
|
|
#[test]
|
|
fn test_pass_through_group_with_opacity() {
|
|
let w = 2u32;
|
|
let h = 2u32;
|
|
|
|
// Background white
|
|
let bg = make_layer("bg", w, h, [255, 255, 255, 255]);
|
|
|
|
// Group with 50% opacity (PassThrough)
|
|
let mut group = make_group("group", w, h, 1);
|
|
group.opacity = 0.5;
|
|
|
|
// Child with Multiply on grey
|
|
let mut child = make_layer("child", w, h, [128, 128, 128, 255]);
|
|
child.blend_mode = BlendMode::Multiply;
|
|
child.parent_id = Some(1);
|
|
|
|
// In a true PassThrough implementation the group opacity would multiply
|
|
// the child's effective opacity. Our MVP skips group pixels entirely,
|
|
// so the child blends at full opacity. We keep this test documenting
|
|
// current MVP behaviour.
|
|
let layers = vec![bg, group, child];
|
|
let out = composite_layers(&layers, w, h);
|
|
|
|
// Multiply full-strength
|
|
let expected = vec![128u8, 128, 128, 255, 128, 128, 128, 255,
|
|
128, 128, 128, 255, 128, 128, 128, 255];
|
|
assert_eq!(out, expected);
|
|
}
|