Showing
5 changed files
with
108 additions
and
11 deletions
@@ -18,9 +18,73 @@ | @@ -18,9 +18,73 @@ | ||
18 | 18 | ||
19 | part of widget; | 19 | part of widget; |
20 | 20 | ||
21 | +void _paintImage({ | ||
22 | + @required PdfGraphics canvas, | ||
23 | + @required PdfRect rect, | ||
24 | + @required PdfImage image, | ||
25 | + double scale = 1.0, | ||
26 | + BoxFit fit, | ||
27 | + Alignment alignment = Alignment.center, | ||
28 | +}) { | ||
29 | + assert(canvas != null); | ||
30 | + assert(image != null); | ||
31 | + assert(alignment != null); | ||
32 | + final PdfPoint outputSize = rect.size; | ||
33 | + final PdfPoint inputSize = | ||
34 | + PdfPoint(image.width.toDouble(), image.height.toDouble()); | ||
35 | + fit ??= BoxFit.scaleDown; | ||
36 | + final FittedSizes fittedSizes = applyBoxFit( | ||
37 | + fit, PdfPoint(inputSize.x / scale, inputSize.y / scale), outputSize); | ||
38 | + final PdfPoint sourceSize = | ||
39 | + PdfPoint(fittedSizes.source.x * scale, fittedSizes.source.y * scale); | ||
40 | + final PdfPoint destinationSize = fittedSizes.destination; | ||
41 | + final double halfWidthDelta = (outputSize.x - destinationSize.x) / 2.0; | ||
42 | + final double halfHeightDelta = (outputSize.y - destinationSize.y) / 2.0; | ||
43 | + final double dx = halfWidthDelta + alignment.x * halfWidthDelta; | ||
44 | + final double dy = halfHeightDelta + alignment.y * halfHeightDelta; | ||
45 | + | ||
46 | + final PdfPoint destinationPosition = rect.topLeft.translate(dx, dy); | ||
47 | + final PdfRect destinationRect = | ||
48 | + PdfRect.fromPoints(destinationPosition, destinationSize); | ||
49 | + final PdfRect sourceRect = alignment.inscribe( | ||
50 | + sourceSize, | ||
51 | + PdfRect.fromPoints(PdfPoint.zero, inputSize), | ||
52 | + ); | ||
53 | + _drawImageRect(canvas, image, sourceRect, destinationRect); | ||
54 | +} | ||
55 | + | ||
56 | +void _drawImageRect(PdfGraphics canvas, PdfImage image, PdfRect sourceRect, | ||
57 | + PdfRect destinationRect) { | ||
58 | + final double fw = destinationRect.width / sourceRect.width; | ||
59 | + final double fh = destinationRect.height / sourceRect.height; | ||
60 | + | ||
61 | + canvas.saveContext(); | ||
62 | + canvas | ||
63 | + ..drawRect( | ||
64 | + destinationRect.x, | ||
65 | + destinationRect.y, | ||
66 | + destinationRect.width, | ||
67 | + destinationRect.height, | ||
68 | + ) | ||
69 | + ..clipPath() | ||
70 | + ..drawImage( | ||
71 | + image, | ||
72 | + destinationRect.x - sourceRect.x * fw, | ||
73 | + destinationRect.y - sourceRect.y * fh, | ||
74 | + image.width.toDouble() * fw, | ||
75 | + image.height.toDouble() * fh, | ||
76 | + ) | ||
77 | + ..restoreContext(); | ||
78 | +} | ||
79 | + | ||
21 | class Image extends Widget { | 80 | class Image extends Widget { |
22 | - Image(this.image, {this.fit = BoxFit.contain}) | ||
23 | - : assert(image != null), | 81 | + Image( |
82 | + this.image, { | ||
83 | + this.fit = BoxFit.contain, | ||
84 | + this.alignment = Alignment.center, | ||
85 | + this.width, | ||
86 | + this.height, | ||
87 | + }) : assert(image != null), | ||
24 | aspectRatio = image.height.toDouble() / image.width.toDouble(); | 88 | aspectRatio = image.height.toDouble() / image.width.toDouble(); |
25 | 89 | ||
26 | final PdfImage image; | 90 | final PdfImage image; |
@@ -29,6 +93,12 @@ class Image extends Widget { | @@ -29,6 +93,12 @@ class Image extends Widget { | ||
29 | 93 | ||
30 | final BoxFit fit; | 94 | final BoxFit fit; |
31 | 95 | ||
96 | + final Alignment alignment; | ||
97 | + | ||
98 | + final double width; | ||
99 | + | ||
100 | + final double height; | ||
101 | + | ||
32 | @override | 102 | @override |
33 | void layout(Context context, BoxConstraints constraints, | 103 | void layout(Context context, BoxConstraints constraints, |
34 | {bool parentUsesSize = false}) { | 104 | {bool parentUsesSize = false}) { |
@@ -50,7 +120,13 @@ class Image extends Widget { | @@ -50,7 +120,13 @@ class Image extends Widget { | ||
50 | void paint(Context context) { | 120 | void paint(Context context) { |
51 | super.paint(context); | 121 | super.paint(context); |
52 | 122 | ||
53 | - context.canvas.drawImage(image, box.x, box.y, box.width, box.height); | 123 | + _paintImage( |
124 | + canvas: context.canvas, | ||
125 | + image: image, | ||
126 | + rect: box, | ||
127 | + alignment: alignment, | ||
128 | + fit: fit, | ||
129 | + ); | ||
54 | } | 130 | } |
55 | } | 131 | } |
56 | 132 |
@@ -26,19 +26,20 @@ import 'package:pdf/widgets.dart'; | @@ -26,19 +26,20 @@ import 'package:pdf/widgets.dart'; | ||
26 | import 'package:test/test.dart'; | 26 | import 'package:test/test.dart'; |
27 | 27 | ||
28 | Document pdf; | 28 | Document pdf; |
29 | +PdfImage image; | ||
29 | 30 | ||
30 | void main() { | 31 | void main() { |
31 | - setUpAll(() { | 32 | + setUpAll(() async { |
32 | Document.debug = true; | 33 | Document.debug = true; |
33 | pdf = Document(); | 34 | pdf = Document(); |
34 | - }); | ||
35 | 35 | ||
36 | - test('Pdf Jpeg Download', () async { | ||
37 | - final PdfImage image = PdfImage.jpeg( | 36 | + image = PdfImage.jpeg( |
38 | pdf.document, | 37 | pdf.document, |
39 | image: await download('https://www.nfet.net/nfet.jpg'), | 38 | image: await download('https://www.nfet.net/nfet.jpg'), |
40 | ); | 39 | ); |
40 | + }); | ||
41 | 41 | ||
42 | + test('Pdf Jpeg Download', () async { | ||
42 | pdf.addPage(Page( | 43 | pdf.addPage(Page( |
43 | build: (Context context) => Center(child: Image(image)), | 44 | build: (Context context) => Center(child: Image(image)), |
44 | )); | 45 | )); |
@@ -64,6 +65,25 @@ void main() { | @@ -64,6 +65,25 @@ void main() { | ||
64 | ); | 65 | ); |
65 | }); | 66 | }); |
66 | 67 | ||
68 | + test('Pdf Image fit', () async { | ||
69 | + pdf.addPage( | ||
70 | + MultiPage( | ||
71 | + build: (Context context) => | ||
72 | + List<Widget>.generate(BoxFit.values.length, (int index) { | ||
73 | + final BoxFit fit = BoxFit.values[index]; | ||
74 | + return SizedBox( | ||
75 | + width: 200, | ||
76 | + height: 100, | ||
77 | + child: Image( | ||
78 | + image, | ||
79 | + fit: fit, | ||
80 | + ), | ||
81 | + ); | ||
82 | + }), | ||
83 | + ), | ||
84 | + ); | ||
85 | + }); | ||
86 | + | ||
67 | tearDownAll(() { | 87 | tearDownAll(() { |
68 | final File file = File('jpeg.pdf'); | 88 | final File file = File('jpeg.pdf'); |
69 | file.writeAsBytesSync(pdf.save()); | 89 | file.writeAsBytesSync(pdf.save()); |
No preview for this file type
No preview for this file type
-
Please register or login to post a comment