int size = (int)rootPages.getCount();
PDPage page = null;
if (size == 0)
{
throw new SignatureException(SignatureException.INVALID_PAGE_FOR_SIGNATURE, "The PDF file has no pages");
}
if (options.getPage()>size)
{
page = kids.get(size-1);
}
else if(options.getPage()<=0)
{
page = kids.get(0);
}
else
{
page = kids.get(options.getPage()-1);
}
// Get the AcroForm from the Root-Dictionary and append the annotation
PDAcroForm acroForm = root.getAcroForm();
root.getCOSObject().setNeedToBeUpdate(true);
if (acroForm==null)
{
acroForm = new PDAcroForm(this);
root.setAcroForm(acroForm);
}
else
{
acroForm.getCOSObject().setNeedToBeUpdate(true);
}
/*
* For invisible signatures, the annotation has a rectangle array with values [ 0 0 0 0 ].
* This annotation is usually attached to the viewed page when the signature is created.
* Despite not having an appearance, the annotation AP and N dictionaries may be present
* in some versions of Acrobat. If present, N references the DSBlankXObj (blank) XObject.
*/
// Create Annotation / Field for signature
List<PDAnnotation> annotations = page.getAnnotations();
List<PDField> fields = acroForm.getFields();
PDSignatureField signatureField = null;
if(fields == null)
{
fields = new ArrayList();
acroForm.setFields(fields);
}
for ( PDField pdField : fields )
{
if (pdField instanceof PDSignatureField)
{
PDSignature signature = ((PDSignatureField)pdField).getSignature();
if (signature != null && signature.getDictionary().equals(sigObject.getDictionary()))
{
signatureField = (PDSignatureField)pdField;
}
}
}
if (signatureField == null)
{
signatureField = new PDSignatureField(acroForm);
signatureField.setSignature(sigObject); // append the signature object
signatureField.getWidget().setPage(page); // backward linking
}
// Set the AcroForm Fields
List<PDField> acroFormFields = acroForm.getFields();
COSDictionary acroFormDict = acroForm.getDictionary();
acroFormDict.setDirect(true);
acroFormDict.setInt(COSName.SIG_FLAGS, 3);
boolean checkFields = false;
for ( PDField field : acroFormFields )
{
if (field instanceof PDSignatureField)
{
if (((PDSignatureField)field).getCOSObject().equals(signatureField.getCOSObject()))
{
checkFields = true;
signatureField.getCOSObject().setNeedToBeUpdate(true);
break;
}
}
}
if (!checkFields)
{
acroFormFields.add(signatureField);
}
// Get the object from the visual signature
COSDocument visualSignature = options.getVisualSignature();
// Distinction of case for visual and non-visual signature
if (visualSignature == null) // non-visual signature
{
// Set rectangle for non-visual signature to 0 0 0 0
signatureField.getWidget().setRectangle(new PDRectangle()); // rectangle array [ 0 0 0 0 ]
// Clear AcroForm / Set DefaultRessource
acroFormDict.setItem(COSName.DR, null);
// Set empty Appearance-Dictionary
PDAppearanceDictionary ap = new PDAppearanceDictionary();
COSStream apsStream = getDocument().createCOSStream();
apsStream.createUnfilteredStream();
PDAppearanceStream aps = new PDAppearanceStream(apsStream);
COSDictionary cosObject = (COSDictionary)aps.getCOSObject();
cosObject.setItem(COSName.SUBTYPE, COSName.FORM);
cosObject.setItem(COSName.BBOX, new PDRectangle());
ap.setNormalAppearance(aps);
ap.getDictionary().setDirect(true);
signatureField.getWidget().setAppearance(ap);
}
else // visual signature
{
// Obtain visual signature object
List<COSObject> cosObjects = visualSignature.getObjects();
boolean annotNotFound = true;
boolean sigFieldNotFound = true;
for ( COSObject cosObject : cosObjects )
{
if (!annotNotFound && !sigFieldNotFound)
{
break;
}
COSBase base = cosObject.getObject();
if (base != null && base instanceof COSDictionary)
{
COSBase ft = ((COSDictionary)base).getItem(COSName.FT);
COSBase type = ((COSDictionary)base).getItem(COSName.TYPE);
COSBase apDict = ((COSDictionary)base).getItem(COSName.AP);
// Search for signature annotation
if (annotNotFound && COSName.ANNOT.equals(type))
{
COSDictionary cosBaseDict = (COSDictionary)base;
// Read and set the Rectangle for visual signature
COSArray rectAry = (COSArray)cosBaseDict.getItem(COSName.RECT);
PDRectangle rect = new PDRectangle(rectAry);
signatureField.getWidget().setRectangle(rect);
annotNotFound = false;
}
// Search for Signature-Field
if (sigFieldNotFound && COSName.SIG.equals(ft) && apDict != null)
{
COSDictionary cosBaseDict = (COSDictionary)base;
// Appearance Dictionary auslesen und setzen
PDAppearanceDictionary ap =
new PDAppearanceDictionary((COSDictionary)cosBaseDict.getItem(COSName.AP));
ap.getDictionary().setDirect(true);
signatureField.getWidget().setAppearance(ap);
// AcroForm DefaultRessource auslesen und setzen
COSBase dr = cosBaseDict.getItem(COSName.DR);
dr.setDirect(true);
dr.setNeedToBeUpdate(true);
acroFormDict.setItem(COSName.DR, dr);
sigFieldNotFound=false;
}
}
}
if (annotNotFound || sigFieldNotFound )
{
throw new SignatureException(SignatureException.VISUAL_SIGNATURE_INVALID,
"Could not read all needed objects from template");
}
}
// Get the annotations of the page and append the signature-annotation to it