Showing
5 changed files
with
113 additions
and
21 deletions
@@ -27,43 +27,52 @@ class SvgImage extends Widget { | @@ -27,43 +27,52 @@ class SvgImage extends Widget { | ||
27 | factory SvgImage({ | 27 | factory SvgImage({ |
28 | @required String svg, | 28 | @required String svg, |
29 | BoxFit fit = BoxFit.contain, | 29 | BoxFit fit = BoxFit.contain, |
30 | + Alignment alignment = Alignment.center, | ||
30 | bool clip = true, | 31 | bool clip = true, |
31 | double width, | 32 | double width, |
32 | double height, | 33 | double height, |
33 | }) { | 34 | }) { |
34 | assert(clip != null); | 35 | assert(clip != null); |
36 | + assert(alignment != null); | ||
35 | 37 | ||
36 | final xml = XmlDocument.parse(svg); | 38 | final xml = XmlDocument.parse(svg); |
37 | final parser = SvgParser(xml: xml); | 39 | final parser = SvgParser(xml: xml); |
38 | 40 | ||
39 | - return SvgImage._fromPainter( | 41 | + return SvgImage._fromParser( |
40 | parser, | 42 | parser, |
41 | fit, | 43 | fit, |
44 | + alignment, | ||
42 | clip, | 45 | clip, |
43 | width, | 46 | width, |
44 | height, | 47 | height, |
45 | ); | 48 | ); |
46 | } | 49 | } |
47 | 50 | ||
48 | - SvgImage._fromPainter( | 51 | + SvgImage._fromParser( |
49 | this._svgParser, | 52 | this._svgParser, |
50 | this.fit, | 53 | this.fit, |
54 | + this.alignment, | ||
51 | this.clip, | 55 | this.clip, |
52 | this.width, | 56 | this.width, |
53 | this.height, | 57 | this.height, |
54 | ) : assert(_svgParser != null), | 58 | ) : assert(_svgParser != null), |
55 | - assert(fit != null); | 59 | + assert(fit != null), |
60 | + assert(alignment != null); | ||
56 | 61 | ||
57 | final SvgParser _svgParser; | 62 | final SvgParser _svgParser; |
58 | 63 | ||
59 | final BoxFit fit; | 64 | final BoxFit fit; |
60 | 65 | ||
66 | + final Alignment alignment; | ||
67 | + | ||
61 | final bool clip; | 68 | final bool clip; |
62 | 69 | ||
63 | final double width; | 70 | final double width; |
64 | 71 | ||
65 | final double height; | 72 | final double height; |
66 | 73 | ||
74 | + FittedSizes sizes; | ||
75 | + | ||
67 | @override | 76 | @override |
68 | void layout(Context context, BoxConstraints constraints, | 77 | void layout(Context context, BoxConstraints constraints, |
69 | {bool parentUsesSize = false}) { | 78 | {bool parentUsesSize = false}) { |
@@ -78,10 +87,7 @@ class SvgImage extends Widget { | @@ -78,10 +87,7 @@ class SvgImage extends Widget { | ||
78 | ? constraints.maxHeight | 87 | ? constraints.maxHeight |
79 | : constraints.constrainHeight(_svgParser.viewBox.height); | 88 | : constraints.constrainHeight(_svgParser.viewBox.height); |
80 | 89 | ||
81 | - final sizes = applyBoxFit( | ||
82 | - fit, | ||
83 | - PdfPoint(_svgParser.viewBox.width, _svgParser.viewBox.height), | ||
84 | - PdfPoint(w, h)); | 90 | + sizes = applyBoxFit(fit, _svgParser.viewBox.size, PdfPoint(w, h)); |
85 | box = PdfRect.fromPoints(PdfPoint.zero, sizes.destination); | 91 | box = PdfRect.fromPoints(PdfPoint.zero, sizes.destination); |
86 | } | 92 | } |
87 | 93 | ||
@@ -89,19 +95,20 @@ class SvgImage extends Widget { | @@ -89,19 +95,20 @@ class SvgImage extends Widget { | ||
89 | void paint(Context context) { | 95 | void paint(Context context) { |
90 | super.paint(context); | 96 | super.paint(context); |
91 | 97 | ||
92 | - final mat = Matrix4.identity(); | ||
93 | - mat.translate( | ||
94 | - box.x, | ||
95 | - box.y + box.height, | ||
96 | - ); | ||
97 | - mat.scale( | ||
98 | - box.width / _svgParser.viewBox.width, | ||
99 | - -box.height / _svgParser.viewBox.height, | ||
100 | - ); | ||
101 | - mat.translate( | ||
102 | - -_svgParser.viewBox.x, | ||
103 | - -_svgParser.viewBox.y, | ||
104 | - ); | 98 | + final _alignment = Alignment(alignment.x, -alignment.y); |
99 | + final sourceRect = _alignment.inscribe(sizes.source, _svgParser.viewBox); | ||
100 | + final sx = sizes.destination.x / sizes.source.x; | ||
101 | + final sy = sizes.destination.y / sizes.source.y; | ||
102 | + final dx = sourceRect.x * sx; | ||
103 | + final dy = sourceRect.y * sy; | ||
104 | + | ||
105 | + final mat = Matrix4.identity() | ||
106 | + ..translate( | ||
107 | + box.x - dx, | ||
108 | + box.y + dy + box.height, | ||
109 | + ) | ||
110 | + ..scale(sx, -sy); | ||
111 | + | ||
105 | context.canvas.saveContext(); | 112 | context.canvas.saveContext(); |
106 | if (clip) { | 113 | if (clip) { |
107 | context.canvas | 114 | context.canvas |
@@ -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: 2.0.0 | 7 | +version: 2.1.0 |
8 | 8 | ||
9 | environment: | 9 | environment: |
10 | sdk: ">=2.3.0 <3.0.0" | 10 | sdk: ">=2.3.0 <3.0.0" |
@@ -110,6 +110,72 @@ void main() { | @@ -110,6 +110,72 @@ void main() { | ||
110 | ); | 110 | ); |
111 | }); | 111 | }); |
112 | 112 | ||
113 | + test('SVG Widgets BoxFit.cover and alignment', () { | ||
114 | + const svg = | ||
115 | + '<?xml version="1.0" encoding="utf-8"?><svg version="1.1" viewBox="10 20 200 200" xmlns="http://www.w3.org/2000/svg"><circle style="fill-opacity: 0.19; fill: rgb(0, 94, 255);" cx="110" cy="120" r="90"/><rect x="10" y="20" width="200" height="200" stroke="blue" fill="none"/><line style="stroke: black;" x1="110" y1="110" x2="110" y2="130"/><line style="stroke: black" x1="100" y1="120" x2="120" y2="120"/></svg>'; | ||
116 | + | ||
117 | + pdf.addPage( | ||
118 | + Page( | ||
119 | + build: (context) => Column( | ||
120 | + children: [ | ||
121 | + GridView( | ||
122 | + crossAxisCount: 3, | ||
123 | + mainAxisSpacing: 10, | ||
124 | + crossAxisSpacing: 10, | ||
125 | + childAspectRatio: 0.3, | ||
126 | + children: [ | ||
127 | + for (final align in <Alignment>[ | ||
128 | + Alignment.topLeft, | ||
129 | + Alignment.topCenter, | ||
130 | + Alignment.topRight, | ||
131 | + Alignment.centerLeft, | ||
132 | + Alignment.center, | ||
133 | + Alignment.centerRight, | ||
134 | + Alignment.bottomLeft, | ||
135 | + Alignment.bottomCenter, | ||
136 | + Alignment.bottomRight, | ||
137 | + ]) | ||
138 | + SvgImage( | ||
139 | + svg: svg, | ||
140 | + fit: BoxFit.cover, | ||
141 | + alignment: align, | ||
142 | + ), | ||
143 | + ], | ||
144 | + ), | ||
145 | + SizedBox(height: 10), | ||
146 | + SizedBox( | ||
147 | + width: 180, | ||
148 | + child: GridView( | ||
149 | + crossAxisCount: 3, | ||
150 | + mainAxisSpacing: 10, | ||
151 | + crossAxisSpacing: 10, | ||
152 | + childAspectRatio: 3.3, | ||
153 | + children: [ | ||
154 | + for (final align in <Alignment>[ | ||
155 | + Alignment.topLeft, | ||
156 | + Alignment.topCenter, | ||
157 | + Alignment.topRight, | ||
158 | + Alignment.centerLeft, | ||
159 | + Alignment.center, | ||
160 | + Alignment.centerRight, | ||
161 | + Alignment.bottomLeft, | ||
162 | + Alignment.bottomCenter, | ||
163 | + Alignment.bottomRight, | ||
164 | + ]) | ||
165 | + SvgImage( | ||
166 | + svg: svg, | ||
167 | + fit: BoxFit.cover, | ||
168 | + alignment: align, | ||
169 | + ), | ||
170 | + ], | ||
171 | + ), | ||
172 | + ), | ||
173 | + ], | ||
174 | + ), | ||
175 | + ), | ||
176 | + ); | ||
177 | + }); | ||
178 | + | ||
113 | tearDownAll(() async { | 179 | tearDownAll(() async { |
114 | final file = File('widgets-svg.pdf'); | 180 | final file = File('widgets-svg.pdf'); |
115 | await file.writeAsBytes(await pdf.save()); | 181 | await file.writeAsBytes(await pdf.save()); |
@@ -16,9 +16,11 @@ | @@ -16,9 +16,11 @@ | ||
16 | 16 | ||
17 | import 'dart:typed_data'; | 17 | import 'dart:typed_data'; |
18 | 18 | ||
19 | +import 'package:flutter/widgets.dart'; | ||
19 | import 'package:flutter_test/flutter_test.dart'; | 20 | import 'package:flutter_test/flutter_test.dart'; |
20 | import 'package:mockito/mockito.dart'; | 21 | import 'package:mockito/mockito.dart'; |
21 | import 'package:pdf/pdf.dart'; | 22 | import 'package:pdf/pdf.dart'; |
23 | + | ||
22 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; | 24 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; |
23 | import 'package:printing/printing.dart'; | 25 | import 'package:printing/printing.dart'; |
24 | import 'package:printing/src/interface.dart'; | 26 | import 'package:printing/src/interface.dart'; |
@@ -112,6 +114,19 @@ void main() { | @@ -112,6 +114,19 @@ void main() { | ||
112 | null, | 114 | null, |
113 | ); | 115 | ); |
114 | }); | 116 | }); |
117 | + | ||
118 | + test('test image', () async { | ||
119 | + final bytes = Uint8List.fromList([ | ||
120 | + 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 1, // | ||
121 | + 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 102, 188, 58, 37, 0, 0, 0, 3, 80, 76, 84, | ||
122 | + 69, 181, 208, 208, 99, 4, 22, 234, 0, 0, 0, 31, 73, 68, 65, 84, 104, | ||
123 | + 129, 237, 193, 1, 13, 0, 0, 0, 194, 160, 247, 79, 109, 14, 55, 160, 0, 0, | ||
124 | + 0, 0, 0, 0, 0, 0, 190, 13, 33, 0, 0, 1, 154, 96, 225, 213, 0, 0, 0, 0, 73, | ||
125 | + 69, 78, 68, 174, 66, 96, 130 | ||
126 | + ]); | ||
127 | + final imageProvider = Image.memory(bytes).image; | ||
128 | + expect(await flutterImageProvider(imageProvider), isNotNull); | ||
129 | + }); | ||
115 | } | 130 | } |
116 | 131 | ||
117 | class MockPrinting extends Mock | 132 | class MockPrinting extends Mock |
-
Please register or login to post a comment