empira / PDFsharp

PDFsharp and MigraDoc Foundation for .NET 6 and .NET Framework
https://docs.pdfsharp.net/
Other
492 stars 114 forks source link

[Suggestion] Add support of annotation flags to signature field #157

Open mebureau opened 1 month ago

mebureau commented 1 month ago

In version 6.2.0 Preview 1, it is not possible to customize the behavior of the signature field, such as marking it as printable. Digital signature components are added during saving, so they cannot be modified before saving, and modifying the document after saving causes a signature validation error. My suggestion is to add PdfAnnotationFlags to DigitalSignatureOptions and pass them when creating the signature field

  public class DigitalSignatureOptions()
  {
      [...]

      /// <summary>
      /// Gets or sets Signature Field flags
      /// </summary>
      public PdfAnnotationFlags FieldFlags { get; init; }
  }
    public class DigitalSignatureHandler
{
    [...]

    PdfSignatureField GetSignatureField(PdfDictionary signatureDic)  // PdfSignatureDictionary
    {
        var signatureField = new PdfSignatureField(Document);

        signatureField.Elements.Add(PdfAcroField.Keys.V, signatureDic);

        // Annotation keys.
        signatureField.Elements.Add(PdfAcroField.Keys.FT, new PdfName("/Sig"));
        signatureField.Elements.Add(PdfAcroField.Keys.T, new PdfString("Signature1")); // TODO If already exists, will it cause error? implement a name chooser if yes.
        signatureField.Elements.Add(PdfAcroField.Keys.Ff, new PdfInteger(132));
        signatureField.Elements.Add(PdfAcroField.Keys.DR, new PdfDictionary());
        signatureField.Elements.Add(PdfSignatureField.Keys.Type, new PdfName("/Annot"));
        signatureField.Elements.Add("/Subtype", new PdfName("/Widget"));
        signatureField.Elements.Add("/P", Document.Pages[Options.PageIndex]);
        signatureField.Elements.Add("/F", new PdfInteger((int)Options.FieldFlags)); //Add flags here

        signatureField.Elements.Add("/Rect", new PdfRectangle(Options.Rectangle));

        signatureField.CustomAppearanceHandler = Options.AppearanceHandler ?? new DefaultSignatureAppearanceHandler()
        {
            Location = Options.Location,
            Reason = Options.Reason,
            Signer = Signer.CertificateName
        };
        // TODO Call RenderCustomAppearance(); here.
        signatureField.PrepareForSave(); // TODO PdfSignatureField.PrepareForSave() is not triggered automatically so let's call it manually from here, but it would be better to be called automatically.

        Document.Internals.AddObject(signatureField);

        return signatureField;
    }
}