mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-31 07:38:16 +00:00
fix(render): animation state never applies to layout and master shapes sharing a slide shape id (fixes #1362)
This commit is contained in:
1 parent
27009cd941
commit
8c8ab9561b
2 files changed
+27
-4
No files matched your search
@@ -267,6 +267,7 @@ impl Default for RenderOpts<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SlideFields {
|
||||
num: u32,
|
||||
/// Text for every date field instead of the date ([`RenderOpts::date_text`]).
|
||||
@@ -667,6 +668,10 @@ impl Renderer {
|
||||
|
||||
/// Background plus the master and layout graphics the slide shows.
|
||||
fn backdrop(&mut self, ctx: &mut RenderContext, f: &Frame, rctx: &Ctx, slide: &Slide, view: Affine) {
|
||||
// Backdrop graphics never take shape states: their ids may clash with the slide's shapes.
|
||||
let bopts = RenderOpts { state: None, date_text: f.opts.date_text.clone(), ..*f.opts };
|
||||
let bf = Frame { pres: f.pres, opts: &bopts, fields: f.fields.clone() };
|
||||
let f = &bf;
|
||||
self.background(ctx, f, rctx, Some(slide), view);
|
||||
let (show_layout, show_master) = resolve::show_master_shapes(slide, rctx.layout);
|
||||
if show_master {
|
||||
@@ -742,14 +747,12 @@ impl Renderer {
|
||||
self.in_shadow_pass = false;
|
||||
let (mut ctx, w, h, view) = Self::canvas(pres, opts, needs_filters(pres, old.0) || needs_filters(pres, new.0));
|
||||
let (Some(co), Some(cn)) = (Ctx::for_slide(pres, old.0), Ctx::for_slide(pres, new.0)) else { return self.finish(ctx, w, h) };
|
||||
// Backdrop graphics never take shape states: their ids may clash with the frame's shapes.
|
||||
let bopts = RenderOpts { state: None, date_text: opts.date_text.clone(), ..*opts };
|
||||
if mix < 1.0 {
|
||||
let f = Frame { pres, opts: &bopts, fields: Self::fields(pres, old.1, opts) };
|
||||
let f = Frame { pres, opts, fields: Self::fields(pres, old.1, opts) };
|
||||
self.backdrop(&mut ctx, &f, &co, old.0, view);
|
||||
}
|
||||
if mix > 0.0 {
|
||||
let f = Frame { pres, opts: &bopts, fields: Self::fields(pres, new.1, opts) };
|
||||
let f = Frame { pres, opts, fields: Self::fields(pres, new.1, opts) };
|
||||
let layered = mix < 1.0;
|
||||
if layered {
|
||||
ctx.push_layer(None, None, Some(mix as f32), None, None);
|
||||
|
||||
@@ -1776,6 +1776,26 @@ fn the_editor_pasteboard_draws_shapes_off_the_slide() {
|
||||
assert!(drawn.x0 <= -100.0 && drawn.y1 >= 660.0 && drawn.x1 >= 960.0, "{drawn:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn animation_state_skips_layout_and_master_shapes_sharing_a_slide_shape_id() {
|
||||
let mut p = Presentation::default();
|
||||
let bar = |x| Shape {
|
||||
id: ShapeId(77),
|
||||
xfrm: Some(Xfrm::new(x, 400.0, 100.0, 60.0)),
|
||||
fill: Some(Fill::solid(ColorRef::rgb(Rgba::rgb(200, 0, 0)))),
|
||||
..Default::default()
|
||||
};
|
||||
let lid = p.slides[0].layout;
|
||||
let m = std::sync::Arc::make_mut(&mut p.masters[0]);
|
||||
m.shapes.push(bar(100.0));
|
||||
m.layouts.iter_mut().find(|l| l.id == lid).expect("layout").shapes.push(bar(400.0));
|
||||
let hide = |_: ShapeId| ShapeState { visible: false, ..Default::default() };
|
||||
let img = render_slide(&p, 0, &RenderOpts { scale: 1.0, state: Some(&hide), ..Default::default() });
|
||||
for x in [150, 450] {
|
||||
assert_eq!(img.pixel(x, 430)[..3], [200, 0, 0], "the backdrop bar at x={x} stays");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn master_graphics_off_the_slide_show_on_the_pasteboard() {
|
||||
let mut p = Presentation::default();
|
||||
|
||||
Reference in new issue
Block a user