M9: visible digital signatures can show a drawn, typed or image graphic (#193) (#934)

* M9: visible digital signatures can show a drawn, typed or image graphic (#193)

A visible certificate signature can show a graphic where the signer's
name is large, as Acrobat's Configure Signature Appearance does: the
saved Fill & Sign signature (drawn, typed or image) or an imported
PNG/JPEG. Sign as previews it and remembers the choice; sign_document
takes `graphic` (image, text or strokes).

pdfcraft-sign gains `Graphic` and `SignOptions::graphic`. Graphics are
checked and size-capped before drawing; images keep alpha as a soft
mask and are encrypted with the rest of the update in encrypted files.

Refs #193

* Refresh catalog hashes

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
Justin Wilkins
2026-10-11 13:47:51 -04:00
committed by GitHub
co-authored by Brandon Thomas
parent 626724bbdd
commit 56c034b0b3
33 changed files with 804 additions and 85 deletions
+7
View File
@@ -96,6 +96,13 @@ pub fn typed_signature_shape(at: [f64; 2], text: &str, height: f64, rotation: i6
let contours = o.contours.iter().map(|c| c.iter().map(|p| to_user((p[0] - left) / width, (p[1] - bottom) / span)).collect()).collect();
Some(Shape::TypedSignature { rect, contours })
}
/// `text` in the script font as the graphic of a visible digital signature, as Fill & Sign types
/// it. `None` for text with no outlines.
pub fn typed_signature_graphic(text: &str) -> Option<pdfcraft_sign::Graphic> {
let o = script_outline(text);
o.contours.iter().any(|c| c.len() > 2).then_some(pdfcraft_sign::Graphic::Outlines(o.contours))
}
/// Comment geometry helpers (text-box line breaking) for frontends.
pub use pdfcraft_annot::appearance as annot_text;
pub use pdfcraft_annot::links::{Highlight as LinkHighlight, LinkAction, LinkItem, LinkStyle};
+7
View File
@@ -164,6 +164,13 @@ impl SignatureImage {
self.size
}
/// This image as the graphic of a visible digital signature.
pub fn graphic(&self) -> pdfcraft_sign::Graphic {
// Sides are at most 4096 pixels; 0 would be refused by the signer, never drawn.
let side = |v: usize| u32::try_from(v).unwrap_or(0);
pdfcraft_sign::Graphic::Image { width: side(self.size[0]), height: side(self.size[1]), rgba: self.rgba.clone() }
}
/// Make near-white paper transparent, keeping darker ink.
pub fn remove_white_background(&self, cutoff: u8, feather: u8) -> Result<Self, SignatureImageError> {
let [w, h] = self.size;