From 298bfd4803092908e29ace10e8b3b43c9870a782 Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Mon, 20 Jul 2026 14:59:41 +0300 Subject: [PATCH] feat(pdf): stroke the wide-polyline band at its world width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The shader-band change stopped emitting a hatch fill for wide polylines, so PDF export — which drew the band from that HatchModel — lost it and plotted only the thin centre-line. Stroke the centre-line wire at the band width instead. In `build_pdf`, a wire carrying `world_width` sets the pen to `world_width * MM_TO_PT` with no `/ scale`: a lineweight is absolute on paper (hence the divide), but a band is drawing-unit geometry and must scale with the plot. The CTM's scale then renders the band at `world_width * scale` on the sheet, matching the geometry, and the linetype dash pattern strokes it dashed. Overrides any CTB pen weight (the width is geometry, not a lineweight). Co-Authored-By: Claude Opus 4.8 --- src/io/pdf_export.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/io/pdf_export.rs b/src/io/pdf_export.rs index c3a9fa1b9..a77e1e084 100644 --- a/src/io/pdf_export.rs +++ b/src/io/pdf_export.rs @@ -289,8 +289,21 @@ fn build_pdf( // `scale` in both branches so pen widths stay absolute under the scaled // CTM above — lineweights are independent of plot scale, so without this // a Fit plot of a large window renders near-invisible hairlines. - let lw_pt = lw_override - .unwrap_or_else(|| (wire.line_weight_px * LW_PX_TO_PT).max(0.1) / scale.max(1e-6)); + // + // A wide polyline is the exception: its band is a geometric width in + // drawing units, so it must SCALE with the plot (no `/ scale`). Stroke + // the centre-line at `world_width`, converted mm → pt exactly like the + // geometry coordinates so the CTM scale renders the band at its true + // size; the linetype dash pattern below then strokes it dashed. This + // replaces the model-space hatch band that the shader-band change + // dropped, and overrides any CTB pen weight (the width is geometry, not + // a lineweight). + let lw_pt = if wire.world_width > 0.0 { + wire.world_width * MM_TO_PT + } else { + lw_override + .unwrap_or_else(|| (wire.line_weight_px * LW_PX_TO_PT).max(0.1) / scale.max(1e-6)) + }; if last_lw.map(|l| (l - lw_pt).abs() > 0.01).unwrap_or(true) { ops.push(Op::SetOutlineThickness { pt: Pt(lw_pt) }); last_lw = Some(lw_pt);