protected internal virtual void Close(IDictionary<String, String> moreInfo)
{
if (closed)
return;
if (useVp) {
SetViewerPreferences();
}
if (flat)
FlatFields();
if (flatFreeText)
FlatFreeTextFields();
AddFieldResources();
PdfDictionary catalog = reader.Catalog;
PdfDictionary acroForm = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.ACROFORM), reader.Catalog);
if (acroFields != null && acroFields.Xfa.Changed) {
MarkUsed(acroForm);
if (!flat)
acroFields.Xfa.SetXfa(this);
}
if (sigFlags != 0) {
if (acroForm != null) {
acroForm.Put(PdfName.SIGFLAGS, new PdfNumber(sigFlags));
MarkUsed(acroForm);
MarkUsed(catalog);
}
}
closed = true;
AddSharedObjectsToBody();
SetOutlines();
SetJavaScript();
AddFileAttachments();
if (openAction != null) {
catalog.Put(PdfName.OPENACTION, openAction);
}
if (pdf.pageLabels != null)
catalog.Put(PdfName.PAGELABELS, pdf.pageLabels.GetDictionary(this));
// OCG
if (documentOCG.Count > 0) {
FillOCProperties(false);
PdfDictionary ocdict = catalog.GetAsDict(PdfName.OCPROPERTIES);
if (ocdict == null) {
reader.Catalog.Put(PdfName.OCPROPERTIES, OCProperties);
}
else {
ocdict.Put(PdfName.OCGS, OCProperties.Get(PdfName.OCGS));
PdfDictionary ddict = ocdict.GetAsDict(PdfName.D);
if (ddict == null) {
ddict = new PdfDictionary();
ocdict.Put(PdfName.D, ddict);
}
ddict.Put(PdfName.ORDER, OCProperties.GetAsDict(PdfName.D).Get(PdfName.ORDER));
ddict.Put(PdfName.RBGROUPS, OCProperties.GetAsDict(PdfName.D).Get(PdfName.RBGROUPS));
ddict.Put(PdfName.OFF, OCProperties.GetAsDict(PdfName.D).Get(PdfName.OFF));
ddict.Put(PdfName.AS, OCProperties.GetAsDict(PdfName.D).Get(PdfName.AS));
}
}
// metadata
int skipInfo = -1;
PdfObject oInfo = reader.Trailer.Get(PdfName.INFO);
PRIndirectReference iInfo = null;
PdfDictionary oldInfo = null;
if (oInfo is PRIndirectReference)
iInfo = (PRIndirectReference)oInfo;
if (iInfo != null)
oldInfo = (PdfDictionary)PdfReader.GetPdfObject(iInfo);
else if (oInfo is PdfDictionary)
oldInfo = (PdfDictionary)oInfo;
String producer = null;
if (iInfo != null)
skipInfo = iInfo.Number;
if (oldInfo != null && oldInfo.Get(PdfName.PRODUCER) != null)
producer = oldInfo.GetAsString(PdfName.PRODUCER).ToUnicodeString();
Version version = Version.GetInstance();
if (producer == null) {
producer = version.GetVersion;
}
else if (producer.IndexOf(version.Product) == -1) {
StringBuilder buf = new StringBuilder(producer);
buf.Append("; modified using ");
buf.Append(version.GetVersion);
producer = buf.ToString();
}
PdfIndirectReference info = null;
PdfDictionary newInfo = new PdfDictionary();
if (oldInfo != null) {
foreach (PdfName key in oldInfo.Keys) {
PdfObject value = PdfReader.GetPdfObject(oldInfo.Get(key));
newInfo.Put(key, value);
}
}
if (moreInfo != null) {
foreach (KeyValuePair<string,string> entry in moreInfo) {
PdfName keyName = new PdfName(entry.Key);
String value = entry.Value;
if (value == null)
newInfo.Remove(keyName);
else
newInfo.Put(keyName, new PdfString(value, PdfObject.TEXT_UNICODE));
}
}
PdfDate date = new PdfDate();
newInfo.Put(PdfName.MODDATE, date);
newInfo.Put(PdfName.PRODUCER, new PdfString(producer, PdfObject.TEXT_UNICODE));
if (append) {
if (iInfo == null)
info = AddToBody(newInfo, false).IndirectReference;
else
info = AddToBody(newInfo, iInfo.Number, false).IndirectReference;
}
else {
info = AddToBody(newInfo, false).IndirectReference;
}
// XMP
byte[] altMetadata = null;
PdfObject xmpo = PdfReader.GetPdfObject(catalog.Get(PdfName.METADATA));
if (xmpo != null && xmpo.IsStream()) {
altMetadata = PdfReader.GetStreamBytesRaw((PRStream)xmpo);
PdfReader.KillIndirect(catalog.Get(PdfName.METADATA));
}
if (xmpMetadata != null) {
altMetadata = xmpMetadata;
}
if (altMetadata != null) {
PdfStream xmp;
try {
XmpReader xmpr;
if (moreInfo == null || xmpMetadata != null) {
xmpr = new XmpReader(altMetadata);
if (!(xmpr.ReplaceNode("http://ns.adobe.com/pdf/1.3/", "Producer", producer)
|| xmpr.ReplaceDescriptionAttribute("http://ns.adobe.com/pdf/1.3/", "Producer", producer)))
xmpr.Add("rdf:Description", "http://ns.adobe.com/pdf/1.3/", "Producer", producer);
if (!(xmpr.ReplaceNode("http://ns.adobe.com/xap/1.0/", "ModifyDate", date.GetW3CDate())
|| xmpr.ReplaceDescriptionAttribute("http://ns.adobe.com/xap/1.0/", "ModifyDate", date.GetW3CDate())))
xmpr.Add("rdf:Description", "http://ns.adobe.com/xap/1.0/", "ModifyDate", date.GetW3CDate());
if (!(xmpr.ReplaceNode("http://ns.adobe.com/xap/1.0/", "MetadataDate", date.GetW3CDate())
|| xmpr.ReplaceDescriptionAttribute("http://ns.adobe.com/xap/1.0/", "MetadataDate", date.GetW3CDate()))) {
}
}
else {
MemoryStream baos = new MemoryStream();
try {
XmpWriter xmpw = new XmpWriter(baos, newInfo, PDFXConformance);
xmpw.Close();
}
catch (IOException) {
}
xmpr = new XmpReader(baos.ToArray());
}
xmp = new PdfStream(xmpr.SerializeDoc());
}
catch {
xmp = new PdfStream(altMetadata);
}
xmp.Put(PdfName.TYPE, PdfName.METADATA);
xmp.Put(PdfName.SUBTYPE, PdfName.XML);
if (crypto != null && !crypto.IsMetadataEncrypted()) {
PdfArray ar = new PdfArray();
ar.Add(PdfName.CRYPT);
xmp.Put(PdfName.FILTER, ar);
}
if (append && xmpo != null) {
body.Add(xmp, xmpo.IndRef);
}
else {
catalog.Put(PdfName.METADATA, body.Add(xmp).IndirectReference);
MarkUsed(catalog);
}
}
Close(info, skipInfo);
}