@@ -20,6 +20,8 @@ public sealed class PdfWriter : IDisposable
20
20
private readonly PageTree _pageTree ;
21
21
private readonly Catalog _catalog ;
22
22
23
+ private bool _endingWritten = false ;
24
+
23
25
/// <summary>
24
26
/// Constructor for <see cref="PdfWriter"/>
25
27
/// </summary>
@@ -68,6 +70,8 @@ public int PageCount
68
70
/// <returns>Returns this <see cref="PdfWriter"/> to chain calls</returns>
69
71
public PdfWriter SetDocumentInfo ( Action < DocumentInformation > infoAction )
70
72
{
73
+ _throwWhenEndingWritten ( ) '; '
74
+
71
75
infoAction ( DocumentInformation ) ;
72
76
73
77
return this ;
@@ -89,6 +93,8 @@ public PdfWriter AddPage(Action<PdfPage> pageAction)
89
93
/// <returns>Returns this <see cref="PdfWriter"/> to chain calls</returns>
90
94
public PdfWriter AddPage < T > ( T data , Action < T , PdfPage > pageAction )
91
95
{
96
+ _throwWhenEndingWritten ( ) ;
97
+
92
98
using ( var page = new PdfPage ( _tableBuilder , _pageTree ) )
93
99
{
94
100
pageAction ( data , page ) ;
@@ -115,6 +121,8 @@ public async Task<PdfWriter> AddPageAsync(Func<PdfPage, Task> pageAction)
115
121
/// <returns>Returns an awaitable task that resolves into this <see cref="PdfWriter"/> to chain calls</returns>
116
122
public async Task < PdfWriter > AddPageAsync < T > ( T data , Func < T , PdfPage , Task > pageAction )
117
123
{
124
+ _throwWhenEndingWritten ( ) ;
125
+
118
126
using ( var page = new PdfPage ( _tableBuilder , _pageTree ) )
119
127
{
120
128
await pageAction ( data , page ) ;
@@ -132,6 +140,8 @@ public async Task<PdfWriter> AddPageAsync<T>(T data, Func<T, PdfPage, Task> page
132
140
/// <returns>The image reference that can be used in pages</returns>
133
141
public Image AddImage ( SixLabors . ImageSharp . Image image )
134
142
{
143
+ _throwWhenEndingWritten ( ) ;
144
+
135
145
var id = _tableBuilder . ReserveId ( ) ;
136
146
137
147
var pdfImage = new Image ( id , image ) ;
@@ -156,6 +166,8 @@ public Image AddImage(SixLabors.ImageSharp.Image image)
156
166
/// <returns>The image reference that can be used in pages</returns>
157
167
public Image AddJpgImageUnsafe ( Stream jpgStream , int originalWidth , int originalHeight )
158
168
{
169
+ _throwWhenEndingWritten ( ) ;
170
+
159
171
var id = _tableBuilder . ReserveId ( ) ;
160
172
161
173
var pdfImage = new Image ( id , jpgStream , originalWidth , originalHeight ) ;
@@ -168,9 +180,17 @@ public Image AddJpgImageUnsafe(Stream jpgStream, int originalWidth, int original
168
180
return pdfImage ;
169
181
}
170
182
171
- /// <inheritdoc />
172
- public void Dispose ( )
183
+ /// <summary>
184
+ /// Write the PDF trailer; indicates that the PDF is done.
185
+ /// </summary>
186
+ /// <remarks>
187
+ /// Other calls to this <see cref="PdfWriter"/> will throw or have no effect after call this.
188
+ /// </remarks>
189
+ public void WriteTrailer ( )
173
190
{
191
+ if ( _endingWritten )
192
+ return ;
193
+
174
194
_writePageTree ( ) ;
175
195
176
196
_writeCatalog ( ) ;
@@ -181,12 +201,27 @@ public void Dispose()
181
201
182
202
_stream . Flush ( ) ;
183
203
204
+ _endingWritten = true ;
205
+ }
206
+
207
+ /// <inheritdoc />
208
+ public void Dispose ( )
209
+ {
210
+ WriteTrailer ( ) ;
211
+
212
+ _stream . Flush ( ) ;
213
+
184
214
if ( _ownsStream )
185
215
{
186
216
_stream . Dispose ( ) ;
187
217
}
188
218
}
189
219
220
+ private void _throwWhenEndingWritten ( )
221
+ {
222
+ if ( _endingWritten ) throw new InvalidOperationException ( "Can't change document information when PDF trailer is written to the stream." ) ;
223
+ }
224
+
190
225
private static void _writeHeader ( PdfStream stream )
191
226
{
192
227
stream . WriteByte ( 0x25 ) ; // %
0 commit comments