///|
fn xml_text(value : String) -> String {
let out = StringBuilder()
for c in value.iter() {
match c {
'&' => out.write_string("&")
'<' => out.write_string("<")
'>' => out.write_string(">")
'"' => out.write_string(""")
'\'' => out.write_string("'")
'\n' | '\r' | '\t' => out.write_char(' ')
_ =>
if c.to_int() < 32 || c == '\u{FFFE}' || c == '\u{FFFF}' {
out.write_char('�')
} else {
out.write_char(c)
}
}
}
out.to_string()
}
///|
fn content_panel(
rect : Rect,
booklet : Booklet,
slot : Slot,
rotation : Int32,
) -> String {
let (logical, label) = match slot {
Blank => ("PADDING", "No source page")
Page(n) =>
(
"Logical \{n}",
match booklet.document.pages[n - 1] {
Empty => "AUTHORED BLANK"
Source(source, page) => "\{source} #\{page}"
},
)
}
let cx = rect.x + rect.width / 2
let cy = rect.y + rect.height / 2
""
}
///|
fn job_face_svg(
job : PrintJob,
sheet_index : Int32,
back : Bool,
) -> Result[String, WorkflowError] {
let sheet = job.booklet.sheets[sheet_index]
let positions = match layout(job.paper, sheet.depth) {
Ok(positions) => positions
Err(_) =>
return Err(
workflow_error("paper", "invalid geometry for requested sheet"),
)
}
let face = if back { sheet.back } else { sheet.front }
let left = content_panel(
positions.left,
job.booklet,
face.left,
face.rotation,
)
let right = content_panel(
positions.right,
job.booklet,
face.right,
face.rotation,
)
let center = job.paper.width / 2
Ok(
"\{left}\{right}",
)
}
///|
/// A dimensioned source-labelled proof; source artwork is not embedded.
pub fn job_proof(
job : PrintJob,
sheet_index : Int32,
back : Bool,
) -> Result[String, WorkflowError] {
match recover_booklet(job.booklet) {
Err(e) => return Err(e)
Ok(_) => ()
}
if sheet_index < 0 || sheet_index >= job.booklet.sheets.length() {
return Err(workflow_error("sheet", "proof sheet index out of range"))
}
let content = match job_face_svg(job, sheet_index, back) {
Ok(svg) => svg
Err(e) => return Err(e)
}
let side = if back { "back" } else { "front" }
Ok(
"",
)
}
///|
/// Paginate large jobs with first_sheet/count; each atlas is limited to 64 sheets.
pub fn proof_atlas(
job : PrintJob,
first_sheet : Int32,
count : Int32,
) -> Result[String, WorkflowError] {
match verify_schedule(job.booklet, job.schedule) {
Err(e) => return Err(e)
Ok(_) => ()
}
if count < 1 ||
count > 64 ||
first_sheet < 0 ||
first_sheet > job.booklet.sheets.length() - count {
return Err(
workflow_error("atlas", "expected a valid range containing 1..64 sheets"),
)
}
let width = job.paper.width * 2 + 12
let row_height = job.paper.height + 16
let height = row_height * count
let fragments : Array[String] = []
for index in first_sheet..<(first_sheet + count) {
let sheet = job.booklet.sheets[index]
let y = (index - first_sheet) * row_height
for side in 0..<2 {
let x = side * (job.paper.width + 12)
let label = if side == 0 { "FRONT" } else { "BACK" }
let content = match job_face_svg(job, index, side == 1) {
Ok(svg) => svg
Err(e) => return Err(e)
}
fragments.push(
"Sheet \{index + 1} / gathering \{sheet.signature + 1} / depth \{sheet.depth} / \{label}",
)
}
}
Ok(
"",
)
}