mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 09:20:56 -06:00
PDF export: warn when a PDF/X file leaves out the document's bleed
Choosing a PDF/X standard without a PDF/X preset writes a file with no bleed (BleedBox = TrimBox) even when Document Setup sets one, and the export gave no warning about it. The export now warns when a PDF/X file has no bleed on a side where the document's bleed has one. The warning comes ahead of the flattening note, because the status bar shows only the first warning. The code adds a warning and does not change what is written. These cases do not warn: the PDF/X presets, Use document bleed settings, a nonzero bleed on every side the document sets, a document with no bleed, files that aren't PDF/X files, and Export for Screens rows whose artboards Include Bleed grows. The warning has a row in every catalog. The Summary's warning and error rows in the Save PDF and Print dialogs now go through the catalog, so they show its translations.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1019,11 +1019,14 @@ fn encode_and_write(export: ScreenExport, writer: &mut dyn FnMut(&str, &[u8]) ->
|
||||
let mut out = Output::default();
|
||||
// The encoders' warnings for every file, each once.
|
||||
let mut warnings: Vec<String> = Vec::new();
|
||||
// Include Bleed: a grown artboard already holds the bleed. Assets, layers and a selection are
|
||||
// written on a page of their own bounds, which it doesn't grow.
|
||||
let bleed_on_page = o.include_bleed && o.assets.is_none() && o.layers.is_none() && o.selection.is_none();
|
||||
let mut write = |doc: &Document, format: &str, options: &Value| -> Result<Vec<u8>> {
|
||||
// The steps are the files: an encoder's own steps (artboards, pages) are not reported.
|
||||
let (bytes, notes) = vectorcraft_doc::cancel::quiet(|| encode_with_warnings(doc, format, options))?;
|
||||
for w in notes {
|
||||
if !warnings.contains(&w) {
|
||||
if !(bleed_on_page && w == super::pdf::BLEED_LEFT_OUT) && !warnings.contains(&w) {
|
||||
warnings.push(w);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,55 @@ fn choosing_a_pdfx_standard_sets_its_version_and_turns_off_what_it_forbids() {
|
||||
}
|
||||
}
|
||||
|
||||
/// A PDF/X file without the bleed the document sets exports as asked and warns; the presets and
|
||||
/// options that take the document's bleed, and files that aren't PDF/X files, don't warn.
|
||||
#[test]
|
||||
fn a_pdfx_file_that_leaves_out_the_document_bleed_warns() {
|
||||
let left_out = |w: &Vec<String>| w.iter().any(|w| w == super::pdf::BLEED_LEFT_OUT);
|
||||
let mut s = session();
|
||||
s.execute("document.setup", &json!({"bleed": 6})).unwrap();
|
||||
for standard in ["pdfX1a", "pdfX3", "pdfX4"] {
|
||||
let (_, warnings) = pdf(&mut s, json!({"standard": standard}));
|
||||
// First: the status bar shows the first warning, and PDF/X-1a and PDF/X-3 add the flattening note.
|
||||
assert_eq!(warnings.first().map(String::as_str), Some(super::pdf::BLEED_LEFT_OUT), "{standard}: {warnings:?}");
|
||||
// The page has no bleed, as asked.
|
||||
let v = s.execute("document.exportPdf", &json!({"standard": standard})).unwrap();
|
||||
let info = s.execute("document.pdfInfo", &json!({"name": "x.pdf", "dataBase64": v["dataBase64"]})).unwrap();
|
||||
let boxes = &info["pageInfo"][0]["boxes"];
|
||||
assert!(boxes["media"].is_array() && boxes["media"] == boxes["trim"] && boxes["media"] == boxes["bleed"], "{standard}: {info}");
|
||||
}
|
||||
let v = s.execute("document.export", &json!({"format": "pdf", "standard": "pdfX4"})).unwrap();
|
||||
assert!(v["warnings"].as_array().unwrap().iter().any(|w| w == super::pdf::BLEED_LEFT_OUT), "{v}");
|
||||
// A side the settings leave out warns, and sides they all keep don't.
|
||||
let (_, warnings) = pdf(&mut s, json!({"standard": "pdfX4", "bleed": {"top": 6, "bottom": 6, "left": 6}}));
|
||||
assert!(left_out(&warnings), "{warnings:?}");
|
||||
for p in [
|
||||
json!({"preset": "PDF/X-1a:2001"}),
|
||||
json!({"preset": "PDF/X-3:2002"}),
|
||||
json!({"preset": "PDF/X-4:2010"}),
|
||||
json!({"standard": "pdfX4", "bleed": {"useDocument": true}}),
|
||||
json!({"standard": "pdfX4", "bleed": {"top": 1, "bottom": 1, "left": 1, "right": 1}}),
|
||||
json!({}),
|
||||
json!({"standard": "pdfA2b"}),
|
||||
] {
|
||||
let (_, warnings) = pdf(&mut s, p.clone());
|
||||
assert!(!left_out(&warnings), "{p}: {warnings:?}");
|
||||
}
|
||||
// The dialog's Summary exports in memory, so it lists the warning too.
|
||||
let v = s.execute("document.pdfSettings", &json!({"standard": "pdfX4", "includeDocument": true})).unwrap();
|
||||
assert!(v["warnings"].as_array().unwrap().iter().any(|w| w == super::pdf::BLEED_LEFT_OUT), "{v}");
|
||||
// A bleed on the top alone: only that side counts.
|
||||
s.execute("document.setup", &json!({"bleed": [6, 0, 0, 0]})).unwrap();
|
||||
let (_, warnings) = pdf(&mut s, json!({"standard": "pdfX4", "bleed": {"top": 1}}));
|
||||
assert!(!left_out(&warnings), "{warnings:?}");
|
||||
let (_, warnings) = pdf(&mut s, json!({"standard": "pdfX4", "bleed": {"bottom": 1}}));
|
||||
assert!(left_out(&warnings), "{warnings:?}");
|
||||
// A document without a bleed has nothing to leave out.
|
||||
s.execute("document.setup", &json!({"bleed": 0})).unwrap();
|
||||
let (_, warnings) = pdf(&mut s, json!({"standard": "pdfX4"}));
|
||||
assert!(!left_out(&warnings), "{warnings:?}");
|
||||
}
|
||||
|
||||
/// The ink amounts (0..1) `doc` shows at `p` in its images (the topmost image there).
|
||||
fn image_inks_at(doc: &vectorcraft_doc::Document, p: vectorcraft_geom::Point) -> Option<[f32; 4]> {
|
||||
fn visit(n: &vectorcraft_doc::Node, out: &mut Vec<vectorcraft_doc::ImageObject>) {
|
||||
|
||||
@@ -526,6 +526,20 @@ fn include_bleed_grows_each_artboard() {
|
||||
assert_eq!(size(&files(&r)[0].1), (40, 30), "without it, the artboard alone");
|
||||
}
|
||||
|
||||
/// Include Bleed puts the bleed on a PDF/X row's page, so the row doesn't warn that it leaves the bleed out.
|
||||
#[test]
|
||||
fn include_bleed_pdfx_rows_do_not_warn_about_the_bleed() {
|
||||
let mut s = session(1);
|
||||
s.execute("document.setup", &json!({"bleed": 6})).unwrap();
|
||||
let warned = |r: &Value| r["warnings"].as_array().unwrap().iter().any(|w| w == super::pdf::BLEED_LEFT_OUT);
|
||||
let row = json!([{"format": "pdf", "standard": "pdfX4"}]);
|
||||
assert!(warned(&export(&mut s, json!({"formats": row}))));
|
||||
assert!(!warned(&export(&mut s, json!({"includeBleed": true, "formats": row}))));
|
||||
// A selection is written on a page of its own bounds, which Include Bleed doesn't grow.
|
||||
s.execute("shape.rectangle", &json!({"x": 5, "y": 5, "width": 10, "height": 10})).unwrap();
|
||||
assert!(warned(&export(&mut s, json!({"includeBleed": true, "selection": "one", "formats": row}))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn png_8_rows_write_indexed_colour() {
|
||||
let mut s = session(1);
|
||||
|
||||
Reference in New Issue
Block a user