2
2
// Use of this source code is governed by a BSD-style license that can be
3
3
// found in the LICENSE file.
4
4
5
+ import 'dart:math' as math;
5
6
import 'dart:ui' as ui;
6
7
7
8
import 'package:flutter/animation.dart' ;
@@ -15,7 +16,7 @@ import 'listener.dart';
15
16
@immutable
16
17
class RasterKey {
17
18
/// Create a new [RasterKey] .
18
- const RasterKey (this .assetKey, this .width, this .height);
19
+ const RasterKey (this .assetKey, this .width, this .height, this .paint );
19
20
20
21
/// An object that is used to identify the raster data this key will store.
21
22
///
@@ -28,16 +29,22 @@ class RasterKey {
28
29
/// The width of this vector graphic raster, in physical pixels.
29
30
final int height;
30
31
32
+ /// The paint of this vector graphic raster.
33
+ final Paint paint;
34
+
31
35
@override
32
36
bool operator == (Object other) {
33
37
return other is RasterKey &&
34
38
other.assetKey == assetKey &&
35
39
other.width == width &&
36
- other.height == height;
40
+ other.height == height &&
41
+ other.paint.color == paint.color &&
42
+ other.paint.colorFilter == paint.colorFilter;
37
43
}
38
44
39
45
@override
40
- int get hashCode => Object .hash (assetKey, width, height);
46
+ int get hashCode =>
47
+ Object .hash (assetKey, width, height, paint.color, paint.colorFilter);
41
48
}
42
49
43
50
/// The cache entry for a rasterized vector graphic.
@@ -81,7 +88,6 @@ class RenderVectorGraphic extends RenderBox {
81
88
this ._colorFilter,
82
89
this ._devicePixelRatio,
83
90
this ._opacity,
84
- this ._scale,
85
91
) {
86
92
_opacity? .addListener (_updateOpacity);
87
93
_updateOpacity ();
@@ -116,6 +122,8 @@ class RenderVectorGraphic extends RenderBox {
116
122
/// An optional [ColorFilter] to apply to the rasterized vector graphic.
117
123
ColorFilter ? get colorFilter => _colorFilter;
118
124
ColorFilter ? _colorFilter;
125
+ double _rasterScaleFactor = 1.0 ;
126
+ final Paint _colorPaint = Paint ();
119
127
set colorFilter (ColorFilter ? value) {
120
128
if (colorFilter == value) {
121
129
return ;
@@ -173,16 +181,6 @@ class RenderVectorGraphic extends RenderBox {
173
181
/// the vector graphic itself has a size of 50x50, and [BoxFit.fill]
174
182
/// is used. This will compute a scale of 2.0, which will result in a
175
183
/// raster that is 100x100.
176
- double get scale => _scale;
177
- double _scale;
178
- set scale (double value) {
179
- assert (value != 0 );
180
- if (value == scale) {
181
- return ;
182
- }
183
- _scale = value;
184
- markNeedsPaint ();
185
- }
186
184
187
185
@override
188
186
bool hitTestSelf (Offset position) => true ;
@@ -196,7 +194,7 @@ class RenderVectorGraphic extends RenderBox {
196
194
}
197
195
198
196
static RasterData _createRaster (
199
- RasterKey key, double scaleFactor, PictureInfo info) {
197
+ RasterKey key, double scaleFactor, PictureInfo info, Paint colorPaint ) {
200
198
final int scaledWidth = key.width;
201
199
final int scaledHeight = key.height;
202
200
// In order to scale a picture, it must be placed in a new picture
@@ -206,9 +204,16 @@ class RenderVectorGraphic extends RenderBox {
206
204
// capture in a raster.
207
205
final ui.PictureRecorder recorder = ui.PictureRecorder ();
208
206
final ui.Canvas canvas = ui.Canvas (recorder);
209
-
207
+ final Rect drawSize =
208
+ ui.Rect .fromLTWH (0 , 0 , scaledWidth.toDouble (), scaledHeight.toDouble ());
209
+ canvas.clipRect (drawSize);
210
+ final int saveCount = canvas.getSaveCount ();
211
+ if (colorPaint.color.opacity != 1.0 || colorPaint.colorFilter != null ) {
212
+ canvas.saveLayer (drawSize, colorPaint);
213
+ }
210
214
canvas.scale (scaleFactor);
211
215
canvas.drawPicture (info.picture);
216
+ canvas.restoreToCount (saveCount);
212
217
final ui.Picture rasterPicture = recorder.endRecording ();
213
218
214
219
final ui.Image pending =
@@ -230,12 +235,14 @@ class RenderVectorGraphic extends RenderBox {
230
235
// Re-create the raster for a given vector graphic if the target size
231
236
// is sufficiently different. Returns `null` if rasterData has been
232
237
// updated immediately.
233
- void _maybeUpdateRaster () {
238
+ void _maybeUpdateRaster (double drawScaleFactor) {
239
+ _rasterScaleFactor = devicePixelRatio * drawScaleFactor;
234
240
final int scaledWidth =
235
- (pictureInfo.size.width * devicePixelRatio / scale ).round ();
241
+ (pictureInfo.size.width * _rasterScaleFactor ).round ();
236
242
final int scaledHeight =
237
- (pictureInfo.size.height * devicePixelRatio / scale).round ();
238
- final RasterKey key = RasterKey (assetKey, scaledWidth, scaledHeight);
243
+ (pictureInfo.size.height * _rasterScaleFactor).round ();
244
+ final RasterKey key =
245
+ RasterKey (assetKey, scaledWidth, scaledHeight, _colorPaint);
239
246
240
247
// First check if the raster is available synchronously. This also handles
241
248
// a no-op change that would resolve to an identical picture.
@@ -249,7 +256,7 @@ class RenderVectorGraphic extends RenderBox {
249
256
return ;
250
257
}
251
258
final RasterData data =
252
- _createRaster (key, devicePixelRatio / scale , pictureInfo);
259
+ _createRaster (key, _rasterScaleFactor , pictureInfo, _colorPaint );
253
260
data.count += 1 ;
254
261
255
262
assert (! _liveRasterCache.containsKey (key));
@@ -296,18 +303,23 @@ class RenderVectorGraphic extends RenderBox {
296
303
return ;
297
304
}
298
305
299
- _maybeUpdateRaster ();
306
+ if (colorFilter != null ) {
307
+ _colorPaint.colorFilter = colorFilter;
308
+ }
309
+ _colorPaint.color = Color .fromRGBO (0 , 0 , 0 , _opacityValue);
310
+
311
+ // Use this transform to get real x/y scale facotr.
312
+ final Float64List transformList = context.canvas.getTransform ();
313
+ final double drawScaleFactor = math.max (
314
+ transformList[0 + 0 * 4 ],
315
+ transformList[1 + 1 * 4 ],
316
+ );
317
+ _maybeUpdateRaster (drawScaleFactor);
318
+
300
319
final ui.Image image = _rasterData! .image;
301
320
final int width = _rasterData! .key.width;
302
321
final int height = _rasterData! .key.height;
303
322
304
- // Use `FilterQuality.low` to scale the image, which corresponds to
305
- // bilinear interpolation.
306
- final Paint colorPaint = Paint ()..filterQuality = ui.FilterQuality .low;
307
- if (colorFilter != null ) {
308
- colorPaint.colorFilter = colorFilter;
309
- }
310
- colorPaint.color = Color .fromRGBO (0 , 0 , 0 , _opacityValue);
311
323
final Rect src = ui.Rect .fromLTWH (
312
324
0 ,
313
325
0 ,
@@ -325,7 +337,7 @@ class RenderVectorGraphic extends RenderBox {
325
337
image,
326
338
src,
327
339
dst,
328
- colorPaint ,
340
+ Paint () ,
329
341
);
330
342
}
331
343
}
0 commit comments