forked from 1b-agent/opencadstudio-upstream
Plot: thin lineweights keep their true width (#1749)
Every weight under 0.26 mm was clamped to the screen's 1 px floor before the PDF and SVG exporters saw it, so 0.00, 0.09, 0.13 and 0.25 mm all plotted alike. The floor now applies on the GPU only. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
2c062daa03
commit
2ba2d1c0a7
5 files changed
+10
-8
No files matched your search
@@ -2907,8 +2907,8 @@ mod tests {
|
||||
assert_eq!(response["status"], "completed", "{response}");
|
||||
|
||||
// The plotted PDF carries two distinct pen widths — the per-layer
|
||||
// 0.13 mm / 0.50 mm hierarchy survives the plot style (thin clamps to
|
||||
// the 1 px floor, so the ratio is the clamped-pixel ratio 1.889).
|
||||
// 0.13 mm / 0.50 mm hierarchy survives the plot style at its true
|
||||
// ratio; the screen's 1 px floor does not reach the plot (#1749).
|
||||
let text =
|
||||
crate::io::pdf_export::pdf_stream_text(&std::fs::read(&pdf).expect("pdf written"));
|
||||
let tokens: Vec<&str> = text.split_whitespace().collect();
|
||||
@@ -2931,7 +2931,7 @@ mod tests {
|
||||
"two layer weights in the plotted PDF: {widths:?}"
|
||||
);
|
||||
assert!(
|
||||
(widths[1] / widths[0] - 1.889).abs() < 0.15,
|
||||
(widths[1] / widths[0] - 50.0 / 13.0).abs() < 0.15,
|
||||
"0.50 mm vs 0.13 mm hierarchy: {widths:?}"
|
||||
);
|
||||
let _ = std::fs::remove_file(&pdf);
|
||||
|
||||
@@ -264,7 +264,7 @@ pub fn extract_circle_instance_from_geom_indexed(
|
||||
}
|
||||
|
||||
let (ch, cl) = split_ds_xyz(center[0], center[1], center[2]);
|
||||
let hw = wire.line_weight_px * 0.5;
|
||||
let hw = wire.line_weight_px.max(1.0) * 0.5;
|
||||
let pat0 = [
|
||||
wire.pattern[0],
|
||||
wire.pattern[1],
|
||||
|
||||
@@ -235,7 +235,7 @@ pub fn extract_ellipse_instance_from_geom(
|
||||
}
|
||||
|
||||
let (ch, cl) = split_ds_xyz(center[0], center[1], center[2]);
|
||||
let hw = wire.line_weight_px * 0.5;
|
||||
let hw = wire.line_weight_px.max(1.0) * 0.5;
|
||||
let pat0 = [
|
||||
wire.pattern[0],
|
||||
wire.pattern[1],
|
||||
|
||||
@@ -863,7 +863,7 @@ pub(crate) fn emit_wire_packed(
|
||||
wire.pattern[6],
|
||||
wire.pattern[7],
|
||||
];
|
||||
let half_width = wire.line_weight_px * 0.5;
|
||||
let half_width = wire.line_weight_px.max(1.0) * 0.5;
|
||||
let n = wire.points.len();
|
||||
let seg_count = n.saturating_sub(1);
|
||||
if seg_count == 0 {
|
||||
@@ -965,7 +965,7 @@ pub(crate) fn emit_wire_native(
|
||||
wire.pattern[6],
|
||||
wire.pattern[7],
|
||||
],
|
||||
half_width: wire.line_weight_px * 0.5,
|
||||
half_width: wire.line_weight_px.max(1.0) * 0.5,
|
||||
pattern_length: wire.pattern_length,
|
||||
draw_depth,
|
||||
align_end,
|
||||
|
||||
@@ -3589,9 +3589,11 @@ pub struct InheritStyle {
|
||||
}
|
||||
|
||||
/// Convert a concrete (already layer-resolved) lineweight to display pixels.
|
||||
/// Kept below 1 px for thin weights so plots and SVG get the true width;
|
||||
/// the GPU paths draw at least 1 px (#1749).
|
||||
pub(crate) fn lineweight_to_px(lw: &LineWeight) -> f32 {
|
||||
lw.millimeters()
|
||||
.map(|mm| (mm as f32 * MM_TO_PX).max(1.0))
|
||||
.map(|mm| mm as f32 * MM_TO_PX)
|
||||
.unwrap_or(1.0)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user