Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions third_party/packages/flutter_svg/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

* Updates minimum supported SDK version to Flutter 3.27/Dart 3.6.

## 2.2.0

* Exposes `renderingStrategy` in `SvgPicture` constructors.

## 2.1.0

* Exposes `colorMapper` in `SvgPicture` constructors.
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