/// <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(); } } }