Merge remote-tracking branch 'origin/main' into HEAD

This commit is contained in:
bflatastic
2026-10-30 09:01:36 +07:00
48 changed files with 1938 additions and 50 deletions
+14 -1
View File
@@ -269,7 +269,20 @@ fn collect_in(ctx: &EvalCtx, layer: &Layer, contents: &PropGroup, arena: &mut Ve
"rect" => {
let size = ctx.v2(layer, g, "size", [100.0; 2]);
let pos = ctx.v2(layer, g, "position", [0.0; 2]);
let p = effectcraft_path::rect(size, pos, ctx.f(layer, g, "roundness", 0.0));
let p = if ctx.b(layer, g, "perCorner") {
effectcraft_path::rect_radii(
size,
pos,
[
ctx.f(layer, g, "topLeftRoundness", 0.0),
ctx.f(layer, g, "topRightRoundness", 0.0),
ctx.f(layer, g, "bottomRightRoundness", 0.0),
ctx.f(layer, g, "bottomLeftRoundness", 0.0),
],
)
} else {
effectcraft_path::rect(size, pos, ctx.f(layer, g, "roundness", 0.0))
};
push_shape(ctx, layer, g, p, arena, &mut live);
}
"ellipse" => {
+30
View File
@@ -715,3 +715,33 @@ fn miter_corner_still_fits_its_buffer() {
let b = shape_buf(&p, cid);
assert!(b.img.height as f64 >= 50.0 + 20.0 * 4.0 * 0.5, "{}", b.img.height);
}
#[test]
fn rect_per_corner_roundness_rounds_the_named_corners() {
let render = |per_corner: bool, radii: [f64; 4], roundness: f64| {
let (p, cid) = shape_comp_sized(200, 100, move |ids| {
let mut g = build::shape_rect(ids, [100.0, 100.0], [0.0, 0.0], roundness);
g.prop_mut("perCorner").unwrap().value = Value::Bool(per_corner);
for (m, v) in
[("topLeftRoundness", radii[0]), ("topRightRoundness", radii[1]), ("bottomRightRoundness", radii[2]), ("bottomLeftRoundness", radii[3])]
{
g.prop_mut(m).unwrap().value = Value::Scalar(v);
}
vec![g, build::shape_fill(ids, RED)]
});
frame(&p, cid)
};
// Only the top-left corner rounds: its corner pixels fade, the other three stay filled.
let img = render(true, [30.0, 0.0, 0.0, 0.0], 0.0);
assert!(alpha(&img, 52, 2) < 0.1, "top-left rounds: {}", alpha(&img, 52, 2));
for (x, y) in [(148, 2), (148, 98), (52, 98)] {
assert!(alpha(&img, x, y) > 0.9, "({x},{y}) stays square: {}", alpha(&img, x, y));
}
// The checkbox off ignores the four values (the single Roundness still rules).
let off = render(false, [30.0; 4], 0.0);
assert!((coverage(&off) - 100.0 * 100.0).abs() < 20.0, "{}", coverage(&off));
// Four equal per-corner radii render like the same Roundness.
let per = render(true, [25.0; 4], 0.0);
let uni = render(false, [0.0; 4], 25.0);
assert!((coverage(&per) - coverage(&uni)).abs() < 5.0, "{} vs {}", coverage(&per), coverage(&uni));
}