mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-22 11:42:57 -05:00
Merge pull request #1271
This commit is contained in:
commit
de7c8d6dd6
2 files changed
+29
-2
No files matched your search
@@ -57,6 +57,10 @@ struct Draw {
|
||||
blend: BlendMode,
|
||||
/// Front / Bevel / Side / Back colours of the paint's extrusion (Advanced 3D).
|
||||
surfaces: SurfaceColors,
|
||||
/// Paint item of the contents group this draw was collected in (as opposed to one bubbled up
|
||||
/// from a nested group). Merge Paths drops only these paints above it (#1174); a group's own
|
||||
/// fill or stroke keeps rendering inside the group.
|
||||
local: bool,
|
||||
}
|
||||
|
||||
/// Straight RGB colours of an extrusion's surfaces, by [`effectcraft_model::extrude::Surface`]
|
||||
@@ -234,6 +238,7 @@ fn collect(ctx: &EvalCtx, layer: &Layer, contents: &PropGroup, arena: &mut Vec<B
|
||||
opacity: opacity(g),
|
||||
blend: blend_mode(ctx, layer, g),
|
||||
surfaces: [None; 4],
|
||||
local: true,
|
||||
});
|
||||
}
|
||||
"stroke" => {
|
||||
@@ -247,6 +252,7 @@ fn collect(ctx: &EvalCtx, layer: &Layer, contents: &PropGroup, arena: &mut Vec<B
|
||||
opacity: opacity(g),
|
||||
blend: blend_mode(ctx, layer, g),
|
||||
surfaces: [None; 4],
|
||||
local: true,
|
||||
});
|
||||
}
|
||||
"gfill" | "gstroke" => {
|
||||
@@ -270,6 +276,7 @@ fn collect(ctx: &EvalCtx, layer: &Layer, contents: &PropGroup, arena: &mut Vec<B
|
||||
opacity: opacity(g),
|
||||
blend: blend_mode(ctx, layer, g),
|
||||
surfaces: [None; 4],
|
||||
local: true,
|
||||
});
|
||||
}
|
||||
"trim" => {
|
||||
@@ -328,8 +335,9 @@ fn collect(ctx: &EvalCtx, layer: &Layer, contents: &PropGroup, arena: &mut Vec<B
|
||||
arena.push(ops::merge(&input, mode));
|
||||
live = vec![arena.len() - 1];
|
||||
// As in After Effects, fills and strokes above a Merge Paths in its group are not
|
||||
// rendered: the merged path is painted by the paint items below it.
|
||||
draws.clear();
|
||||
// rendered: the merged path is painted by the paint items below it. Paint inside
|
||||
// groups above the merge still renders — it belongs to those groups (#1174).
|
||||
draws.retain(|d| !d.local);
|
||||
}
|
||||
"group" => {
|
||||
let Some(inner) = g.sub("contents") else { continue };
|
||||
@@ -341,6 +349,7 @@ fn collect(ctx: &EvalCtx, layer: &Layer, contents: &PropGroup, arena: &mut Vec<B
|
||||
for mut d in cd {
|
||||
d.xf = m * d.xf;
|
||||
d.opacity *= op;
|
||||
d.local = false;
|
||||
draws.push(d);
|
||||
}
|
||||
live.extend(cl);
|
||||
|
||||
@@ -76,6 +76,24 @@ fn merge_add_feeds_fill_below_and_drops_paint_above() {
|
||||
assert!((coverage(&img) - 80.0 * 40.0).abs() < 20.0, "{}", coverage(&img));
|
||||
}
|
||||
|
||||
/// #1174: Adding Merge Paths to a shape layer's Contents, after the group that holds the
|
||||
/// shape and its paint, erased the render. The merge drops paints above it *in its group* —
|
||||
/// not paint that belongs to a group above it.
|
||||
#[test]
|
||||
fn merge_paths_below_a_group_keeps_the_group_paint() {
|
||||
for mode in [0u32, 1] {
|
||||
let (p, cid) = shape_comp(|ids| {
|
||||
let rect = build::shape_rect(ids, [40.0, 40.0], [0.0, 0.0], 0.0);
|
||||
let fill = build::shape_fill(ids, RED);
|
||||
vec![build::shape_group(ids, "Group 1", vec![rect, fill]), op(ids, "merge", &[("mode", Value::Enum(mode))])]
|
||||
});
|
||||
let img = frame(&p, cid);
|
||||
let c = img.get(100, 50);
|
||||
assert!(c[0] > 0.99 && c[1] < 0.01 && c[3] > 0.99, "mode {mode}: group rectangle must still render, got {c:?}");
|
||||
assert!((coverage(&img) - 40.0 * 40.0).abs() < 20.0, "mode {mode}: {}", coverage(&img));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_subtract_and_intersect() {
|
||||
let sub = |mode: u32| {
|
||||
|
||||
Reference in new issue
Block a user