public void PreClose(Dictionary<PdfName, int> exclusionSizes)
{
if (preClosed)
throw new DocumentException(MessageLocalization.GetComposedMessage("document.already.pre.closed"));
stamper.MergeVerification();
preClosed = true;
AcroFields af = writer.AcroFields;
String name = FieldName;
bool fieldExists = !(IsInvisible() || IsNewField());
PdfIndirectReference refSig = writer.PdfIndirectReference;
writer.SigFlags = 3;
PdfDictionary fieldLock = null;
if (fieldExists) {
PdfDictionary widget = af.GetFieldItem(name).GetWidget(0);
writer.MarkUsed(widget);
fieldLock = widget.GetAsDict(PdfName.LOCK);
widget.Put(PdfName.P, writer.GetPageReference(Page));
widget.Put(PdfName.V, refSig);
PdfObject obj = PdfReader.GetPdfObjectRelease(widget.Get(PdfName.F));
int flags = 0;
if (obj != null && obj.IsNumber())
flags = ((PdfNumber)obj).IntValue;
flags |= PdfAnnotation.FLAGS_LOCKED;
widget.Put(PdfName.F, new PdfNumber(flags));
PdfDictionary ap = new PdfDictionary();
ap.Put(PdfName.N, GetAppearance().IndirectReference);
widget.Put(PdfName.AP, ap);
}
else {
PdfFormField sigField = PdfFormField.CreateSignature(writer);
sigField.FieldName = name;
sigField.Put(PdfName.V, refSig);
sigField.Flags = PdfAnnotation.FLAGS_PRINT | PdfAnnotation.FLAGS_LOCKED;
int pagen = Page;
if (!IsInvisible())
sigField.SetWidget(PageRect, null);
else
sigField.SetWidget(new Rectangle(0, 0), null);
sigField.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, GetAppearance());
sigField.Page = pagen;
writer.AddAnnotation(sigField, pagen);
}
exclusionLocations = new Dictionary<PdfName,PdfLiteral>();
if (cryptoDictionary == null) {
throw new DocumentException("No crypto dictionary defined.");
}
else {
PdfLiteral lit = new PdfLiteral(80);
exclusionLocations[PdfName.BYTERANGE] = lit;
cryptoDictionary.Put(PdfName.BYTERANGE, lit);
foreach (KeyValuePair<PdfName,int> entry in exclusionSizes) {
PdfName key = entry.Key;
int v = entry.Value;
lit = new PdfLiteral(v);
exclusionLocations[key] = lit;
cryptoDictionary.Put(key, lit);
}
if (certificationLevel > 0)
AddDocMDP(cryptoDictionary);
if (fieldLock != null)
AddFieldMDP(cryptoDictionary, fieldLock);
if (signatureEvent != null)
signatureEvent.GetSignatureDictionary(cryptoDictionary);
writer.AddToBody(cryptoDictionary, refSig, false);
}
if (certificationLevel > 0) {
// add DocMDP entry to root
PdfDictionary docmdp = new PdfDictionary();
docmdp.Put(new PdfName("DocMDP"), refSig);
writer.reader.Catalog.Put(new PdfName("Perms"), docmdp);
}
writer.Close(stamper.MoreInfo);
range = new long[exclusionLocations.Count * 2];
long byteRangePosition = exclusionLocations[PdfName.BYTERANGE].Position;
exclusionLocations.Remove(PdfName.BYTERANGE);
int idx = 1;
foreach (PdfLiteral lit in exclusionLocations.Values) {
long n = lit.Position;
range[idx++] = n;
range[idx++] = lit.PosLength + n;
}
Array.Sort(range, 1, range.Length - 2);
for (int k = 3; k < range.Length - 2; k += 2)
range[k] -= range[k - 1];
if (tempFile == null) {
bout = sigout.Buffer;
boutLen = sigout.Size;
range[range.Length - 1] = boutLen - range[range.Length - 2];
ByteBuffer bf = new ByteBuffer();
bf.Append('[');
for (int k = 0; k < range.Length; ++k)
bf.Append(range[k]).Append(' ');
bf.Append(']');
Array.Copy(bf.Buffer, 0, bout, byteRangePosition, bf.Size);
}
else {
try {
raf = new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite);
long len = raf.Length;
range[range.Length - 1] = len - range[range.Length - 2];
ByteBuffer bf = new ByteBuffer();
bf.Append('[');
for (int k = 0; k < range.Length; ++k)
bf.Append(range[k]).Append(' ');
bf.Append(']');
raf.Seek(byteRangePosition, SeekOrigin.Begin);
raf.Write(bf.Buffer, 0, bf.Size);
}
catch (IOException e) {
try{raf.Close();}catch{}
try{File.Delete(tempFile);}catch{}
throw e;
}
}
}