paint method

  1. @override
void paint(
  1. Canvas canvas,
  2. Rect rect,
  3. Path? clipPath,
  4. ImageConfiguration configuration,
)
override

Draw the image onto the given canvas.

The image is drawn at the position and size given by the rect argument.

The image is clipped to the given clipPath, if any.

The configuration object is used to resolve the image (e.g. to pick resolution-specific assets), and to implement the DecorationImageToo.matchTextDirection feature.

If the image needs to be painted again, e.g. because it is animated or because it had not yet been loaded the first time this method was called, then the onChanged callback passed to DecorationImageToo.createPainter will be called.

Implementation

@override
void paint(Canvas canvas, Rect rect, Path? clipPath,
    ImageConfiguration configuration) {
  var flipHorizontally = false;
  if (_details.matchTextDirection) {
    assert(() {
      // We check this first so that the assert will fire immediately, not
      // just when the image is ready.
      if (configuration.textDirection == null) {
        throw FlutterError.fromParts(<DiagnosticsNode>[
          ErrorSummary('DecorationImage.matchTextDirection can only be used '
              'when a TextDirection is available.'),
          ErrorDescription(
            'When DecorationImagePainter.paint() was called, '
            'there was no text direction provided in the '
            'ImageConfiguration object to match.',
          ),
          DiagnosticsProperty<DecorationImageToo>(
              'The DecorationImage was', _details,
              style: DiagnosticsTreeStyle.errorProperty),
          DiagnosticsProperty<ImageConfiguration>(
              'The ImageConfiguration was', configuration,
              style: DiagnosticsTreeStyle.errorProperty),
        ]);
      }
      return true;
    }());
    if (configuration.textDirection == TextDirection.rtl) {
      flipHorizontally = true;
    }
  }

  final newImageStream = _details.image.resolve(configuration);
  if (newImageStream.key != _imageStream?.key) {
    final listener = ImageStreamListener(
      _handleImage,
      onError: _details.onError,
    );
    _imageStream?.removeListener(listener);
    _imageStream = newImageStream;
    _imageStream!.addListener(listener);
  }
  if (_image == null) return;

  if (clipPath != null) {
    canvas
      ..save()
      ..clipPath(clipPath);
  }

  /// Expanded [paintImage] method that accepts a [Repeat].
  paintImageToo(
    canvas: canvas,
    rect: rect,
    image: _image!.image,
    debugImageLabel: _image!.debugLabel,
    scale: _details.scale * _image!.scale,
    colorFilter: _details.colorFilter,
    fit: _details.fit,
    alignment: _details.alignment.resolve(configuration.textDirection),
    centerSlice: _details.centerSlice,
    // FINALLY the meat and potatoes:
    // enabling mirroring tiles in the paint method.
    repeat: _details.repeatMode,
    mirrorOffset: _details.mirrorOffset,
    flipHorizontally: flipHorizontally,
    filterQuality: FilterQuality.low,
  );

  if (clipPath != null) canvas.restore();
}