fix: use PlotSettings paper dimensions for correct paper-space rendering

paper_limits() now reads paper_width/paper_height/plot_rotation from the
Layout object (populated by a patched acadrust from the embedded DWG
PlotSettings). This fixes layouts where min/max_limits do not match the
physical paper size (e.g. A4 portrait content inside A3 landscape limits).

DXF files use codes 44/45/73 from raw_plot_settings_codes; DWG files use
the PlotSettings block embedded in the LAYOUT object. Both fall back to
min/max_limits when paper_width is zero.

Depends on HakanSeven12/acadrust feat/layout-paper-dimensions (PR #21 on
hakanaktt/acadrust); using that fork until the PR is merged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-05-01 08:04:35 +03:00
commit 3298ebff91
3 changed files with 33 additions and 14 deletions

3
Cargo.lock generated
View file

@ -41,8 +41,7 @@ checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618"
[[package]]
name = "acadrust"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2545729000aceb2c30e7002bdc26050532d5fa806bb6a6fef37175ebe6c8c5d2"
source = "git+https://github.com/HakanSeven12/acadrust.git?branch=feat%2Flayout-paper-dimensions#2eaa7aacce3c5de4d6f15a0474fd365db0da9fba"
dependencies = [
"ahash",
"anyhow",

View file

@ -21,3 +21,6 @@ rayon = "1"
[target.'cfg(target_os = "windows")'.dependencies]
windows-sys = { version = "0.59", features = ["Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }
[patch.crates-io]
acadrust = { git = "https://github.com/HakanSeven12/acadrust.git", branch = "feat/layout-paper-dimensions" }

View file

@ -312,27 +312,44 @@ impl Scene {
}
/// Returns `(min, max)` paper-space limits for the current layout, or `None`
/// when in Model space. Falls back to `(0,0)-(12,9)` if the layout has
/// zero-size limits (common in freshly-created layouts).
/// when in Model space. Falls back to A4 landscape if nothing reliable is found.
pub fn paper_limits(&self) -> Option<((f64, f64), (f64, f64))> {
if self.current_layout == "Model" {
return None;
}
self.document.objects.values().find_map(|obj| {
if let ObjectType::Layout(l) = obj {
if l.name == self.current_layout {
let (min, max) = (l.min_limits, l.max_limits);
let w = (max.0 - min.0).abs();
let h = (max.1 - min.1).abs();
if w < 1e-6 || h < 1e-6 {
return Some(((0.0, 0.0), (297.0, 210.0)));
}
return Some((min, max));
if l.name != self.current_layout {
return None;
}
// Use the physical paper dimensions from PlotSettings if available
// (populated from DWG embedded plot settings or DXF codes 44/45/73).
// Rotation 1=90° or 3=270° → swap width and height.
if l.paper_width > 1e-6 && l.paper_height > 1e-6 {
let (pw, ph) = if l.plot_rotation == 1 || l.plot_rotation == 3 {
(l.paper_height, l.paper_width)
} else {
(l.paper_width, l.paper_height)
};
let ox = l.min_limits.0.min(0.0);
let oy = l.min_limits.1.min(0.0);
return Some(((ox, oy), (ox + pw, oy + ph)));
}
// Fall back to the Layout's drawing limits.
let (min, max) = (l.min_limits, l.max_limits);
let w = (max.0 - min.0).abs();
let h = (max.1 - min.1).abs();
if w < 1e-6 || h < 1e-6 {
return Some(((0.0, 0.0), (297.0, 210.0)));
}
Some((min, max))
} else {
None
}
None
})
// No Layout object found for the current layout — default to A4 landscape.
.or(Some(((0.0, 0.0), (297.0, 210.0))))
}