Skip to content

[vector_graphics_compiler] fix: Stroke opacity not applied #8986

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 22, 2025
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
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,4 @@ Alexander Rabin <alex.rabin@sentracam.com>
LinXunFeng <linxunfeng@yeah.net>
Hashir Shoaib <hashirshoaeb@gmail.com>
Ricardo Dalarme <ricardodalarme@outlook.com>
Andrei Kabylin <sys.int64@gmail.com>
4 changes: 4 additions & 0 deletions packages/vector_graphics_compiler/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.1.17

* Fixes a bug where stroke opacity not applied by color mapper.

## 1.1.16

* Sets stroke-width to 1 by default when an invalid value is parsed instead of throwing an exception.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2306,7 +2306,7 @@ class SvgStrokeAttributes {
}

return Stroke(
color: color.color!.withOpacity(opacity ?? 1.0),
color: opacity == null ? color.color : color.color!.withOpacity(opacity!),
shader: shader,
join: join,
cap: cap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ VectorInstructions parseWithoutOptimizers(
String key = '',
bool warningsAsErrors = false,
SvgTheme theme = const SvgTheme(),
ColorMapper? colorMapper,
}) {
return parse(
xml,
Expand All @@ -49,6 +50,7 @@ VectorInstructions parseWithoutOptimizers(
enableClippingOptimizer: false,
enableMaskingOptimizer: false,
enableOverdrawOptimizer: false,
colorMapper: colorMapper,
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/vector_graphics_compiler/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: vector_graphics_compiler
description: A compiler to convert SVGs to the binary format used by `package:vector_graphics`.
repository: https://github.com/flutter/packages/tree/main/packages/vector_graphics_compiler
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+vector_graphics%22
version: 1.1.16
version: 1.1.17

executables:
vector_graphics_compiler:
Expand Down
69 changes: 69 additions & 0 deletions packages/vector_graphics_compiler/test/parser_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ import 'package:vector_graphics_compiler/vector_graphics_compiler.dart';

import 'test_svg_strings.dart';

class _TestOpacityColorMapper implements ColorMapper {
const _TestOpacityColorMapper();

@override
Color substitute(
String? id,
String elementName,
String attributeName,
Color color,
) {
if (color.value == 0xff000000) {
return const Color(0x7fff0000);
} else {
return color;
}
}
}

void main() {
test('Reuse ID self-referentially', () {
final VectorInstructions instructions = parseWithoutOptimizers('''
Expand Down Expand Up @@ -266,6 +284,24 @@ void main() {
);
});

test('preserve opacity from color mapper for strokes', () {
const String strokeOpacitySvg = '''
<svg viewBox="0 0 10 10" fill="none">
<rect x="0" y="0" width="5" height="5" stroke="#000000" />
</svg>
''';

final VectorInstructions instructions = parseWithoutOptimizers(
strokeOpacitySvg,
colorMapper: const _TestOpacityColorMapper(),
);

expect(
instructions.paints.single,
const Paint(stroke: Stroke(color: Color(0x7fff0000))),
);
});

test('text attributes are preserved', () {
final VectorInstructions instructions = parseWithoutOptimizers(textTspan);
expect(
Expand Down Expand Up @@ -352,6 +388,39 @@ void main() {
);
});

test('currentColor stoke opacity', () {
const String currentColorSvg = '''
<svg viewBox="0 0 10 10">
<rect x="0" y="0" width="5" height="5" fill="currentColor" stroke="currentColor" />
</svg>
''';

final VectorInstructions blueInstructions = parseWithoutOptimizers(
currentColorSvg,
theme: const SvgTheme(currentColor: Color(0x7F0000FF)),
);
final VectorInstructions redInstructions = parseWithoutOptimizers(
currentColorSvg,
theme: const SvgTheme(currentColor: Color(0x7FFF0000)),
);

expect(
blueInstructions.paints.single,
const Paint(
fill: Fill(color: Color(0x7F0000FF)),
stroke: Stroke(color: Color(0x7F0000FF)),
),
);

expect(
redInstructions.paints.single,
const Paint(
fill: Fill(color: Color(0x7FFF0000)),
stroke: Stroke(color: Color(0x7FFF0000)),
),
);
});

test('Opacity with a save layer does not continue to inherit', () {
final VectorInstructions instructions = parseWithoutOptimizers('''
<svg width="283" height="180" viewBox="0 0 283 180" fill="none" xmlns="http://www.w3.org/2000/svg">
Expand Down