/// <summary> /// Dispatches PrepareForSave to the objects that need it. /// </summary> internal override void PrepareForSave() { PDFDocumentInformation info = Info; // Add patch level to producer if it is not '0'. string pdfSharpProducer = VersionMetadata.Header; if (!VersionMetadata.VersionPatch.Equals("0")) { pdfSharpProducer = VersionMetadata.Header; } // Set Creator if value is undefined. if (info.Elements[PDFDocumentInformation.Keys.Creator] == null) { info.Creator = pdfSharpProducer; } // Keep original producer if file was imported. string producer = info.Producer; if (producer.Length == 0) { producer = pdfSharpProducer; } else { // Prevent endless concatenation if file is edited with PDFSharp more than once. if (!producer.StartsWith(VersionMetadata.Title)) { producer = pdfSharpProducer + " (Original: " + producer + ")"; } } info.Elements.SetString(PDFDocumentInformation.Keys.Producer, producer); // Prepare used fonts. if (_fontTable != null) { _fontTable.PrepareForSave(); } // Let catalog do the rest. Catalog.PrepareForSave(); // Remove all unreachable objects (e.g. from deleted pages) int removed = IrefTable.Compact(); if (removed != 0) { Debug.WriteLine("PrepareForSave: Number of deleted unreachable objects: " + removed); } IrefTable.Renumber(); }
/// <summary> /// Implements saving a PDF file. /// </summary> void DoSave(PDFWriter writer) { if (_pages == null || _pages.Count == 0) { if (OutStream != null) { // Give feedback if the wrong constructor was used. throw new InvalidOperationException("Cannot save a PDF document with no pages. Do not use \"public PDFDocument(string filename)\" or \"public PDFDocument(Stream outputStream)\" if you want to open an existing PDF document from a file or stream; use PDFReader.Open() for that purpose."); } throw new InvalidOperationException("Cannot save a PDF document with no pages."); } try { // HACK: Remove XRefTrailer if (Trailer is PDFCrossReferenceStream) { // HACK^2: Preserve the SecurityHandler. PDFStandardSecurityHandler securityHandler = _securitySettings.SecurityHandler; Trailer = new PDFTrailer((PDFCrossReferenceStream)Trailer) { _securityHandler = securityHandler }; } bool encrypt = _securitySettings.DocumentSecurityLevel != PDFDocumentSecurityLevel.None; if (encrypt) { PDFStandardSecurityHandler securityHandler = _securitySettings.SecurityHandler; if (securityHandler.Reference == null) { IrefTable.Add(securityHandler); } else { Debug.Assert(IrefTable.Contains(securityHandler.ObjectID)); } Trailer.Elements[PDFTrailer.Keys.Encrypt] = _securitySettings.SecurityHandler.Reference; } else { Trailer.Elements.Remove(PDFTrailer.Keys.Encrypt); } PrepareForSave(); if (encrypt) { _securitySettings.SecurityHandler.PrepareEncryption(); } writer.WriteFileHeader(this); PDFReference[] irefs = IrefTable.AllReferences; int count = irefs.Length; for (int idx = 0; idx < count; idx++) { PDFReference iref = irefs[idx]; iref.Position = writer.Position; iref.Value.WriteObject(writer); } int startxref = writer.Position; IrefTable.WriteObject(writer); writer.WriteRaw("trailer\n"); Trailer.Elements.SetInteger("/Size", count + 1); Trailer.WriteObject(writer); writer.WriteEof(this, startxref); } finally { if (writer != null) { writer.Stream.Flush(); } } }