Showing
3 changed files
with
475 additions
and
158 deletions
@@ -107,6 +107,10 @@ class PdfGraphics { | @@ -107,6 +107,10 @@ class PdfGraphics { | ||
107 | /// Ellipse 4-spline magic number | 107 | /// Ellipse 4-spline magic number |
108 | static const double _m4 = 0.551784; | 108 | static const double _m4 = 0.551784; |
109 | 109 | ||
110 | + static const int _commentIndent = 35; | ||
111 | + static const int _indentAmount = 2; | ||
112 | + int _indent = _indentAmount; | ||
113 | + | ||
110 | /// Graphic context | 114 | /// Graphic context |
111 | late _PdfGraphicsContext _context; | 115 | late _PdfGraphicsContext _context; |
112 | final Queue<_PdfGraphicsContext> _contextQueue = Queue<_PdfGraphicsContext>(); | 116 | final Queue<_PdfGraphicsContext> _contextQueue = Queue<_PdfGraphicsContext>(); |
@@ -122,78 +126,136 @@ class PdfGraphics { | @@ -122,78 +126,136 @@ class PdfGraphics { | ||
122 | /// Draw a surface on the previously defined shape | 126 | /// Draw a surface on the previously defined shape |
123 | /// set evenOdd to false to use the nonzero winding number rule to determine the region to fill and to true to use the even-odd rule to determine the region to fill | 127 | /// set evenOdd to false to use the nonzero winding number rule to determine the region to fill and to true to use the even-odd rule to determine the region to fill |
124 | void fillPath({bool evenOdd = false}) { | 128 | void fillPath({bool evenOdd = false}) { |
129 | + var o = 0; | ||
125 | assert(() { | 130 | assert(() { |
126 | if (_page.pdfDocument.verbose) { | 131 | if (_page.pdfDocument.verbose) { |
127 | - _buf.putComment('fillPath evenOdd:$evenOdd'); | 132 | + o = _buf.offset; |
133 | + _buf.putString(' ' * (_indent)); | ||
128 | } | 134 | } |
129 | return true; | 135 | return true; |
130 | }()); | 136 | }()); |
131 | 137 | ||
132 | - _buf.putString('f${evenOdd ? '*' : ''}\n'); | 138 | + _buf.putString('f${evenOdd ? '*' : ''} '); |
139 | + | ||
140 | + assert(() { | ||
141 | + if (_page.pdfDocument.verbose) { | ||
142 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
143 | + _buf.putComment('fillPath(evenOdd: $evenOdd)'); | ||
144 | + } | ||
145 | + return true; | ||
146 | + }()); | ||
133 | } | 147 | } |
134 | 148 | ||
135 | /// Draw the contour of the previously defined shape | 149 | /// Draw the contour of the previously defined shape |
136 | void strokePath({bool close = false}) { | 150 | void strokePath({bool close = false}) { |
151 | + var o = 0; | ||
137 | assert(() { | 152 | assert(() { |
138 | if (_page.pdfDocument.verbose) { | 153 | if (_page.pdfDocument.verbose) { |
139 | - _buf.putComment('strokePath close:$close'); | 154 | + o = _buf.offset; |
155 | + _buf.putString(' ' * (_indent)); | ||
140 | } | 156 | } |
141 | return true; | 157 | return true; |
142 | }()); | 158 | }()); |
143 | 159 | ||
144 | - _buf.putString('${close ? 's' : 'S'}\n'); | 160 | + _buf.putString('${close ? 's' : 'S'} '); |
161 | + | ||
162 | + assert(() { | ||
163 | + if (_page.pdfDocument.verbose) { | ||
164 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
165 | + _buf.putComment('strokePath(close: $close)'); | ||
166 | + } | ||
167 | + return true; | ||
168 | + }()); | ||
145 | } | 169 | } |
146 | 170 | ||
147 | /// Close the path with a line | 171 | /// Close the path with a line |
148 | void closePath() { | 172 | void closePath() { |
149 | assert(() { | 173 | assert(() { |
150 | if (_page.pdfDocument.verbose) { | 174 | if (_page.pdfDocument.verbose) { |
151 | - _buf.putComment('closePath'); | 175 | + _buf.putString(' ' * (_indent)); |
152 | } | 176 | } |
153 | return true; | 177 | return true; |
154 | }()); | 178 | }()); |
155 | 179 | ||
156 | - _buf.putString('h\n'); | 180 | + _buf.putString('h '); |
181 | + | ||
182 | + assert(() { | ||
183 | + if (_page.pdfDocument.verbose) { | ||
184 | + _buf.putString(' ' * (_commentIndent - 2 - _indent)); | ||
185 | + _buf.putComment('closePath()'); | ||
186 | + } | ||
187 | + return true; | ||
188 | + }()); | ||
157 | } | 189 | } |
158 | 190 | ||
159 | /// Create a clipping surface from the previously defined shape, | 191 | /// Create a clipping surface from the previously defined shape, |
160 | /// to prevent any further drawing outside | 192 | /// to prevent any further drawing outside |
161 | void clipPath({bool evenOdd = false, bool end = true}) { | 193 | void clipPath({bool evenOdd = false, bool end = true}) { |
194 | + var o = 0; | ||
162 | assert(() { | 195 | assert(() { |
163 | if (_page.pdfDocument.verbose) { | 196 | if (_page.pdfDocument.verbose) { |
164 | - _buf.putComment('clipPath evenOdd:$evenOdd end:$end'); | 197 | + o = _buf.offset; |
198 | + _buf.putString(' ' * (_indent)); | ||
165 | } | 199 | } |
166 | return true; | 200 | return true; |
167 | }()); | 201 | }()); |
168 | 202 | ||
169 | - _buf.putString('W${evenOdd ? '*' : ''}${end ? ' n' : ''}\n'); | 203 | + _buf.putString('W${evenOdd ? '*' : ''}${end ? ' n' : ''} '); |
204 | + | ||
205 | + assert(() { | ||
206 | + if (_page.pdfDocument.verbose) { | ||
207 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
208 | + _buf.putComment('clipPath(evenOdd: $evenOdd, end: $end)'); | ||
209 | + } | ||
210 | + return true; | ||
211 | + }()); | ||
170 | } | 212 | } |
171 | 213 | ||
172 | /// Draw a surface on the previously defined shape and then draw the contour | 214 | /// Draw a surface on the previously defined shape and then draw the contour |
173 | /// set evenOdd to false to use the nonzero winding number rule to determine the region to fill and to true to use the even-odd rule to determine the region to fill | 215 | /// set evenOdd to false to use the nonzero winding number rule to determine the region to fill and to true to use the even-odd rule to determine the region to fill |
174 | void fillAndStrokePath({bool evenOdd = false, bool close = false}) { | 216 | void fillAndStrokePath({bool evenOdd = false, bool close = false}) { |
217 | + var o = 0; | ||
175 | assert(() { | 218 | assert(() { |
176 | if (_page.pdfDocument.verbose) { | 219 | if (_page.pdfDocument.verbose) { |
177 | - _buf.putComment('fillAndStrokePath evenOdd:$evenOdd close:$close'); | 220 | + o = _buf.offset; |
221 | + _buf.putString(' ' * (_indent)); | ||
178 | } | 222 | } |
179 | return true; | 223 | return true; |
180 | }()); | 224 | }()); |
181 | 225 | ||
182 | - _buf.putString('${close ? 'b' : 'B'}${evenOdd ? '*' : ''}\n'); | 226 | + _buf.putString('${close ? 'b' : 'B'}${evenOdd ? '*' : ''} '); |
227 | + | ||
228 | + assert(() { | ||
229 | + if (_page.pdfDocument.verbose) { | ||
230 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
231 | + _buf.putComment('fillAndStrokePath(evenOdd:$evenOdd, close:$close)'); | ||
232 | + } | ||
233 | + return true; | ||
234 | + }()); | ||
183 | } | 235 | } |
184 | 236 | ||
185 | /// Apply a shader | 237 | /// Apply a shader |
186 | void applyShader(PdfShading shader) { | 238 | void applyShader(PdfShading shader) { |
239 | + var o = 0; | ||
187 | assert(() { | 240 | assert(() { |
188 | if (_page.pdfDocument.verbose) { | 241 | if (_page.pdfDocument.verbose) { |
189 | - _buf.putComment('applyShader'); | 242 | + o = _buf.offset; |
243 | + _buf.putString(' ' * (_indent)); | ||
190 | } | 244 | } |
191 | return true; | 245 | return true; |
192 | }()); | 246 | }()); |
193 | 247 | ||
194 | // The shader needs to be registered in the page resources | 248 | // The shader needs to be registered in the page resources |
195 | _page.addShader(shader); | 249 | _page.addShader(shader); |
196 | - _buf.putString('${shader.name} sh\n'); | 250 | + _buf.putString('${shader.name} sh '); |
251 | + | ||
252 | + assert(() { | ||
253 | + if (_page.pdfDocument.verbose) { | ||
254 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
255 | + _buf.putComment('applyShader(${shader.ref()})'); | ||
256 | + } | ||
257 | + return true; | ||
258 | + }()); | ||
197 | } | 259 | } |
198 | 260 | ||
199 | /// This releases any resources used by this Graphics object. You must use | 261 | /// This releases any resources used by this Graphics object. You must use |
@@ -202,17 +264,26 @@ class PdfGraphics { | @@ -202,17 +264,26 @@ class PdfGraphics { | ||
202 | /// When using [PdfPage], you can create another fresh Graphics instance, | 264 | /// When using [PdfPage], you can create another fresh Graphics instance, |
203 | /// which will draw over this one. | 265 | /// which will draw over this one. |
204 | void restoreContext() { | 266 | void restoreContext() { |
267 | + if (_contextQueue.isNotEmpty) { | ||
205 | assert(() { | 268 | assert(() { |
269 | + _indent -= _indentAmount; | ||
206 | if (_page.pdfDocument.verbose) { | 270 | if (_page.pdfDocument.verbose) { |
207 | - _buf.putComment('restoreContext'); | 271 | + _buf.putString(' ' * (_indent)); |
208 | } | 272 | } |
209 | return true; | 273 | return true; |
210 | }()); | 274 | }()); |
211 | 275 | ||
212 | - if (_contextQueue.isNotEmpty) { | ||
213 | // restore graphics context | 276 | // restore graphics context |
214 | - _buf.putString('Q\n'); | 277 | + _buf.putString('Q '); |
215 | _context = _contextQueue.removeLast(); | 278 | _context = _contextQueue.removeLast(); |
279 | + | ||
280 | + assert(() { | ||
281 | + if (_page.pdfDocument.verbose) { | ||
282 | + _buf.putString(' ' * (_commentIndent - 2 - _indent)); | ||
283 | + _buf.putComment('restoreContext()'); | ||
284 | + } | ||
285 | + return true; | ||
286 | + }()); | ||
216 | } | 287 | } |
217 | } | 288 | } |
218 | 289 | ||
@@ -220,20 +291,29 @@ class PdfGraphics { | @@ -220,20 +291,29 @@ class PdfGraphics { | ||
220 | void saveContext() { | 291 | void saveContext() { |
221 | assert(() { | 292 | assert(() { |
222 | if (_page.pdfDocument.verbose) { | 293 | if (_page.pdfDocument.verbose) { |
223 | - _buf.putComment('saveContext'); | 294 | + _buf.putString(' ' * (_indent)); |
224 | } | 295 | } |
225 | return true; | 296 | return true; |
226 | }()); | 297 | }()); |
227 | - | ||
228 | - _buf.putString('q\n'); | 298 | + _buf.putString('q '); |
229 | _contextQueue.addLast(_context.copy()); | 299 | _contextQueue.addLast(_context.copy()); |
300 | + assert(() { | ||
301 | + if (_page.pdfDocument.verbose) { | ||
302 | + _buf.putString(' ' * (_commentIndent - 2 - _indent)); | ||
303 | + _buf.putComment('saveContext()'); | ||
304 | + } | ||
305 | + _indent += _indentAmount; | ||
306 | + return true; | ||
307 | + }()); | ||
230 | } | 308 | } |
231 | 309 | ||
232 | /// Draws an image onto the page. | 310 | /// Draws an image onto the page. |
233 | void drawImage(PdfImage img, double x, double y, [double? w, double? h]) { | 311 | void drawImage(PdfImage img, double x, double y, [double? w, double? h]) { |
312 | + var o = 0; | ||
234 | assert(() { | 313 | assert(() { |
235 | if (_page.pdfDocument.verbose) { | 314 | if (_page.pdfDocument.verbose) { |
236 | - _buf.putComment('drawImage x:$x y:$y'); | 315 | + o = _buf.offset; |
316 | + _buf.putString(' ' * (_indent)); | ||
237 | } | 317 | } |
238 | return true; | 318 | return true; |
239 | }()); | 319 | }()); |
@@ -273,18 +353,20 @@ class PdfGraphics { | @@ -273,18 +353,20 @@ class PdfGraphics { | ||
273 | break; | 353 | break; |
274 | } | 354 | } |
275 | 355 | ||
276 | - _buf.putString(' cm ${img.name} Do Q\n'); | 356 | + _buf.putString(' cm ${img.name} Do Q '); |
277 | } | 357 | } |
278 | 358 | ||
279 | - /// Draws a line between two coordinates. | ||
280 | - void drawLine(double x1, double y1, double x2, double y2) { | ||
281 | assert(() { | 359 | assert(() { |
282 | if (_page.pdfDocument.verbose) { | 360 | if (_page.pdfDocument.verbose) { |
283 | - _buf.putComment('drawLine x1:$x1 y1:$y1 x2:$x2 y2:$y2'); | 361 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); |
362 | + _buf.putComment('drawImage(${img.ref()}, x: $x, y: $y, w: $w, h: $h)'); | ||
284 | } | 363 | } |
285 | return true; | 364 | return true; |
286 | }()); | 365 | }()); |
366 | + } | ||
287 | 367 | ||
368 | + /// Draws a line between two coordinates. | ||
369 | + void drawLine(double x1, double y1, double x2, double y2) { | ||
288 | moveTo(x1, y1); | 370 | moveTo(x1, y1); |
289 | lineTo(x2, y2); | 371 | lineTo(x2, y2); |
290 | } | 372 | } |
@@ -294,13 +376,6 @@ class PdfGraphics { | @@ -294,13 +376,6 @@ class PdfGraphics { | ||
294 | /// Use clockwise=false to draw the inside of a donut | 376 | /// Use clockwise=false to draw the inside of a donut |
295 | void drawEllipse(double x, double y, double r1, double r2, | 377 | void drawEllipse(double x, double y, double r1, double r2, |
296 | {bool clockwise = true}) { | 378 | {bool clockwise = true}) { |
297 | - assert(() { | ||
298 | - if (_page.pdfDocument.verbose) { | ||
299 | - _buf.putComment('drawEllipse x:$x y:$y r1:$r1 r2:$r2'); | ||
300 | - } | ||
301 | - return true; | ||
302 | - }()); | ||
303 | - | ||
304 | moveTo(x, y - r2); | 379 | moveTo(x, y - r2); |
305 | if (clockwise) { | 380 | if (clockwise) { |
306 | curveTo(x + _m4 * r1, y - r2, x + r1, y - _m4 * r2, x + r1, y); | 381 | curveTo(x + _m4 * r1, y - r2, x + r1, y - _m4 * r2, x + r1, y); |
@@ -316,21 +391,26 @@ class PdfGraphics { | @@ -316,21 +391,26 @@ class PdfGraphics { | ||
316 | } | 391 | } |
317 | 392 | ||
318 | /// Draws a Rectangle | 393 | /// Draws a Rectangle |
319 | - void drawRect( | ||
320 | - double x, | ||
321 | - double y, | ||
322 | - double w, | ||
323 | - double h, | ||
324 | - ) { | 394 | + void drawRect(double x, double y, double w, double h) { |
395 | + var o = 0; | ||
325 | assert(() { | 396 | assert(() { |
326 | if (_page.pdfDocument.verbose) { | 397 | if (_page.pdfDocument.verbose) { |
327 | - _buf.putComment('drawRect x:$x y:$y w:$w h:$h'); | 398 | + o = _buf.offset; |
399 | + _buf.putString(' ' * (_indent)); | ||
328 | } | 400 | } |
329 | return true; | 401 | return true; |
330 | }()); | 402 | }()); |
331 | 403 | ||
332 | PdfNumList([x, y, w, h]).output(_buf); | 404 | PdfNumList([x, y, w, h]).output(_buf); |
333 | - _buf.putString(' re\n'); | 405 | + _buf.putString(' re '); |
406 | + | ||
407 | + assert(() { | ||
408 | + if (_page.pdfDocument.verbose) { | ||
409 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
410 | + _buf.putComment('drawRect(x: $x, y: $y, w: $w, h: $h)'); | ||
411 | + } | ||
412 | + return true; | ||
413 | + }()); | ||
334 | } | 414 | } |
335 | 415 | ||
336 | /// Draws a Rectangle | 416 | /// Draws a Rectangle |
@@ -340,13 +420,6 @@ class PdfGraphics { | @@ -340,13 +420,6 @@ class PdfGraphics { | ||
340 | 420 | ||
341 | /// Draws a Rounded Rectangle | 421 | /// Draws a Rounded Rectangle |
342 | void drawRRect(double x, double y, double w, double h, double rv, double rh) { | 422 | void drawRRect(double x, double y, double w, double h, double rv, double rh) { |
343 | - assert(() { | ||
344 | - if (_page.pdfDocument.verbose) { | ||
345 | - _buf.putComment('drawRRect x:$x y:$y w:$w h:$h rv:$rv rh:$rh'); | ||
346 | - } | ||
347 | - return true; | ||
348 | - }()); | ||
349 | - | ||
350 | moveTo(x, y + rv); | 423 | moveTo(x, y + rv); |
351 | curveTo(x, y - _m4 * rv + rv, x - _m4 * rh + rh, y, x + rh, y); | 424 | curveTo(x, y - _m4 * rv + rv, x - _m4 * rh + rh, y, x + rh, y); |
352 | lineTo(x + w - rh, y); | 425 | lineTo(x + w - rh, y); |
@@ -366,38 +439,51 @@ class PdfGraphics { | @@ -366,38 +439,51 @@ class PdfGraphics { | ||
366 | double? charSpace, | 439 | double? charSpace, |
367 | double? wordSpace, | 440 | double? wordSpace, |
368 | double? scale, | 441 | double? scale, |
369 | - PdfTextRenderingMode? mode = PdfTextRenderingMode.fill, | 442 | + PdfTextRenderingMode mode = PdfTextRenderingMode.fill, |
370 | double? rise, | 443 | double? rise, |
371 | }) { | 444 | }) { |
445 | + var o = 0; | ||
372 | assert(() { | 446 | assert(() { |
373 | if (_page.pdfDocument.verbose) { | 447 | if (_page.pdfDocument.verbose) { |
374 | - _buf.putComment('setFont'); | 448 | + o = _buf.offset; |
449 | + _buf.putString(' ' * (_indent)); | ||
375 | } | 450 | } |
376 | return true; | 451 | return true; |
377 | }()); | 452 | }()); |
378 | 453 | ||
454 | + _page.addFont(font); | ||
455 | + | ||
379 | _buf.putString('${font.name} '); | 456 | _buf.putString('${font.name} '); |
380 | PdfNum(size).output(_buf); | 457 | PdfNum(size).output(_buf); |
381 | - _buf.putString(' Tf\n'); | 458 | + _buf.putString(' Tf '); |
382 | if (charSpace != null) { | 459 | if (charSpace != null) { |
383 | PdfNum(charSpace).output(_buf); | 460 | PdfNum(charSpace).output(_buf); |
384 | - _buf.putString(' Tc\n'); | 461 | + _buf.putString(' Tc '); |
385 | } | 462 | } |
386 | if (wordSpace != null) { | 463 | if (wordSpace != null) { |
387 | PdfNum(wordSpace).output(_buf); | 464 | PdfNum(wordSpace).output(_buf); |
388 | - _buf.putString(' Tw\n'); | 465 | + _buf.putString(' Tw '); |
389 | } | 466 | } |
390 | if (scale != null) { | 467 | if (scale != null) { |
391 | PdfNum(scale * 100).output(_buf); | 468 | PdfNum(scale * 100).output(_buf); |
392 | - _buf.putString(' Tz\n'); | 469 | + _buf.putString(' Tz '); |
393 | } | 470 | } |
394 | if (rise != null) { | 471 | if (rise != null) { |
395 | PdfNum(rise).output(_buf); | 472 | PdfNum(rise).output(_buf); |
396 | - _buf.putString(' Ts\n'); | 473 | + _buf.putString(' Ts '); |
397 | } | 474 | } |
398 | if (mode != PdfTextRenderingMode.fill) { | 475 | if (mode != PdfTextRenderingMode.fill) { |
399 | - _buf.putString('${mode!.index} Tr\n'); | 476 | + _buf.putString('${mode.index} Tr '); |
477 | + } | ||
478 | + | ||
479 | + assert(() { | ||
480 | + if (_page.pdfDocument.verbose) { | ||
481 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
482 | + _buf.putComment( | ||
483 | + 'setFont(${font.ref()}, size: $size, charSpace: $charSpace, wordSpace: $wordSpace, scale: $scale, mode: ${mode.name}, rise: $rise)'); | ||
400 | } | 484 | } |
485 | + return true; | ||
486 | + }()); | ||
401 | } | 487 | } |
402 | 488 | ||
403 | /// This draws a string. | 489 | /// This draws a string. |
@@ -407,44 +493,103 @@ class PdfGraphics { | @@ -407,44 +493,103 @@ class PdfGraphics { | ||
407 | String s, | 493 | String s, |
408 | double x, | 494 | double x, |
409 | double y, { | 495 | double y, { |
410 | - double charSpace = 0, | ||
411 | - double wordSpace = 0, | ||
412 | - double scale = 1, | 496 | + double? charSpace, |
497 | + double? wordSpace, | ||
498 | + double? scale, | ||
413 | PdfTextRenderingMode mode = PdfTextRenderingMode.fill, | 499 | PdfTextRenderingMode mode = PdfTextRenderingMode.fill, |
414 | - double rise = 0, | 500 | + double? rise, |
415 | }) { | 501 | }) { |
416 | assert(() { | 502 | assert(() { |
417 | if (_page.pdfDocument.verbose) { | 503 | if (_page.pdfDocument.verbose) { |
418 | - _buf.putComment('drawString x:$x y:$y size:$size "$s"'); | 504 | + _buf.putString(' ' * (_indent)); |
419 | } | 505 | } |
420 | return true; | 506 | return true; |
421 | }()); | 507 | }()); |
422 | 508 | ||
423 | - _page.addFont(font); | ||
424 | - | ||
425 | _buf.putString('BT '); | 509 | _buf.putString('BT '); |
426 | - PdfNumList([x, y]).output(_buf); | ||
427 | - _buf.putString(' Td '); | 510 | + |
511 | + assert(() { | ||
512 | + if (_page.pdfDocument.verbose) { | ||
513 | + _buf.putString(' ' * (_commentIndent - 3 - _indent)); | ||
514 | + _buf.putComment('beginText()'); | ||
515 | + _indent += _indentAmount; | ||
516 | + } | ||
517 | + return true; | ||
518 | + }()); | ||
519 | + | ||
428 | setFont(font, size, | 520 | setFont(font, size, |
429 | charSpace: charSpace, | 521 | charSpace: charSpace, |
430 | mode: mode, | 522 | mode: mode, |
431 | rise: rise, | 523 | rise: rise, |
432 | scale: scale, | 524 | scale: scale, |
433 | wordSpace: wordSpace); | 525 | wordSpace: wordSpace); |
526 | + | ||
527 | + var o = 0; | ||
528 | + assert(() { | ||
529 | + if (_page.pdfDocument.verbose) { | ||
530 | + o = _buf.offset; | ||
531 | + _buf.putString(' ' * (_indent)); | ||
532 | + } | ||
533 | + return true; | ||
534 | + }()); | ||
535 | + | ||
536 | + PdfNumList([x, y]).output(_buf); | ||
537 | + _buf.putString(' Td '); | ||
538 | + | ||
539 | + assert(() { | ||
540 | + if (_page.pdfDocument.verbose) { | ||
541 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
542 | + _buf.putComment('moveCursor($x, $y)'); | ||
543 | + o = _buf.offset; | ||
544 | + _buf.putString(' ' * (_indent)); | ||
545 | + } | ||
546 | + return true; | ||
547 | + }()); | ||
548 | + | ||
434 | _buf.putString('['); | 549 | _buf.putString('['); |
435 | font.putText(_buf, s); | 550 | font.putText(_buf, s); |
436 | - _buf.putString(']TJ ET\n'); | 551 | + _buf.putString(']TJ '); |
552 | + | ||
553 | + assert(() { | ||
554 | + if (_page.pdfDocument.verbose) { | ||
555 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
556 | + _buf.putComment('drawString("$s")'); | ||
557 | + o = _buf.offset; | ||
558 | + _indent -= _indentAmount; | ||
559 | + _buf.putString(' ' * (_indent)); | ||
560 | + } | ||
561 | + return true; | ||
562 | + }()); | ||
563 | + | ||
564 | + _buf.putString('ET '); | ||
565 | + | ||
566 | + assert(() { | ||
567 | + if (_page.pdfDocument.verbose) { | ||
568 | + _buf.putString(' ' * (_commentIndent - 3 - _indent)); | ||
569 | + _buf.putComment('endText()'); | ||
570 | + } | ||
571 | + return true; | ||
572 | + }()); | ||
573 | + | ||
437 | } | 574 | } |
438 | 575 | ||
439 | void reset() { | 576 | void reset() { |
440 | assert(() { | 577 | assert(() { |
441 | if (_page.pdfDocument.verbose) { | 578 | if (_page.pdfDocument.verbose) { |
442 | - _buf.putComment('reset'); | 579 | + _buf.putString(' ' * (_indent)); |
443 | } | 580 | } |
444 | return true; | 581 | return true; |
445 | }()); | 582 | }()); |
446 | 583 | ||
447 | - _buf.putString('0 Tr\n'); | 584 | + _buf.putString('0 Tr '); |
585 | + | ||
586 | + assert(() { | ||
587 | + if (_page.pdfDocument.verbose) { | ||
588 | + _buf.putString(' ' * (_commentIndent - 5 - _indent)); | ||
589 | + _buf.putComment('reset()'); | ||
590 | + } | ||
591 | + return true; | ||
592 | + }()); | ||
448 | } | 593 | } |
449 | 594 | ||
450 | /// Sets the color for drawing | 595 | /// Sets the color for drawing |
@@ -455,9 +600,11 @@ class PdfGraphics { | @@ -455,9 +600,11 @@ class PdfGraphics { | ||
455 | 600 | ||
456 | /// Sets the fill color for drawing | 601 | /// Sets the fill color for drawing |
457 | void setFillColor(PdfColor? color) { | 602 | void setFillColor(PdfColor? color) { |
603 | + var o = 0; | ||
458 | assert(() { | 604 | assert(() { |
459 | if (_page.pdfDocument.verbose) { | 605 | if (_page.pdfDocument.verbose) { |
460 | - _buf.putComment('setFillColor ${color?.toHex()}'); | 606 | + o = _buf.offset; |
607 | + _buf.putString(' ' * (_indent)); | ||
461 | } | 608 | } |
462 | return true; | 609 | return true; |
463 | }()); | 610 | }()); |
@@ -465,18 +612,28 @@ class PdfGraphics { | @@ -465,18 +612,28 @@ class PdfGraphics { | ||
465 | if (color is PdfColorCmyk) { | 612 | if (color is PdfColorCmyk) { |
466 | PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black]) | 613 | PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black]) |
467 | .output(_buf); | 614 | .output(_buf); |
468 | - _buf.putString(' k\n'); | 615 | + _buf.putString(' k '); |
469 | } else { | 616 | } else { |
470 | PdfNumList(<double>[color!.red, color.green, color.blue]).output(_buf); | 617 | PdfNumList(<double>[color!.red, color.green, color.blue]).output(_buf); |
471 | - _buf.putString(' rg\n'); | 618 | + _buf.putString(' rg '); |
619 | + } | ||
620 | + | ||
621 | + assert(() { | ||
622 | + if (_page.pdfDocument.verbose) { | ||
623 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
624 | + _buf.putComment('setFillColor(${color?.toHex()})'); | ||
472 | } | 625 | } |
626 | + return true; | ||
627 | + }()); | ||
473 | } | 628 | } |
474 | 629 | ||
475 | /// Sets the stroke color for drawing | 630 | /// Sets the stroke color for drawing |
476 | void setStrokeColor(PdfColor? color) { | 631 | void setStrokeColor(PdfColor? color) { |
632 | + var o = 0; | ||
477 | assert(() { | 633 | assert(() { |
478 | if (_page.pdfDocument.verbose) { | 634 | if (_page.pdfDocument.verbose) { |
479 | - _buf.putComment('setStrokeColor ${color?.toHex()}'); | 635 | + o = _buf.offset; |
636 | + _buf.putString(' ' * (_indent)); | ||
480 | } | 637 | } |
481 | return true; | 638 | return true; |
482 | }()); | 639 | }()); |
@@ -484,67 +641,116 @@ class PdfGraphics { | @@ -484,67 +641,116 @@ class PdfGraphics { | ||
484 | if (color is PdfColorCmyk) { | 641 | if (color is PdfColorCmyk) { |
485 | PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black]) | 642 | PdfNumList(<double>[color.cyan, color.magenta, color.yellow, color.black]) |
486 | .output(_buf); | 643 | .output(_buf); |
487 | - _buf.putString(' K\n'); | 644 | + _buf.putString(' K '); |
488 | } else { | 645 | } else { |
489 | PdfNumList(<double>[color!.red, color.green, color.blue]).output(_buf); | 646 | PdfNumList(<double>[color!.red, color.green, color.blue]).output(_buf); |
490 | - _buf.putString(' RG\n'); | 647 | + _buf.putString(' RG '); |
648 | + } | ||
649 | + | ||
650 | + assert(() { | ||
651 | + if (_page.pdfDocument.verbose) { | ||
652 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
653 | + _buf.putComment('setStrokeColor(${color?.toHex()})'); | ||
491 | } | 654 | } |
655 | + return true; | ||
656 | + }()); | ||
492 | } | 657 | } |
493 | 658 | ||
494 | /// Sets the fill pattern for drawing | 659 | /// Sets the fill pattern for drawing |
495 | void setFillPattern(PdfPattern pattern) { | 660 | void setFillPattern(PdfPattern pattern) { |
661 | + var o = 0; | ||
496 | assert(() { | 662 | assert(() { |
497 | if (_page.pdfDocument.verbose) { | 663 | if (_page.pdfDocument.verbose) { |
498 | - _buf.putComment('setFillPattern'); | 664 | + o = _buf.offset; |
665 | + _buf.putString(' ' * (_indent)); | ||
499 | } | 666 | } |
500 | return true; | 667 | return true; |
501 | }()); | 668 | }()); |
502 | 669 | ||
503 | // The shader needs to be registered in the page resources | 670 | // The shader needs to be registered in the page resources |
504 | _page.addPattern(pattern); | 671 | _page.addPattern(pattern); |
505 | - _buf.putString('/Pattern cs${pattern.name} scn\n'); | 672 | + _buf.putString('/Pattern cs${pattern.name} scn '); |
673 | + | ||
674 | + assert(() { | ||
675 | + if (_page.pdfDocument.verbose) { | ||
676 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
677 | + _buf.putComment('setFillPattern(${pattern.ref()})'); | ||
678 | + } | ||
679 | + return true; | ||
680 | + }()); | ||
506 | } | 681 | } |
507 | 682 | ||
508 | /// Sets the stroke pattern for drawing | 683 | /// Sets the stroke pattern for drawing |
509 | void setStrokePattern(PdfPattern pattern) { | 684 | void setStrokePattern(PdfPattern pattern) { |
685 | + var o = 0; | ||
510 | assert(() { | 686 | assert(() { |
511 | if (_page.pdfDocument.verbose) { | 687 | if (_page.pdfDocument.verbose) { |
512 | - _buf.putComment('setStrokePattern'); | 688 | + o = _buf.offset; |
689 | + _buf.putString(' ' * (_indent)); | ||
513 | } | 690 | } |
514 | return true; | 691 | return true; |
515 | }()); | 692 | }()); |
516 | 693 | ||
517 | // The shader needs to be registered in the page resources | 694 | // The shader needs to be registered in the page resources |
518 | _page.addPattern(pattern); | 695 | _page.addPattern(pattern); |
519 | - _buf.putString('/Pattern CS${pattern.name} SCN\n'); | 696 | + _buf.putString('/Pattern CS${pattern.name} SCN '); |
697 | + | ||
698 | + assert(() { | ||
699 | + if (_page.pdfDocument.verbose) { | ||
700 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
701 | + _buf.putComment('setStrokePattern(${pattern.ref()})'); | ||
702 | + } | ||
703 | + return true; | ||
704 | + }()); | ||
520 | } | 705 | } |
521 | 706 | ||
522 | /// Set the graphic state for drawing | 707 | /// Set the graphic state for drawing |
523 | void setGraphicState(PdfGraphicState state) { | 708 | void setGraphicState(PdfGraphicState state) { |
709 | + var o = 0; | ||
524 | assert(() { | 710 | assert(() { |
525 | if (_page.pdfDocument.verbose) { | 711 | if (_page.pdfDocument.verbose) { |
526 | - _buf.putComment('setGraphicState $state'); | 712 | + o = _buf.offset; |
713 | + _buf.putString(' ' * (_indent)); | ||
527 | } | 714 | } |
528 | return true; | 715 | return true; |
529 | }()); | 716 | }()); |
530 | 717 | ||
531 | final name = _page.stateName(state); | 718 | final name = _page.stateName(state); |
532 | - _buf.putString('$name gs\n'); | 719 | + _buf.putString('$name gs '); |
720 | + | ||
721 | + assert(() { | ||
722 | + if (_page.pdfDocument.verbose) { | ||
723 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
724 | + _buf.putComment('setGraphicState($state)'); | ||
725 | + } | ||
726 | + return true; | ||
727 | + }()); | ||
533 | } | 728 | } |
534 | 729 | ||
535 | /// Set the transformation Matrix | 730 | /// Set the transformation Matrix |
536 | void setTransform(Matrix4 t) { | 731 | void setTransform(Matrix4 t) { |
732 | + var o = 0; | ||
537 | assert(() { | 733 | assert(() { |
538 | if (_page.pdfDocument.verbose) { | 734 | if (_page.pdfDocument.verbose) { |
539 | - _buf.putComment('setTransform\n$t'); | 735 | + o = _buf.offset; |
736 | + _buf.putString(' ' * (_indent)); | ||
540 | } | 737 | } |
541 | return true; | 738 | return true; |
542 | }()); | 739 | }()); |
543 | 740 | ||
544 | final s = t.storage; | 741 | final s = t.storage; |
545 | PdfNumList(<double>[s[0], s[1], s[4], s[5], s[12], s[13]]).output(_buf); | 742 | PdfNumList(<double>[s[0], s[1], s[4], s[5], s[12], s[13]]).output(_buf); |
546 | - _buf.putString(' cm\n'); | 743 | + _buf.putString(' cm '); |
547 | _context.ctm.multiply(t); | 744 | _context.ctm.multiply(t); |
745 | + | ||
746 | + assert(() { | ||
747 | + if (_page.pdfDocument.verbose) { | ||
748 | + final n = math.max(0, _commentIndent - _buf.offset + o); | ||
749 | + _buf.putString(' ' * n); | ||
750 | + _buf.putComment('setTransform($s)'); | ||
751 | + } | ||
752 | + return true; | ||
753 | + }()); | ||
548 | } | 754 | } |
549 | 755 | ||
550 | /// Get the transformation Matrix | 756 | /// Get the transformation Matrix |
@@ -554,28 +760,48 @@ class PdfGraphics { | @@ -554,28 +760,48 @@ class PdfGraphics { | ||
554 | 760 | ||
555 | /// This adds a line segment to the current path | 761 | /// This adds a line segment to the current path |
556 | void lineTo(double x, double y) { | 762 | void lineTo(double x, double y) { |
763 | + var o = 0; | ||
557 | assert(() { | 764 | assert(() { |
558 | if (_page.pdfDocument.verbose) { | 765 | if (_page.pdfDocument.verbose) { |
559 | - _buf.putComment('lineTo x:$x y:$y'); | 766 | + o = _buf.offset; |
767 | + _buf.putString(' ' * (_indent)); | ||
560 | } | 768 | } |
561 | return true; | 769 | return true; |
562 | }()); | 770 | }()); |
563 | 771 | ||
564 | PdfNumList([x, y]).output(_buf); | 772 | PdfNumList([x, y]).output(_buf); |
565 | - _buf.putString(' l\n'); | 773 | + _buf.putString(' l '); |
774 | + | ||
775 | + assert(() { | ||
776 | + if (_page.pdfDocument.verbose) { | ||
777 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
778 | + _buf.putComment('lineTo($x, $y)'); | ||
779 | + } | ||
780 | + return true; | ||
781 | + }()); | ||
566 | } | 782 | } |
567 | 783 | ||
568 | /// This moves the current drawing point. | 784 | /// This moves the current drawing point. |
569 | void moveTo(double x, double y) { | 785 | void moveTo(double x, double y) { |
786 | + var o = 0; | ||
570 | assert(() { | 787 | assert(() { |
571 | if (_page.pdfDocument.verbose) { | 788 | if (_page.pdfDocument.verbose) { |
572 | - _buf.putComment('moveTo x:$x y:$y'); | 789 | + o = _buf.offset; |
790 | + _buf.putString(' ' * (_indent)); | ||
573 | } | 791 | } |
574 | return true; | 792 | return true; |
575 | }()); | 793 | }()); |
576 | 794 | ||
577 | PdfNumList([x, y]).output(_buf); | 795 | PdfNumList([x, y]).output(_buf); |
578 | - _buf.putString(' m\n'); | 796 | + _buf.putString(' m '); |
797 | + | ||
798 | + assert(() { | ||
799 | + if (_page.pdfDocument.verbose) { | ||
800 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
801 | + _buf.putComment('moveTo($x, $y)'); | ||
802 | + } | ||
803 | + return true; | ||
804 | + }()); | ||
579 | } | 805 | } |
580 | 806 | ||
581 | /// Draw a cubic bézier curve from the current point to (x3,y3) | 807 | /// Draw a cubic bézier curve from the current point to (x3,y3) |
@@ -583,15 +809,25 @@ class PdfGraphics { | @@ -583,15 +809,25 @@ class PdfGraphics { | ||
583 | /// and (x2,y2) as the control point at the end of the curve. | 809 | /// and (x2,y2) as the control point at the end of the curve. |
584 | void curveTo( | 810 | void curveTo( |
585 | double x1, double y1, double x2, double y2, double x3, double y3) { | 811 | double x1, double y1, double x2, double y2, double x3, double y3) { |
812 | + var o = 0; | ||
586 | assert(() { | 813 | assert(() { |
587 | if (_page.pdfDocument.verbose) { | 814 | if (_page.pdfDocument.verbose) { |
588 | - _buf.putComment('curveTo x1:$x1 y1:$y1 x2:$x2 y2:$y2 x3:$x3 y3:$y3'); | 815 | + o = _buf.offset; |
816 | + _buf.putString(' ' * (_indent)); | ||
589 | } | 817 | } |
590 | return true; | 818 | return true; |
591 | }()); | 819 | }()); |
592 | 820 | ||
593 | PdfNumList([x1, y1, x2, y2, x3, y3]).output(_buf); | 821 | PdfNumList([x1, y1, x2, y2, x3, y3]).output(_buf); |
594 | - _buf.putString(' c\n'); | 822 | + _buf.putString(' c '); |
823 | + | ||
824 | + assert(() { | ||
825 | + if (_page.pdfDocument.verbose) { | ||
826 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
827 | + _buf.putComment('curveTo($x1, $y1, $x2, $y2, $x3, $y3)'); | ||
828 | + } | ||
829 | + return true; | ||
830 | + }()); | ||
595 | } | 831 | } |
596 | 832 | ||
597 | double _vectorAngle(double ux, double uy, double vx, double vy) { | 833 | double _vectorAngle(double ux, double uy, double vx, double vy) { |
@@ -753,51 +989,87 @@ class PdfGraphics { | @@ -753,51 +989,87 @@ class PdfGraphics { | ||
753 | void setLineCap(PdfLineCap cap) { | 989 | void setLineCap(PdfLineCap cap) { |
754 | assert(() { | 990 | assert(() { |
755 | if (_page.pdfDocument.verbose) { | 991 | if (_page.pdfDocument.verbose) { |
756 | - _buf.putComment('setLineCap $cap'); | 992 | + _buf.putString(' ' * (_indent)); |
757 | } | 993 | } |
758 | return true; | 994 | return true; |
759 | }()); | 995 | }()); |
760 | 996 | ||
761 | - _buf.putString('${cap.index} J\n'); | 997 | + _buf.putString('${cap.index} J '); |
998 | + | ||
999 | + assert(() { | ||
1000 | + if (_page.pdfDocument.verbose) { | ||
1001 | + _buf.putString(' ' * (_commentIndent - 4 - _indent)); | ||
1002 | + _buf.putComment('setLineCap(${cap.name})'); | ||
1003 | + } | ||
1004 | + return true; | ||
1005 | + }()); | ||
762 | } | 1006 | } |
763 | 1007 | ||
764 | /// Set line join type | 1008 | /// Set line join type |
765 | void setLineJoin(PdfLineJoin join) { | 1009 | void setLineJoin(PdfLineJoin join) { |
766 | assert(() { | 1010 | assert(() { |
767 | if (_page.pdfDocument.verbose) { | 1011 | if (_page.pdfDocument.verbose) { |
768 | - _buf.putComment('setLineJoin $join'); | 1012 | + _buf.putString(' ' * (_indent)); |
769 | } | 1013 | } |
770 | return true; | 1014 | return true; |
771 | }()); | 1015 | }()); |
772 | 1016 | ||
773 | - _buf.putString('${join.index} j\n'); | 1017 | + _buf.putString('${join.index} j '); |
1018 | + | ||
1019 | + assert(() { | ||
1020 | + if (_page.pdfDocument.verbose) { | ||
1021 | + _buf.putString(' ' * (_commentIndent - 4 - _indent)); | ||
1022 | + _buf.putComment('setLineJoin(${join.name})'); | ||
1023 | + } | ||
1024 | + return true; | ||
1025 | + }()); | ||
774 | } | 1026 | } |
775 | 1027 | ||
776 | /// Set line width | 1028 | /// Set line width |
777 | void setLineWidth(double width) { | 1029 | void setLineWidth(double width) { |
1030 | + var o = 0; | ||
778 | assert(() { | 1031 | assert(() { |
779 | if (_page.pdfDocument.verbose) { | 1032 | if (_page.pdfDocument.verbose) { |
780 | - _buf.putComment('setLineWidth $width'); | 1033 | + o = _buf.offset; |
1034 | + _buf.putString(' ' * (_indent)); | ||
781 | } | 1035 | } |
782 | return true; | 1036 | return true; |
783 | }()); | 1037 | }()); |
784 | 1038 | ||
785 | PdfNum(width).output(_buf); | 1039 | PdfNum(width).output(_buf); |
786 | - _buf.putString(' w\n'); | 1040 | + _buf.putString(' w '); |
1041 | + | ||
1042 | + assert(() { | ||
1043 | + if (_page.pdfDocument.verbose) { | ||
1044 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
1045 | + _buf.putComment('setLineWidth($width)'); | ||
1046 | + } | ||
1047 | + return true; | ||
1048 | + }()); | ||
787 | } | 1049 | } |
788 | 1050 | ||
789 | /// Set line joint miter limit, applies if the | 1051 | /// Set line joint miter limit, applies if the |
790 | void setMiterLimit(double limit) { | 1052 | void setMiterLimit(double limit) { |
1053 | + var o = 0; | ||
791 | assert(() { | 1054 | assert(() { |
792 | if (_page.pdfDocument.verbose) { | 1055 | if (_page.pdfDocument.verbose) { |
793 | - _buf.putComment('setMiterLimit $limit'); | 1056 | + o = _buf.offset; |
1057 | + _buf.putString(' ' * (_indent)); | ||
794 | } | 1058 | } |
795 | return true; | 1059 | return true; |
796 | }()); | 1060 | }()); |
797 | 1061 | ||
798 | assert(limit >= 1.0); | 1062 | assert(limit >= 1.0); |
799 | PdfNum(limit).output(_buf); | 1063 | PdfNum(limit).output(_buf); |
800 | - _buf.putString(' M\n'); | 1064 | + _buf.putString(' M '); |
1065 | + | ||
1066 | + assert(() { | ||
1067 | + if (_page.pdfDocument.verbose) { | ||
1068 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
1069 | + _buf.putComment('setMiterLimit($limit)'); | ||
1070 | + } | ||
1071 | + return true; | ||
1072 | + }()); | ||
801 | } | 1073 | } |
802 | 1074 | ||
803 | /// The dash array shall be cycled through, adding up the lengths of dashes and gaps. | 1075 | /// The dash array shall be cycled through, adding up the lengths of dashes and gaps. |
@@ -805,38 +1077,66 @@ class PdfGraphics { | @@ -805,38 +1077,66 @@ class PdfGraphics { | ||
805 | /// | 1077 | /// |
806 | /// Example: [2 1] will create a dash pattern with 2 on, 1 off, 2 on, 1 off, ... | 1078 | /// Example: [2 1] will create a dash pattern with 2 on, 1 off, 2 on, 1 off, ... |
807 | void setLineDashPattern([List<num> array = const <num>[], int phase = 0]) { | 1079 | void setLineDashPattern([List<num> array = const <num>[], int phase = 0]) { |
1080 | + var o = 0; | ||
808 | assert(() { | 1081 | assert(() { |
809 | if (_page.pdfDocument.verbose) { | 1082 | if (_page.pdfDocument.verbose) { |
810 | - _buf.putComment('setLineDashPattern $array phase:$phase'); | 1083 | + o = _buf.offset; |
1084 | + _buf.putString(' ' * (_indent)); | ||
811 | } | 1085 | } |
812 | return true; | 1086 | return true; |
813 | }()); | 1087 | }()); |
814 | 1088 | ||
815 | PdfArray.fromNum(array).output(_buf); | 1089 | PdfArray.fromNum(array).output(_buf); |
816 | - _buf.putString(' $phase d\n'); | 1090 | + _buf.putString(' $phase d '); |
1091 | + | ||
1092 | + assert(() { | ||
1093 | + if (_page.pdfDocument.verbose) { | ||
1094 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
1095 | + _buf.putComment('setLineDashPattern($array, $phase)'); | ||
1096 | + } | ||
1097 | + return true; | ||
1098 | + }()); | ||
817 | } | 1099 | } |
818 | 1100 | ||
819 | void markContentBegin(PdfName tag) { | 1101 | void markContentBegin(PdfName tag) { |
1102 | + var o = 0; | ||
820 | assert(() { | 1103 | assert(() { |
821 | if (_page.pdfDocument.verbose) { | 1104 | if (_page.pdfDocument.verbose) { |
822 | - _buf.putComment('markContentBegin'); | 1105 | + o = _buf.offset; |
1106 | + _buf.putString(' ' * (_indent)); | ||
823 | } | 1107 | } |
824 | return true; | 1108 | return true; |
825 | }()); | 1109 | }()); |
826 | 1110 | ||
827 | tag.output(_buf); | 1111 | tag.output(_buf); |
828 | - _buf.putString(' BMC\n'); | 1112 | + _buf.putString(' BMC '); |
1113 | + | ||
1114 | + assert(() { | ||
1115 | + if (_page.pdfDocument.verbose) { | ||
1116 | + _buf.putString(' ' * math.max(0, _commentIndent - _buf.offset + o)); | ||
1117 | + _buf.putComment('markContentBegin($tag)'); | ||
1118 | + } | ||
1119 | + return true; | ||
1120 | + }()); | ||
829 | } | 1121 | } |
830 | 1122 | ||
831 | void markContentEnd() { | 1123 | void markContentEnd() { |
832 | assert(() { | 1124 | assert(() { |
833 | if (_page.pdfDocument.verbose) { | 1125 | if (_page.pdfDocument.verbose) { |
834 | - _buf.putComment('markContentEnd'); | 1126 | + _buf.putString(' ' * (_indent)); |
835 | } | 1127 | } |
836 | return true; | 1128 | return true; |
837 | }()); | 1129 | }()); |
838 | 1130 | ||
839 | - _buf.putString('EMC\n'); | 1131 | + _buf.putString('EMC '); |
1132 | + | ||
1133 | + assert(() { | ||
1134 | + if (_page.pdfDocument.verbose) { | ||
1135 | + _buf.putString(' ' * (_commentIndent - 4 - _indent)); | ||
1136 | + _buf.putComment('markContentEnd()'); | ||
1137 | + } | ||
1138 | + return true; | ||
1139 | + }()); | ||
840 | } | 1140 | } |
841 | } | 1141 | } |
842 | 1142 | ||
@@ -891,8 +1191,8 @@ class _PathBBProxy extends PathProxy { | @@ -891,8 +1191,8 @@ class _PathBBProxy extends PathProxy { | ||
891 | @override | 1191 | @override |
892 | void cubicTo( | 1192 | void cubicTo( |
893 | double x1, double y1, double x2, double y2, double x3, double y3) { | 1193 | double x1, double y1, double x2, double y2, double x3, double y3) { |
894 | - final tvalues = <double>[]; | ||
895 | - double a, b, c, t, t1, t2, b2ac, sqrtb2ac; | 1194 | + final tValues = <double>[]; |
1195 | + double a, b, c, t, t1, t2, b2ac, sqrtB2ac; | ||
896 | 1196 | ||
897 | for (var i = 0; i < 2; ++i) { | 1197 | for (var i = 0; i < 2; ++i) { |
898 | if (i == 0) { | 1198 | if (i == 0) { |
@@ -910,7 +1210,7 @@ class _PathBBProxy extends PathProxy { | @@ -910,7 +1210,7 @@ class _PathBBProxy extends PathProxy { | ||
910 | } | 1210 | } |
911 | t = -c / b; | 1211 | t = -c / b; |
912 | if (0 < t && t < 1) { | 1212 | if (0 < t && t < 1) { |
913 | - tvalues.add(t); | 1213 | + tValues.add(t); |
914 | } | 1214 | } |
915 | continue; | 1215 | continue; |
916 | } | 1216 | } |
@@ -919,23 +1219,23 @@ class _PathBBProxy extends PathProxy { | @@ -919,23 +1219,23 @@ class _PathBBProxy extends PathProxy { | ||
919 | if (b2ac.abs() < 1e-12) { | 1219 | if (b2ac.abs() < 1e-12) { |
920 | t = -b / (2 * a); | 1220 | t = -b / (2 * a); |
921 | if (0 < t && t < 1) { | 1221 | if (0 < t && t < 1) { |
922 | - tvalues.add(t); | 1222 | + tValues.add(t); |
923 | } | 1223 | } |
924 | } | 1224 | } |
925 | continue; | 1225 | continue; |
926 | } | 1226 | } |
927 | - sqrtb2ac = math.sqrt(b2ac); | ||
928 | - t1 = (-b + sqrtb2ac) / (2 * a); | 1227 | + sqrtB2ac = math.sqrt(b2ac); |
1228 | + t1 = (-b + sqrtB2ac) / (2 * a); | ||
929 | if (0 < t1 && t1 < 1) { | 1229 | if (0 < t1 && t1 < 1) { |
930 | - tvalues.add(t1); | 1230 | + tValues.add(t1); |
931 | } | 1231 | } |
932 | - t2 = (-b - sqrtb2ac) / (2 * a); | 1232 | + t2 = (-b - sqrtB2ac) / (2 * a); |
933 | if (0 < t2 && t2 < 1) { | 1233 | if (0 < t2 && t2 < 1) { |
934 | - tvalues.add(t2); | 1234 | + tValues.add(t2); |
935 | } | 1235 | } |
936 | } | 1236 | } |
937 | 1237 | ||
938 | - for (final t in tvalues) { | 1238 | + for (final t in tValues) { |
939 | final mt = 1 - t; | 1239 | final mt = 1 - t; |
940 | _updateMinMax( | 1240 | _updateMinMax( |
941 | (mt * mt * mt * _pX) + | 1241 | (mt * mt * mt * _pX) + |
@@ -94,7 +94,6 @@ class PdfOutput with PdfDiagnostic { | @@ -94,7 +94,6 @@ class PdfOutput with PdfDiagnostic { | ||
94 | signatureID = ob; | 94 | signatureID = ob; |
95 | } | 95 | } |
96 | 96 | ||
97 | - xref.add(PdfXref(ob.objser, os.offset)); | ||
98 | assert(() { | 97 | assert(() { |
99 | if (verbose) { | 98 | if (verbose) { |
100 | ob.setInsertion(os); | 99 | ob.setInsertion(os); |
@@ -102,6 +101,7 @@ class PdfOutput with PdfDiagnostic { | @@ -102,6 +101,7 @@ class PdfOutput with PdfDiagnostic { | ||
102 | } | 101 | } |
103 | return true; | 102 | return true; |
104 | }()); | 103 | }()); |
104 | + xref.add(PdfXref(ob.objser, os.offset, generation: ob.objgen)); | ||
105 | ob.write(os); | 105 | ob.write(os); |
106 | assert(() { | 106 | assert(() { |
107 | if (verbose) { | 107 | if (verbose) { |
@@ -145,36 +145,15 @@ class PdfOutput with PdfDiagnostic { | @@ -145,36 +145,15 @@ class PdfOutput with PdfDiagnostic { | ||
145 | params['/Prev'] = PdfNum(rootID!.pdfDocument.prev!.xrefOffset); | 145 | params['/Prev'] = PdfNum(rootID!.pdfDocument.prev!.xrefOffset); |
146 | } | 146 | } |
147 | 147 | ||
148 | - final _xref = os.offset; | ||
149 | - if (isCompressed) { | ||
150 | - xref.outputCompressed(rootID!, os, params); | ||
151 | - } else { | ||
152 | - assert(() { | ||
153 | - if (verbose) { | ||
154 | - os.putComment(''); | ||
155 | - os.putComment('-' * 78); | ||
156 | - } | ||
157 | - return true; | ||
158 | - }()); | ||
159 | - xref.output(os); | ||
160 | - | ||
161 | - // the trailer object | ||
162 | - assert(() { | ||
163 | - if (verbose) { | ||
164 | - os.putComment(''); | ||
165 | - os.putComment('-' * 78); | ||
166 | - } | ||
167 | - return true; | ||
168 | - }()); | ||
169 | - os.putString('trailer\n'); | ||
170 | - params.output(os, verbose ? 0 : null); | ||
171 | - os.putByte(0x0a); | ||
172 | - } | 148 | + final _xref = isCompressed |
149 | + ? xref.outputCompressed(rootID!, os, params) | ||
150 | + : xref.outputLegacy(rootID!, os, params); | ||
173 | 151 | ||
174 | assert(() { | 152 | assert(() { |
175 | if (verbose) { | 153 | if (verbose) { |
176 | os.putComment(''); | 154 | os.putComment(''); |
177 | os.putComment('-' * 78); | 155 | os.putComment('-' * 78); |
156 | + os.putComment('$runtimeType'); | ||
178 | } | 157 | } |
179 | return true; | 158 | return true; |
180 | }()); | 159 | }()); |
@@ -83,7 +83,7 @@ class PdfXref { | @@ -83,7 +83,7 @@ class PdfXref { | ||
83 | } | 83 | } |
84 | 84 | ||
85 | @override | 85 | @override |
86 | - String toString() => '$runtimeType $id $generation $offset $type'; | 86 | + String toString() => '$id $generation obj ${type.name} $offset'; |
87 | 87 | ||
88 | @override | 88 | @override |
89 | int get hashCode => offset; | 89 | int get hashCode => offset; |
@@ -101,8 +101,8 @@ class PdfXrefTable extends PdfDataType { | @@ -101,8 +101,8 @@ class PdfXrefTable extends PdfDataType { | ||
101 | } | 101 | } |
102 | 102 | ||
103 | /// Writes a block of references to the Pdf file | 103 | /// Writes a block of references to the Pdf file |
104 | - void _writeblock(PdfStream s, int firstid, List<PdfXref> block) { | ||
105 | - s.putString('$firstid ${block.length}\n'); | 104 | + void _writeBlock(PdfStream s, int firstId, List<PdfXref> block) { |
105 | + s.putString('$firstId ${block.length}\n'); | ||
106 | 106 | ||
107 | for (final x in block) { | 107 | for (final x in block) { |
108 | s.putString(x.ref()); | 108 | s.putString(x.ref()); |
@@ -111,14 +111,32 @@ class PdfXrefTable extends PdfDataType { | @@ -111,14 +111,32 @@ class PdfXrefTable extends PdfDataType { | ||
111 | } | 111 | } |
112 | 112 | ||
113 | @override | 113 | @override |
114 | - void output(PdfStream s, [int? indent]) { | ||
115 | - s.putString('xref\n'); | 114 | + void output(PdfStream s, [int? indent]) {} |
116 | 115 | ||
116 | + @override | ||
117 | + String toString() { | ||
118 | + final s = StringBuffer(); | ||
119 | + for (final x in offsets) { | ||
120 | + s.writeln(' $x'); | ||
121 | + } | ||
122 | + return s.toString(); | ||
123 | + } | ||
124 | + | ||
125 | + int outputLegacy(PdfObject object, PdfStream s, PdfDict params) { | ||
117 | // Now scan through the offsets list. They should be in sequence. | 126 | // Now scan through the offsets list. They should be in sequence. |
118 | offsets.sort((a, b) => a.id.compareTo(b.id)); | 127 | offsets.sort((a, b) => a.id.compareTo(b.id)); |
119 | 128 | ||
120 | - var firstid = 0; // First id in block | ||
121 | - var lastid = 0; // The last id used | 129 | + assert(() { |
130 | + if (object.pdfDocument.verbose) { | ||
131 | + s.putComment(''); | ||
132 | + s.putComment('-' * 78); | ||
133 | + s.putComment('$runtimeType ${object.pdfDocument.version.name}\n$this'); | ||
134 | + } | ||
135 | + return true; | ||
136 | + }()); | ||
137 | + | ||
138 | + var firstId = 0; // First id in block | ||
139 | + var lastId = 0; // The last id used | ||
122 | final block = <PdfXref>[]; // xrefs in this block | 140 | final block = <PdfXref>[]; // xrefs in this block |
123 | 141 | ||
124 | // We need block 0 to exist | 142 | // We need block 0 to exist |
@@ -129,26 +147,42 @@ class PdfXrefTable extends PdfDataType { | @@ -129,26 +147,42 @@ class PdfXrefTable extends PdfDataType { | ||
129 | type: PdfCrossRefEntryType.free, | 147 | type: PdfCrossRefEntryType.free, |
130 | )); | 148 | )); |
131 | 149 | ||
150 | + final objOffset = s.offset; | ||
151 | + s.putString('xref\n'); | ||
152 | + | ||
132 | for (final x in offsets) { | 153 | for (final x in offsets) { |
133 | // check to see if block is in range | 154 | // check to see if block is in range |
134 | - if (x.id != (lastid + 1)) { | 155 | + if (x.id != (lastId + 1)) { |
135 | // no, so write this block, and reset | 156 | // no, so write this block, and reset |
136 | - _writeblock(s, firstid, block); | 157 | + _writeBlock(s, firstId, block); |
137 | block.clear(); | 158 | block.clear(); |
138 | - firstid = x.id; | 159 | + firstId = x.id; |
139 | } | 160 | } |
140 | 161 | ||
141 | // now add to block | 162 | // now add to block |
142 | block.add(x); | 163 | block.add(x); |
143 | - lastid = x.id; | 164 | + lastId = x.id; |
144 | } | 165 | } |
145 | 166 | ||
146 | // now write the last block | 167 | // now write the last block |
147 | - _writeblock(s, firstid, block); | 168 | + _writeBlock(s, firstId, block); |
169 | + | ||
170 | + // the trailer object | ||
171 | + assert(() { | ||
172 | + if (object.pdfDocument.verbose) { | ||
173 | + s.putComment(''); | ||
174 | + } | ||
175 | + return true; | ||
176 | + }()); | ||
177 | + s.putString('trailer\n'); | ||
178 | + params.output(s, object.pdfDocument.verbose ? 0 : null); | ||
179 | + s.putByte(0x0a); | ||
180 | + | ||
181 | + return objOffset; | ||
148 | } | 182 | } |
149 | 183 | ||
150 | /// Output a compressed cross-reference table | 184 | /// Output a compressed cross-reference table |
151 | - void outputCompressed(PdfObject object, PdfStream s, PdfDict params) { | 185 | + int outputCompressed(PdfObject object, PdfStream s, PdfDict params) { |
152 | final offset = s.offset; | 186 | final offset = s.offset; |
153 | 187 | ||
154 | // Sort all references | 188 | // Sort all references |
@@ -161,24 +195,24 @@ class PdfXrefTable extends PdfDataType { | @@ -161,24 +195,24 @@ class PdfXrefTable extends PdfDataType { | ||
161 | params['/Type'] = const PdfName('/XRef'); | 195 | params['/Type'] = const PdfName('/XRef'); |
162 | params['/Size'] = PdfNum(id + 1); | 196 | params['/Size'] = PdfNum(id + 1); |
163 | 197 | ||
164 | - var firstid = 0; // First id in block | ||
165 | - var lastid = 0; // The last id used | 198 | + var firstId = 0; // First id in block |
199 | + var lastId = 0; // The last id used | ||
166 | final blocks = <int>[]; // xrefs in this block first, count | 200 | final blocks = <int>[]; // xrefs in this block first, count |
167 | 201 | ||
168 | // We need block 0 to exist | 202 | // We need block 0 to exist |
169 | - blocks.add(firstid); | 203 | + blocks.add(firstId); |
170 | 204 | ||
171 | for (final x in offsets) { | 205 | for (final x in offsets) { |
172 | // check to see if block is in range | 206 | // check to see if block is in range |
173 | - if (x.id != (lastid + 1)) { | 207 | + if (x.id != (lastId + 1)) { |
174 | // no, so store this block, and reset | 208 | // no, so store this block, and reset |
175 | - blocks.add(lastid - firstid + 1); | ||
176 | - firstid = x.id; | ||
177 | - blocks.add(firstid); | 209 | + blocks.add(lastId - firstId + 1); |
210 | + firstId = x.id; | ||
211 | + blocks.add(firstId); | ||
178 | } | 212 | } |
179 | - lastid = x.id; | 213 | + lastId = x.id; |
180 | } | 214 | } |
181 | - blocks.add(lastid - firstid + 1); | 215 | + blocks.add(lastId - firstId + 1); |
182 | 216 | ||
183 | if (!(blocks.length == 2 && blocks[0] == 0 && blocks[1] == id + 1)) { | 217 | if (!(blocks.length == 2 && blocks[0] == 0 && blocks[1] == id + 1)) { |
184 | params['/Index'] = PdfArray.fromNum(blocks); | 218 | params['/Index'] = PdfArray.fromNum(blocks); |
@@ -203,10 +237,13 @@ class PdfXrefTable extends PdfDataType { | @@ -203,10 +237,13 @@ class PdfXrefTable extends PdfDataType { | ||
203 | if (object.pdfDocument.verbose) { | 237 | if (object.pdfDocument.verbose) { |
204 | s.putComment(''); | 238 | s.putComment(''); |
205 | s.putComment('-' * 78); | 239 | s.putComment('-' * 78); |
206 | - s.putComment('$runtimeType $this'); | 240 | + s.putComment('$runtimeType ${object.pdfDocument.version.name}\n$this'); |
207 | } | 241 | } |
208 | return true; | 242 | return true; |
209 | }()); | 243 | }()); |
244 | + | ||
245 | + final objOffset = s.offset; | ||
246 | + | ||
210 | s.putString('$id 0 obj\n'); | 247 | s.putString('$id 0 obj\n'); |
211 | 248 | ||
212 | PdfDictStream( | 249 | PdfDictStream( |
@@ -218,5 +255,6 @@ class PdfXrefTable extends PdfDataType { | @@ -218,5 +255,6 @@ class PdfXrefTable extends PdfDataType { | ||
218 | ).output(s, object.pdfDocument.verbose ? 0 : null); | 255 | ).output(s, object.pdfDocument.verbose ? 0 : null); |
219 | 256 | ||
220 | s.putString('endobj\n'); | 257 | s.putString('endobj\n'); |
258 | + return objOffset; | ||
221 | } | 259 | } |
222 | } | 260 | } |
-
Please register or login to post a comment