mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 17:56:50 -06:00
Merge pull request #2183 from dotCooCoo/fix/export-for-screens-formats-text
Export for Screens: the params text and the format error list every format a row writes
This commit is contained in:
@@ -133,7 +133,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"Export for Screens",
|
||||
["File", "Export"],
|
||||
None,
|
||||
"{folder?, zip?: false (one store-only .zip of every file: no folder → {name, dataBase64, bytes, files: [name…]}; with a folder it is written there → {path, bytes, files}), artboards?: [index…] | range?: \"1-3\" (default all), assets?: [asset id…] (instead of artboards: each asset's art alone, cropped to its bounds and named after the asset; see assets.list), fullDocument?: false (one file per format instead: a PDF of every artboard, other formats the bounds of all visible art, named after the document), includeBleed?: false (artboards grown by the document's bleed), subfolders?: false (each row's files in a sub-folder: its folder, else its size for raster (1x, 2x, 100w…) or its format (SVG, PDF)), preset?: mobile (PNG 1x, 2x, 3x) | density (PNG 0.75x–4x in ldpi…xxxhdpi sub-folders) instead of formats (turns subfolders on), formats?: [{format: png|png8|jpg|webp|gif|svg|svgz|pdf, scale?: 1 | \"2x\" | \"100w\" | \"100h\" | \"72ppi\", width?: px | height?: px | ppi? (raster only; width, then height, then ppi win over scale), suffix?: (raster default: @2x, @100w, @100h, none at 1x; vector formats drop size suffixes), folder?: (its sub-folder), quality?: (jpg 0–100), …the format's options (antiAlias, background, preset (pdf)…)}], settings?: {png|png8|jpg|webp|gif|svg|pdf: {…options for every row of that format}} (rows' own options win), prefix?, antiAlias?: none|art|type (raster rows without their own), openLocation?: (remembered; the app shows the files after exporting)} one file per artboard and format (a PDF holds its artboard alone; artboards with the same name, in any case, get -2, -3…; an unnamed one is Artboard-N) → {files: [path…]}; no folder → {files: [{name, dataBase64}]} (names include sub-folders: 2x/Icon@2x.png). The params (but zip and assets) are remembered in the document (document.exportSettings; not an undo step)",
|
||||
"{folder?, zip?: false (one store-only .zip of every file: no folder → {name, dataBase64, bytes, files: [name…]}; with a folder it is written there → {path, bytes, files}), artboards?: [index…] | range?: \"1-3\" (default all), assets?: [asset id…] (instead of artboards: each asset's art alone, cropped to its bounds and named after the asset; see assets.list), fullDocument?: false (one file per format instead: a PDF of every artboard, other formats the bounds of all visible art, named after the document), includeBleed?: false (artboards grown by the document's bleed), subfolders?: false (each row's files in a sub-folder: its folder, else its size for raster (1x, 2x, 100w…) or its format (SVG, PDF)), preset?: mobile (PNG 1x, 2x, 3x) | density (PNG 0.75x–4x in ldpi…xxxhdpi sub-folders) instead of formats (turns subfolders on), formats?: [{format: png|png8|jpg|webp|gif|tiff|bmp|tga|psd|svg|svgz|pdf, scale?: 1 | \"2x\" | \"100w\" | \"100h\" | \"72ppi\", width?: px | height?: px | ppi? (raster only; width, then height, then ppi win over scale), suffix?: (raster default: @2x, @100w, @100h, none at 1x; vector formats drop size suffixes), folder?: (its sub-folder), quality?: (jpg 0–100), …the format's options (antiAlias, background, preset (pdf)…)}], settings?: {png|png8|jpg|webp|gif|tiff|bmp|tga|psd|svg|svgz|pdf: {…options for every row of that format}} (rows' own options win), prefix?, antiAlias?: none|art|type (raster rows without their own), openLocation?: (remembered; the app shows the files after exporting)} one file per artboard and format (a PDF holds its artboard alone; artboards with the same name, in any case, get -2, -3…; an unnamed one is Artboard-N) → {files: [path…]}; no folder → {files: [{name, dataBase64}]} (names include sub-folders: 2x/Icon@2x.png). The params (but zip and assets) are remembered in the document (document.exportSettings; not an undo step)",
|
||||
has_doc,
|
||||
screens::export_for_screens
|
||||
),
|
||||
|
||||
@@ -170,7 +170,7 @@ impl Row {
|
||||
}
|
||||
let format = writable(C, Some(str_param(row, "format").unwrap_or("png")), None)?;
|
||||
if matches!(format.id, "vectorcraft" | "template" | "ai" | "txt" | "dxf" | "eps" | "emf" | "wmf") {
|
||||
return Err(bad(C, "Export for Screens writes png, png8, jpg, webp, gif, svg, svgz or pdf"));
|
||||
return Err(bad(C, "Export for Screens writes png, png8, jpg, webp, gif, tiff, bmp, tga, psd, svg, svgz or pdf"));
|
||||
}
|
||||
// Vector formats have no pixel size: it doesn't apply and adds no @2x suffix (not even one
|
||||
// left over from a raster row switched to SVG or PDF).
|
||||
|
||||
@@ -225,6 +225,43 @@ fn format_settings_apply_to_their_rows_and_rows_win() {
|
||||
assert!(f[2].1.len() < f[3].1.len(), "quality 5 is smaller than quality 100");
|
||||
}
|
||||
|
||||
/// The format ids `text` lists as `a|b|c` after `start`, up to `end`, sorted.
|
||||
fn listed(text: &str, start: &str, end: char) -> Vec<String> {
|
||||
let (_, rest) = text.split_once(start).unwrap_or_else(|| panic!("no `{start}` in {text}"));
|
||||
let mut ids: Vec<String> = rest.split(end).next().unwrap_or_default().split('|').map(|f| f.trim().to_string()).collect();
|
||||
ids.sort();
|
||||
ids
|
||||
}
|
||||
|
||||
/// The params text (a row's `format` and the keys of `settings`) and the refusal of a format a row
|
||||
/// can't have list exactly the formats a row writes.
|
||||
#[test]
|
||||
fn the_params_and_the_refusal_list_every_format_a_row_writes() {
|
||||
let mut s = session(1);
|
||||
let (mut written, mut refusals) = (vec![], vec![]);
|
||||
for f in FORMATS.iter().filter(|f| f.write) {
|
||||
match s.execute("document.exportForScreens", &json!({"formats": [{"format": f.id}]})) {
|
||||
Ok(r) => {
|
||||
assert_eq!(files(&r).len(), 1, "{}", f.id);
|
||||
written.push(f.id.to_string());
|
||||
}
|
||||
Err(crate::EngineError::BadParams { msg, .. }) => refusals.push(msg),
|
||||
Err(e) => panic!("{}: {e}", f.id),
|
||||
}
|
||||
}
|
||||
written.sort();
|
||||
let params = crate::cmd::find_command("document.exportForScreens").unwrap().params;
|
||||
assert_eq!(listed(params, "[{format: ", ','), written, "a row's format");
|
||||
assert_eq!(listed(params, "settings?: {", ':'), written, "the keys of settings");
|
||||
assert!(!refusals.is_empty());
|
||||
for msg in refusals {
|
||||
let list = msg.strip_prefix("Export for Screens writes ").unwrap_or_else(|| panic!("{msg}"));
|
||||
let mut ids: Vec<String> = list.replace(" or ", ", ").split(", ").map(str::to_string).collect();
|
||||
ids.sort();
|
||||
assert_eq!(ids, written, "{msg}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zip_downloads_round_trip() {
|
||||
let mut s = session(2);
|
||||
|
||||
Reference in New Issue
Block a user