Пример #1
0
        /**
        * Signals that the <CODE>Document</CODE> was closed and that no other
        * <CODE>Elements</CODE> will be added.
        * <P>
        * The pages-tree is built and written to the outputstream.
        * A Catalog is constructed, as well as an Info-object,
        * the referencetable is composed and everything is written
        * to the outputstream embedded in a Trailer.
        */
        public override void Close() {
            if (open) {
                if ((currentPageNumber - 1) != pageReferences.Count)
                    throw new Exception("The page " + pageReferences.Count +
                    " was requested but the document has only " + (currentPageNumber - 1) + " pages.");
                pdf.Close();
                AddSharedObjectsToBody();
                foreach (IPdfOCG layer in documentOCG.Keys) {
                    AddToBody(layer.PdfObject, layer.Ref);
                }
                // add the root to the body
                PdfIndirectReference rootRef = root.WritePageTree();
                // make the catalog-object and add it to the body
                PdfDictionary catalog = GetCatalog(rootRef);
                // [C9] if there is XMP data to add: add it
                if (xmpMetadata != null) {
                    PdfStream xmp = new PdfStream(xmpMetadata);
                    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);
                    }
                    catalog.Put(PdfName.METADATA, body.Add(xmp).IndirectReference);
                }
                // [C10] make pdfx conformant
                if (IsPdfX()) {
                    CompleteInfoDictionary(Info);
                    CompleteExtraCatalog(ExtraCatalog);
                }
                // [C11] Output Intents
                if (extraCatalog != null) {
                    catalog.MergeDifferent(extraCatalog);
                }
                
                WriteOutlines(catalog, false);

                // add the Catalog to the body
                PdfIndirectObject indirectCatalog = AddToBody(catalog, false);
                // add the info-object to the body
                PdfIndirectObject infoObj = AddToBody(Info, false);

                // [F1] encryption
                PdfIndirectReference encryption = null;
                PdfObject fileID = null;
                body.FlushObjStm();
                if (crypto != null) {
                    PdfIndirectObject encryptionObject = AddToBody(crypto.GetEncryptionDictionary(), false);
                    encryption = encryptionObject.IndirectReference;
                    fileID = crypto.FileID;
                }
                else
                    fileID = PdfEncryption.CreateInfoId(PdfEncryption.CreateDocumentId());
                
                // write the cross-reference table of the body
                body.WriteCrossReferenceTable(os, indirectCatalog.IndirectReference,
                    infoObj.IndirectReference, encryption,  fileID, prevxref);

                // make the trailer
                // [F2] full compression
                if (fullCompression) {
                    WriteKeyInfo(os);
                    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,
                    indirectCatalog.IndirectReference,
                    infoObj.IndirectReference,
                    encryption,
                    fileID, prevxref);
                    trailer.ToPdf(this, os);
                }
                base.Close();
            }
        }
Пример #2
0
 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 acroForm = (PdfDictionary)PdfReader.GetPdfObject(reader.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);
         }
     }
     closed = true;
     AddSharedObjectsToBody();
     SetOutlines();
     SetJavaScript();
     AddFileAttachments();
     PdfDictionary catalog = reader.Catalog;
     if (openAction != null) {
         catalog.Put(PdfName.OPENACTION, openAction);
     }
     byte[] altMetadata = xmpMetadata;
     if (altMetadata == null) {
         PdfObject xmpo = PdfReader.GetPdfObject(catalog.Get(PdfName.METADATA));
         if (xmpo != null && xmpo.IsStream()) {
             altMetadata = PdfReader.GetStreamBytesRaw((PRStream)xmpo);
             PdfReader.KillIndirect(xmpo);
         }
     }
     // if there is XMP data to add: add it
     if (altMetadata != null) {
         PdfStream 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);
         }
         catalog.Put(PdfName.METADATA, body.Add(xmp).IndirectReference);
         MarkUsed(catalog);
     }
     PRIndirectReference iInfo = null;
     try {
         file.ReOpen();
         AlterContents();
         iInfo = (PRIndirectReference)reader.trailer.Get(PdfName.INFO);
         int skip = -1;
         if (iInfo != null)
             skip = iInfo.Number;
         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 && skip != 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 && skip != 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;
     }
     PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.Get(PdfName.ROOT);
     PdfIndirectReference root = new PdfIndirectReference(0, GetNewObjectNumber(reader, iRoot.Number, 0));
     PdfIndirectReference info = null;
     PdfDictionary oldInfo = (PdfDictionary)PdfReader.GetPdfObject(iInfo);
     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));
         }
     }
     if (append) {
         if (iInfo == null)
             info = AddToBody(newInfo, false).IndirectReference;
         else
             info = AddToBody(newInfo, iInfo.Number, false).IndirectReference;
     }
     else {
         if (newInfo.Size != 0)
             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();
 }
Пример #3
0
 protected virtual void Close(PdfIndirectReference info, int skipInfo) {
     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, obj.IndRef, 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);
             }
         }
     }
     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.GetFileID(true);
     }
     else {
         PdfArray IDs = reader.trailer.GetAsArray(PdfName.ID);
         if(IDs != null && IDs.GetAsString(0) != null) {
             fileID = PdfEncryption.CreateInfoId(IDs.GetAsString(0).GetBytes(), true);
         }
         else {
             fileID = PdfEncryption.CreateInfoId(PdfEncryption.CreateDocumentId(), true);
         }
     }
     PRIndirectReference iRoot = (PRIndirectReference)reader.trailer.Get(PdfName.ROOT);
     PdfIndirectReference root = new PdfIndirectReference(0, GetNewObjectNumber(reader, iRoot.Number, 0));
     // write the cross-reference table of the body
     body.WriteCrossReferenceTable(os, root, info, encryption, fileID, prevxref);
     if (fullCompression) {
         WriteKeyInfo(os);
         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();
     GetCounter().Written(os.Counter);
 }
Пример #4
0
 internal void Close(IDictionary<String, String> 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;
     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();
     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();
     }
     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) {
                 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);
         }
     }
     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));
     // 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();
 }