diff --git a/src/scene/camera_ops.rs b/src/scene/camera_ops.rs index 5012e5f17..5e5b87628 100644 --- a/src/scene/camera_ops.rs +++ b/src/scene/camera_ops.rs @@ -1385,6 +1385,9 @@ impl Scene { // LAYOUTCREATEVIEWPORT, it gets its first viewport. let unopened = self.unopened_layouts.remove(&layout); let initialized = self.initialize_layout_page_setup(&layout); + if unopened && !initialized { + self.fit_layout_sheet(&layout); + } self.ensure_sheet_viewport(&layout); if unopened || initialized { self.add_layout_default_viewport(&layout); diff --git a/src/scene/layout.rs b/src/scene/layout.rs index 80e4a6d01..765683c04 100644 --- a/src/scene/layout.rs +++ b/src/scene/layout.rs @@ -24,15 +24,9 @@ impl Scene { /// cached layout-name list is invalidated on insert. pub fn add_layout(&mut self, name: &str) -> codec::Result { let handle = self.document.add_layout(name)?; - // The layout has no viewports until it first opens (the sheet the - // document makes for it is placed at the origin, not on its page); - // opening it makes the sheet and, with LAYOUTCREATEVIEWPORT, its - // first viewport. - let block = match self.document.objects.get(&handle) { - Some(ObjectType::Layout(layout)) => layout.block_record, - _ => codec::Handle::NULL, - }; - crate::scene::drop_layout_viewports(&mut self.document, block); + // Opening it fits the sheet the document made for it (placed at the + // origin) to its page and, with LAYOUTCREATEVIEWPORT, gives it its + // first viewport; saved before that, it is written with none. self.unopened_layouts.insert(name.to_string()); self.bump_layout_epoch(); Ok(handle) diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 12c43d65e..8dbfd5428 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -4819,6 +4819,22 @@ impl Scene { true } + /// Fit a layout's sheet viewport to its page. (Taking the sheet out + /// instead would leave a viewport onto the model looking like the sheet.) + pub fn fit_layout_sheet(&mut self, layout_name: &str) { + let layout = self.document.objects.values().find_map(|object| match object { + ObjectType::Layout(layout) if layout.name == layout_name => Some(layout.clone()), + _ => None, + }); + let Some(layout) = layout else { + return; + }; + let sheet = Self::layout_sheet_viewport_handle(&self.document, &layout); + if let Some(EntityType::Viewport(vp)) = self.document.get_entity_mut(sheet) { + fit_sheet_viewport(vp, layout.min_limits, layout.max_limits); + } + } + /// Gives a layout whose page setup was never initialized (no paper size /// and no media name, as the reference leaves a layout until it is first /// opened) the default page setup; true when it did. @@ -4831,16 +4847,9 @@ impl Scene { return false; } crate::scene::apply_default_page_setup(layout, &plot_style); - let limits = (layout.min_limits, layout.max_limits); - let layout = layout.clone(); // A sheet written for a layout never set up is not the - // page's; it is fitted to the page. (Taking it out instead - // would leave a viewport onto the model looking like the - // sheet.) - let sheet = Self::layout_sheet_viewport_handle(&self.document, &layout); - if let Some(EntityType::Viewport(vp)) = self.document.get_entity_mut(sheet) { - fit_sheet_viewport(vp, limits.0, limits.1); - } + // page's; it is fitted to the page. + self.fit_layout_sheet(layout_name); self.bump_layout_epoch(); return true; }