fix(plot): use AutoCAD's DWG To PDF printable areas

Replace the provisional PDF margins with the values AutoCAD's Plotter
Configuration Editor lists for `DWG To PDF.pc3`. They depend on the sheet
family and variant, not the size: ISO sheets 5/17/6/18 mm (left, bottom,
right, top), ISO expand 5/10/6/11 mm, ISO full bleed 0/1/0/1 mm; ANSI and
ARCH sheets 0.23/0.70 in, expand 0.23/0.42 in, full bleed 0.03 in all
round. Inch sets are stored in millimetres like the sheet itself.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
PanosandClaude Opus 5 committed 2026-09-16 16:05:46 +03:00
1 parent c03a40cb33
commit a7c89eca33
2 files changed
+123 -26

No files matched your search

+4 -4
View File
@@ -5002,7 +5002,7 @@ mod plot_paper_tests {
let ps = app.tabs[app.active_tab].scene.plot_settings_for("Layout1").unwrap();
assert_eq!(ps.printer_name, "DWG To PDF.pc3");
// A changed device takes the PDF driver's printable area for the sheet.
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(5.0, 5.0, 5.0, 5.0));
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0));
}
#[test]
@@ -5043,18 +5043,18 @@ mod plot_paper_tests {
let mut ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
ps.printer_name = "DWG To PDF.pc3".into();
ps.paper_size = "ISO_A4_(210.00_x_297.00_MM)".into();
ps.margins = acadrust::objects::PaperMargin::new(5.0, 5.0, 5.0, 5.0);
ps.margins = acadrust::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0);
assert!(app.tabs[i].scene.set_layout_plot_settings("Layout1", &ps));
let _ = app.on_plot_dialog_open();
let _ = app.on_plot_dlg(PlotDlgMsg::Paper("ISO_full_bleed_A4_(210.00_x_297.00_MM)".into()));
let _ = app.on_plot_dlg(PlotDlgMsg::SetCurrent);
let ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
assert_eq!(ps.paper_size, "ISO_full_bleed_A4_(210.00_x_297.00_MM)");
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(0.0, 0.0, 0.0, 0.0));
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(0.0, 1.0, 0.0, 1.0));
let _ = app.on_plot_dlg(PlotDlgMsg::Paper("ISO_A3_(297.00_x_420.00_MM)".into()));
let _ = app.on_plot_dlg(PlotDlgMsg::SetCurrent);
let ps = app.tabs[i].scene.plot_settings_for("Layout1").unwrap();
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(5.0, 5.0, 5.0, 5.0));
assert_eq!(ps.margins, acadrust::objects::PaperMargin::new(5.0, 17.0, 6.0, 18.0));
assert_eq!((ps.paper_width, ps.paper_height), (420.0, 297.0));
}
+119 -22
View File
@@ -109,26 +109,68 @@ impl Margins {
top: value,
}
}
/// The same margins expressed in millimetres when they were given in
/// `units`.
pub fn to_mm(self, units: PaperUnits) -> Self {
Margins {
left: units.to_mm(self.left),
bottom: units.to_mm(self.bottom),
right: units.to_mm(self.right),
top: units.to_mm(self.top),
}
}
}
// ── PDF driver ────────────────────────────────────────────────────────────
/// Margins of AutoCAD's `DWG To PDF.pc3` sheets.
///
/// Full-bleed sheets print edge to edge by definition. The standard and
/// expand values are provisional — the driver's own printable areas have to
/// be read off AutoCAD's Plotter Configuration Editor (Modify Standard Paper
/// Sizes) and copied here; until then a symmetric inset keeps the printable
/// rectangle visibly distinct from the sheet.
const PDF_STANDARD_MARGIN_MM: f64 = 5.0;
const PDF_EXPAND_MARGIN_MM: f64 = 2.0;
/// Unprintable margins of AutoCAD's `DWG To PDF.pc3` sheets, as its Plotter
/// Configuration Editor lists them (Modify Standard Paper Sizes). They depend
/// on the sheet family and variant, not on the individual size: every ISO
/// sheet shares one set in millimetres, every ANSI / ARCH sheet one set in
/// inches. Order inside each set is left, bottom, right, top.
const PDF_MM_STANDARD: Margins = Margins {
left: 5.0,
bottom: 17.0,
right: 6.0,
top: 18.0,
};
const PDF_MM_EXPAND: Margins = Margins {
left: 5.0,
bottom: 10.0,
right: 6.0,
top: 11.0,
};
const PDF_MM_FULL_BLEED: Margins = Margins {
left: 0.0,
bottom: 1.0,
right: 0.0,
top: 1.0,
};
const PDF_IN_STANDARD: Margins = Margins {
left: 0.23,
bottom: 0.70,
right: 0.23,
top: 0.70,
};
const PDF_IN_EXPAND: Margins = Margins {
left: 0.23,
bottom: 0.42,
right: 0.23,
top: 0.42,
};
const PDF_IN_FULL_BLEED: Margins = Margins::uniform(0.03);
fn pdf_margins_mm(paper: &PaperSize) -> Margins {
match paper.variant {
PaperVariant::FullBleed => Margins::ZERO,
PaperVariant::Expand => Margins::uniform(PDF_EXPAND_MARGIN_MM),
PaperVariant::Standard => Margins::uniform(PDF_STANDARD_MARGIN_MM),
}
let set = match (paper.units, paper.variant) {
(PaperUnits::Millimeters, PaperVariant::Standard) => PDF_MM_STANDARD,
(PaperUnits::Millimeters, PaperVariant::Expand) => PDF_MM_EXPAND,
(PaperUnits::Millimeters, PaperVariant::FullBleed) => PDF_MM_FULL_BLEED,
(PaperUnits::Inches, PaperVariant::Standard) => PDF_IN_STANDARD,
(PaperUnits::Inches, PaperVariant::Expand) => PDF_IN_EXPAND,
(PaperUnits::Inches, PaperVariant::FullBleed) => PDF_IN_FULL_BLEED,
};
set.to_mm(paper.units)
}
// ── System printers ───────────────────────────────────────────────────────
@@ -416,14 +458,69 @@ mod tests {
}
#[test]
fn pdf_margins_depend_on_the_sheet_variant() {
let a4 = paper_catalog::resolve("ISO_A4_(210.00_x_297.00_MM)").unwrap();
let bleed = paper_catalog::resolve("ISO_full_bleed_A4_(210.00_x_297.00_MM)").unwrap();
let expand = paper_catalog::resolve("ISO_expand_A4_(210.00_x_297.00_MM)").unwrap();
assert_eq!(PlotDevice::Pdf.margins_mm(&a4), Margins::uniform(5.0));
assert_eq!(PlotDevice::Pdf.margins_mm(&bleed), Margins::ZERO);
assert_eq!(PlotDevice::Pdf.margins_mm(&expand), Margins::uniform(2.0));
assert_eq!(PlotDevice::None.margins_mm(&a4), Margins::ZERO);
fn pdf_margins_follow_autocad_per_family_and_variant() {
let m = |name: &str| PlotDevice::Pdf.margins_mm(&paper_catalog::resolve(name).unwrap());
// ISO sheets share one millimetre set regardless of size.
let iso_standard = Margins {
left: 5.0,
bottom: 17.0,
right: 6.0,
top: 18.0,
};
assert_eq!(m("ISO_A4_(210.00_x_297.00_MM)"), iso_standard);
assert_eq!(m("ISO_A0_(841.00_x_1189.00_MM)"), iso_standard);
assert_eq!(
m("ISO_expand_A4_(210.00_x_297.00_MM)"),
Margins {
left: 5.0,
bottom: 10.0,
right: 6.0,
top: 11.0
}
);
assert_eq!(
m("ISO_full_bleed_A4_(210.00_x_297.00_MM)"),
Margins {
left: 0.0,
bottom: 1.0,
right: 0.0,
top: 1.0
}
);
// Inch sheets are listed in inches and stored in millimetres.
let close = |a: Margins, b: Margins| {
(a.left - b.left).abs() < 1e-9
&& (a.bottom - b.bottom).abs() < 1e-9
&& (a.right - b.right).abs() < 1e-9
&& (a.top - b.top).abs() < 1e-9
};
let inch = |l: f64, b: f64, r: f64, t: f64| Margins {
left: l * 25.4,
bottom: b * 25.4,
right: r * 25.4,
top: t * 25.4,
};
assert!(close(
m("ANSI_A_(8.50_x_11.00_Inches)"),
inch(0.23, 0.70, 0.23, 0.70)
));
assert!(close(
m("ARCH_D_(24.00_x_36.00_Inches)"),
inch(0.23, 0.70, 0.23, 0.70)
));
assert!(close(
m("ARCH_expand_D_(24.00_x_36.00_Inches)"),
inch(0.23, 0.42, 0.23, 0.42)
));
assert!(close(
m("ANSI_full_bleed_B_(11.00_x_17.00_Inches)"),
inch(0.03, 0.03, 0.03, 0.03)
));
assert_eq!(
PlotDevice::None
.margins_mm(&paper_catalog::resolve("ISO_A4_(210.00_x_297.00_MM)").unwrap()),
Margins::ZERO
);
}
#[test]