Skip to content

Commit 675eb2e

Browse files
authored
Use .vec SVG class for vector_graphics_compiler transformed assets (#685)
## What does this change? In the SVG integration, assets that have a [`vector_graphics_compiler`](https://pub.dev/packages/vector_graphics_compiler) [asset transformer](https://docs.flutter.dev/ui/assets/asset-transformation) will use `SvgGenImage.vec` constructor to use correct bytes loader. Fixes #684 🎯
1 parent 3e0108f commit 675eb2e

File tree

10 files changed

+159
-20
lines changed

10 files changed

+159
-20
lines changed

README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,10 @@ flutter:
204204
- assets/images/
205205
- assets/images/chip3/chip.jpg
206206
- assets/images/chip4/chip.jpg
207-
- assets/images/icons/paint.svg
207+
- path: assets/images/icons/paint.svg
208+
- path: assets/images/icons/transformed.svg
209+
transformers:
210+
- package: vector_graphics_compiler
208211
- assets/images/icons/[email protected]
209212
- assets/json/fruits.json
210213
- assets/flare/Penguin.flr
@@ -380,7 +383,7 @@ flutter_gen:
380383
image: false
381384
```
382385

383-
If you are using SVG images with [flutter_svg](https://pub.dev/packages/flutter_svg) you can use the integration feature.
386+
If you are using SVG images with [flutter_svg](https://pub.dev/packages/flutter_svg) you can use the integration feature. This feature also supports using `vector_graphics_compiler` transformer and the produced code will use the `AssetBytesLoader` for such transformed assets.
384387

385388
```yaml
386389
# pubspec.yaml
@@ -391,6 +394,9 @@ flutter_gen:
391394
flutter:
392395
assets:
393396
- assets/images/icons/paint.svg
397+
- path: assets/images/icons/transformed.svg
398+
transformers:
399+
- package: vector_graphics_compiler
394400
```
395401

396402
```dart

packages/core/lib/generators/assets_generator.dart

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,32 +176,45 @@ List<FlavoredAsset> _getAssetRelativePathList(
176176
) {
177177
// Normalize.
178178
final normalizedAssets = <Object>{...assets.whereType<String>()};
179-
final normalizingMap = <String, Set<String>>{};
180-
// Resolve flavored assets.
179+
final normalizingMap =
180+
<String, ({Set<String> flavors, Set<String> transformers})>{};
181+
// Resolve flavored or transformed assets.
181182
for (final map in assets.whereType<YamlMap>()) {
182183
final path = (map['path'] as String).trim();
183184
final flavors =
184185
(map['flavors'] as YamlList?)?.toSet().cast<String>() ?? <String>{};
186+
final transformers = (map['transformers'] as YamlList?)
187+
?.map(((t) => (t as YamlMap)['package'] as String))
188+
.toSet() ??
189+
{};
185190
if (normalizingMap.containsKey(path)) {
186191
// https://github.com/flutter/flutter/blob/5187cab7bdd434ca74abb45895d17e9fa553678a/packages/flutter_tools/lib/src/asset.dart#L1137-L1139
187192
throw StateError(
188193
'Multiple assets entries include the file "$path", '
189-
'but they specify different lists of flavors.',
194+
'but they specify different lists of flavors or transformers.',
190195
);
191196
}
192-
normalizingMap[path] = flavors;
197+
normalizingMap[path] = (flavors: flavors, transformers: transformers);
193198
}
194199
for (final entry in normalizingMap.entries) {
195200
normalizedAssets.add(
196-
YamlMap.wrap({'path': entry.key, 'flavors': entry.value}),
201+
YamlMap.wrap({
202+
'path': entry.key,
203+
'flavors': entry.value.flavors,
204+
'transformers': entry.value.transformers,
205+
}),
197206
);
198207
}
199208

200209
final assetRelativePathList = <FlavoredAsset>[];
201210
for (final asset in normalizedAssets) {
202211
final FlavoredAsset tempAsset;
203212
if (asset is YamlMap) {
204-
tempAsset = FlavoredAsset(path: asset['path'], flavors: asset['flavors']);
213+
tempAsset = FlavoredAsset(
214+
path: asset['path'],
215+
flavors: asset['flavors'],
216+
transformers: asset['transformers'],
217+
);
205218
} else {
206219
tempAsset = FlavoredAsset(path: (asset as String).trim());
207220
}
@@ -238,14 +251,24 @@ AssetType _constructAssetTree(
238251
) {
239252
// Relative path is the key
240253
final assetTypeMap = <String, AssetType>{
241-
'.': AssetType(rootPath: rootPath, path: '.', flavors: {}),
254+
'.': AssetType(
255+
rootPath: rootPath,
256+
path: '.',
257+
flavors: {},
258+
transformers: {},
259+
),
242260
};
243261
for (final asset in assetRelativePathList) {
244262
String path = asset.path;
245263
while (path != '.') {
246264
assetTypeMap.putIfAbsent(
247265
path,
248-
() => AssetType(rootPath: rootPath, path: path, flavors: asset.flavors),
266+
() => AssetType(
267+
rootPath: rootPath,
268+
path: path,
269+
flavors: asset.flavors,
270+
transformers: asset.transformers,
271+
),
249272
);
250273
path = dirname(path);
251274
}
@@ -462,6 +485,7 @@ Future<String> _flatStyleDefinition(
462485
rootPath: config.rootPath,
463486
path: assetPath.path,
464487
flavors: assetPath.flavors,
488+
transformers: assetPath.transformers,
465489
),
466490
)
467491
.mapToUniqueAssetType(style)

packages/core/lib/generators/integrations/svg_integration.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,15 @@ ${isPackage ? "\n static const String package = '$packageName';" : ''}
103103
@override
104104
String get className => 'SvgGenImage';
105105

106+
static const vectorCompileTransformer = 'vector_graphics_compiler';
107+
106108
@override
107109
String classInstantiate(AssetType asset) {
108110
// Query extra information about the SVG.
109111
final info = parseMetadata ? _getMetadata(asset) : null;
110112
final buffer = StringBuffer(className);
111-
if (asset.extension == '.vec') {
113+
if (asset.extension == '.vec' ||
114+
asset.transformers.contains(vectorCompileTransformer)) {
112115
buffer.write('.vec');
113116
}
114117
buffer.write('(');

packages/core/lib/settings/asset_type.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ class AssetType {
1010
required this.rootPath,
1111
required this.path,
1212
required this.flavors,
13+
required this.transformers,
1314
});
1415

1516
final String rootPath;
1617
final String path;
1718
final Set<String> flavors;
19+
final Set<String> transformers;
1820

1921
final List<AssetType> _children = List.empty(growable: true);
2022
late final children = _children.sortedBy((e) => e.path);
@@ -55,7 +57,8 @@ class AssetType {
5557
String toString() => 'AssetType('
5658
'rootPath: $rootPath, '
5759
'path: $path, '
58-
'flavors: $flavors'
60+
'flavors: $flavors, '
61+
'transformers: $transformers'
5962
')';
6063
}
6164

@@ -74,6 +77,7 @@ class UniqueAssetType extends AssetType {
7477
rootPath: assetType.rootPath,
7578
path: assetType.path,
7679
flavors: assetType.flavors,
80+
transformers: assetType.transformers,
7781
);
7882

7983
/// Convert the asset name to a correctly styled name, e.g camelCase or
@@ -113,7 +117,9 @@ class UniqueAssetType extends AssetType {
113117
'path: $path, '
114118
'style: $style, '
115119
'needExtension: $needExtension, '
116-
'suffix: $suffix}';
120+
'suffix: $suffix, '
121+
'flavors: $flavors, '
122+
'transformers: $transformers}';
117123
}
118124
}
119125

packages/core/lib/settings/flavored_asset.dart

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,26 @@ class FlavoredAsset {
22
const FlavoredAsset({
33
required this.path,
44
this.flavors = const {},
5+
this.transformers = const {},
56
});
67

78
final String path;
89
final Set<String> flavors;
10+
final Set<String> transformers;
911

10-
FlavoredAsset copyWith({String? path, Set<String>? flavors}) {
12+
FlavoredAsset copyWith({
13+
String? path,
14+
Set<String>? flavors,
15+
Set<String>? transformers,
16+
}) {
1117
return FlavoredAsset(
1218
path: path ?? this.path,
1319
flavors: flavors ?? this.flavors,
20+
transformers: transformers ?? this.transformers,
1421
);
1522
}
1623

1724
@override
18-
String toString() => 'FlavoredAsset(path: $path, flavors: $flavors)';
25+
String toString() =>
26+
'FlavoredAsset(path: $path, flavors: $flavors, transformers: $transformers)';
1927
}

packages/core/test/assets_gen_integrations_test.dart

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,12 @@ void main() {
4545
test('Integration.classInstantiate', () {
4646
expect(
4747
TestIntegration().classInstantiate(
48-
AssetType(rootPath: resPath, path: 'assets/path', flavors: {'test'}),
48+
AssetType(
49+
rootPath: resPath,
50+
path: 'assets/path',
51+
flavors: {'test'},
52+
transformers: {},
53+
),
4954
),
5055
'TestIntegration(\'assets/path\', flavors: {\'test\'},)',
5156
);
@@ -63,6 +68,7 @@ void main() {
6368
rootPath: resPath,
6469
path: 'assets/path',
6570
flavors: {},
71+
transformers: {},
6672
),
6773
),
6874
'SvgGenImage(\'assets/path\')',
@@ -73,26 +79,62 @@ void main() {
7379
rootPath: resPath,
7480
path: 'assets/path',
7581
flavors: {'test'},
82+
transformers: {},
7683
),
7784
),
7885
'SvgGenImage(\'assets/path\', flavors: {\'test\'},)',
7986
);
87+
expect(
88+
integration.classInstantiate(
89+
AssetType(
90+
rootPath: resPath,
91+
path: 'assets/path/dog.svg',
92+
flavors: {},
93+
transformers: {},
94+
),
95+
),
96+
'SvgGenImage(\'assets/path/dog.svg\')',
97+
);
8098
expect(
8199
integration.classInstantiate(
82100
AssetType(
83101
rootPath: resPath,
84102
path: 'assets/path/dog.vec',
85103
flavors: {},
104+
transformers: {},
86105
),
87106
),
88107
'SvgGenImage.vec(\'assets/path/dog.vec\')',
89108
);
109+
expect(
110+
integration.classInstantiate(
111+
AssetType(
112+
rootPath: resPath,
113+
path: 'assets/path/dog.svg',
114+
flavors: {},
115+
transformers: {'test'},
116+
),
117+
),
118+
'SvgGenImage(\'assets/path/dog.svg\')',
119+
);
120+
expect(
121+
integration.classInstantiate(
122+
AssetType(
123+
rootPath: resPath,
124+
path: 'assets/path/dog.svg',
125+
flavors: {},
126+
transformers: {'vector_graphics_compiler'},
127+
),
128+
),
129+
'SvgGenImage.vec(\'assets/path/dog.svg\')',
130+
);
90131
expect(
91132
integration.isSupport(
92133
AssetType(
93134
rootPath: resPath,
94135
path: 'assets/path/dog.svg',
95136
flavors: {},
137+
transformers: {},
96138
),
97139
),
98140
isTrue,
@@ -103,6 +145,18 @@ void main() {
103145
rootPath: resPath,
104146
path: 'assets/path/dog.vec',
105147
flavors: {},
148+
transformers: {},
149+
),
150+
),
151+
isTrue,
152+
);
153+
expect(
154+
integration.isSupport(
155+
AssetType(
156+
rootPath: resPath,
157+
path: 'assets/path/dog.svg',
158+
flavors: {},
159+
transformers: {'test'},
106160
),
107161
),
108162
isTrue,
@@ -113,6 +167,7 @@ void main() {
113167
rootPath: resPath,
114168
path: 'assets/path/dog.png',
115169
flavors: {},
170+
transformers: {},
116171
),
117172
),
118173
isFalse,
@@ -147,6 +202,7 @@ void main() {
147202
rootPath: resPath,
148203
path: 'assets/path',
149204
flavors: {},
205+
transformers: {},
150206
),
151207
),
152208
'RiveGenImage(\'assets/path\')',
@@ -157,6 +213,7 @@ void main() {
157213
rootPath: resPath,
158214
path: 'assets/path/dog.riv',
159215
flavors: {},
216+
transformers: {},
160217
),
161218
),
162219
isTrue,
@@ -167,6 +224,7 @@ void main() {
167224
rootPath: resPath,
168225
path: 'assets/path/dog.json',
169226
flavors: {},
227+
transformers: {},
170228
),
171229
),
172230
isFalse,
@@ -194,6 +252,7 @@ void main() {
194252
rootPath: resPath,
195253
path: 'assets/lottie',
196254
flavors: {},
255+
transformers: {},
197256
),
198257
),
199258
'LottieGenImage(\'assets/lottie\')',
@@ -204,6 +263,7 @@ void main() {
204263
rootPath: resPath,
205264
path: 'assets/lottie/hamburger_arrow.json',
206265
flavors: {},
266+
transformers: {},
207267
),
208268
),
209269
isTrue,
@@ -214,6 +274,7 @@ void main() {
214274
rootPath: resPath,
215275
path: 'assets/lottie/hamburger_arrow_without_version.json',
216276
flavors: {},
277+
transformers: {},
217278
),
218279
),
219280
isFalse,

packages/core/test/assets_gen_test.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,14 @@ void main() {
167167

168168
final List<AssetType> assets = tests.keys
169169
.sorted()
170-
.map((e) => AssetType(rootPath: '', path: e, flavors: {}))
170+
.map(
171+
(e) => AssetType(
172+
rootPath: '',
173+
path: e,
174+
flavors: {},
175+
transformers: {},
176+
),
177+
)
171178
.toList();
172179

173180
final got = assets.mapToUniqueAssetType(camelCase);

0 commit comments

Comments
 (0)