From 38fe2b0b088ffa105f3ea3e132b6bb3134ecb9b5 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Mon, 28 Sep 2026 19:01:56 +0300 Subject: [PATCH] fix(plot): text and leader background masks plot paper-white, not black The mask is filled with the canvas colour; plotting carried that dark colour (or the light-to-black rule) onto the sheet. Fixes #1072 Co-Authored-By: Claude Opus 5.5 --- src/app/update/file.rs | 12 ++++++++++++ src/io/pdf_export.rs | 29 +++++++++++++++++------------ src/scene/mod.rs | 2 +- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/app/update/file.rs b/src/app/update/file.rs index 1b8ce9da2..c5cbfebb4 100644 --- a/src/app/update/file.rs +++ b/src/app/update/file.rs @@ -412,12 +412,24 @@ fn plot_scene_content( })) }); model_wires.retain(|wire| wire.plot_visible); + // A text / leader background mask is filled with the canvas colour so it + // hides what is behind it; on paper that colour is the sheet's, not the + // dark screen's. Mark such fills so the export paints them paper-white + // instead of plotting the canvas colour (or turning it black). (#1072) + let canvas = scene.current_bg(); let with_depth = |wires: Vec| { let depths = scene.plot_wire_depths(&wires); wires .into_iter() .zip(depths) .map(|(mut wire, draw_depth)| { + if !wire.fill_tris.is_empty() && wire.color[..3] == canvas[..3] { + wire.bg_adapt = Some(Box::new(crate::scene::model::wire_model::BgAdaptInputs { + raw_color: wire.color, + canvas_color: true, + ..Default::default() + })); + } plot_owner_aci(scene, &mut wire); crate::io::pdf_export::PlotWire { wire, draw_depth } }) diff --git a/src/io/pdf_export.rs b/src/io/pdf_export.rs index 2a1361922..5fef9656f 100644 --- a/src/io/pdf_export.rs +++ b/src/io/pdf_export.rs @@ -1133,21 +1133,26 @@ fn emit_wire_fills( if a < 0.01 { continue; } - let mut screening = 1.0; - let mut color_overridden = false; - if let Some(table) = plot_style { - if wire.aci > 0 { - if let Some(color) = table.resolve_color(wire.aci) { - [r, g, b] = color; - color_overridden = true; + if wire.bg_adapt.as_deref().is_some_and(|adapt| adapt.canvas_color) { + // A background mask: it covers with the paper itself. + [r, g, b] = [1.0, 1.0, 1.0]; + } else { + let mut screening = 1.0; + let mut color_overridden = false; + if let Some(table) = plot_style { + if wire.aci > 0 { + if let Some(color) = table.resolve_color(wire.aci) { + [r, g, b] = color; + color_overridden = true; + } + screening = table.resolve_screening(wire.aci); } - screening = table.resolve_screening(wire.aci); } + if !color_overridden { + [r, g, b] = adapt_text_color([r, g, b]); + } + [r, g, b] = plotted_color([r, g, b], a, screening, options); } - if !color_overridden { - [r, g, b] = adapt_text_color([r, g, b]); - } - [r, g, b] = plotted_color([r, g, b], a, screening, options); ops.push(Op::SetFillColor { col: Color::Rgb(Rgb { r, diff --git a/src/scene/mod.rs b/src/scene/mod.rs index a69397491..6fe667be0 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -8573,7 +8573,7 @@ impl Scene { } /// Background colour for the current layout (model vs paper). - fn current_bg(&self) -> [f32; 4] { + pub(crate) fn current_bg(&self) -> [f32; 4] { if self.current_layout != "Model" { self.paper_bg_color } else {