Showing
3 changed files
with
480 additions
and
163 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() { |
| 205 | - assert(() { | ||
| 206 | - if (_page.pdfDocument.verbose) { | ||
| 207 | - _buf.putComment('restoreContext'); | ||
| 208 | - } | ||
| 209 | - return true; | ||
| 210 | - }()); | ||
| 211 | - | ||
| 212 | if (_contextQueue.isNotEmpty) { | 267 | if (_contextQueue.isNotEmpty) { |
| 268 | + assert(() { | ||
| 269 | + _indent -= _indentAmount; | ||
| 270 | + if (_page.pdfDocument.verbose) { | ||
| 271 | + _buf.putString(' ' * (_indent)); | ||
| 272 | + } | ||
| 273 | + return true; | ||
| 274 | + }()); | ||
| 275 | + | ||
| 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 '); |
| 400 | } | 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)'); | ||
| 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 '); |
| 472 | } | 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()})'); | ||
| 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 '); |
| 491 | } | 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()})'); | ||
| 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