mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-14 14:26:45 -04:00
Squash of PR #598 by @MarekSpodBiedry. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
73c91cbac5
commit
0b5a0a2eb8
3 files changed
+47
-5
No files matched your search
@@ -339,7 +339,7 @@ fn run_preview(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let (from, k, to) = if fit || space == Space::Model {
|
||||
(if b.is_empty() { Vec2::ZERO } else { b.center() }, plot_scale(&b, &sheet, fit, scale), sheet.printable.center())
|
||||
} else {
|
||||
(Vec2::ZERO, 1.0, Vec2::ZERO)
|
||||
(Vec2::ZERO, plot_scale(&b, &sheet, fit, scale), Vec2::ZERO)
|
||||
};
|
||||
let world = Bounds2::new((Vec2::ZERO - to) / k + from, (sheet.size - to) / k + from);
|
||||
if ![world.min.x, world.min.y, world.max.x, world.max.y].iter().all(|v| v.is_finite()) {
|
||||
@@ -576,6 +576,17 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preview_applies_an_explicit_layout_scale() {
|
||||
let mut s = Session::new();
|
||||
s.execute("layout.set", &json!({ "name": "Layout1" })).unwrap();
|
||||
s.execute("line", &json!({ "points": [[1.0, 1.0], [5.0, 1.0]] })).unwrap();
|
||||
let png = |s: &mut Session, p: Value| s.execute("preview", &p).unwrap()["data"].as_str().unwrap_or_default().to_string();
|
||||
let default = png(&mut s, json!({ "layout": "Layout1", "width": 200 }));
|
||||
assert_eq!(png(&mut s, json!({ "layout": "Layout1", "width": 200, "fit": false, "scale": 1 })), default, "scale 1 is the 1:1 default");
|
||||
assert_ne!(png(&mut s, json!({ "layout": "Layout1", "width": 200, "fit": false, "scale": 0.5 })), default, "scale 0.5 is not 1:1");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn publish_plots_every_sheet() {
|
||||
our_hooks();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
//! Vector PDF plotting (PLOT / EXPORTPDF): a minimal PDF writer of our own (pure Rust, no file
|
||||
//! access, so it runs on the web too).
|
||||
//!
|
||||
//! One page per sheet: model-space extents fitted to a sheet, or a layout at 1:1 on its paper
|
||||
//! (paper units are millimetres in metric drawings, inches otherwise). Lines are stroked paths
|
||||
//! (`m`/`l`/`S`), fills are `f` paths, colours are RGB with colour 7 printing black on white
|
||||
//! One page per sheet: model-space extents fitted to a sheet, or a layout at 1:1 (or the given
|
||||
//! `scale`) on its paper (paper units are millimetres in metric drawings, inches otherwise).
|
||||
//! Lines are stroked paths (`m`/`l`/`S`), fills are `f` paths, colours are RGB with colour 7 printing black on white
|
||||
//! paper, and line widths come from lineweights when enabled. The page setup's plot style
|
||||
//! table (or the `plotStyleTable` option) sets the printed colours, linetypes and lineweights.
|
||||
//!
|
||||
@@ -318,7 +318,7 @@ fn sheet(d: &Drawing, space: &Space, o: &PdfOptions) -> Result<SheetPage> {
|
||||
let from = if b.is_empty() { Vec2::ZERO } else { b.center() };
|
||||
Map { from, s, to: sheet.printable.center(), k }
|
||||
} else {
|
||||
Map { from: Vec2::ZERO, s: 1.0, to: Vec2::ZERO, k }
|
||||
Map { from: Vec2::ZERO, s, to: Vec2::ZERO, k }
|
||||
};
|
||||
// Plot style ends, joins and fill patterns at the plot scale (a layout's are already drawn).
|
||||
let mut list = list;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
//! An explicit numeric `scale` on a non-fitted layout plot scales the geometry (issue #490).
|
||||
|
||||
use cadcraft_doc::{Common, Drawing, EntityKind, Line, Space};
|
||||
use cadcraft_geom::Vec3;
|
||||
use serde_json::{Value, json};
|
||||
|
||||
/// Plotted length in millimetres of the one 90-unit line in Layout1.
|
||||
fn plotted_mm(opts: Value) -> f64 {
|
||||
let mut d = Drawing::new_metric();
|
||||
let line = EntityKind::Line(Line { a: Vec3::new(10.0, 10.0, 0.0), b: Vec3::new(100.0, 10.0, 0.0) });
|
||||
d.add(&Space::Paper("Layout1".into()), Common::default(), line).unwrap();
|
||||
let mut o = json!({"compress": false});
|
||||
if let (Some(o), Some(e)) = (o.as_object_mut(), opts.as_object()) {
|
||||
o.extend(e.clone());
|
||||
}
|
||||
let bytes = cadcraft_io::plot(&d, &Space::Paper("Layout1".into()), &o).unwrap();
|
||||
let text = String::from_utf8_lossy(&bytes).into_owned();
|
||||
let xs: Vec<f64> = text.lines().filter(|l| l.ends_with(" m") || l.ends_with(" l")).filter_map(|l| l.split(' ').next()?.parse().ok()).collect();
|
||||
assert_eq!(xs.len(), 2, "{text}");
|
||||
(xs[1] - xs[0]).abs() * 25.4 / 72.0
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn layout_plot_honours_explicit_scale_without_fit() {
|
||||
for (scale, mm) in [(1.0, 90.0), (0.5, 45.0), (2.0, 180.0)] {
|
||||
let got = plotted_mm(json!({"fit": false, "scale": scale}));
|
||||
assert!((got - mm).abs() < 0.01, "scale {scale}: {got} mm, want {mm}");
|
||||
}
|
||||
let default = plotted_mm(json!({}));
|
||||
assert!((default - 90.0).abs() < 0.01, "default stays 1:1: {default}");
|
||||
}
|
||||
Reference in new issue
Block a user