fix(plot): align paper space output

Use the same area pipeline as model space while keeping Layout bound to the physical sheet and printable margins. Share scale, rotation, clipping, and viewport fills across preview, PDF, and printer output.
This commit is contained in:
Hakan Seven committed 2026-07-31 11:16:14 +03:00
1 parent 7285e3de51
commit eb0861cf6e
8 files changed
+1032 -370

No files matched your search

+15 -5
View File
@@ -170,9 +170,12 @@ fn build_pdf(
let needs_state = rotation_deg != 0 || (scale - 1.0).abs() > 1e-6 || clip.is_some();
if needs_state {
let (cos_a, sin_a, tx, ty) = match rotation_deg {
90 => (0.0_f64, 1.0_f64, 0.0, paper_h as f64),
// `paper_w`/`paper_h` are already the effective, rotation-swapped
// page dimensions. A 90° turn maps x' = page_w - y, y' = x;
// 270° maps x' = y, y' = page_h - x.
90 => (0.0_f64, 1.0_f64, paper_w as f64, 0.0),
180 => (-1.0_f64, 0.0_f64, paper_w as f64, paper_h as f64),
270 => (0.0_f64, -1.0_f64, paper_w as f64, 0.0),
270 => (0.0_f64, -1.0_f64, 0.0, paper_h as f64),
_ => (1.0_f64, 0.0_f64, 0.0, 0.0),
};
let s = scale as f64;
@@ -245,8 +248,9 @@ fn build_pdf(
if a < 0.01 {
continue;
}
// Skip the paper-boundary wire — the white PDF background already provides it.
if wire.name == "__paper_boundary__" {
// Skip screen-only paper helpers. The PDF page supplies its own white
// boundary, and the printable-area rectangle is a UI guide, not ink.
if matches!(wire.name.as_str(), "__paper_boundary__" | "paper_printable_area") {
continue;
}
// Apply CTB plot style table overrides (color + lineweight).
@@ -433,7 +437,13 @@ fn emit_hatch(ops: &mut Vec<Op>, hatch: &HatchModel, ox: f64, oy: f64) {
// would vanish white-on-white on paper. Force near-white/near-yellow → black
// and near-cyan → dark blue, matching AutoCAD's colour-7-on-white plotting.
// Genuine colours are untouched; WIPEOUTS keep their paper-white mask.
if hatch.name != "WIPEOUT_FILL" {
if hatch.name == "WIPEOUT_FILL" {
// Screen wipeouts match the configured canvas colour; printed
// wipeouts must mask with the white paper colour.
r = 1.0;
g = 1.0;
b = 1.0;
} else {
let is_light = r > 0.80 && g > 0.80 && b > 0.80;
let is_yellow = r > 0.80 && g > 0.70 && b < 0.30;
let is_cyan = r < 0.30 && g > 0.70 && b > 0.70;
+12 -4
View File
@@ -44,6 +44,8 @@ pub async fn print_wires(
_offset_x: f64,
_offset_y: f64,
_rotation_deg: i32,
_scale: f32,
_clip: Option<(f32, f32, f32, f32)>,
_plot_style: Option<PlotStyleTable>,
) -> Result<String, String> {
Err("Printing is not available in the web version.".into())
@@ -65,6 +67,8 @@ pub async fn print_wires_with(
_offset_x: f64,
_offset_y: f64,
_rotation_deg: i32,
_scale: f32,
_clip: Option<(f32, f32, f32, f32)>,
_plot_style: Option<PlotStyleTable>,
_opts: PrintOptions,
) -> Result<String, String> {
@@ -95,6 +99,8 @@ pub async fn print_wires(
offset_x: f64,
offset_y: f64,
rotation_deg: i32,
scale: f32,
clip: Option<(f32, f32, f32, f32)>,
plot_style: Option<PlotStyleTable>,
) -> Result<String, String> {
// ── 1. Write to a named temp file ─────────────────────────────────────
@@ -108,8 +114,8 @@ pub async fn print_wires(
offset_x,
offset_y,
rotation_deg,
1.0,
None,
scale,
clip,
&tmp_path,
plot_style.as_ref(),
)?;
@@ -158,6 +164,8 @@ pub async fn print_wires_with(
offset_x: f64,
offset_y: f64,
rotation_deg: i32,
scale: f32,
clip: Option<(f32, f32, f32, f32)>,
plot_style: Option<PlotStyleTable>,
opts: PrintOptions,
) -> Result<String, String> {
@@ -171,8 +179,8 @@ pub async fn print_wires_with(
offset_x,
offset_y,
rotation_deg,
1.0,
None,
scale,
clip,
&tmp_path,
plot_style.as_ref(),
)?;