How to use a PDF page as a Digital Signature appearance?

Question:
Given a PDF page as a source, how do I set the appearance of a Digital Signature using the PDF page?

Answer:
The following code will work with any annotation, to set a custom appearance.

// annot should already be on a page so that appearance is always "right side" up to a user
// srcPage is the page to use as the appearance
static void SetAppearance(PDFDoc annotsPdfDoc, Annot annot, Page srcPage)
{
	if(!annot.GetPage().IsValid())
	{
		throw new Exception("Target annotation should be on a page already so that rotation can be calculated");
	}
	ArrayList import_list = new ArrayList();
	import_list.Add(srcPage);
	ArrayList imported_pages = annotsPdfDoc.ImportPages(import_list);
	Page importedPage = (Page)imported_pages[0];
	Rect bbox = importedPage.GetCropBox();
	using (ElementBuilder builder = new ElementBuilder())
	using (ElementWriter writer = new ElementWriter())
    {
		writer.Begin(annotsPdfDoc);
		Element element = builder.CreateForm(importedPage);
		writer.WritePlacedElement(element);
		Obj appObj = writer.End();
		appObj.PutRect("BBox", bbox.x1, bbox.y1, bbox.x2, bbox.y2);
		appObj.PutName("Subtype", "Form");
		appObj.PutName("Type", "XObject");
		Page.Rotate pageRotation = annot.GetPage().GetRotation();
		if (pageRotation != Page.Rotate.e_0)
		{
			Matrix2D rot = Matrix2D.RotationMatrix(pdftron.PDF.Page.RotationToDegree(pageRotation) / 180.0 * -Math.PI);
			var mtxArray = appObj.PutArray("Matrix");
			mtxArray.PushBackNumber(rot.m_a);
			mtxArray.PushBackNumber(rot.m_b);
			mtxArray.PushBackNumber(rot.m_c);
			mtxArray.PushBackNumber(rot.m_d);
			mtxArray.PushBackNumber(rot.m_h);
			mtxArray.PushBackNumber(rot.m_v);
		}
		annot.SetAppearance(appObj);
	}
}

Example usage would be

using (PDFDoc doc = new PDFDoc(in_docpath))
{
	// Retrieve the unsigned approval signature field.
	Field found_approval_field = doc.GetField(in_approval_field_name);
	DigitalSignatureField found_approval_signature_digsig_field = new DigitalSignatureField(found_approval_field);
	SignatureWidget found_approval_signature_widget = new SignatureWidget(found_approval_field.GetSDFObj());
	////////////////////////
	// Set custom appearance
	var tempPdfDoc = new PDFDoc(in_appearance_path);
	SetAppearance(doc, found_approval_signature_widget, tempPdfDoc.GetPage(1));
	tempPdfDoc.Close();
	////////////////////////
	found_approval_signature_digsig_field.SignOnNextSave(in_private_key_file_path, in_keyfile_password);
	doc.Save(in_outpath, SDFDoc.SaveOptions.e_incremental);
}

Attached is modified Digital Signatures sample showing the full usage.

DigitalSignaturesTest.cs.txt (3.7 KB)

1 Like