internal void Close(Hashtable moreInfo) { if (closed) return; if (useVp) { reader.SetViewerPreferences(viewerPreferences); MarkUsed(reader.Trailer.Get(PdfName.ROOT)); } if (flat) FlatFields(); if (flatFreeText) FlatFreeTextFields(); AddFieldResources(); PdfDictionary catalog = reader.Catalog; PdfDictionary pages = (PdfDictionary)PdfReader.GetPdfObject(catalog.Get(PdfName.PAGES)); pages.Put(PdfName.ITXT, new PdfString(Document.Release)); MarkUsed(pages); 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; PRIndirectReference iInfo = (PRIndirectReference)reader.Trailer.Get(PdfName.INFO); PdfDictionary oldInfo = (PdfDictionary)PdfReader.GetPdfObject(iInfo); String producer = null; if (iInfo != null) skipInfo = iInfo.Number; if (oldInfo != null && oldInfo.Get(PdfName.PRODUCER) != null) producer = oldInfo.GetAsString(PdfName.PRODUCER).ToString(); if (producer == null) { producer = Document.Version; } else if (producer.IndexOf(Document.Product) == -1) { StringBuilder buf = new StringBuilder(producer); buf.Append("; modified using "); buf.Append(Document.Version); producer = buf.ToString(); } // 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 there is XMP data to add: add it PdfDate date = new PdfDate(); if (altMetadata != null) { PdfStream xmp; try { XmpReader xmpr = new XmpReader(altMetadata); if (!xmpr.Replace("http://ns.adobe.com/pdf/1.3/", "Producer", producer)) xmpr.Add("rdf:Description", "http://ns.adobe.com/pdf/1.3/", "pdf:Producer", producer); if (!xmpr.Replace("http://ns.adobe.com/xap/1.0/", "ModifyDate", date.GetW3CDate())) xmpr.Add("rdf:Description", "http://ns.adobe.com/xap/1.0/", "xmp:ModifyDate", date.GetW3CDate()); xmpr.Replace("http://ns.adobe.com/xap/1.0/", "MetadataDate", date.GetW3CDate()); 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); } } try { file.ReOpen(); AlterContents(); int rootN = ((PRIndirectReference)reader.trailer.Get(PdfName.ROOT)).Number; if (append) { int[] keys = marked.GetKeys(); for (int k = 0; k < keys.Length; ++k) { int j = keys[k]; PdfObject obj = reader.GetPdfObjectRelease(j); if (obj != null && skipInfo != j && j < initialXrefSize) { AddToBody(obj, j, j != rootN); } } for (int k = initialXrefSize; k < reader.XrefSize; ++k) { PdfObject obj = reader.GetPdfObject(k); if (obj != null) { AddToBody(obj, GetNewObjectNumber(reader, k, 0)); } } } else { for (int k = 1; k < reader.XrefSize; ++k) { PdfObject obj = reader.GetPdfObjectRelease(k); if (obj != null && skipInfo != k) { AddToBody(obj, GetNewObjectNumber(reader, k, 0), k != rootN); } } } } finally { try { file.Close(); } catch { // empty on purpose } } PdfIndirectReference encryption = null; PdfObject fileID = null; if (crypto != null) { if (append) { encryption = reader.GetCryptoRef(); } else { PdfIndirectObject encryptionObject = AddToBody(crypto.GetEncryptionDictionary(), false); encryption = encryptionObject.IndirectReference; } fileID = crypto.FileID; } else fileID = PdfEncryption.CreateInfoId(PdfEncryption.CreateDocumentId()); PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.Get(PdfName.ROOT); PdfIndirectReference root = new PdfIndirectReference(0, GetNewObjectNumber(reader, iRoot.Number, 0)); 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 (DictionaryEntry entry in moreInfo) { PdfName keyName = new PdfName((String)entry.Key); String value = (String)entry.Value; if (value == null) newInfo.Remove(keyName); else newInfo.Put(keyName, new PdfString(value, PdfObject.TEXT_UNICODE)); } } newInfo.Put(PdfName.MODDATE, date); newInfo.Put(PdfName.PRODUCER, new PdfString(producer)); if (append) { if (iInfo == null) info = AddToBody(newInfo, false).IndirectReference; else info = AddToBody(newInfo, iInfo.Number, false).IndirectReference; } else { info = AddToBody(newInfo, false).IndirectReference; } // write the cross-reference table of the body body.WriteCrossReferenceTable(os, root, info, encryption, fileID, prevxref); if (fullCompression) { byte[] tmp = GetISOBytes("startxref\n"); os.Write(tmp, 0, tmp.Length); tmp = GetISOBytes(body.Offset.ToString()); os.Write(tmp, 0, tmp.Length); tmp = GetISOBytes("\n%%EOF\n"); os.Write(tmp, 0, tmp.Length); } else { PdfTrailer trailer = new PdfTrailer(body.Size, body.Offset, root, info, encryption, fileID, prevxref); trailer.ToPdf(this, os); } os.Flush(); if (CloseStream) os.Close(); reader.Close(); }
/** * Adds the date of creation to the document. */ internal void AddCreationDate() { PdfString date = new PdfDate(); Put(PdfName.CREATIONDATE, date); Put(PdfName.MODDATE, date); }