b09795ccff
- Add `persistence.rs` for stable serialization of dock layouts without runtime identifiers. - Introduce `preview.rs` for geometry handling of dock drop previews. - Create `sizing.rs` to manage content-aware sizing policies and constraint solving for dock panels. - Implement `welcome.rs` to provide a welcome surface when no documents are open, featuring New and Open actions.
107 lines
3.1 KiB
Rust
107 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);
|
|
}
|