Unverified Commit be868397 authored by Alexandre Ardhuin's avatar Alexandre Ardhuin Committed by GitHub

migrate part of painting to nullsafety (#63495)

parent 72619b86
...@@ -510,7 +510,7 @@ abstract class OutlinedBorder extends ShapeBorder { ...@@ -510,7 +510,7 @@ abstract class OutlinedBorder extends ShapeBorder {
/// Returns a copy of this OutlinedBorder that draws its outline with the /// Returns a copy of this OutlinedBorder that draws its outline with the
/// specified [side], if [side] is non-null. /// specified [side], if [side] is non-null.
OutlinedBorder copyWith({ BorderSide side }); OutlinedBorder copyWith({ BorderSide? side });
} }
/// Represents the addition of two otherwise-incompatible borders. /// Represents the addition of two otherwise-incompatible borders.
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math; import 'dart:math' as math;
...@@ -40,21 +39,21 @@ class CircleBorder extends OutlinedBorder { ...@@ -40,21 +39,21 @@ class CircleBorder extends OutlinedBorder {
ShapeBorder scale(double t) => CircleBorder(side: side.scale(t)); ShapeBorder scale(double t) => CircleBorder(side: side.scale(t));
@override @override
ShapeBorder lerpFrom(ShapeBorder a, double t) { ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
if (a is CircleBorder) if (a is CircleBorder)
return CircleBorder(side: BorderSide.lerp(a.side, side, t)); return CircleBorder(side: BorderSide.lerp(a.side, side, t));
return super.lerpFrom(a, t); return super.lerpFrom(a, t);
} }
@override @override
ShapeBorder lerpTo(ShapeBorder b, double t) { ShapeBorder? lerpTo(ShapeBorder? b, double t) {
if (b is CircleBorder) if (b is CircleBorder)
return CircleBorder(side: BorderSide.lerp(side, b.side, t)); return CircleBorder(side: BorderSide.lerp(side, b.side, t));
return super.lerpTo(b, t); return super.lerpTo(b, t);
} }
@override @override
Path getInnerPath(Rect rect, { TextDirection textDirection }) { Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
return Path() return Path()
..addOval(Rect.fromCircle( ..addOval(Rect.fromCircle(
center: rect.center, center: rect.center,
...@@ -63,7 +62,7 @@ class CircleBorder extends OutlinedBorder { ...@@ -63,7 +62,7 @@ class CircleBorder extends OutlinedBorder {
} }
@override @override
Path getOuterPath(Rect rect, { TextDirection textDirection }) { Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
return Path() return Path()
..addOval(Rect.fromCircle( ..addOval(Rect.fromCircle(
center: rect.center, center: rect.center,
...@@ -72,12 +71,12 @@ class CircleBorder extends OutlinedBorder { ...@@ -72,12 +71,12 @@ class CircleBorder extends OutlinedBorder {
} }
@override @override
CircleBorder copyWith({ BorderSide side }) { CircleBorder copyWith({ BorderSide? side }) {
return CircleBorder(side: side ?? this.side); return CircleBorder(side: side ?? this.side);
} }
@override @override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) { void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
switch (side.style) { switch (side.style) {
case BorderStyle.none: case BorderStyle.none:
break; break;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' show Canvas, Clip, Path, Paint, Rect, RRect; import 'dart:ui' show Canvas, Clip, Path, Paint, Rect, RRect;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math; import 'dart:math' as math;
...@@ -61,24 +60,24 @@ class ContinuousRectangleBorder extends OutlinedBorder { ...@@ -61,24 +60,24 @@ class ContinuousRectangleBorder extends OutlinedBorder {
} }
@override @override
ShapeBorder lerpFrom(ShapeBorder a, double t) { ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
assert(t != null); assert(t != null);
if (a is ContinuousRectangleBorder) { if (a is ContinuousRectangleBorder) {
return ContinuousRectangleBorder( return ContinuousRectangleBorder(
side: BorderSide.lerp(a.side, side, t), side: BorderSide.lerp(a.side, side, t),
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t)!,
); );
} }
return super.lerpFrom(a, t); return super.lerpFrom(a, t);
} }
@override @override
ShapeBorder lerpTo(ShapeBorder b, double t) { ShapeBorder? lerpTo(ShapeBorder? b, double t) {
assert(t != null); assert(t != null);
if (b is ContinuousRectangleBorder) { if (b is ContinuousRectangleBorder) {
return ContinuousRectangleBorder( return ContinuousRectangleBorder(
side: BorderSide.lerp(side, b.side, t), side: BorderSide.lerp(side, b.side, t),
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t)!,
); );
} }
return super.lerpTo(b, t); return super.lerpTo(b, t);
...@@ -125,17 +124,17 @@ class ContinuousRectangleBorder extends OutlinedBorder { ...@@ -125,17 +124,17 @@ class ContinuousRectangleBorder extends OutlinedBorder {
} }
@override @override
Path getInnerPath(Rect rect, { TextDirection textDirection }) { Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
return _getPath(borderRadius.resolve(textDirection).toRRect(rect).deflate(side.width)); return _getPath(borderRadius.resolve(textDirection).toRRect(rect).deflate(side.width));
} }
@override @override
Path getOuterPath(Rect rect, { TextDirection textDirection }) { Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
return _getPath(borderRadius.resolve(textDirection).toRRect(rect)); return _getPath(borderRadius.resolve(textDirection).toRRect(rect));
} }
@override @override
ContinuousRectangleBorder copyWith({ BorderSide side, BorderRadius borderRadius }) { ContinuousRectangleBorder copyWith({ BorderSide? side, BorderRadius? borderRadius }) {
return ContinuousRectangleBorder( return ContinuousRectangleBorder(
side: side ?? this.side, side: side ?? this.side,
borderRadius: borderRadius ?? this.borderRadius, borderRadius: borderRadius ?? this.borderRadius,
...@@ -143,7 +142,7 @@ class ContinuousRectangleBorder extends OutlinedBorder { ...@@ -143,7 +142,7 @@ class ContinuousRectangleBorder extends OutlinedBorder {
} }
@override @override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) { void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
if (rect.isEmpty) if (rect.isEmpty)
return; return;
switch (side.style) { switch (side.style) {
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -58,7 +57,7 @@ abstract class Decoration with Diagnosticable { ...@@ -58,7 +57,7 @@ abstract class Decoration with Diagnosticable {
/// [EdgeInsetsGeometry.resolve] to obtain an absolute [EdgeInsets]. (For /// [EdgeInsetsGeometry.resolve] to obtain an absolute [EdgeInsets]. (For
/// example, [BorderDirectional] will return an [EdgeInsetsDirectional] for /// example, [BorderDirectional] will return an [EdgeInsetsDirectional] for
/// its [padding].) /// its [padding].)
EdgeInsetsGeometry get padding => EdgeInsets.zero; EdgeInsetsGeometry? get padding => EdgeInsets.zero;
/// Whether this decoration is complex enough to benefit from caching its painting. /// Whether this decoration is complex enough to benefit from caching its painting.
bool get isComplex => false; bool get isComplex => false;
...@@ -89,7 +88,7 @@ abstract class Decoration with Diagnosticable { ...@@ -89,7 +88,7 @@ abstract class Decoration with Diagnosticable {
/// ///
/// Instead of calling this directly, use [Decoration.lerp]. /// Instead of calling this directly, use [Decoration.lerp].
@protected @protected
Decoration lerpFrom(Decoration a, double t) => null; Decoration? lerpFrom(Decoration? a, double t) => null;
/// Linearly interpolates from `this` to another [Decoration] (which may be of /// Linearly interpolates from `this` to another [Decoration] (which may be of
/// a different class). /// a different class).
...@@ -118,7 +117,7 @@ abstract class Decoration with Diagnosticable { ...@@ -118,7 +117,7 @@ abstract class Decoration with Diagnosticable {
/// ///
/// Instead of calling this directly, use [Decoration.lerp]. /// Instead of calling this directly, use [Decoration.lerp].
@protected @protected
Decoration lerpTo(Decoration b, double t) => null; Decoration? lerpTo(Decoration? b, double t) => null;
/// Linearly interpolates between two [Decoration]s. /// Linearly interpolates between two [Decoration]s.
/// ///
...@@ -127,12 +126,12 @@ abstract class Decoration with Diagnosticable { ...@@ -127,12 +126,12 @@ abstract class Decoration with Diagnosticable {
/// interpolated, then the interpolation is done via null (at `t == 0.5`). /// interpolated, then the interpolation is done via null (at `t == 0.5`).
/// ///
/// {@macro dart.ui.shadow.lerp} /// {@macro dart.ui.shadow.lerp}
static Decoration lerp(Decoration a, Decoration b, double t) { static Decoration? lerp(Decoration? a, Decoration? b, double t) {
assert(t != null); assert(t != null);
if (a == null && b == null) if (a == null && b == null)
return null; return null;
if (a == null) if (a == null)
return b.lerpFrom(null, t) ?? b; return b!.lerpFrom(null, t) ?? b;
if (b == null) if (b == null)
return a.lerpTo(null, t) ?? a; return a.lerpTo(null, t) ?? a;
if (t == 0.0) if (t == 0.0)
...@@ -159,7 +158,7 @@ abstract class Decoration with Diagnosticable { ...@@ -159,7 +158,7 @@ abstract class Decoration with Diagnosticable {
/// is what [Container] uses), the `textDirection` parameter will be populated /// is what [Container] uses), the `textDirection` parameter will be populated
/// based on the ambient [Directionality] (by way of the [RenderDecoratedBox] /// based on the ambient [Directionality] (by way of the [RenderDecoratedBox]
/// renderer). /// renderer).
bool hitTest(Size size, Offset position, { TextDirection textDirection }) => true; bool hitTest(Size size, Offset position, { TextDirection? textDirection }) => true;
/// Returns a [BoxPainter] that will paint this decoration. /// Returns a [BoxPainter] that will paint this decoration.
/// ///
...@@ -170,7 +169,7 @@ abstract class Decoration with Diagnosticable { ...@@ -170,7 +169,7 @@ abstract class Decoration with Diagnosticable {
BoxPainter createBoxPainter([ VoidCallback onChanged ]); BoxPainter createBoxPainter([ VoidCallback onChanged ]);
/// Returns a closed [Path] that describes the outer edge of this decoration. /// Returns a closed [Path] that describes the outer edge of this decoration.
Path getClipPath(Rect rect, TextDirection textDirection) => null; Path? getClipPath(Rect rect, TextDirection textDirection) => null;
} }
/// A stateful class that can paint a particular [Decoration]. /// A stateful class that can paint a particular [Decoration].
...@@ -220,7 +219,7 @@ abstract class BoxPainter { ...@@ -220,7 +219,7 @@ abstract class BoxPainter {
/// ///
/// Resources might not start to load until after [paint] has been called, /// Resources might not start to load until after [paint] has been called,
/// because they might depend on the configuration. /// because they might depend on the configuration.
final VoidCallback onChanged; final VoidCallback? onChanged;
/// Discard any resources being held by the object. /// Discard any resources being held by the object.
/// ///
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:developer' as developer; import 'dart:developer' as developer;
import 'dart:ui' as ui show Image; import 'dart:ui' as ui show Image;
...@@ -44,7 +43,7 @@ class DecorationImage { ...@@ -44,7 +43,7 @@ class DecorationImage {
/// The [image], [alignment], [repeat], and [matchTextDirection] arguments /// The [image], [alignment], [repeat], and [matchTextDirection] arguments
/// must not be null. /// must not be null.
const DecorationImage({ const DecorationImage({
@required this.image, required this.image,
this.onError, this.onError,
this.colorFilter, this.colorFilter,
this.fit, this.fit,
...@@ -66,10 +65,10 @@ class DecorationImage { ...@@ -66,10 +65,10 @@ class DecorationImage {
final ImageProvider image; final ImageProvider image;
/// An optional error callback for errors emitted when loading [image]. /// An optional error callback for errors emitted when loading [image].
final ImageErrorListener onError; final ImageErrorListener? onError;
/// A color filter to apply to the image before painting it. /// A color filter to apply to the image before painting it.
final ColorFilter colorFilter; final ColorFilter? colorFilter;
/// How the image should be inscribed into the box. /// How the image should be inscribed into the box.
/// ///
...@@ -77,7 +76,7 @@ class DecorationImage { ...@@ -77,7 +76,7 @@ class DecorationImage {
/// [BoxFit.fill] if [centerSlice] is not null. /// [BoxFit.fill] if [centerSlice] is not null.
/// ///
/// See the discussion at [paintImage] for more details. /// See the discussion at [paintImage] for more details.
final BoxFit fit; final BoxFit? fit;
/// How to align the image within its bounds. /// How to align the image within its bounds.
/// ///
...@@ -121,7 +120,7 @@ class DecorationImage { ...@@ -121,7 +120,7 @@ class DecorationImage {
/// destination image size will result in [centerSlice] having no effect /// destination image size will result in [centerSlice] having no effect
/// (since the nine regions of the image will be rendered with the same /// (since the nine regions of the image will be rendered with the same
/// scaling, as if it wasn't specified). /// scaling, as if it wasn't specified).
final Rect centerSlice; final Rect? centerSlice;
/// How to paint any portions of the box that would not otherwise be covered /// How to paint any portions of the box that would not otherwise be covered
/// by the image. /// by the image.
...@@ -212,8 +211,8 @@ class DecorationImagePainter { ...@@ -212,8 +211,8 @@ class DecorationImagePainter {
final DecorationImage _details; final DecorationImage _details;
final VoidCallback _onChanged; final VoidCallback _onChanged;
ImageStream _imageStream; ImageStream? _imageStream;
ImageInfo _image; ImageInfo? _image;
/// Draw the image onto the given canvas. /// Draw the image onto the given canvas.
/// ///
...@@ -229,7 +228,7 @@ class DecorationImagePainter { ...@@ -229,7 +228,7 @@ class DecorationImagePainter {
/// because it had not yet been loaded the first time this method was called, /// because it had not yet been loaded the first time this method was called,
/// then the `onChanged` callback passed to [DecorationImage.createPainter] /// then the `onChanged` callback passed to [DecorationImage.createPainter]
/// will be called. /// will be called.
void paint(Canvas canvas, Rect rect, Path clipPath, ImageConfiguration configuration) { void paint(Canvas canvas, Rect rect, Path? clipPath, ImageConfiguration configuration) {
assert(canvas != null); assert(canvas != null);
assert(rect != null); assert(rect != null);
assert(configuration != null); assert(configuration != null);
...@@ -264,7 +263,7 @@ class DecorationImagePainter { ...@@ -264,7 +263,7 @@ class DecorationImagePainter {
); );
_imageStream?.removeListener(listener); _imageStream?.removeListener(listener);
_imageStream = newImageStream; _imageStream = newImageStream;
_imageStream.addListener(listener); _imageStream!.addListener(listener);
} }
if (_image == null) if (_image == null)
return; return;
...@@ -277,9 +276,9 @@ class DecorationImagePainter { ...@@ -277,9 +276,9 @@ class DecorationImagePainter {
paintImage( paintImage(
canvas: canvas, canvas: canvas,
rect: rect, rect: rect,
image: _image.image, image: _image!.image,
debugImageLabel: _image.debugLabel, debugImageLabel: _image!.debugLabel,
scale: _details.scale * _image.scale, scale: _details.scale * _image!.scale,
colorFilter: _details.colorFilter, colorFilter: _details.colorFilter,
fit: _details.fit, fit: _details.fit,
alignment: _details.alignment.resolve(configuration.textDirection), alignment: _details.alignment.resolve(configuration.textDirection),
...@@ -409,15 +408,15 @@ void debugFlushLastFrameImageSizeInfo() { ...@@ -409,15 +408,15 @@ void debugFlushLastFrameImageSizeInfo() {
/// * [DecorationImage], which holds a configuration for calling this function. /// * [DecorationImage], which holds a configuration for calling this function.
/// * [BoxDecoration], which uses this function to paint a [DecorationImage]. /// * [BoxDecoration], which uses this function to paint a [DecorationImage].
void paintImage({ void paintImage({
@required Canvas canvas, required Canvas canvas,
@required Rect rect, required Rect rect,
@required ui.Image image, required ui.Image image,
String debugImageLabel, String? debugImageLabel,
double scale = 1.0, double scale = 1.0,
ColorFilter colorFilter, ColorFilter? colorFilter,
BoxFit fit, BoxFit? fit,
Alignment alignment = Alignment.center, Alignment alignment = Alignment.center,
Rect centerSlice, Rect? centerSlice,
ImageRepeat repeat = ImageRepeat.noRepeat, ImageRepeat repeat = ImageRepeat.noRepeat,
bool flipHorizontally = false, bool flipHorizontally = false,
bool invertColors = false, bool invertColors = false,
...@@ -434,7 +433,7 @@ void paintImage({ ...@@ -434,7 +433,7 @@ void paintImage({
return; return;
Size outputSize = rect.size; Size outputSize = rect.size;
Size inputSize = Size(image.width.toDouble(), image.height.toDouble()); Size inputSize = Size(image.width.toDouble(), image.height.toDouble());
Offset sliceBorder; Offset? sliceBorder;
if (centerSlice != null) { if (centerSlice != null) {
sliceBorder = Offset( sliceBorder = Offset(
centerSlice.left + inputSize.width - centerSlice.right, centerSlice.left + inputSize.width - centerSlice.right,
...@@ -449,7 +448,7 @@ void paintImage({ ...@@ -449,7 +448,7 @@ void paintImage({
final Size sourceSize = fittedSizes.source * scale; final Size sourceSize = fittedSizes.source * scale;
Size destinationSize = fittedSizes.destination; Size destinationSize = fittedSizes.destination;
if (centerSlice != null) { if (centerSlice != null) {
outputSize += sliceBorder; outputSize += sliceBorder!;
destinationSize += sliceBorder; destinationSize += sliceBorder;
// We don't have the ability to draw a subset of the image at the same time // We don't have the ability to draw a subset of the image at the same time
// as we apply a nine-patch stretch. // as we apply a nine-patch stretch.
...@@ -523,23 +522,23 @@ void paintImage({ ...@@ -523,23 +522,23 @@ void paintImage({
}()); }());
// Avoid emitting events that are the same as those emitted in the last frame. // Avoid emitting events that are the same as those emitted in the last frame.
if (!_lastFrameImageSizeInfo.contains(sizeInfo)) { if (!_lastFrameImageSizeInfo.contains(sizeInfo)) {
final ImageSizeInfo existingSizeInfo = _pendingImageSizeInfo[sizeInfo.source]; final ImageSizeInfo? existingSizeInfo = _pendingImageSizeInfo[sizeInfo.source];
if (existingSizeInfo == null || existingSizeInfo.displaySizeInBytes < sizeInfo.displaySizeInBytes) { if (existingSizeInfo == null || existingSizeInfo.displaySizeInBytes < sizeInfo.displaySizeInBytes) {
_pendingImageSizeInfo[sizeInfo.source] = sizeInfo; _pendingImageSizeInfo[sizeInfo.source!] = sizeInfo;
} }
if (debugOnPaintImage != null) { if (debugOnPaintImage != null) {
debugOnPaintImage(sizeInfo); debugOnPaintImage!(sizeInfo);
} }
SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) { SchedulerBinding.instance!.addPostFrameCallback((Duration timeStamp) {
_lastFrameImageSizeInfo = _pendingImageSizeInfo.values.toSet(); _lastFrameImageSizeInfo = _pendingImageSizeInfo.values.toSet();
if (_pendingImageSizeInfo.isEmpty) { if (_pendingImageSizeInfo.isEmpty) {
return; return;
} }
developer.postEvent( developer.postEvent(
'Flutter.ImageSizesForFrame', 'Flutter.ImageSizesForFrame',
<Object, Object>{ <String, Object>{
for (ImageSizeInfo imageSizeInfo in _pendingImageSizeInfo.values) for (ImageSizeInfo imageSizeInfo in _pendingImageSizeInfo.values)
imageSizeInfo.source: imageSizeInfo.toJson() imageSizeInfo.source!: imageSizeInfo.toJson()
}, },
); );
_pendingImageSizeInfo = <String, ImageSizeInfo>{}; _pendingImageSizeInfo = <String, ImageSizeInfo>{};
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' as ui show lerpDouble; import 'dart:ui' as ui show lerpDouble;
...@@ -139,16 +138,14 @@ class FractionalOffset extends Alignment { ...@@ -139,16 +138,14 @@ class FractionalOffset extends Alignment {
Alignment operator -(Alignment other) { Alignment operator -(Alignment other) {
if (other is! FractionalOffset) if (other is! FractionalOffset)
return super - other; return super - other;
final FractionalOffset typedOther = other as FractionalOffset; return FractionalOffset(dx - other.dx, dy - other.dy);
return FractionalOffset(dx - typedOther.dx, dy - typedOther.dy);
} }
@override @override
Alignment operator +(Alignment other) { Alignment operator +(Alignment other) {
if (other is! FractionalOffset) if (other is! FractionalOffset)
return super + other; return super + other;
final FractionalOffset typedOther = other as FractionalOffset; return FractionalOffset(dx + other.dx, dy + other.dy);
return FractionalOffset(dx + typedOther.dx, dy + typedOther.dy);
} }
@override @override
...@@ -181,15 +178,15 @@ class FractionalOffset extends Alignment { ...@@ -181,15 +178,15 @@ class FractionalOffset extends Alignment {
/// If either is null, this function interpolates from [FractionalOffset.center]. /// If either is null, this function interpolates from [FractionalOffset.center].
/// ///
/// {@macro dart.ui.shadow.lerp} /// {@macro dart.ui.shadow.lerp}
static FractionalOffset lerp(FractionalOffset a, FractionalOffset b, double t) { static FractionalOffset? lerp(FractionalOffset? a, FractionalOffset? b, double t) {
assert(t != null); assert(t != null);
if (a == null && b == null) if (a == null && b == null)
return null; return null;
if (a == null) if (a == null)
return FractionalOffset(ui.lerpDouble(0.5, b.dx, t), ui.lerpDouble(0.5, b.dy, t)); return FractionalOffset(ui.lerpDouble(0.5, b!.dx, t)!, ui.lerpDouble(0.5, b.dy, t)!);
if (b == null) if (b == null)
return FractionalOffset(ui.lerpDouble(a.dx, 0.5, t), ui.lerpDouble(a.dy, 0.5, t)); return FractionalOffset(ui.lerpDouble(a.dx, 0.5, t)!, ui.lerpDouble(a.dy, 0.5, t)!);
return FractionalOffset(ui.lerpDouble(a.dx, b.dx, t), ui.lerpDouble(a.dy, b.dy, t)); return FractionalOffset(ui.lerpDouble(a.dx, b.dx, t)!, ui.lerpDouble(a.dy, b.dy, t)!);
} }
@override @override
......
...@@ -2,12 +2,9 @@ ...@@ -2,12 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:math' as math; import 'dart:math' as math;
import 'package:flutter/foundation.dart';
import 'basic_types.dart'; import 'basic_types.dart';
/// Position a child box within a container box, either above or below a target /// Position a child box within a container box, either above or below a target
...@@ -41,10 +38,10 @@ import 'basic_types.dart'; ...@@ -41,10 +38,10 @@ import 'basic_types.dart';
/// ///
/// The arguments must not be null. /// The arguments must not be null.
Offset positionDependentBox({ Offset positionDependentBox({
@required Size size, required Size size,
@required Size childSize, required Size childSize,
@required Offset target, required Offset target,
@required bool preferBelow, required bool preferBelow,
double verticalOffset = 0.0, double verticalOffset = 0.0,
double margin = 10.0, double margin = 10.0,
}) { }) {
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
...@@ -23,7 +22,7 @@ import 'binding.dart'; ...@@ -23,7 +22,7 @@ import 'binding.dart';
/// [PaintingBinding.instantiateImageCodec], and therefore can be mocked in /// [PaintingBinding.instantiateImageCodec], and therefore can be mocked in
/// tests. /// tests.
Future<ui.Image> decodeImageFromList(Uint8List bytes) async { Future<ui.Image> decodeImageFromList(Uint8List bytes) async {
final ui.Codec codec = await PaintingBinding.instance.instantiateImageCodec(bytes); final ui.Codec codec = await PaintingBinding.instance!.instantiateImageCodec(bytes);
final ui.FrameInfo frameInfo = await codec.getNextFrame(); final ui.FrameInfo frameInfo = await codec.getNextFrame();
return frameInfo.image; return frameInfo.image;
} }
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:collection'; import 'dart:collection';
...@@ -153,11 +152,11 @@ class AssetImage extends AssetBundleImageProvider { ...@@ -153,11 +152,11 @@ class AssetImage extends AssetBundleImageProvider {
/// ///
/// The image is obtained by calling [AssetBundle.load] on the given [bundle] /// The image is obtained by calling [AssetBundle.load] on the given [bundle]
/// using the key given by [keyName]. /// using the key given by [keyName].
final AssetBundle bundle; final AssetBundle? bundle;
/// The name of the package from which the image is included. See the /// The name of the package from which the image is included. See the
/// documentation for the [AssetImage] class itself for details. /// documentation for the [AssetImage] class itself for details.
final String package; final String? package;
// We assume the main asset is designed for a device pixel ratio of 1.0 // We assume the main asset is designed for a device pixel ratio of 1.0
static const double _naturalResolution = 1.0; static const double _naturalResolution = 1.0;
...@@ -171,16 +170,16 @@ class AssetImage extends AssetBundleImageProvider { ...@@ -171,16 +170,16 @@ class AssetImage extends AssetBundleImageProvider {
// that we resolve each future in a new call frame, and thus not in this // that we resolve each future in a new call frame, and thus not in this
// build/layout/paint sequence.) // build/layout/paint sequence.)
final AssetBundle chosenBundle = bundle ?? configuration.bundle ?? rootBundle; final AssetBundle chosenBundle = bundle ?? configuration.bundle ?? rootBundle;
Completer<AssetBundleImageKey> completer; Completer<AssetBundleImageKey>? completer;
Future<AssetBundleImageKey> result; Future<AssetBundleImageKey>? result;
chosenBundle.loadStructuredData<Map<String, List<String>>>(_kAssetManifestFileName, _manifestParser).then<void>( chosenBundle.loadStructuredData<Map<String, List<String>>?>(_kAssetManifestFileName, _manifestParser).then<void>(
(Map<String, List<String>> manifest) { (Map<String, List<String>>? manifest) {
final String chosenName = _chooseVariant( final String chosenName = _chooseVariant(
keyName, keyName,
configuration, configuration,
manifest == null ? null : manifest[keyName], manifest == null ? null : manifest[keyName],
); )!;
final double chosenScale = _parseScale(chosenName); final double chosenScale = _parseScale(chosenName);
final AssetBundleImageKey key = AssetBundleImageKey( final AssetBundleImageKey key = AssetBundleImageKey(
bundle: chosenBundle, bundle: chosenBundle,
...@@ -200,17 +199,17 @@ class AssetImage extends AssetBundleImageProvider { ...@@ -200,17 +199,17 @@ class AssetImage extends AssetBundleImageProvider {
result = SynchronousFuture<AssetBundleImageKey>(key); result = SynchronousFuture<AssetBundleImageKey>(key);
} }
} }
).catchError((dynamic error, StackTrace stack) { ).catchError((Object error, StackTrace stack) {
// We had an error. (This guarantees we weren't called synchronously.) // We had an error. (This guarantees we weren't called synchronously.)
// Forward the error to the caller. // Forward the error to the caller.
assert(completer != null); assert(completer != null);
assert(result == null); assert(result == null);
completer.completeError(error, stack); completer!.completeError(error, stack);
}); });
if (result != null) { if (result != null) {
// The code above ran synchronously, and came up with an answer. // The code above ran synchronously, and came up with an answer.
// Return the SynchronousFuture that we created above. // Return the SynchronousFuture that we created above.
return result; return result!;
} }
// The code above hasn't yet run its "then" handler yet. Let's prepare a // The code above hasn't yet run its "then" handler yet. Let's prepare a
// completer for it to use when it does run. // completer for it to use when it does run.
...@@ -218,9 +217,9 @@ class AssetImage extends AssetBundleImageProvider { ...@@ -218,9 +217,9 @@ class AssetImage extends AssetBundleImageProvider {
return completer.future; return completer.future;
} }
static Future<Map<String, List<String>>> _manifestParser(String jsonData) { static Future<Map<String, List<String>>?> _manifestParser(String? jsonData) {
if (jsonData == null) if (jsonData == null)
return SynchronousFuture<Map<String, List<String>>>(null); return SynchronousFuture<Map<String, List<String>>?>(null);
// TODO(ianh): JSON decoding really shouldn't be on the main thread. // TODO(ianh): JSON decoding really shouldn't be on the main thread.
final Map<String, dynamic> parsedJson = json.decode(jsonData) as Map<String, dynamic>; final Map<String, dynamic> parsedJson = json.decode(jsonData) as Map<String, dynamic>;
final Iterable<String> keys = parsedJson.keys; final Iterable<String> keys = parsedJson.keys;
...@@ -228,10 +227,10 @@ class AssetImage extends AssetBundleImageProvider { ...@@ -228,10 +227,10 @@ class AssetImage extends AssetBundleImageProvider {
Map<String, List<String>>.fromIterables(keys, Map<String, List<String>>.fromIterables(keys,
keys.map<List<String>>((String key) => List<String>.from(parsedJson[key] as List<dynamic>))); keys.map<List<String>>((String key) => List<String>.from(parsedJson[key] as List<dynamic>)));
// TODO(ianh): convert that data structure to the right types. // TODO(ianh): convert that data structure to the right types.
return SynchronousFuture<Map<String, List<String>>>(parsedManifest); return SynchronousFuture<Map<String, List<String>>?>(parsedManifest);
} }
String _chooseVariant(String main, ImageConfiguration config, List<String> candidates) { String? _chooseVariant(String main, ImageConfiguration config, List<String>? candidates) {
if (config.devicePixelRatio == null || candidates == null || candidates.isEmpty) if (config.devicePixelRatio == null || candidates == null || candidates.isEmpty)
return main; return main;
// TODO(ianh): Consider moving this parsing logic into _manifestParser. // TODO(ianh): Consider moving this parsing logic into _manifestParser.
...@@ -241,15 +240,15 @@ class AssetImage extends AssetBundleImageProvider { ...@@ -241,15 +240,15 @@ class AssetImage extends AssetBundleImageProvider {
// TODO(ianh): implement support for config.locale, config.textDirection, // TODO(ianh): implement support for config.locale, config.textDirection,
// config.size, config.platform (then document this over in the Image.asset // config.size, config.platform (then document this over in the Image.asset
// docs) // docs)
return _findNearest(mapping, config.devicePixelRatio); return _findNearest(mapping, config.devicePixelRatio!);
} }
// Return the value for the key in a [SplayTreeMap] nearest the provided key. // Return the value for the key in a [SplayTreeMap] nearest the provided key.
String _findNearest(SplayTreeMap<double, String> candidates, double value) { String? _findNearest(SplayTreeMap<double, String> candidates, double value) {
if (candidates.containsKey(value)) if (candidates.containsKey(value))
return candidates[value]; return candidates[value]!;
final double lower = candidates.lastKeyBefore(value); final double? lower = candidates.lastKeyBefore(value);
final double upper = candidates.firstKeyAfter(value); final double? upper = candidates.firstKeyAfter(value);
if (lower == null) if (lower == null)
return candidates[upper]; return candidates[upper];
if (upper == null) if (upper == null)
...@@ -273,9 +272,9 @@ class AssetImage extends AssetBundleImageProvider { ...@@ -273,9 +272,9 @@ class AssetImage extends AssetBundleImageProvider {
directoryPath = assetUri.pathSegments[assetUri.pathSegments.length - 2]; directoryPath = assetUri.pathSegments[assetUri.pathSegments.length - 2];
} }
final Match match = _extractRatioRegExp.firstMatch(directoryPath); final Match? match = _extractRatioRegExp.firstMatch(directoryPath);
if (match != null && match.groupCount > 0) if (match != null && match.groupCount > 0)
return double.parse(match.group(1)); return double.parse(match.group(1)!);
return _naturalResolution; // i.e. default to 1.0x return _naturalResolution; // i.e. default to 1.0x
} }
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data'; import 'dart:typed_data';
...@@ -22,7 +21,7 @@ class MatrixUtils { ...@@ -22,7 +21,7 @@ class MatrixUtils {
/// nothing but a 2D translation. /// nothing but a 2D translation.
/// ///
/// Otherwise, returns null. /// Otherwise, returns null.
static Offset getAsTranslation(Matrix4 transform) { static Offset? getAsTranslation(Matrix4 transform) {
assert(transform != null); assert(transform != null);
final Float64List values = transform.storage; final Float64List values = transform.storage;
// Values are stored in column-major order. // Values are stored in column-major order.
...@@ -49,7 +48,7 @@ class MatrixUtils { ...@@ -49,7 +48,7 @@ class MatrixUtils {
/// scale, if the matrix is nothing but a symmetric 2D scale transform. /// scale, if the matrix is nothing but a symmetric 2D scale transform.
/// ///
/// Otherwise, returns null. /// Otherwise, returns null.
static double getAsScale(Matrix4 transform) { static double? getAsScale(Matrix4 transform) {
assert(transform != null); assert(transform != null);
final Float64List values = transform.storage; final Float64List values = transform.storage;
// Values are stored in column-major order. // Values are stored in column-major order.
...@@ -75,12 +74,12 @@ class MatrixUtils { ...@@ -75,12 +74,12 @@ class MatrixUtils {
/// Returns true if the given matrices are exactly equal, and false /// Returns true if the given matrices are exactly equal, and false
/// otherwise. Null values are assumed to be the identity matrix. /// otherwise. Null values are assumed to be the identity matrix.
static bool matrixEquals(Matrix4 a, Matrix4 b) { static bool matrixEquals(Matrix4? a, Matrix4? b) {
if (identical(a, b)) if (identical(a, b))
return true; return true;
assert(a != null || b != null); assert(a != null || b != null);
if (a == null) if (a == null)
return isIdentity(b); return isIdentity(b!);
if (b == null) if (b == null)
return isIdentity(a); return isIdentity(a);
assert(a != null && b != null); assert(a != null && b != null);
...@@ -165,8 +164,6 @@ class MatrixUtils { ...@@ -165,8 +164,6 @@ class MatrixUtils {
storage[7] == 0.0 && storage[7] == 0.0 &&
storage[15] == 1.0; storage[15] == 1.0;
_minMax ??= Float64List(4);
_accumulate(storage, rect.left, rect.top, true, isAffine); _accumulate(storage, rect.left, rect.top, true, isAffine);
_accumulate(storage, rect.right, rect.top, false, isAffine); _accumulate(storage, rect.right, rect.top, false, isAffine);
_accumulate(storage, rect.left, rect.bottom, false, isAffine); _accumulate(storage, rect.left, rect.bottom, false, isAffine);
...@@ -175,7 +172,7 @@ class MatrixUtils { ...@@ -175,7 +172,7 @@ class MatrixUtils {
return Rect.fromLTRB(_minMax[0], _minMax[1], _minMax[2], _minMax[3]); return Rect.fromLTRB(_minMax[0], _minMax[1], _minMax[2], _minMax[3]);
} }
static Float64List _minMax; static late final Float64List _minMax = Float64List(4);
static void _accumulate(Float64List m, double x, double y, bool first, bool isAffine) { static void _accumulate(Float64List m, double x, double y, bool first, bool isAffine) {
final double w = isAffine ? 1.0 : 1.0 / (m[3] * x + m[7] * y + m[15]); final double w = isAffine ? 1.0 : 1.0 / (m[3] * x + m[7] * y + m[15]);
final double tx = (m[0] * x + m[4] * y + m[12]) * w; final double tx = (m[0] * x + m[4] * y + m[12]) * w;
...@@ -485,8 +482,8 @@ class MatrixUtils { ...@@ -485,8 +482,8 @@ class MatrixUtils {
/// almost always possible to end up seeing the inner side of the cylinder /// almost always possible to end up seeing the inner side of the cylinder
/// or the back side of the transformed plane before π / 2 when perspective > 0. /// or the back side of the transformed plane before π / 2 when perspective > 0.
static Matrix4 createCylindricalProjectionTransform({ static Matrix4 createCylindricalProjectionTransform({
@required double radius, required double radius,
@required double angle, required double angle,
double perspective = 0.001, double perspective = 0.001,
Axis orientation = Axis.vertical, Axis orientation = Axis.vertical,
}) { }) {
...@@ -541,7 +538,7 @@ class MatrixUtils { ...@@ -541,7 +538,7 @@ class MatrixUtils {
/// useful for [TransformProperty]. /// useful for [TransformProperty].
/// ///
/// If the argument is null, returns a list with the single string "null". /// If the argument is null, returns a list with the single string "null".
List<String> debugDescribeTransform(Matrix4 transform) { List<String> debugDescribeTransform(Matrix4? transform) {
if (transform == null) if (transform == null)
return const <String>['null']; return const <String>['null'];
return <String>[ return <String>[
...@@ -559,9 +556,9 @@ class TransformProperty extends DiagnosticsProperty<Matrix4> { ...@@ -559,9 +556,9 @@ class TransformProperty extends DiagnosticsProperty<Matrix4> {
/// The [showName] and [level] arguments must not be null. /// The [showName] and [level] arguments must not be null.
TransformProperty( TransformProperty(
String name, String name,
Matrix4 value, { Matrix4? value, {
bool showName = true, bool showName = true,
Object defaultValue = kNoDefaultValue, Object? defaultValue = kNoDefaultValue,
DiagnosticLevel level = DiagnosticLevel.info, DiagnosticLevel level = DiagnosticLevel.info,
}) : assert(showName != null), }) : assert(showName != null),
assert(level != null), assert(level != null),
...@@ -574,15 +571,15 @@ class TransformProperty extends DiagnosticsProperty<Matrix4> { ...@@ -574,15 +571,15 @@ class TransformProperty extends DiagnosticsProperty<Matrix4> {
); );
@override @override
String valueToString({ TextTreeConfiguration parentConfiguration }) { String valueToString({ TextTreeConfiguration? parentConfiguration }) {
if (parentConfiguration != null && !parentConfiguration.lineBreakProperties) { if (parentConfiguration != null && !parentConfiguration.lineBreakProperties) {
// Format the value on a single line to be compatible with the parent's // Format the value on a single line to be compatible with the parent's
// style. // style.
final List<String> values = <String>[ final List<String> values = <String>[
'${debugFormatDouble(value.entry(0, 0))},${debugFormatDouble(value.entry(0, 1))},${debugFormatDouble(value.entry(0, 2))},${debugFormatDouble(value.entry(0, 3))}', '${debugFormatDouble(value!.entry(0, 0))},${debugFormatDouble(value!.entry(0, 1))},${debugFormatDouble(value!.entry(0, 2))},${debugFormatDouble(value!.entry(0, 3))}',
'${debugFormatDouble(value.entry(1, 0))},${debugFormatDouble(value.entry(1, 1))},${debugFormatDouble(value.entry(1, 2))},${debugFormatDouble(value.entry(1, 3))}', '${debugFormatDouble(value!.entry(1, 0))},${debugFormatDouble(value!.entry(1, 1))},${debugFormatDouble(value!.entry(1, 2))},${debugFormatDouble(value!.entry(1, 3))}',
'${debugFormatDouble(value.entry(2, 0))},${debugFormatDouble(value.entry(2, 1))},${debugFormatDouble(value.entry(2, 2))},${debugFormatDouble(value.entry(2, 3))}', '${debugFormatDouble(value!.entry(2, 0))},${debugFormatDouble(value!.entry(2, 1))},${debugFormatDouble(value!.entry(2, 2))},${debugFormatDouble(value!.entry(2, 3))}',
'${debugFormatDouble(value.entry(3, 0))},${debugFormatDouble(value.entry(3, 1))},${debugFormatDouble(value.entry(3, 2))},${debugFormatDouble(value.entry(3, 3))}', '${debugFormatDouble(value!.entry(3, 0))},${debugFormatDouble(value!.entry(3, 1))},${debugFormatDouble(value!.entry(3, 2))},${debugFormatDouble(value!.entry(3, 3))}',
]; ];
return '[${values.join('; ')}]'; return '[${values.join('; ')}]';
} }
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:ui' as ui show lerpDouble; import 'dart:ui' as ui show lerpDouble;
...@@ -54,12 +53,12 @@ class RoundedRectangleBorder extends OutlinedBorder { ...@@ -54,12 +53,12 @@ class RoundedRectangleBorder extends OutlinedBorder {
} }
@override @override
ShapeBorder lerpFrom(ShapeBorder a, double t) { ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
assert(t != null); assert(t != null);
if (a is RoundedRectangleBorder) { if (a is RoundedRectangleBorder) {
return RoundedRectangleBorder( return RoundedRectangleBorder(
side: BorderSide.lerp(a.side, side, t), side: BorderSide.lerp(a.side, side, t),
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t)!,
); );
} }
if (a is CircleBorder) { if (a is CircleBorder) {
...@@ -73,12 +72,12 @@ class RoundedRectangleBorder extends OutlinedBorder { ...@@ -73,12 +72,12 @@ class RoundedRectangleBorder extends OutlinedBorder {
} }
@override @override
ShapeBorder lerpTo(ShapeBorder b, double t) { ShapeBorder? lerpTo(ShapeBorder? b, double t) {
assert(t != null); assert(t != null);
if (b is RoundedRectangleBorder) { if (b is RoundedRectangleBorder) {
return RoundedRectangleBorder( return RoundedRectangleBorder(
side: BorderSide.lerp(side, b.side, t), side: BorderSide.lerp(side, b.side, t),
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t)!,
); );
} }
if (b is CircleBorder) { if (b is CircleBorder) {
...@@ -94,7 +93,7 @@ class RoundedRectangleBorder extends OutlinedBorder { ...@@ -94,7 +93,7 @@ class RoundedRectangleBorder extends OutlinedBorder {
/// Returns a copy of this RoundedRectangleBorder with the given fields /// Returns a copy of this RoundedRectangleBorder with the given fields
/// replaced with the new values. /// replaced with the new values.
@override @override
RoundedRectangleBorder copyWith({ BorderSide side, BorderRadius borderRadius }) { RoundedRectangleBorder copyWith({ BorderSide? side, BorderRadius? borderRadius }) {
return RoundedRectangleBorder( return RoundedRectangleBorder(
side: side ?? this.side, side: side ?? this.side,
borderRadius: borderRadius ?? this.borderRadius, borderRadius: borderRadius ?? this.borderRadius,
...@@ -102,19 +101,19 @@ class RoundedRectangleBorder extends OutlinedBorder { ...@@ -102,19 +101,19 @@ class RoundedRectangleBorder extends OutlinedBorder {
} }
@override @override
Path getInnerPath(Rect rect, { TextDirection textDirection }) { Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
return Path() return Path()
..addRRect(borderRadius.resolve(textDirection).toRRect(rect).deflate(side.width)); ..addRRect(borderRadius.resolve(textDirection).toRRect(rect).deflate(side.width));
} }
@override @override
Path getOuterPath(Rect rect, { TextDirection textDirection }) { Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
return Path() return Path()
..addRRect(borderRadius.resolve(textDirection).toRRect(rect)); ..addRRect(borderRadius.resolve(textDirection).toRRect(rect));
} }
@override @override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) { void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
switch (side.style) { switch (side.style) {
case BorderStyle.none: case BorderStyle.none:
break; break;
...@@ -154,7 +153,7 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder { ...@@ -154,7 +153,7 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
const _RoundedRectangleToCircleBorder({ const _RoundedRectangleToCircleBorder({
BorderSide side = BorderSide.none, BorderSide side = BorderSide.none,
this.borderRadius = BorderRadius.zero, this.borderRadius = BorderRadius.zero,
@required this.circleness, required this.circleness,
}) : assert(side != null), }) : assert(side != null),
assert(borderRadius != null), assert(borderRadius != null),
assert(circleness != null), assert(circleness != null),
...@@ -179,12 +178,12 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder { ...@@ -179,12 +178,12 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
} }
@override @override
ShapeBorder lerpFrom(ShapeBorder a, double t) { ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
assert(t != null); assert(t != null);
if (a is RoundedRectangleBorder) { if (a is RoundedRectangleBorder) {
return _RoundedRectangleToCircleBorder( return _RoundedRectangleToCircleBorder(
side: BorderSide.lerp(a.side, side, t), side: BorderSide.lerp(a.side, side, t),
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t)!,
circleness: circleness * t, circleness: circleness * t,
); );
} }
...@@ -198,19 +197,19 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder { ...@@ -198,19 +197,19 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
if (a is _RoundedRectangleToCircleBorder) { if (a is _RoundedRectangleToCircleBorder) {
return _RoundedRectangleToCircleBorder( return _RoundedRectangleToCircleBorder(
side: BorderSide.lerp(a.side, side, t), side: BorderSide.lerp(a.side, side, t),
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t)!,
circleness: ui.lerpDouble(a.circleness, circleness, t), circleness: ui.lerpDouble(a.circleness, circleness, t)!,
); );
} }
return super.lerpFrom(a, t); return super.lerpFrom(a, t);
} }
@override @override
ShapeBorder lerpTo(ShapeBorder b, double t) { ShapeBorder? lerpTo(ShapeBorder? b, double t) {
if (b is RoundedRectangleBorder) { if (b is RoundedRectangleBorder) {
return _RoundedRectangleToCircleBorder( return _RoundedRectangleToCircleBorder(
side: BorderSide.lerp(side, b.side, t), side: BorderSide.lerp(side, b.side, t),
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t)!,
circleness: circleness * (1.0 - t), circleness: circleness * (1.0 - t),
); );
} }
...@@ -224,8 +223,8 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder { ...@@ -224,8 +223,8 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
if (b is _RoundedRectangleToCircleBorder) { if (b is _RoundedRectangleToCircleBorder) {
return _RoundedRectangleToCircleBorder( return _RoundedRectangleToCircleBorder(
side: BorderSide.lerp(side, b.side, t), side: BorderSide.lerp(side, b.side, t),
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t), borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t)!,
circleness: ui.lerpDouble(circleness, b.circleness, t), circleness: ui.lerpDouble(circleness, b.circleness, t)!,
); );
} }
return super.lerpTo(b, t); return super.lerpTo(b, t);
...@@ -253,7 +252,7 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder { ...@@ -253,7 +252,7 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
} }
} }
BorderRadius _adjustBorderRadius(Rect rect, TextDirection textDirection) { BorderRadius? _adjustBorderRadius(Rect rect, TextDirection? textDirection) {
final BorderRadius resolvedRadius = borderRadius.resolve(textDirection); final BorderRadius resolvedRadius = borderRadius.resolve(textDirection);
if (circleness == 0.0) if (circleness == 0.0)
return resolvedRadius; return resolvedRadius;
...@@ -261,19 +260,19 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder { ...@@ -261,19 +260,19 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
} }
@override @override
Path getInnerPath(Rect rect, { TextDirection textDirection }) { Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
return Path() return Path()
..addRRect(_adjustBorderRadius(rect, textDirection).toRRect(_adjustRect(rect)).deflate(side.width)); ..addRRect(_adjustBorderRadius(rect, textDirection)!.toRRect(_adjustRect(rect)).deflate(side.width));
} }
@override @override
Path getOuterPath(Rect rect, { TextDirection textDirection }) { Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
return Path() return Path()
..addRRect(_adjustBorderRadius(rect, textDirection).toRRect(_adjustRect(rect))); ..addRRect(_adjustBorderRadius(rect, textDirection)!.toRRect(_adjustRect(rect)));
} }
@override @override
_RoundedRectangleToCircleBorder copyWith({ BorderSide side, BorderRadius borderRadius, double circleness }) { _RoundedRectangleToCircleBorder copyWith({ BorderSide? side, BorderRadius? borderRadius, double? circleness }) {
return _RoundedRectangleToCircleBorder( return _RoundedRectangleToCircleBorder(
side: side ?? this.side, side: side ?? this.side,
borderRadius: borderRadius ?? this.borderRadius, borderRadius: borderRadius ?? this.borderRadius,
...@@ -282,16 +281,16 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder { ...@@ -282,16 +281,16 @@ class _RoundedRectangleToCircleBorder extends OutlinedBorder {
} }
@override @override
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) { void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
switch (side.style) { switch (side.style) {
case BorderStyle.none: case BorderStyle.none:
break; break;
case BorderStyle.solid: case BorderStyle.solid:
final double width = side.width; final double width = side.width;
if (width == 0.0) { if (width == 0.0) {
canvas.drawRRect(_adjustBorderRadius(rect, textDirection).toRRect(_adjustRect(rect)), side.toPaint()); canvas.drawRRect(_adjustBorderRadius(rect, textDirection)!.toRRect(_adjustRect(rect)), side.toPaint());
} else { } else {
final RRect outer = _adjustBorderRadius(rect, textDirection).toRRect(_adjustRect(rect)); final RRect outer = _adjustBorderRadius(rect, textDirection)!.toRRect(_adjustRect(rect));
final RRect inner = outer.deflate(width); final RRect inner = outer.deflate(width);
final Paint paint = Paint() final Paint paint = Paint()
..color = side.color; ..color = side.color;
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -77,7 +76,7 @@ class ShapeDecoration extends Decoration { ...@@ -77,7 +76,7 @@ class ShapeDecoration extends Decoration {
this.image, this.image,
this.gradient, this.gradient,
this.shadows, this.shadows,
@required this.shape, required this.shape,
}) : assert(!(color != null && gradient != null)), }) : assert(!(color != null && gradient != null)),
assert(shape != null); assert(shape != null);
...@@ -97,18 +96,18 @@ class ShapeDecoration extends Decoration { ...@@ -97,18 +96,18 @@ class ShapeDecoration extends Decoration {
switch (source.shape) { switch (source.shape) {
case BoxShape.circle: case BoxShape.circle:
if (source.border != null) { if (source.border != null) {
assert(source.border.isUniform); assert(source.border!.isUniform);
shape = CircleBorder(side: source.border.top); shape = CircleBorder(side: source.border!.top);
} else { } else {
shape = const CircleBorder(); shape = const CircleBorder();
} }
break; break;
case BoxShape.rectangle: case BoxShape.rectangle:
if (source.borderRadius != null) { if (source.borderRadius != null) {
assert(source.border == null || source.border.isUniform); assert(source.border == null || source.border!.isUniform);
shape = RoundedRectangleBorder( shape = RoundedRectangleBorder(
side: source.border?.top ?? BorderSide.none, side: source.border?.top ?? BorderSide.none,
borderRadius: source.borderRadius, borderRadius: source.borderRadius!,
); );
} else { } else {
shape = source.border ?? const Border(); shape = source.border ?? const Border();
...@@ -134,19 +133,19 @@ class ShapeDecoration extends Decoration { ...@@ -134,19 +133,19 @@ class ShapeDecoration extends Decoration {
/// The color is under the [image]. /// The color is under the [image].
/// ///
/// If a [gradient] is specified, [color] must be null. /// If a [gradient] is specified, [color] must be null.
final Color color; final Color? color;
/// A gradient to use when filling the shape. /// A gradient to use when filling the shape.
/// ///
/// The gradient is under the [image]. /// The gradient is under the [image].
/// ///
/// If a [color] is specified, [gradient] must be null. /// If a [color] is specified, [gradient] must be null.
final Gradient gradient; final Gradient? gradient;
/// An image to paint inside the shape (clipped to its outline). /// An image to paint inside the shape (clipped to its outline).
/// ///
/// The image is drawn over the [color] or [gradient]. /// The image is drawn over the [color] or [gradient].
final DecorationImage image; final DecorationImage? image;
/// A list of shadows cast by the [shape]. /// A list of shadows cast by the [shape].
/// ///
...@@ -155,7 +154,7 @@ class ShapeDecoration extends Decoration { ...@@ -155,7 +154,7 @@ class ShapeDecoration extends Decoration {
/// * [kElevationToShadow], for some predefined shadows used in Material /// * [kElevationToShadow], for some predefined shadows used in Material
/// Design. /// Design.
/// * [PhysicalModel], a widget for showing shadows. /// * [PhysicalModel], a widget for showing shadows.
final List<BoxShadow> shadows; final List<BoxShadow>? shadows;
/// The shape to fill the [color], [gradient], and [image] into and to cast as /// The shape to fill the [color], [gradient], and [image] into and to cast as
/// the [shadows]. /// the [shadows].
...@@ -191,23 +190,23 @@ class ShapeDecoration extends Decoration { ...@@ -191,23 +190,23 @@ class ShapeDecoration extends Decoration {
bool get isComplex => shadows != null; bool get isComplex => shadows != null;
@override @override
ShapeDecoration lerpFrom(Decoration a, double t) { ShapeDecoration? lerpFrom(Decoration? a, double t) {
if (a is BoxDecoration) { if (a is BoxDecoration) {
return ShapeDecoration.lerp(ShapeDecoration.fromBoxDecoration(a), this, t); return ShapeDecoration.lerp(ShapeDecoration.fromBoxDecoration(a), this, t);
} else if (a == null || a is ShapeDecoration) { } else if (a == null || a is ShapeDecoration) {
return ShapeDecoration.lerp(a as ShapeDecoration, this, t); return ShapeDecoration.lerp(a as ShapeDecoration, this, t);
} }
return super.lerpFrom(a, t) as ShapeDecoration; return super.lerpFrom(a, t) as ShapeDecoration?;
} }
@override @override
ShapeDecoration lerpTo(Decoration b, double t) { ShapeDecoration? lerpTo(Decoration? b, double t) {
if (b is BoxDecoration) { if (b is BoxDecoration) {
return ShapeDecoration.lerp(this, ShapeDecoration.fromBoxDecoration(b), t); return ShapeDecoration.lerp(this, ShapeDecoration.fromBoxDecoration(b), t);
} else if (b == null || b is ShapeDecoration) { } else if (b == null || b is ShapeDecoration) {
return ShapeDecoration.lerp(this, b as ShapeDecoration, t); return ShapeDecoration.lerp(this, b as ShapeDecoration, t);
} }
return super.lerpTo(b, t) as ShapeDecoration; return super.lerpTo(b, t) as ShapeDecoration?;
} }
/// Linearly interpolate between two shapes. /// Linearly interpolate between two shapes.
...@@ -228,7 +227,7 @@ class ShapeDecoration extends Decoration { ...@@ -228,7 +227,7 @@ class ShapeDecoration extends Decoration {
/// * [lerpFrom] and [lerpTo], which are used to implement [Decoration.lerp] /// * [lerpFrom] and [lerpTo], which are used to implement [Decoration.lerp]
/// and which use [ShapeDecoration.lerp] when interpolating two /// and which use [ShapeDecoration.lerp] when interpolating two
/// [ShapeDecoration]s or a [ShapeDecoration] to or from null. /// [ShapeDecoration]s or a [ShapeDecoration] to or from null.
static ShapeDecoration lerp(ShapeDecoration a, ShapeDecoration b, double t) { static ShapeDecoration? lerp(ShapeDecoration? a, ShapeDecoration? b, double t) {
assert(t != null); assert(t != null);
if (a == null && b == null) if (a == null && b == null)
return null; return null;
...@@ -241,9 +240,9 @@ class ShapeDecoration extends Decoration { ...@@ -241,9 +240,9 @@ class ShapeDecoration extends Decoration {
return ShapeDecoration( return ShapeDecoration(
color: Color.lerp(a?.color, b?.color, t), color: Color.lerp(a?.color, b?.color, t),
gradient: Gradient.lerp(a?.gradient, b?.gradient, t), gradient: Gradient.lerp(a?.gradient, b?.gradient, t),
image: t < 0.5 ? a.image : b.image, // TODO(ianh): cross-fade the image image: t < 0.5 ? a!.image : b!.image, // TODO(ianh): cross-fade the image
shadows: BoxShadow.lerpList(a?.shadows, b?.shadows, t), shadows: BoxShadow.lerpList(a?.shadows, b?.shadows, t),
shape: ShapeBorder.lerp(a?.shape, b?.shape, t), shape: ShapeBorder.lerp(a?.shape, b?.shape, t)!,
); );
} }
...@@ -284,14 +283,14 @@ class ShapeDecoration extends Decoration { ...@@ -284,14 +283,14 @@ class ShapeDecoration extends Decoration {
} }
@override @override
bool hitTest(Size size, Offset position, { TextDirection textDirection }) { bool hitTest(Size size, Offset position, { TextDirection? textDirection }) {
return shape.getOuterPath(Offset.zero & size, textDirection: textDirection).contains(position); return shape.getOuterPath(Offset.zero & size, textDirection: textDirection).contains(position);
} }
@override @override
_ShapeDecorationPainter createBoxPainter([ VoidCallback onChanged ]) { _ShapeDecorationPainter createBoxPainter([ VoidCallback? onChanged ]) {
assert(onChanged != null || image == null); assert(onChanged != null || image == null);
return _ShapeDecorationPainter(this, onChanged); return _ShapeDecorationPainter(this, onChanged!);
} }
} }
...@@ -303,16 +302,19 @@ class _ShapeDecorationPainter extends BoxPainter { ...@@ -303,16 +302,19 @@ class _ShapeDecorationPainter extends BoxPainter {
final ShapeDecoration _decoration; final ShapeDecoration _decoration;
Rect _lastRect; Rect? _lastRect;
TextDirection _lastTextDirection; TextDirection? _lastTextDirection;
Path _outerPath; late Path _outerPath;
Path _innerPath; Path? _innerPath;
Paint _interiorPaint; Paint? _interiorPaint;
int _shadowCount; int? _shadowCount;
List<Path> _shadowPaths; late List<Path> _shadowPaths;
List<Paint> _shadowPaints; late List<Paint> _shadowPaints;
void _precache(Rect rect, TextDirection textDirection) { @override
VoidCallback get onChanged => super.onChanged!;
void _precache(Rect rect, TextDirection? textDirection) {
assert(rect != null); assert(rect != null);
if (rect == _lastRect && textDirection == _lastTextDirection) if (rect == _lastRect && textDirection == _lastTextDirection)
return; return;
...@@ -324,22 +326,22 @@ class _ShapeDecorationPainter extends BoxPainter { ...@@ -324,22 +326,22 @@ class _ShapeDecorationPainter extends BoxPainter {
if (_interiorPaint == null && (_decoration.color != null || _decoration.gradient != null)) { if (_interiorPaint == null && (_decoration.color != null || _decoration.gradient != null)) {
_interiorPaint = Paint(); _interiorPaint = Paint();
if (_decoration.color != null) if (_decoration.color != null)
_interiorPaint.color = _decoration.color; _interiorPaint!.color = _decoration.color!;
} }
if (_decoration.gradient != null) if (_decoration.gradient != null)
_interiorPaint.shader = _decoration.gradient.createShader(rect); _interiorPaint!.shader = _decoration.gradient!.createShader(rect);
if (_decoration.shadows != null) { if (_decoration.shadows != null) {
if (_shadowCount == null) { if (_shadowCount == null) {
_shadowCount = _decoration.shadows.length; _shadowCount = _decoration.shadows!.length;
_shadowPaths = List<Path>(_shadowCount); _shadowPaints = <Paint>[
_shadowPaints = List<Paint>(_shadowCount); ..._decoration.shadows!.map((BoxShadow shadow) => shadow.toPaint()),
for (int index = 0; index < _shadowCount; index += 1) ];
_shadowPaints[index] = _decoration.shadows[index].toPaint();
}
for (int index = 0; index < _shadowCount; index += 1) {
final BoxShadow shadow = _decoration.shadows[index];
_shadowPaths[index] = _decoration.shape.getOuterPath(rect.shift(shadow.offset).inflate(shadow.spreadRadius), textDirection: textDirection);
} }
_shadowPaths = <Path>[
..._decoration.shadows!.map((BoxShadow shadow) {
return _decoration.shape.getOuterPath(rect.shift(shadow.offset).inflate(shadow.spreadRadius), textDirection: textDirection);
}),
];
} }
if (_interiorPaint != null || _shadowCount != null) if (_interiorPaint != null || _shadowCount != null)
_outerPath = _decoration.shape.getOuterPath(rect, textDirection: textDirection); _outerPath = _decoration.shape.getOuterPath(rect, textDirection: textDirection);
...@@ -352,22 +354,22 @@ class _ShapeDecorationPainter extends BoxPainter { ...@@ -352,22 +354,22 @@ class _ShapeDecorationPainter extends BoxPainter {
void _paintShadows(Canvas canvas) { void _paintShadows(Canvas canvas) {
if (_shadowCount != null) { if (_shadowCount != null) {
for (int index = 0; index < _shadowCount; index += 1) for (int index = 0; index < _shadowCount!; index += 1)
canvas.drawPath(_shadowPaths[index], _shadowPaints[index]); canvas.drawPath(_shadowPaths[index], _shadowPaints[index]);
} }
} }
void _paintInterior(Canvas canvas) { void _paintInterior(Canvas canvas) {
if (_interiorPaint != null) if (_interiorPaint != null)
canvas.drawPath(_outerPath, _interiorPaint); canvas.drawPath(_outerPath, _interiorPaint!);
} }
DecorationImagePainter _imagePainter; DecorationImagePainter? _imagePainter;
void _paintImage(Canvas canvas, ImageConfiguration configuration) { void _paintImage(Canvas canvas, ImageConfiguration configuration) {
if (_decoration.image == null) if (_decoration.image == null)
return; return;
_imagePainter ??= _decoration.image.createPainter(onChanged); _imagePainter ??= _decoration.image!.createPainter(onChanged);
_imagePainter.paint(canvas, _lastRect, _innerPath, configuration); _imagePainter!.paint(canvas, _lastRect!, _innerPath, configuration);
} }
@override @override
...@@ -380,8 +382,8 @@ class _ShapeDecorationPainter extends BoxPainter { ...@@ -380,8 +382,8 @@ class _ShapeDecorationPainter extends BoxPainter {
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
assert(configuration != null); assert(configuration != null);
assert(configuration.size != null); assert(configuration.size != null);
final Rect rect = offset & configuration.size; final Rect rect = offset & configuration.size!;
final TextDirection textDirection = configuration.textDirection; final TextDirection? textDirection = configuration.textDirection;
_precache(rect, textDirection); _precache(rect, textDirection);
_paintShadows(canvas); _paintShadows(canvas);
_paintInterior(canvas); _paintInterior(canvas);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment