Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion third_party/packages/flutter_svg/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 2.2.0

* Exposes `renderingStrategy` in `SvgPicture` constructors.
* Updates minimum supported SDK version to Flutter 3.27/Dart 3.6.

## 2.1.0
Expand Down
13 changes: 9 additions & 4 deletions third_party/packages/flutter_svg/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,15 @@ import 'dart:ui' as ui;
```

The `SvgPicture` helps to automate this logic, and it provides some convenience
wrappers for getting assets from multiple sources. Unlike the `vector_graphics`
package, this package _does not render the data to an `Image` at any point_.
This carries a performance penalty for some common use cases, but also allows
for more flexibility around scaling.
wrappers for getting assets from multiple sources.

This package now supports a render strategy setting, allowing certain
applications to achieve better performance when needed. By default, the
rendering uses the original `picture` mode, which retains full flexibility in
scaling. Alternatively, when using the `raster` strategy, the SVG data is
rendered into an `Image`, which is then drawn using drawImage. This approach may
sacrifice some flexibility—especially around resolution scaling—but can
significantly improve rendering performance in specific use cases.

## Precompiling and Optimizing SVGs

Expand Down
15 changes: 15 additions & 0 deletions third_party/packages/flutter_svg/lib/svg.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class SvgPicture extends StatelessWidget {
'The SVG theme must be set on the bytesLoader.')
SvgTheme? theme,
@Deprecated('This no longer does anything.') bool cacheColorFilter = false,
this.renderingStrategy = RenderingStrategy.picture,
});

/// Instantiates a widget that renders an SVG picture from an [AssetBundle].
Expand Down Expand Up @@ -201,6 +202,7 @@ class SvgPicture extends StatelessWidget {
@Deprecated('Use colorFilter instead.')
ui.BlendMode colorBlendMode = ui.BlendMode.srcIn,
@Deprecated('This no longer does anything.') bool cacheColorFilter = false,
this.renderingStrategy = RenderingStrategy.picture,
}) : bytesLoader = SvgAssetLoader(
assetName,
packageName: package,
Expand Down Expand Up @@ -265,6 +267,7 @@ class SvgPicture extends StatelessWidget {
SvgTheme? theme,
ColorMapper? colorMapper,
http.Client? httpClient,
this.renderingStrategy = RenderingStrategy.picture,
}) : bytesLoader = SvgNetworkLoader(
url,
headers: headers,
Expand Down Expand Up @@ -325,6 +328,7 @@ class SvgPicture extends StatelessWidget {
SvgTheme? theme,
ColorMapper? colorMapper,
@Deprecated('This no longer does anything.') bool cacheColorFilter = false,
this.renderingStrategy = RenderingStrategy.picture,
}) : bytesLoader = SvgFileLoader(
file,
theme: theme,
Expand Down Expand Up @@ -380,6 +384,7 @@ class SvgPicture extends StatelessWidget {
SvgTheme? theme,
ColorMapper? colorMapper,
@Deprecated('This no longer does anything.') bool cacheColorFilter = false,
this.renderingStrategy = RenderingStrategy.picture,
}) : bytesLoader = SvgBytesLoader(
bytes,
theme: theme,
Expand Down Expand Up @@ -435,6 +440,7 @@ class SvgPicture extends StatelessWidget {
SvgTheme? theme,
ColorMapper? colorMapper,
@Deprecated('This no longer does anything.') bool cacheColorFilter = false,
this.renderingStrategy = RenderingStrategy.picture,
}) : bytesLoader = SvgStringLoader(
string,
theme: theme,
Expand Down Expand Up @@ -526,6 +532,14 @@ class SvgPicture extends StatelessWidget {
/// The color filter, if any, to apply to this widget.
final ColorFilter? colorFilter;

/// Widget rendering strategy used to balance flexibility and performance.
///
/// See the enum [RenderingStrategy] for details of all possible options and their common
/// use cases.
///
/// Defaults to [RenderingStrategy.picture].
final RenderingStrategy renderingStrategy;

@override
Widget build(BuildContext context) {
return createCompatVectorGraphic(
Expand All @@ -540,6 +554,7 @@ class SvgPicture extends StatelessWidget {
errorBuilder: errorBuilder,
colorFilter: colorFilter,
placeholderBuilder: placeholderBuilder,
strategy: renderingStrategy,
clipViewbox: !allowDrawingOutsideViewBox,
matchTextDirection: matchTextDirection,
);
Expand Down
2 changes: 1 addition & 1 deletion third_party/packages/flutter_svg/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: flutter_svg
description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files.
repository: https://github.com/flutter/packages/tree/main/third_party/packages/flutter_svg
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_svg%22
version: 2.1.0
version: 2.2.0

environment:
sdk: ^3.6.0
Expand Down
108 changes: 108 additions & 0 deletions third_party/packages/flutter_svg/test/widget_svg_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:flutter_svg/flutter_svg.dart';

import 'package:flutter_test/flutter_test.dart';
import 'package:http/http.dart' as http;
import 'package:vector_graphics/vector_graphics_compat.dart';

class _TolerantComparator extends LocalFileComparator {
_TolerantComparator(super.testFile);
Expand Down Expand Up @@ -139,6 +140,28 @@ void main() {
await _checkWidgetAndGolden(key, 'flutter_logo.string.png');
});

testWidgets('SvgPicture.string with renderingStrategy',
(WidgetTester tester) async {
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
MediaQuery(
data: mediaQueryData,
child: RepaintBoundary(
key: key,
child: SvgPicture.string(
svgStr,
width: 100.0,
height: 100.0,
renderingStrategy: RenderingStrategy.raster,
),
),
),
);

await tester.pumpAndSettle();
await _checkWidgetAndGolden(key, 'flutter_logo.string.png');
});

testWidgets('SvgPicture.string with colorMapper',
(WidgetTester tester) async {
final GlobalKey key = GlobalKey();
Expand Down Expand Up @@ -295,6 +318,25 @@ void main() {
await _checkWidgetAndGolden(key, 'flutter_logo.memory.png');
});

testWidgets('SvgPicture.memory with strategy', (WidgetTester tester) async {
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
MediaQuery(
data: mediaQueryData,
child: RepaintBoundary(
key: key,
child: SvgPicture.memory(
svgBytes,
renderingStrategy: RenderingStrategy.raster,
),
),
),
);
await tester.pumpAndSettle();

await _checkWidgetAndGolden(key, 'flutter_logo.memory.png');
});

testWidgets('SvgPicture.memory with colorMapper',
(WidgetTester tester) async {
final GlobalKey key = GlobalKey();
Expand Down Expand Up @@ -334,6 +376,26 @@ void main() {
await _checkWidgetAndGolden(key, 'flutter_logo.asset.png');
});

testWidgets('SvgPicture.asset with strategy', (WidgetTester tester) async {
final FakeAssetBundle fakeAsset = FakeAssetBundle();
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
MediaQuery(
data: mediaQueryData,
child: RepaintBoundary(
key: key,
child: SvgPicture.asset(
'test.svg',
bundle: fakeAsset,
renderingStrategy: RenderingStrategy.raster,
),
),
),
);
await tester.pumpAndSettle();
await _checkWidgetAndGolden(key, 'flutter_logo.asset.png');
});

testWidgets('SvgPicture.asset with colorMapper', (WidgetTester tester) async {
final FakeAssetBundle fakeAsset = FakeAssetBundle();
final GlobalKey key = GlobalKey();
Expand Down Expand Up @@ -380,6 +442,33 @@ void main() {
await _checkWidgetAndGolden(key, 'flutter_logo.asset.png');
});

testWidgets('SvgPicture.asset DefaultAssetBundle with strategy',
(WidgetTester tester) async {
final FakeAssetBundle fakeAsset = FakeAssetBundle();
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: mediaQueryData,
child: DefaultAssetBundle(
bundle: fakeAsset,
child: RepaintBoundary(
key: key,
child: SvgPicture.asset(
'test.svg',
semanticsLabel: 'Test SVG',
renderingStrategy: RenderingStrategy.raster,
),
),
),
),
),
);
await tester.pumpAndSettle();
await _checkWidgetAndGolden(key, 'flutter_logo.asset.png');
});

testWidgets('SvgPicture.asset DefaultAssetBundle with colorMapper',
(WidgetTester tester) async {
final FakeAssetBundle fakeAsset = FakeAssetBundle();
Expand Down Expand Up @@ -425,6 +514,25 @@ void main() {
await _checkWidgetAndGolden(key, 'flutter_logo.network.png');
});

testWidgets('SvgPicture.network with strategy', (WidgetTester tester) async {
final GlobalKey key = GlobalKey();
await tester.pumpWidget(
MediaQuery(
data: mediaQueryData,
child: RepaintBoundary(
key: key,
child: SvgPicture.network(
'test.svg',
httpClient: FakeHttpClient(),
renderingStrategy: RenderingStrategy.raster,
),
),
),
);
await tester.pumpAndSettle();
await _checkWidgetAndGolden(key, 'flutter_logo.network.png');
});

testWidgets('SvgPicture.network with colorMapper',
(WidgetTester tester) async {
final GlobalKey key = GlobalKey();
Expand Down