forked from 1b-agent/opencadstudio-upstream
fix(layout): complete paperspace integration
Apply each layout's embedded page setup and plot style consistently across display, PDF, printing, and multi-layout output.\n\nRefs #844
This commit is contained in:
1 parent
9c8f841f71
commit
8c61d89b1e
18 files changed
+1393
-373
No files matched your search
@@ -30,6 +30,7 @@ impl OpenCADStudio {
|
||||
.document
|
||||
.header
|
||||
.paper_space_insertion_base = pt;
|
||||
self.tabs[i].scene.persist_current_layout_state();
|
||||
} else {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
|
||||
@@ -412,14 +412,7 @@ impl OpenCADStudio {
|
||||
vec![]
|
||||
};
|
||||
|
||||
// Blocks: everything the layout-reachability walk above did
|
||||
// NOT mark live. That covers unreferenced named blocks,
|
||||
// leftover anonymous blocks (*U hatch/unnamed, orphaned *D
|
||||
// dimension, *T table, dynamic-block variants — AutoCAD drops
|
||||
// these too), AND whole dead subgraphs a detached xref leaves
|
||||
// behind. Live xrefs stay (an attached xref's blocks are
|
||||
// reached from the layout that inserts them); the *Model_Space
|
||||
// / *Paper_Space containers are never removed.
|
||||
// Remove unreachable blocks but retain live xrefs and space containers.
|
||||
let block_remove: Vec<String> = if do_blocks {
|
||||
self.tabs[i]
|
||||
.scene
|
||||
@@ -494,15 +487,7 @@ impl OpenCADStudio {
|
||||
n_blocks += block_remove.len();
|
||||
}
|
||||
|
||||
// Draw-order cleanup. A SortEntitiesTable lists a block's
|
||||
// entities in draw order; purging the block drops the entities
|
||||
// and the block record, but this object lingers, still holding
|
||||
// the (now dangling) handle of every deleted entity. On a
|
||||
// detached-xref purge that is hundreds of thousands of stale
|
||||
// handles — megabytes of dead weight the save re-emits, which is
|
||||
// why an OCS-purged file stayed far larger than AutoCAD's.
|
||||
// Drop every SortEntitiesTable whose owning block is gone
|
||||
// (AutoCAD's "orphaned data").
|
||||
// Remove draw-order tables whose owning blocks are gone.
|
||||
let mut n_sortents = 0usize;
|
||||
if do_blocks {
|
||||
let live_blocks: rustc_hash::FxHashSet<acadrust::Handle> = self.tabs[i]
|
||||
@@ -1913,6 +1898,9 @@ impl OpenCADStudio {
|
||||
if name == "FILLMODE" {
|
||||
self.tabs[i].scene.bump_geometry();
|
||||
}
|
||||
if matches!(name.as_str(), "PSLTSCALE" | "PLIMCHECK") {
|
||||
self.tabs[i].scene.persist_current_layout_state();
|
||||
}
|
||||
self.command_line.push_output(&msg);
|
||||
} else {
|
||||
// Queried with no value (`changed == false`):
|
||||
|
||||
+20
-34
@@ -568,63 +568,49 @@ impl OpenCADStudio {
|
||||
}
|
||||
} else {
|
||||
// ── Preset viewport layout ───────────────────────────
|
||||
// Determine paper dimensions from PlotSettings (fallback A4 landscape).
|
||||
let layout_name = scene.current_layout.clone();
|
||||
let (paper_w, paper_h) = {
|
||||
use acadrust::objects::ObjectType;
|
||||
let mut pw = 297.0_f64;
|
||||
let mut ph = 210.0_f64;
|
||||
for (_, obj) in &scene.document.objects {
|
||||
if let ObjectType::PlotSettings(ps) = obj {
|
||||
if ps.page_name == layout_name && ps.paper_width > 0.0 {
|
||||
pw = ps.paper_width;
|
||||
ph = ps.paper_height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
(pw, ph)
|
||||
};
|
||||
let margin = 5.0_f64; // mm margin around the usable area
|
||||
let uw = paper_w - 2.0 * margin; // usable width
|
||||
let uh = paper_h - 2.0 * margin; // usable height
|
||||
// Collect rectangle specs: (cx, cz, w, h) in mm
|
||||
let ((x0, y0), (x1, y1)) = scene
|
||||
.printable_area_limits()
|
||||
.unwrap_or(((0.0, 0.0), (297.0, 210.0)));
|
||||
let uw = (x1 - x0).max(1.0);
|
||||
let uh = (y1 - y0).max(1.0);
|
||||
let gap = 2.0 * scene.paper_space_unit_factor();
|
||||
let rects: Vec<(f64, f64, f64, f64)> = match sub.as_str() {
|
||||
"2H" => {
|
||||
// Two viewports side by side (horizontal split)
|
||||
let vw = (uw - 2.0) / 2.0;
|
||||
let vw = (uw - gap) / 2.0;
|
||||
vec![
|
||||
(margin + vw / 2.0, margin + uh / 2.0, vw, uh),
|
||||
(margin + vw + 2.0 + vw / 2.0, margin + uh / 2.0, vw, uh),
|
||||
(x0 + vw / 2.0, y0 + uh / 2.0, vw, uh),
|
||||
(x0 + vw + gap + vw / 2.0, y0 + uh / 2.0, vw, uh),
|
||||
]
|
||||
}
|
||||
"2V" => {
|
||||
// Two viewports stacked (vertical split)
|
||||
let vh = (uh - 2.0) / 2.0;
|
||||
let vh = (uh - gap) / 2.0;
|
||||
vec![
|
||||
(margin + uw / 2.0, margin + vh + 2.0 + vh / 2.0, uw, vh),
|
||||
(margin + uw / 2.0, margin + vh / 2.0, uw, vh),
|
||||
(x0 + uw / 2.0, y0 + vh + gap + vh / 2.0, uw, vh),
|
||||
(x0 + uw / 2.0, y0 + vh / 2.0, uw, vh),
|
||||
]
|
||||
}
|
||||
"4" => {
|
||||
// Four equal viewports (2×2 grid)
|
||||
let vw = (uw - 2.0) / 2.0;
|
||||
let vh = (uh - 2.0) / 2.0;
|
||||
let vw = (uw - gap) / 2.0;
|
||||
let vh = (uh - gap) / 2.0;
|
||||
vec![
|
||||
(margin + vw / 2.0, margin + vh + 2.0 + vh / 2.0, vw, vh),
|
||||
(x0 + vw / 2.0, y0 + vh + gap + vh / 2.0, vw, vh),
|
||||
(
|
||||
margin + vw + 2.0 + vw / 2.0,
|
||||
margin + vh + 2.0 + vh / 2.0,
|
||||
x0 + vw + gap + vw / 2.0,
|
||||
y0 + vh + gap + vh / 2.0,
|
||||
vw,
|
||||
vh,
|
||||
),
|
||||
(margin + vw / 2.0, margin + vh / 2.0, vw, vh),
|
||||
(margin + vw + 2.0 + vw / 2.0, margin + vh / 2.0, vw, vh),
|
||||
(x0 + vw / 2.0, y0 + vh / 2.0, vw, vh),
|
||||
(x0 + vw + gap + vw / 2.0, y0 + vh / 2.0, vw, vh),
|
||||
]
|
||||
}
|
||||
"SINGLE" | "1" => {
|
||||
// Single full-page viewport
|
||||
vec![(margin + uw / 2.0, margin + uh / 2.0, uw, uh)]
|
||||
vec![(x0 + uw / 2.0, y0 + uh / 2.0, uw, uh)]
|
||||
}
|
||||
_ => {
|
||||
self.command_line.push_error(
|
||||
|
||||
Reference in new issue
Block a user