Combine PdfFieldSignature with PdfSignatureAppearance

This commit is contained in:
Adrian-George Bostan 2019-02-13 20:28:24 +02:00
parent 2ef5b5ab53
commit c2d1efb653
4 changed files with 44 additions and 82 deletions

View File

@ -1,50 +0,0 @@
/*
* This file is subject to the terms and conditions defined in
* file 'LICENSE.md', which is part of this source code package.
*/
package model
import "github.com/unidoc/unidoc/pdf/core"
// PdfSignatureAppearance defines a signature with a specified form field and
// annotation widget for appearance styling.
type PdfSignatureAppearance struct {
*PdfField
*PdfAnnotationWidget
Signature *PdfSignature
}
// NewPdfSignatureAppearance returns an initialized signature field appearance.
func NewPdfSignatureAppearance() *PdfSignatureAppearance {
app := &PdfSignatureAppearance{}
app.PdfField = NewPdfField()
app.PdfAnnotationWidget = NewPdfAnnotationWidget()
app.PdfField.SetContext(app)
app.PdfAnnotationWidget.SetContext(app)
app.PdfAnnotationWidget.container = app.PdfField.container
return app
}
// ToPdfObject implements interface PdfModel.
func (app *PdfSignatureAppearance) ToPdfObject() core.PdfObject {
if app.Signature != nil {
app.V = app.Signature.ToPdfObject()
}
app.PdfAnnotation.ToPdfObject()
app.PdfField.ToPdfObject()
container := app.container
d := container.PdfObject.(*core.PdfObjectDictionary)
d.SetIfNotNil("Subtype", core.MakeName("Widget"))
d.SetIfNotNil("H", app.H)
d.SetIfNotNil("MK", app.MK)
d.SetIfNotNil("A", app.A)
d.SetIfNotNil("AA", app.PdfAnnotationWidget.AA)
d.SetIfNotNil("BS", app.BS)
d.SetIfNotNil("Parent", app.PdfAnnotationWidget.Parent)
return container
}

View File

@ -381,8 +381,8 @@ func (a *PdfAppender) ReplacePage(pageNum int, page *PdfPage) {
}
// Sign signs a specific page with a digital signature using a specified signature handler.
// Returns an Acroform and PdfAppearance that can be used to customize the signature appearance.
func (a *PdfAppender) Sign(pageNum int, handler SignatureHandler) (acroForm *PdfAcroForm, appearance *PdfSignatureAppearance, err error) {
// Returns an Acroform and PdfFieldSignature that can be used to customize the signature appearance.
func (a *PdfAppender) Sign(pageNum int, handler SignatureHandler) (acroForm *PdfAcroForm, signatureField *PdfFieldSignature, err error) {
acroForm = a.Reader.AcroForm
if acroForm == nil {
acroForm = NewPdfAcroForm()
@ -411,32 +411,31 @@ func (a *PdfAppender) Sign(pageNum int, handler SignatureHandler) (acroForm *Pdf
}
a.addNewObjects(sig.container)
appearance = NewPdfSignatureAppearance()
fields := append(acroForm.AllFields(), appearance.PdfField)
signatureField = NewPdfFieldSignature()
fields := append(acroForm.AllFields(), signatureField.PdfField)
acroForm.Fields = &fields
procPage(page)
appearance.V = sig.ToPdfObject()
appearance.FT = core.MakeName("Sig")
appearance.V = sig.ToPdfObject()
appearance.T = core.MakeString("Signature1")
appearance.F = core.MakeInteger(132)
appearance.P = page.ToPdfObject()
appearance.Rect = core.MakeArray(core.MakeInteger(0), core.MakeInteger(0), core.MakeInteger(0),
core.MakeInteger(0))
appearance.Signature = sig
// Add the signature appearance to the page annotations.
page.Annotations = append(page.Annotations, appearance.PdfAnnotationWidget.PdfAnnotation)
signatureField.FT = core.MakeName("Sig")
signatureField.V = sig
signatureField.T = core.MakeString("Signature1")
signatureField.F = core.MakeInteger(132)
signatureField.P = page.ToPdfObject()
signatureField.Rect = core.MakeArray(
core.MakeInteger(0),
core.MakeInteger(0),
core.MakeInteger(0),
core.MakeInteger(0),
)
// Add the signature field to the page annotations.
page.Annotations = append(page.Annotations, signatureField.PdfAnnotationWidget.PdfAnnotation)
a.pages[pageIndex] = page
// Update acroform.
a.ReplaceAcroForm(acroForm)
return acroForm, appearance, nil
return acroForm, signatureField, nil
}
// ReplaceAcroForm replaces the acrobat form. It appends a new form to the Pdf which

View File

@ -453,8 +453,8 @@ func TestAppenderSignPage4(t *testing.T) {
return
}
appearance.Signature.Name = core.MakeString("Test Appender")
appearance.Signature.Reason = core.MakeString("TestAppenderSignPage4")
appearance.V.Name = core.MakeString("Test Appender")
appearance.V.Reason = core.MakeString("TestAppenderSignPage4")
err = appender.WriteToFile(tempFile("appender_sign_page_4.pdf"))
if err != nil {
@ -520,8 +520,8 @@ func TestAppenderSignMultiple(t *testing.T) {
return
}
appearance.Signature.Name = core.MakeString(fmt.Sprintf("Test Appender - Round %d", i+1))
appearance.Signature.Reason = core.MakeString("TestAppenderSignPage4")
appearance.V.Name = core.MakeString(fmt.Sprintf("Test Appender - Round %d", i+1))
appearance.V.Reason = core.MakeString("TestAppenderSignPage4")
outPath := tempFile(fmt.Sprintf("appender_sign_multiple_%d.pdf", i+1))

View File

@ -433,28 +433,41 @@ func (ch *PdfFieldChoice) ToPdfObject() core.PdfObject {
// the name of the signer and verifying document contents.
type PdfFieldSignature struct {
*PdfField
*PdfAnnotationWidget
V *PdfSignature
Lock *core.PdfIndirectObject
SV *core.PdfIndirectObject
}
// NewPdfFieldSignature returns an initialized signature field.
func NewPdfFieldSignature() *PdfFieldSignature {
sig := &PdfFieldSignature{}
sig.PdfField = NewPdfField()
sig.PdfAnnotationWidget = NewPdfAnnotationWidget()
sig.PdfField.SetContext(sig)
sig.PdfAnnotationWidget.SetContext(sig)
sig.PdfAnnotationWidget.container = sig.PdfField.container
return sig
}
// ToPdfObject returns an indirect object containing the signature field dictionary.
func (sig *PdfFieldSignature) ToPdfObject() core.PdfObject {
// Set general field attributes
if sig.PdfAnnotationWidget != nil {
sig.PdfAnnotation.ToPdfObject()
}
sig.PdfField.ToPdfObject()
container := sig.container
// Handle signature field specific attributes
container := sig.container
d := container.PdfObject.(*core.PdfObjectDictionary)
d.Set("FT", core.MakeName("Sig"))
d.SetIfNotNil("FT", core.MakeName("Sig"))
d.SetIfNotNil("Lock", sig.Lock)
d.SetIfNotNil("SV", sig.SV)
if sig.V != nil {
d.Set("V", sig.V.ToPdfObject())
}
if sig.Lock != nil {
d.Set("Lock", sig.Lock)
}
if sig.SV != nil {
d.Set("SV", sig.SV)
d.SetIfNotNil("V", sig.V.ToPdfObject())
}
return container