Redact: refuse Redact marks written in place; remove replies and pop-ups listed on other pages; delete form fields by object, not name; resolve Do by its last operand like the renderer; sanitize drops PCAdded and flattens widgets before hidden-content cleanup. Sign: freed signed objects and edits to an already-signed widget are modifications. Cos: only reading trusts /Type /XRef to skip encryption.
pdfcraft-content
Layer L2: content streams (ISO 32000-2 §7.8.2, §8, §9).
let parsed = parse(&stream.decoded()?); // operators with operands and source spans
for op in &parsed.ops { if op.is("Tj") { /* … */ } }
let bytes = serialize_ops(&parsed.ops); // write back (inline images kept whole)
let m = Matrix::from_operands(&op.operands); // cm / Tm arithmetic, invert, bbox
The parser is tolerant (unreadable bytes are skipped and counted, never fatal) and never
panics. redact and (later) edit build their interpreters on it; the graphics-state tracker
and the Patch API of architecture §6 grow here.
An inline image ends where the renderer's tokenizer (hayro-syntax) ends it, so the parser
and the renderer read the same operators after the image, and redaction removes what the page
actually draws. Only where that tokenizer reads no image (its parameters don't read, or no EI
passes its checks) does the parser locate EI by its own rules: unfiltered images with built-in
or Indexed colour spaces, and image masks, by their sample layout (including per-row byte
padding), other images by the tolerant delimiter heuristic. Such an image is counted in
Parsed::ambiguous_images, because the operators after it may not be the ones the page draws.