Showing
7 changed files
with
177 additions
and
49 deletions
@@ -158,7 +158,8 @@ class Invoice { | @@ -158,7 +158,8 @@ class Invoice { | ||
158 | ), | 158 | ), |
159 | pw.Container( | 159 | pw.Container( |
160 | decoration: pw.BoxDecoration( | 160 | decoration: pw.BoxDecoration( |
161 | - borderRadius: 2, | 161 | + borderRadiusEx: |
162 | + pw.BorderRadius.all(pw.Radius.circular(2)), | ||
162 | color: accentColor, | 163 | color: accentColor, |
163 | ), | 164 | ), |
164 | padding: const pw.EdgeInsets.only( | 165 | padding: const pw.EdgeInsets.only( |
@@ -497,7 +498,7 @@ class Invoice { | @@ -497,7 +498,7 @@ class Invoice { | ||
497 | border: null, | 498 | border: null, |
498 | cellAlignment: pw.Alignment.centerLeft, | 499 | cellAlignment: pw.Alignment.centerLeft, |
499 | headerDecoration: pw.BoxDecoration( | 500 | headerDecoration: pw.BoxDecoration( |
500 | - borderRadius: 2, | 501 | + borderRadiusEx: pw.BorderRadius.all(pw.Radius.circular(2)), |
501 | color: baseColor, | 502 | color: baseColor, |
502 | ), | 503 | ), |
503 | headerHeight: 25, | 504 | headerHeight: 25, |
@@ -262,7 +262,10 @@ class _Category extends pw.StatelessWidget { | @@ -262,7 +262,10 @@ class _Category extends pw.StatelessWidget { | ||
262 | @override | 262 | @override |
263 | pw.Widget build(pw.Context context) { | 263 | pw.Widget build(pw.Context context) { |
264 | return pw.Container( | 264 | return pw.Container( |
265 | - decoration: const pw.BoxDecoration(color: lightGreen, borderRadius: 6), | 265 | + decoration: const pw.BoxDecoration( |
266 | + color: lightGreen, | ||
267 | + borderRadiusEx: pw.BorderRadius.all(pw.Radius.circular(6)), | ||
268 | + ), | ||
266 | margin: const pw.EdgeInsets.only(bottom: 10, top: 20), | 269 | margin: const pw.EdgeInsets.only(bottom: 10, top: 20), |
267 | padding: const pw.EdgeInsets.fromLTRB(10, 7, 10, 4), | 270 | padding: const pw.EdgeInsets.fromLTRB(10, 7, 10, 4), |
268 | child: pw.Text(title, textScaleFactor: 1.5)); | 271 | child: pw.Text(title, textScaleFactor: 1.5)); |
@@ -130,7 +130,7 @@ class BoxBorder { | @@ -130,7 +130,7 @@ class BoxBorder { | ||
130 | ..strokePath(); | 130 | ..strokePath(); |
131 | } | 131 | } |
132 | 132 | ||
133 | - void paintRRect(Context context, PdfRect box, double borderRadius) { | 133 | + void paintRRect(Context context, PdfRect box, BorderRadius borderRadius) { |
134 | assert(box.x != null); | 134 | assert(box.x != null); |
135 | assert(box.y != null); | 135 | assert(box.y != null); |
136 | assert(box.width != null); | 136 | assert(box.width != null); |
@@ -138,10 +138,9 @@ class BoxBorder { | @@ -138,10 +138,9 @@ class BoxBorder { | ||
138 | 138 | ||
139 | context.canvas | 139 | context.canvas |
140 | ..setStrokeColor(color) | 140 | ..setStrokeColor(color) |
141 | - ..setLineWidth(width) | ||
142 | - ..drawRRect( | ||
143 | - box.x, box.y, box.width, box.height, borderRadius, borderRadius) | ||
144 | - ..strokePath(); | 141 | + ..setLineWidth(width); |
142 | + borderRadius.paint(context, box); | ||
143 | + context.canvas.strokePath(); | ||
145 | } | 144 | } |
146 | } | 145 | } |
147 | 146 | ||
@@ -408,26 +407,6 @@ class BoxShadow { | @@ -408,26 +407,6 @@ class BoxShadow { | ||
408 | return shadow; | 407 | return shadow; |
409 | } | 408 | } |
410 | 409 | ||
411 | - im.Image _rRect(double width, double height, double rv, double rh) { | ||
412 | - final im.Image shadow = im.Image( | ||
413 | - (width + spreadRadius * 2).round(), | ||
414 | - (height + spreadRadius * 2).round(), | ||
415 | - ); | ||
416 | - | ||
417 | - im.fillRect( | ||
418 | - shadow, | ||
419 | - spreadRadius.round(), | ||
420 | - spreadRadius.round(), | ||
421 | - (spreadRadius + width).round(), | ||
422 | - (spreadRadius + height).round(), | ||
423 | - color.toInt(), | ||
424 | - ); | ||
425 | - | ||
426 | - im.gaussianBlur(shadow, blurRadius.round()); | ||
427 | - | ||
428 | - return shadow; | ||
429 | - } | ||
430 | - | ||
431 | im.Image _ellipse(double width, double height) { | 410 | im.Image _ellipse(double width, double height) { |
432 | final im.Image shadow = im.Image( | 411 | final im.Image shadow = im.Image( |
433 | (width + spreadRadius * 2).round(), | 412 | (width + spreadRadius * 2).round(), |
@@ -452,27 +431,171 @@ enum BoxShape { circle, rectangle } | @@ -452,27 +431,171 @@ enum BoxShape { circle, rectangle } | ||
452 | 431 | ||
453 | enum PaintPhase { all, background, foreground } | 432 | enum PaintPhase { all, background, foreground } |
454 | 433 | ||
434 | +/// A radius for either circular or elliptical shapes. | ||
435 | +class Radius { | ||
436 | + /// Constructs a circular radius. [x] and [y] will have the same radius value. | ||
437 | + const Radius.circular(double radius) : this.elliptical(radius, radius); | ||
438 | + | ||
439 | + /// Constructs an elliptical radius with the given radii. | ||
440 | + const Radius.elliptical(this.x, this.y); | ||
441 | + | ||
442 | + /// The radius value on the horizontal axis. | ||
443 | + final double x; | ||
444 | + | ||
445 | + /// The radius value on the vertical axis. | ||
446 | + final double y; | ||
447 | + | ||
448 | + /// A radius with [x] and [y] values set to zero. | ||
449 | + static const Radius zero = Radius.circular(0.0); | ||
450 | +} | ||
451 | + | ||
452 | +/// An immutable set of radii for each corner of a rectangle. | ||
453 | +class BorderRadius { | ||
454 | + /// Creates a border radius where all radii are [radius]. | ||
455 | + const BorderRadius.all(Radius radius) | ||
456 | + : this.only( | ||
457 | + topLeft: radius, | ||
458 | + topRight: radius, | ||
459 | + bottomLeft: radius, | ||
460 | + bottomRight: radius, | ||
461 | + ); | ||
462 | + | ||
463 | + /// Creates a border radius where all radii are [Radius.circular(radius)]. | ||
464 | + BorderRadius.circular(double radius) | ||
465 | + : this.all( | ||
466 | + Radius.circular(radius), | ||
467 | + ); | ||
468 | + | ||
469 | + /// Creates a vertically symmetric border radius where the top and bottom | ||
470 | + /// sides of the rectangle have the same radii. | ||
471 | + const BorderRadius.vertical({ | ||
472 | + Radius top = Radius.zero, | ||
473 | + Radius bottom = Radius.zero, | ||
474 | + }) : this.only( | ||
475 | + topLeft: top, | ||
476 | + topRight: top, | ||
477 | + bottomLeft: bottom, | ||
478 | + bottomRight: bottom, | ||
479 | + ); | ||
480 | + | ||
481 | + /// Creates a horizontally symmetrical border radius where the left and right | ||
482 | + /// sides of the rectangle have the same radii. | ||
483 | + const BorderRadius.horizontal({ | ||
484 | + Radius left = Radius.zero, | ||
485 | + Radius right = Radius.zero, | ||
486 | + }) : this.only( | ||
487 | + topLeft: left, | ||
488 | + topRight: right, | ||
489 | + bottomLeft: left, | ||
490 | + bottomRight: right, | ||
491 | + ); | ||
492 | + | ||
493 | + /// Creates a border radius with only the given non-zero values. The other | ||
494 | + /// corners will be right angles. | ||
495 | + const BorderRadius.only({ | ||
496 | + this.topLeft = Radius.zero, | ||
497 | + this.topRight = Radius.zero, | ||
498 | + this.bottomLeft = Radius.zero, | ||
499 | + this.bottomRight = Radius.zero, | ||
500 | + }); | ||
501 | + | ||
502 | + /// A border radius with all zero radii. | ||
503 | + static const BorderRadius zero = BorderRadius.all(Radius.zero); | ||
504 | + | ||
505 | + /// The top-left [Radius]. | ||
506 | + final Radius topLeft; | ||
507 | + | ||
508 | + /// The top-right [Radius]. | ||
509 | + final Radius topRight; | ||
510 | + | ||
511 | + /// The bottom-left [Radius]. | ||
512 | + final Radius bottomLeft; | ||
513 | + | ||
514 | + /// The bottom-right [Radius]. | ||
515 | + final Radius bottomRight; | ||
516 | + | ||
517 | + void paint(Context context, PdfRect box) { | ||
518 | + // Ellipse 4-spline magic number | ||
519 | + const double _m4 = 0.551784; | ||
520 | + | ||
521 | + context.canvas | ||
522 | + // Start | ||
523 | + ..moveTo(box.x, box.y + bottomLeft.y) | ||
524 | + // bottomLeft | ||
525 | + ..curveTo( | ||
526 | + box.x, | ||
527 | + box.y - _m4 * bottomLeft.y + bottomLeft.y, | ||
528 | + box.x - _m4 * bottomLeft.x + bottomLeft.x, | ||
529 | + box.y, | ||
530 | + box.x + bottomLeft.x, | ||
531 | + box.y) | ||
532 | + // bottom | ||
533 | + ..lineTo(box.x + box.width - bottomRight.x, box.y) | ||
534 | + // bottomRight | ||
535 | + ..curveTo( | ||
536 | + box.x + _m4 * bottomRight.x + box.width - bottomRight.x, | ||
537 | + box.y, | ||
538 | + box.x + box.width, | ||
539 | + box.y - _m4 * bottomRight.y + bottomRight.y, | ||
540 | + box.x + box.width, | ||
541 | + box.y + bottomRight.y) | ||
542 | + // right | ||
543 | + ..lineTo(box.x + box.width, box.y + box.height - topRight.y) | ||
544 | + // topRight | ||
545 | + ..curveTo( | ||
546 | + box.x + box.width, | ||
547 | + box.y + _m4 * topRight.y + box.height - topRight.y, | ||
548 | + box.x + _m4 * topRight.x + box.width - topRight.x, | ||
549 | + box.y + box.height, | ||
550 | + box.x + box.width - topRight.x, | ||
551 | + box.y + box.height) | ||
552 | + // top | ||
553 | + ..lineTo(box.x + topLeft.x, box.y + box.height) | ||
554 | + // topLeft | ||
555 | + ..curveTo( | ||
556 | + box.x - _m4 * topLeft.x + topLeft.x, | ||
557 | + box.y + box.height, | ||
558 | + box.x, | ||
559 | + box.y + _m4 * topLeft.y + box.height - topLeft.y, | ||
560 | + box.x, | ||
561 | + box.y + box.height - topLeft.y) | ||
562 | + // left | ||
563 | + ..lineTo(box.x, box.y + bottomLeft.y); | ||
564 | + } | ||
565 | +} | ||
566 | + | ||
455 | @immutable | 567 | @immutable |
456 | class BoxDecoration { | 568 | class BoxDecoration { |
457 | const BoxDecoration({ | 569 | const BoxDecoration({ |
458 | this.color, | 570 | this.color, |
459 | this.border, | 571 | this.border, |
460 | - this.borderRadius, | 572 | + @Deprecated('Use borderRadiusEx with `BorderRadius.all(Radius.circular(20))`') |
573 | + double borderRadius, | ||
574 | + BorderRadius borderRadiusEx, | ||
461 | this.boxShadow, | 575 | this.boxShadow, |
462 | this.gradient, | 576 | this.gradient, |
463 | this.image, | 577 | this.image, |
464 | this.shape = BoxShape.rectangle, | 578 | this.shape = BoxShape.rectangle, |
465 | - }) : assert(shape != null); | 579 | + }) : assert(shape != null), |
580 | + assert(!(borderRadius != null && borderRadiusEx != null), | ||
581 | + 'Don\'t set both borderRadius and borderRadiusEx'), | ||
582 | + _borderRadius = borderRadiusEx, | ||
583 | + _radius = borderRadius; | ||
466 | 584 | ||
467 | /// The color to fill in the background of the box. | 585 | /// The color to fill in the background of the box. |
468 | final PdfColor color; | 586 | final PdfColor color; |
469 | final BoxBorder border; | 587 | final BoxBorder border; |
470 | - final double borderRadius; | 588 | + final BorderRadius _borderRadius; |
589 | + final double _radius; | ||
471 | final BoxShape shape; | 590 | final BoxShape shape; |
472 | final DecorationImage image; | 591 | final DecorationImage image; |
473 | final Gradient gradient; | 592 | final Gradient gradient; |
474 | final List<BoxShadow> boxShadow; | 593 | final List<BoxShadow> boxShadow; |
475 | 594 | ||
595 | + BorderRadius get borderRadius => | ||
596 | + _borderRadius ?? | ||
597 | + (_radius == null ? null : BorderRadius.all(Radius.circular(_radius))); | ||
598 | + | ||
476 | void paint( | 599 | void paint( |
477 | Context context, | 600 | Context context, |
478 | PdfRect box, [ | 601 | PdfRect box, [ |
@@ -504,8 +627,7 @@ class BoxDecoration { | @@ -504,8 +627,7 @@ class BoxDecoration { | ||
504 | } else { | 627 | } else { |
505 | if (boxShadow != null) { | 628 | if (boxShadow != null) { |
506 | for (final BoxShadow s in boxShadow) { | 629 | for (final BoxShadow s in boxShadow) { |
507 | - final im.Image i = s._rRect( | ||
508 | - box.width, box.height, borderRadius, borderRadius); | 630 | + final im.Image i = s._rect(box.width, box.height); |
509 | final PdfImage m = | 631 | final PdfImage m = |
510 | PdfImage.fromImage(context.document, image: i); | 632 | PdfImage.fromImage(context.document, image: i); |
511 | context.canvas.drawImage( | 633 | context.canvas.drawImage( |
@@ -515,8 +637,7 @@ class BoxDecoration { | @@ -515,8 +637,7 @@ class BoxDecoration { | ||
515 | ); | 637 | ); |
516 | } | 638 | } |
517 | } | 639 | } |
518 | - context.canvas.drawRRect(box.x, box.y, box.width, box.height, | ||
519 | - borderRadius, borderRadius); | 640 | + borderRadius.paint(context, box); |
520 | } | 641 | } |
521 | break; | 642 | break; |
522 | case BoxShape.circle: | 643 | case BoxShape.circle: |
@@ -547,8 +668,7 @@ class BoxDecoration { | @@ -547,8 +668,7 @@ class BoxDecoration { | ||
547 | if (borderRadius == null) { | 668 | if (borderRadius == null) { |
548 | context.canvas.drawRect(box.x, box.y, box.width, box.height); | 669 | context.canvas.drawRect(box.x, box.y, box.width, box.height); |
549 | } else { | 670 | } else { |
550 | - context.canvas.drawRRect(box.x, box.y, box.width, box.height, | ||
551 | - borderRadius, borderRadius); | 671 | + borderRadius.paint(context, box); |
552 | } | 672 | } |
553 | break; | 673 | break; |
554 | case BoxShape.circle: | 674 | case BoxShape.circle: |
@@ -572,10 +692,8 @@ class BoxDecoration { | @@ -572,10 +692,8 @@ class BoxDecoration { | ||
572 | break; | 692 | break; |
573 | case BoxShape.rectangle: | 693 | case BoxShape.rectangle: |
574 | if (borderRadius != null) { | 694 | if (borderRadius != null) { |
575 | - context.canvas | ||
576 | - ..drawRRect(box.x, box.y, box.width, box.height, borderRadius, | ||
577 | - borderRadius) | ||
578 | - ..clipPath(); | 695 | + borderRadius.paint(context, box); |
696 | + context.canvas.clipPath(); | ||
579 | } | 697 | } |
580 | break; | 698 | break; |
581 | } | 699 | } |
@@ -4,7 +4,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl | @@ -4,7 +4,7 @@ description: A pdf producer for Dart. It can create pdf files for both web or fl | ||
4 | homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf | 4 | homepage: https://github.com/DavBfr/dart_pdf/tree/master/pdf |
5 | repository: https://github.com/DavBfr/dart_pdf | 5 | repository: https://github.com/DavBfr/dart_pdf |
6 | issue_tracker: https://github.com/DavBfr/dart_pdf/issues | 6 | issue_tracker: https://github.com/DavBfr/dart_pdf/issues |
7 | -version: 1.12.0 | 7 | +version: 1.13.0 |
8 | 8 | ||
9 | environment: | 9 | environment: |
10 | sdk: ">=2.3.0 <3.0.0" | 10 | sdk: ">=2.3.0 <3.0.0" |
@@ -40,7 +40,7 @@ void main() { | @@ -40,7 +40,7 @@ void main() { | ||
40 | padding: const EdgeInsets.all(20), | 40 | padding: const EdgeInsets.all(20), |
41 | decoration: const BoxDecoration( | 41 | decoration: const BoxDecoration( |
42 | color: PdfColors.blue, | 42 | color: PdfColors.blue, |
43 | - borderRadius: 20, | 43 | + borderRadiusEx: BorderRadius.all(Radius.circular(20)), |
44 | border: BoxBorder( | 44 | border: BoxBorder( |
45 | color: PdfColors.blue800, | 45 | color: PdfColors.blue800, |
46 | top: true, | 46 | top: true, |
@@ -67,7 +67,7 @@ void main() { | @@ -67,7 +67,7 @@ void main() { | ||
67 | alignment: Alignment.center, | 67 | alignment: Alignment.center, |
68 | decoration: BoxDecoration( | 68 | decoration: BoxDecoration( |
69 | shape: shape, | 69 | shape: shape, |
70 | - borderRadius: 10, | 70 | + borderRadiusEx: const BorderRadius.all(Radius.circular(10)), |
71 | image: DecorationImage(image: image, fit: fit), | 71 | image: DecorationImage(image: image, fit: fit), |
72 | ), | 72 | ), |
73 | width: 100, | 73 | width: 100, |
@@ -121,7 +121,7 @@ void main() { | @@ -121,7 +121,7 @@ void main() { | ||
121 | width: 200.0, | 121 | width: 200.0, |
122 | decoration: const BoxDecoration( | 122 | decoration: const BoxDecoration( |
123 | shape: BoxShape.rectangle, | 123 | shape: BoxShape.rectangle, |
124 | - borderRadius: 40, | 124 | + borderRadiusEx: BorderRadius.all(Radius.circular(40)), |
125 | border: BoxBorder( | 125 | border: BoxBorder( |
126 | bottom: true, | 126 | bottom: true, |
127 | top: true, | 127 | top: true, |
@@ -144,7 +144,7 @@ void main() { | @@ -144,7 +144,7 @@ void main() { | ||
144 | margin: const EdgeInsets.all(30), | 144 | margin: const EdgeInsets.all(30), |
145 | padding: const EdgeInsets.all(20), | 145 | padding: const EdgeInsets.all(20), |
146 | decoration: const BoxDecoration( | 146 | decoration: const BoxDecoration( |
147 | - borderRadius: 20, | 147 | + borderRadiusEx: BorderRadius.all(Radius.circular(20)), |
148 | gradient: LinearGradient( | 148 | gradient: LinearGradient( |
149 | colors: <PdfColor>[ | 149 | colors: <PdfColor>[ |
150 | PdfColors.blue, | 150 | PdfColors.blue, |
@@ -177,7 +177,7 @@ void main() { | @@ -177,7 +177,7 @@ void main() { | ||
177 | margin: const EdgeInsets.all(30), | 177 | margin: const EdgeInsets.all(30), |
178 | padding: const EdgeInsets.all(20), | 178 | padding: const EdgeInsets.all(20), |
179 | decoration: const BoxDecoration( | 179 | decoration: const BoxDecoration( |
180 | - borderRadius: 20, | 180 | + borderRadiusEx: BorderRadius.all(Radius.circular(20)), |
181 | gradient: RadialGradient( | 181 | gradient: RadialGradient( |
182 | colors: <PdfColor>[ | 182 | colors: <PdfColor>[ |
183 | PdfColors.blue, | 183 | PdfColors.blue, |
@@ -51,7 +51,10 @@ List<TableRow> buildTable( | @@ -51,7 +51,10 @@ List<TableRow> buildTable( | ||
51 | child: Text('${h.toInt()}°', style: Theme.of(context).tableCell)), | 51 | child: Text('${h.toInt()}°', style: Theme.of(context).tableCell)), |
52 | Container( | 52 | Container( |
53 | margin: const EdgeInsets.all(5), | 53 | margin: const EdgeInsets.all(5), |
54 | - decoration: BoxDecoration(color: color, borderRadius: 5), | 54 | + decoration: BoxDecoration( |
55 | + color: color, | ||
56 | + borderRadiusEx: const BorderRadius.all(Radius.circular(5)), | ||
57 | + ), | ||
55 | height: Theme.of(context).tableCell.fontSize), | 58 | height: Theme.of(context).tableCell.fontSize), |
56 | Container( | 59 | Container( |
57 | margin: const EdgeInsets.all(5), | 60 | margin: const EdgeInsets.all(5), |
@@ -208,7 +211,7 @@ void main() { | @@ -208,7 +211,7 @@ void main() { | ||
208 | border: null, | 211 | border: null, |
209 | cellAlignment: Alignment.center, | 212 | cellAlignment: Alignment.center, |
210 | headerDecoration: const BoxDecoration( | 213 | headerDecoration: const BoxDecoration( |
211 | - borderRadius: 2, | 214 | + borderRadiusEx: BorderRadius.all(Radius.circular(2)), |
212 | color: PdfColors.indigo, | 215 | color: PdfColors.indigo, |
213 | ), | 216 | ), |
214 | headerHeight: 25, | 217 | headerHeight: 25, |
-
Please register or login to post a comment