@@ -231,6 +231,7 @@ class _RenderSnapshotWidget extends RenderProxyBox {
231
231
}
232
232
233
233
ui.Image ? _childRaster;
234
+ Size ? _childRasterSize;
234
235
// Set to true if the snapshot mode was not forced and a platform view
235
236
// was encountered while attempting to snapshot the child.
236
237
bool _disableSnapshotAttempt = false ;
@@ -249,6 +250,7 @@ class _RenderSnapshotWidget extends RenderProxyBox {
249
250
painter.removeListener (markNeedsPaint);
250
251
_childRaster? .dispose ();
251
252
_childRaster = null ;
253
+ _childRasterSize = null ;
252
254
super .detach ();
253
255
}
254
256
@@ -258,13 +260,15 @@ class _RenderSnapshotWidget extends RenderProxyBox {
258
260
painter.removeListener (markNeedsPaint);
259
261
_childRaster? .dispose ();
260
262
_childRaster = null ;
263
+ _childRasterSize = null ;
261
264
super .dispose ();
262
265
}
263
266
264
267
void _onRasterValueChanged () {
265
268
_disableSnapshotAttempt = false ;
266
269
_childRaster? .dispose ();
267
270
_childRaster = null ;
271
+ _childRasterSize = null ;
268
272
markNeedsPaint ();
269
273
}
270
274
@@ -296,19 +300,24 @@ class _RenderSnapshotWidget extends RenderProxyBox {
296
300
if (size.isEmpty) {
297
301
_childRaster? .dispose ();
298
302
_childRaster = null ;
303
+ _childRasterSize = null ;
299
304
return ;
300
305
}
301
306
if (! controller.allowSnapshotting || _disableSnapshotAttempt) {
302
307
_childRaster? .dispose ();
303
308
_childRaster = null ;
309
+ _childRasterSize = null ;
304
310
painter.paint (context, offset, size, super .paint);
305
311
return ;
306
312
}
307
- _childRaster ?? = _paintAndDetachToImage ();
313
+ if (_childRaster == null ) {
314
+ _childRaster = _paintAndDetachToImage ();
315
+ _childRasterSize = size * devicePixelRatio;
316
+ }
308
317
if (_childRaster == null ) {
309
318
painter.paint (context, offset, size, super .paint);
310
319
} else {
311
- painter.paintSnapshot (context, offset, size, _childRaster! , devicePixelRatio);
320
+ painter.paintSnapshot (context, offset, size, _childRaster! , _childRasterSize ! , devicePixelRatio);
312
321
}
313
322
}
314
323
}
@@ -356,19 +365,21 @@ abstract class SnapshotPainter extends ChangeNotifier {
356
365
/// [SnapshotPainter] paints the snapshot. This must account for the fact that the image
357
366
/// width and height will be given in physical pixels, while the image must be painted with
358
367
/// device independent pixels. That is, the width and height of the image is the widget and
359
- /// height of the provided `size` , multiplied by the `pixelRatio` :
368
+ /// height of the provided `size` , multiplied by the `pixelRatio` . In addition, the actual
369
+ /// size of the scene captured by the `image` is not `image.width` or `image.height` , but
370
+ /// indeed `sourceSize` , because the former is a rounded inaccurate integer:
360
371
///
361
372
/// ```dart
362
- /// void paint(PaintingContext context, Offset offset, Size size, ui.Image image, double pixelRatio) {
363
- /// final Rect src = Rect.fromLTWH(0, 0, image .width.toDouble(), image .height.toDouble() );
373
+ /// void paint(PaintingContext context, Offset offset, Size size, ui.Image image, Size sourceSize, double pixelRatio) {
374
+ /// final Rect src = Rect.fromLTWH(0, 0, sourceSize .width, sourceSize .height);
364
375
/// final Rect dst = Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height);
365
376
/// final Paint paint = Paint()
366
377
/// ..filterQuality = FilterQuality.low;
367
378
/// context.canvas.drawImageRect(image, src, dst, paint);
368
379
/// }
369
380
/// ```
370
381
/// {@end-tool}
371
- void paintSnapshot (PaintingContext context, Offset offset, Size size, ui.Image image, double pixelRatio);
382
+ void paintSnapshot (PaintingContext context, Offset offset, Size size, ui.Image image, Size sourceSize, double pixelRatio);
372
383
373
384
/// Paint the child via [painter] , applying any effects that would have been painted
374
385
/// in [SnapshotPainter.paintSnapshot] .
@@ -427,8 +438,8 @@ class _DefaultSnapshotPainter implements SnapshotPainter {
427
438
}
428
439
429
440
@override
430
- void paintSnapshot (PaintingContext context, ui.Offset offset, ui.Size size, ui.Image image, double pixelRatio) {
431
- final Rect src = Rect .fromLTWH (0 , 0 , image .width. toDouble (), image .height. toDouble () );
441
+ void paintSnapshot (PaintingContext context, ui.Offset offset, ui.Size size, ui.Image image, Size sourceSize, double pixelRatio) {
442
+ final Rect src = Rect .fromLTWH (0 , 0 , sourceSize .width, sourceSize .height);
432
443
final Rect dst = Rect .fromLTWH (offset.dx, offset.dy, size.width, size.height);
433
444
final Paint paint = Paint ()
434
445
..filterQuality = FilterQuality .low;
0 commit comments