CLI, MCP: the raster scale no longer resizes DXF exports

`vectorcraft-cli run/convert --scale` and the MCP export tool's `scale`
are raster pixels per point, but they were passed to every export, and
DXF reads `scale` as drawing units per unit: a 2x PNG next to a DXF
doubled the drawing and left it unitless ($INSUNITS 0). They now go
only to raster formats. DXF's own scale stays reachable through the
format options.
This commit is contained in:
MortenHusted
2026-10-18 23:50:57 +07:00
committed by bflatastic
parent 88494319da
commit eba9abc21e
4 changed files with 66 additions and 8 deletions
+17 -4
View File
@@ -79,14 +79,16 @@ USAGE:
vectorcraft-cli run [--in FILE] [--cmd ID [--params JSON]]... [--export FILE]... [--scale N]
Headless batch: open FILE (any readable format) or start a new document, run commands in
order, export each FILE in the format its extension picks (see Writable formats; a .ait FILE
is a template, written as file.saveAsTemplate writes it). Prints one JSON result per step.
is a template, written as file.saveAsTemplate writes it). --scale sizes raster exports
(pixels per point, default 1); other formats leave it out. Prints one JSON result per step.
vectorcraft-cli commands
Print the command catalogue as JSON.
vectorcraft-cli convert IN OUT [--scale N] [--artboard I | --range R] [--outline-text] [--decimals N] [--replace-lossy] [--editing-data] [--ai-version 7|pdf] [--hidden-objects layer|omit|visible] [--transparent-images flatten|omit]
Open IN (any readable format) and export OUT in the format its extension picks (see Writable
formats). --artboard is 0-based, --range 1-based (\"1-3,5\"); a PDF gets every artboard
formats). --scale sizes a raster OUT (pixels per point, default 1); other formats leave it
out. --artboard is 0-based, --range 1-based (\"1-3,5\"); a PDF gets every artboard
unless one of them is given, EPS the bounds of the art, the other formats the first artboard.
A .ait OUT is a template of every artboard, written as file.saveAsTemplate writes it (not with
--artboard or --range).
@@ -278,7 +280,8 @@ fn convert(args: &[String]) -> Result<(), String> {
} else {
// A conversion keeps hidden layers and objects, written hidden, where the format can (SVG,
// PSD).
let mut params = json!({"path": output, "scale": scale, "artboard": artboard, "range": range, "outlineText": outline_text, "hiddenLayers": true, "acknowledgeLoss": replace_lossy});
let params = json!({"path": output, "artboard": artboard, "range": range, "outlineText": outline_text, "hiddenLayers": true, "acknowledgeLoss": replace_lossy});
let mut params = with_pixel_scale(params, &output, scale);
if let Some(decimals) = decimals {
params["decimals"] = json!(decimals);
}
@@ -302,6 +305,16 @@ fn is_template(path: &str) -> bool {
vectorcraft_engine::cmd::fileio::format_for_name(path).is_some_and(|f| f.id == "ait")
}
/// The export `params` for `path`, with `--scale` (pixels per point) when its format is raster.
/// DXF has a `scale` of its own (drawing units per unit), which would resize the drawing and leave
/// its units unset.
fn with_pixel_scale(mut params: Value, path: &str, scale: f64) -> Value {
if vectorcraft_engine::cmd::fileio::writable_format(None, Some(path)).is_ok_and(|f| f.raster) {
params["scale"] = json!(scale);
}
params
}
fn info(args: &[String]) -> Result<(), String> {
let file = args.first().ok_or("info needs a FILE")?;
let mut h = Headless::new();
@@ -391,7 +404,7 @@ fn run(args: &[String]) -> Result<(), String> {
let r = if is_template(&path) {
h.call("engine.execute", json!({"command": "file.saveAsTemplate", "params": {"path": path, "format": "ait"}}))
} else {
h.call("app.export", json!({"path": path, "scale": scale}))
h.call("app.export", with_pixel_scale(json!({"path": path}), &path, scale))
};
let r = r.map_err(|e| format!("export {path}: {e}"))?;
emit(json!({"step": "export", "result": r}))?;