Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ff8593f

Browse files
authored
[web] Fix svg based stroke rendering. (#23969)
1 parent fad9ae8 commit ff8593f

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

lib/web_ui/dev/goldens_lock.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
repository: https://github.com/flutter/goldens.git
2-
revision: f331294a781874e213a01f093f8113a2206d3e59
2+
revision: de71e99520d92bd82b2b64004cd8e74be08fba05

lib/web_ui/lib/src/engine/dom_canvas.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ html.Element _pathToSvgElement(SurfacePath path, SurfacePaintData paint,
256256
if (paint.style == ui.PaintingStyle.stroke) {
257257
sb.write('stroke="${colorToCssString(color)}" ');
258258
sb.write('stroke-width="${paint.strokeWidth}" ');
259+
sb.write('fill="none" ');
259260
} else if (paint.color != null) {
260261
sb.write('fill="${colorToCssString(color)}" ');
261262
} else {

lib/web_ui/test/golden_tests/engine/path_to_svg_golden_test.dart

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,42 @@ void main() {
1919
void testMain() async {
2020
final Rect region = Rect.fromLTWH(8, 8, 600, 800); // Compensate for old scuba tester padding
2121

22-
Future<void> testPath(Path path, String scubaFileName, {Paint paint, double maxDiffRatePercent = null}) async {
22+
Future<void> testPath(Path path, String scubaFileName,
23+
{Paint paint, double maxDiffRatePercent = null, bool write = false,
24+
bool strokeEnabled = true, bool enableFill = true}) async {
2325
const Rect canvasBounds = Rect.fromLTWH(0, 0, 600, 800);
2426
final BitmapCanvas bitmapCanvas = BitmapCanvas(canvasBounds,
2527
RenderStrategy());
2628
final RecordingCanvas canvas = RecordingCanvas(canvasBounds);
2729

28-
paint ??= Paint()
29-
..color = const Color(0x807F7F7F)
30-
..style = PaintingStyle.fill;
31-
32-
canvas.drawPath(path, paint);
30+
if (enableFill) {
31+
paint ??= Paint()
32+
..color = const Color(0x807F7F7F)
33+
..style = PaintingStyle.fill;
34+
canvas.drawPath(path, paint);
35+
}
3336

34-
paint = Paint()
35-
..strokeWidth = 2
36-
..color = const Color(0xFFFF0000)
37-
..style = PaintingStyle.stroke;
37+
if (strokeEnabled) {
38+
paint = Paint()
39+
..strokeWidth = 2
40+
..color = enableFill ? const Color(0xFFFF0000) :
41+
const Color(0xFF000000)
42+
..style = PaintingStyle.stroke;
43+
}
3844

3945
canvas.drawPath(path, paint);
4046

41-
final html.Element svgElement = pathToSvgElement(path, paint);
47+
final html.Element svgElement = pathToSvgElement(path, paint,
48+
enableFill);
4249

4350
html.document.body.append(bitmapCanvas.rootElement);
4451
html.document.body.append(svgElement);
4552

4653
canvas.endRecording();
4754
canvas.apply(bitmapCanvas, canvasBounds);
4855

49-
await matchGoldenFile('$scubaFileName.png', region: region, maxDiffRatePercent: maxDiffRatePercent);
56+
await matchGoldenFile('$scubaFileName.png', region: region,
57+
maxDiffRatePercent: maxDiffRatePercent, write: write);
5058

5159
bitmapCanvas.rootElement.remove();
5260
svgElement.remove();
@@ -131,17 +139,42 @@ void testMain() async {
131139
path.lineTo(0, 10);
132140
await testPath(path, 'svg_notch');
133141
});
142+
143+
/// Regression test for https://github.com/flutter/flutter/issues/70980
144+
test('render notch', () async {
145+
const double w = 0.7;
146+
final Path path = Path();
147+
path.moveTo(0.5, 14);
148+
path.conicTo(0.5, 10.5, 4, 10.5, w);
149+
path.moveTo(4, 10.5);
150+
path.lineTo(6.5, 10.5);
151+
path.moveTo(36.0, 10.5);
152+
path.lineTo(158, 10.5);
153+
path.conicTo(161.5, 10.5, 161.5, 14, w);
154+
path.moveTo(161.5, 14);
155+
path.lineTo(161.5, 48);
156+
path.conicTo(161.5, 51.5, 158, 51.5, w);
157+
path.lineTo(4, 51.5);
158+
path.conicTo(0.5, 51.5, 0.5, 48, w);
159+
path.lineTo(0.5, 14);
160+
await testPath(path, 'svg_editoutline', enableFill: false);
161+
});
134162
}
135163

136-
html.Element pathToSvgElement(Path path, Paint paint) {
164+
html.Element pathToSvgElement(Path path, Paint paint,
165+
bool enableFill) {
137166
final Rect bounds = path.getBounds();
138167
final StringBuffer sb = StringBuffer();
139168
sb.write(
140-
'<svg viewBox="0 0 ${bounds.right} ${bounds.bottom}" width="${bounds.right}" height="${bounds.bottom}">');
169+
'<svg viewBox="0 0 ${bounds.right} ${bounds.bottom}" '
170+
'width="${bounds.right}" height="${bounds.bottom}">');
141171
sb.write('<path ');
142172
if (paint.style == PaintingStyle.stroke) {
143173
sb.write('stroke="${colorToCssString(paint.color)}" ');
144174
sb.write('stroke-width="${paint.strokeWidth}" ');
175+
if (!enableFill) {
176+
sb.write('fill="none" ');
177+
}
145178
}
146179
if (paint.style == PaintingStyle.fill) {
147180
sb.write('fill="${colorToCssString(paint.color)}" ');

0 commit comments

Comments
 (0)