diff --git a/analysis_options.yaml b/analysis_options.yaml index b60ac5b8..ae848fce 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -20,6 +20,7 @@ analyzer: strong-mode: + implicit-casts: false implicit-dynamic: false errors: # treat missing required parameters as a warning (not a hint) @@ -43,7 +44,7 @@ linter: - always_specify_types - annotate_overrides # - avoid_annotating_with_dynamic # conflicts with always_specify_types - - avoid_as + # - avoid_as # conflicts with implicit-casts: false # - avoid_bool_literals_in_conditional_expressions # not yet tested # - avoid_catches_without_on_clauses # we do this commonly # - avoid_catching_errors # we do this commonly diff --git a/lib/avd.dart b/lib/avd.dart index 068b2e16..dbc32d50 100644 --- a/lib/avd.dart +++ b/lib/avd.dart @@ -21,7 +21,7 @@ final Avd avd = Avd._(); class Avd { Avd._(); - FutureOr avdPictureDecoder( + Future avdPictureDecoder( Uint8List raw, bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, @@ -33,7 +33,7 @@ class Avd { return PictureInfo(picture: pic, viewport: avdRoot.viewport.viewBoxRect); } - FutureOr avdPictureStringDecoder( + Future avdPictureStringDecoder( String raw, bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, @@ -49,7 +49,7 @@ class Avd { ); } - FutureOr fromAvdBytes(Uint8List raw, String key) async { + Future fromAvdBytes(Uint8List raw, String key) async { // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. // See: https://github.com/dart-lang/sdk/issues/31954 diff --git a/lib/src/picture_provider.dart b/lib/src/picture_provider.dart index 20d2e626..853d95a7 100644 --- a/lib/src/picture_provider.dart +++ b/lib/src/picture_provider.dart @@ -87,7 +87,7 @@ class PictureConfiguration { Locale locale, TextDirection textDirection, Rect viewBox, - String platform, + TargetPlatform platform, ColorFilter colorFilter, }) { return PictureConfiguration( @@ -132,13 +132,13 @@ class PictureConfiguration { if (other.runtimeType != runtimeType) { return false; } - final PictureConfiguration typedOther = other; - return typedOther.bundle == bundle && - typedOther.locale == locale && - typedOther.textDirection == textDirection && - typedOther.viewBox == viewBox && - typedOther.platform == platform && - typedOther.colorFilter == colorFilter; + return other is PictureConfiguration && + other.bundle == bundle && + other.locale == locale && + other.textDirection == textDirection && + other.viewBox == viewBox && + other.platform == platform && + other.colorFilter == colorFilter; } @override @@ -399,10 +399,10 @@ class AssetBundlePictureKey { if (other.runtimeType != runtimeType) { return false; } - final AssetBundlePictureKey typedOther = other; - return bundle == typedOther.bundle && - name == typedOther.name && - colorFilter == typedOther.colorFilter; + return other is AssetBundlePictureKey && + bundle == other.bundle && + name == other.name && + colorFilter == other.colorFilter; } @override @@ -516,8 +516,9 @@ class NetworkPicture extends PictureProvider { if (other.runtimeType != runtimeType) { return false; } - final NetworkPicture typedOther = other; - return url == typedOther.url && colorFilter == typedOther.colorFilter; + return other is NetworkPicture && + url == other.url && + colorFilter == other.colorFilter; } @override @@ -583,9 +584,9 @@ class FilePicture extends PictureProvider { if (other.runtimeType != runtimeType) { return false; } - final FilePicture typedOther = other; - return file?.path == typedOther.file?.path && - typedOther.colorFilter == colorFilter; + return other is FilePicture && + file?.path == other.file?.path && + other.colorFilter == colorFilter; } @override @@ -649,8 +650,9 @@ class MemoryPicture extends PictureProvider { if (other.runtimeType != runtimeType) { return false; } - final MemoryPicture typedOther = other; - return bytes == typedOther.bytes && colorFilter == typedOther.colorFilter; + return other is MemoryPicture && + bytes == other.bytes && + colorFilter == other.colorFilter; } @override @@ -715,8 +717,9 @@ class StringPicture extends PictureProvider { if (other.runtimeType != runtimeType) { return false; } - final StringPicture typedOther = other; - return string == typedOther.string && colorFilter == typedOther.colorFilter; + return other is StringPicture && + string == other.string && + colorFilter == other.colorFilter; } @override @@ -858,10 +861,10 @@ class ExactAssetPicture extends AssetBundlePictureProvider { if (other.runtimeType != runtimeType) { return false; } - final ExactAssetPicture typedOther = other; - return keyName == typedOther.keyName && - bundle == typedOther.bundle && - colorFilter == typedOther.colorFilter; + return other is ExactAssetPicture && + keyName == other.keyName && + bundle == other.bundle && + colorFilter == other.colorFilter; } @override diff --git a/lib/src/picture_stream.dart b/lib/src/picture_stream.dart index 7dffdbcb..b580b533 100644 --- a/lib/src/picture_stream.dart +++ b/lib/src/picture_stream.dart @@ -50,10 +50,10 @@ class PictureInfo { if (other.runtimeType != runtimeType) { return false; } - final PictureInfo typedOther = other; - return typedOther.picture == picture && - typedOther.viewport == viewport && - typedOther.size == size; + return other is PictureInfo && + other.picture == picture && + other.viewport == viewport && + other.size == size; } } @@ -253,7 +253,7 @@ abstract class PictureStreamCompleter extends Diagnosticable { DiagnosticsNode context, dynamic exception, dynamic stack) { FlutterError.reportError(FlutterErrorDetails( exception: exception, - stack: stack, + stack: stack as StackTrace, library: 'SVG', context: context, )); diff --git a/lib/src/render_picture.dart b/lib/src/render_picture.dart index c06daa0a..f428c332 100644 --- a/lib/src/render_picture.dart +++ b/lib/src/render_picture.dart @@ -208,7 +208,12 @@ void scaleCanvasToViewBox( desiredSize.width / viewBox.width, desiredSize.height / viewBox.height, ); - final Offset shift = desiredSize / 2.0 - viewBox.size * scale / 2.0; + final Size scaledHalfViewBoxSize = viewBox.size * scale / 2.0; + final Size halfDesiredSize = desiredSize / 2.0; + final Offset shift = Offset( + halfDesiredSize.width - scaledHalfViewBoxSize.width, + halfDesiredSize.height - scaledHalfViewBoxSize.height, + ); canvas.translate(shift.dx, shift.dy); canvas.scale(scale, scale); } diff --git a/lib/src/svg/parsers.dart b/lib/src/svg/parsers.dart index cb600a0e..e93e383e 100644 --- a/lib/src/svg/parsers.dart +++ b/lib/src/svg/parsers.dart @@ -200,7 +200,8 @@ Future resolveImage(String href) async { return null; } - final Function decodeImage = (Uint8List bytes) async { + final Future Function(Uint8List) decodeImage = + (Uint8List bytes) async { final Codec codec = await instantiateImageCodec(bytes); final FrameInfo frame = await codec.getNextFrame(); return frame.image; diff --git a/lib/src/svg/xml_parsers.dart b/lib/src/svg/xml_parsers.dart index f3314154..ba13ad5b 100644 --- a/lib/src/svg/xml_parsers.dart +++ b/lib/src/svg/xml_parsers.dart @@ -147,7 +147,7 @@ DashOffset parseDashOffset(List attributes) { double parseOpacity(List attributes) { final String rawOpacity = getAttribute(attributes, 'opacity', def: null); if (rawOpacity != null) { - return parseDouble(rawOpacity).clamp(0.0, 1.0); + return parseDouble(rawOpacity).clamp(0.0, 1.0).toDouble(); } return null; } @@ -181,7 +181,7 @@ DrawablePaint parseStroke( def: '1.0', ); final String rawOpacity = getAttribute(attributes, 'opacity'); - double opacity = parseDouble(rawStrokeOpacity).clamp(0.0, 1.0); + double opacity = parseDouble(rawStrokeOpacity).clamp(0.0, 1.0).toDouble(); if (rawOpacity != '') { opacity *= parseDouble(rawOpacity).clamp(0.0, 1.0); } @@ -244,7 +244,7 @@ DrawablePaint parseFill( final String rawFill = getAttribute(el, 'fill'); final String rawFillOpacity = getAttribute(el, 'fill-opacity', def: '1.0'); final String rawOpacity = getAttribute(el, 'opacity'); - double opacity = parseDouble(rawFillOpacity).clamp(0.0, 1.0); + double opacity = parseDouble(rawFillOpacity).clamp(0.0, 1.0).toDouble(); if (rawOpacity != '') { opacity *= parseDouble(rawOpacity).clamp(0.0, 1.0); } diff --git a/lib/src/vector_drawable.dart b/lib/src/vector_drawable.dart index a811b684..41465b52 100644 --- a/lib/src/vector_drawable.dart +++ b/lib/src/vector_drawable.dart @@ -604,7 +604,7 @@ class DrawableDefinitionServer { /// Retreive a gradient from the pre-defined [DrawableGradient] collection. T getGradient(String id) { assert(id != null); - return _gradients[id]; + return _gradients[id] as T; } /// Add a [DrawableGradient] to the pre-defined collection by [id]. @@ -1108,7 +1108,12 @@ class DrawableRasterImage implements Drawable { ); } if (scale != 1.0 || offset != Offset.zero || transform != null) { - final Offset shift = desiredSize / 2.0 - imageSize * scale / 2.0; + final Size halfDesiredSize = desiredSize / 2.0; + final Size scaledHalfImageSize = imageSize * scale / 2.0; + final Offset shift = Offset( + halfDesiredSize.width - scaledHalfImageSize.width, + halfDesiredSize.height - scaledHalfImageSize.height, + ); canvas.save(); canvas.translate(offset.dx + shift.dx, offset.dy + shift.dy); canvas.scale(scale, scale); diff --git a/lib/svg.dart b/lib/svg.dart index 88adb6cd..0b72b74b 100644 --- a/lib/svg.dart +++ b/lib/svg.dart @@ -36,7 +36,7 @@ class Svg { /// The `colorFilter` property will be applied to any [Paint] objects used during drawing. /// /// The [key] will be used for debugging purposes. - FutureOr svgPictureDecoder( + Future svgPictureDecoder( Uint8List raw, bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, @@ -64,7 +64,7 @@ class Svg { /// The `colorFilter` property will be applied to any [Paint] objects used during drawing. /// /// The [key] will be used for debugging purposes. - FutureOr svgPictureStringDecoder( + Future svgPictureStringDecoder( String raw, bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, @@ -84,7 +84,7 @@ class Svg { /// Produces a [Drawableroot] from a [Uint8List] of SVG byte data (assumes UTF8 encoding). /// /// The [key] will be used for debugging purposes. - FutureOr fromSvgBytes(Uint8List raw, String key) async { + Future fromSvgBytes(Uint8List raw, String key) async { // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. // See: https://github.com/dart-lang/sdk/issues/31954 diff --git a/test/widget_svg_test.dart b/test/widget_svg_test.dart index 45e993da..4e448a62 100644 --- a/test/widget_svg_test.dart +++ b/test/widget_svg_test.dart @@ -61,7 +61,7 @@ void main() { '''; - final Uint8List svg = utf8.encode(svgStr); + final Uint8List svg = utf8.encode(svgStr) as Uint8List; testWidgets('SvgPicture can work with a FittedBox', (WidgetTester tester) async { @@ -258,10 +258,14 @@ void main() { onError: anyNamed('onError'), cancelOnError: anyNamed('cancelOnError'))) .thenAnswer((Invocation invocation) { - final void Function(Uint8List) onData = invocation.positionalArguments[0]; - final void Function(Object) onError = invocation.namedArguments[#onError]; - final void Function() onDone = invocation.namedArguments[#onDone]; - final bool cancelOnError = invocation.namedArguments[#cancelOnError]; + final void Function(Uint8List) onData = + invocation.positionalArguments[0] as void Function(Uint8List); + final void Function(Object) onError = + invocation.namedArguments[#onError] as void Function(Object); + final VoidCallback onDone = + invocation.namedArguments[#onDone] as VoidCallback; + final bool cancelOnError = + invocation.namedArguments[#cancelOnError] as bool; return Stream.fromIterable([svg]).listen( onData, diff --git a/test/xml_svg_test.dart b/test/xml_svg_test.dart index 6d7d4b11..eb0a0c5d 100644 --- a/test/xml_svg_test.dart +++ b/test/xml_svg_test.dart @@ -9,12 +9,13 @@ import 'package:flutter_svg/src/utilities/xml.dart'; void main() { test('Xlink href tests', () { final XmlStartElementEvent el = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; final XmlStartElementEvent elXlink = parseEvents('') - .first; + .first as XmlStartElementEvent; expect(getHrefAttribute(el.attributes), 'http://localhost'); expect(getHrefAttribute(elXlink.attributes), 'http://localhost'); @@ -24,7 +25,7 @@ void main() { final XmlStartElementEvent el = parseEvents('') - .first; + .first as XmlStartElementEvent; expect(getAttribute(el.attributes, 'stroke'), '#fff'); expect(getAttribute(el.attributes, 'fill'), '#eee'); @@ -40,7 +41,8 @@ void main() { // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved test('Attribute WhiteSpace test', () { final XmlStartElementEvent xd = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; expect( xd.attributes[0].value, @@ -60,15 +62,19 @@ void main() { const Rect rect = Rect.fromLTWH(0.0, 0.0, 100.0, 100.0); final XmlStartElementEvent svgWithViewBox = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; final XmlStartElementEvent svgWithViewBoxAndWidthHeight = parseEvents('') - .first; + .first as XmlStartElementEvent; final XmlStartElementEvent svgWithWidthHeight = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; final XmlStartElementEvent svgWithViewBoxMinXMinY = - parseEvents('').first; - final XmlStartElementEvent svgWithNoSizeInfo = parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; + final XmlStartElementEvent svgWithNoSizeInfo = + parseEvents('').first as XmlStartElementEvent; expect(parseViewBox(svgWithViewBoxAndWidthHeight.attributes).size, const Size(50, 50)); @@ -86,15 +92,20 @@ void main() { test('TileMode tests', () { final XmlStartElementEvent pad = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; final XmlStartElementEvent reflect = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; final XmlStartElementEvent repeat = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; final XmlStartElementEvent invalid = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; - final XmlStartElementEvent none = parseEvents('').first; + final XmlStartElementEvent none = + parseEvents('').first as XmlStartElementEvent; expect(parseTileMode(pad.attributes), TileMode.clamp); expect(parseTileMode(invalid.attributes), TileMode.clamp); @@ -106,9 +117,11 @@ void main() { test('@stroke-dashoffset tests', () { final XmlStartElementEvent abs = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; final XmlStartElementEvent pct = - parseEvents('').first; + parseEvents('').first + as XmlStartElementEvent; // TODO(dnfield): DashOffset is completely opaque right now, maybe expose the raw value? expect(parseDashOffset(abs.attributes), isNotNull);