1
+ import 'dart:core' ;
1
2
import 'dart:ui' as ui;
2
3
3
4
import 'package:flutter/widgets.dart' ;
@@ -58,21 +59,12 @@ class PolylineLayer extends StatelessWidget {
58
59
59
60
final bool polylineCulling;
60
61
61
- /// {@macro newPolylinePainter.saveLayers}
62
- ///
63
- /// By default, this value is set to `false` to improve performance on
64
- /// layers containing a lot of polylines.
65
- ///
66
- /// You might want to set this to `true` if you get unwanted darker lines
67
- /// where they overlap but, keep in mind that this might reduce the
68
- /// performance of the layer.
69
- final bool saveLayers;
70
-
71
62
const PolylineLayer ({
72
63
super .key,
73
64
this .polylines = const [],
74
65
this .polylineCulling = false ,
75
- this .saveLayers = false ,
66
+ @Deprecated ('No longer needed and will be removed.' )
67
+ bool saveLayers = false ,
76
68
});
77
69
78
70
@override
@@ -87,7 +79,7 @@ class PolylineLayer extends StatelessWidget {
87
79
: polylines;
88
80
89
81
return CustomPaint (
90
- painter: PolylinePainter (lines, saveLayers, map),
82
+ painter: PolylinePainter (lines, map),
91
83
size: size,
92
84
isComplex: true ,
93
85
);
@@ -97,17 +89,10 @@ class PolylineLayer extends StatelessWidget {
97
89
class PolylinePainter extends CustomPainter {
98
90
final List <Polyline > polylines;
99
91
100
- /// {@template newPolylinePainter.saveLayers}
101
- /// If `true` , the canvas will be updated on every frame by calling the
102
- /// methods [Canvas.saveLayer] and [Canvas.restore] .
103
- /// {@endtemplate}
104
- final bool saveLayers;
105
-
106
92
final FlutterMapState map;
107
93
final LatLngBounds bounds;
108
94
109
- PolylinePainter (this .polylines, this .saveLayers, this .map)
110
- : bounds = map.bounds;
95
+ PolylinePainter (this .polylines, this .map) : bounds = map.bounds;
111
96
112
97
int get hash {
113
98
_hash ?? = Object .hashAll (polylines);
@@ -134,26 +119,35 @@ class PolylinePainter extends CustomPainter {
134
119
var borderPath = ui.Path ();
135
120
var filterPath = ui.Path ();
136
121
var paint = Paint ();
122
+ bool needsLayerSaving = false ;
123
+
137
124
Paint ? borderPaint;
138
125
Paint ? filterPaint;
139
126
int ? lastHash;
140
127
141
128
void drawPaths () {
142
- canvas.drawPath (path, paint);
143
- path = ui.Path ();
144
- paint = Paint ();
129
+ final hasBorder = borderPaint != null && filterPaint != null ;
130
+ if (hasBorder) {
131
+ if (needsLayerSaving) {
132
+ canvas.saveLayer (rect, Paint ());
133
+ }
145
134
146
- if (borderPaint != null ) {
147
135
canvas.drawPath (borderPath, borderPaint! );
148
136
borderPath = ui.Path ();
149
137
borderPaint = null ;
150
- }
151
138
152
- if (filterPaint != null ) {
153
- canvas.drawPath (filterPath, filterPaint! );
154
- filterPath = ui.Path ();
155
- filterPaint = null ;
139
+ if (needsLayerSaving) {
140
+ canvas.drawPath (filterPath, filterPaint! );
141
+ filterPath = ui.Path ();
142
+ filterPaint = null ;
143
+
144
+ canvas.restore ();
145
+ }
156
146
}
147
+
148
+ canvas.drawPath (path, paint);
149
+ path = ui.Path ();
150
+ paint = Paint ();
157
151
}
158
152
159
153
for (final polyline in polylines) {
@@ -163,10 +157,12 @@ class PolylinePainter extends CustomPainter {
163
157
}
164
158
165
159
final hash = polyline.renderHashCode;
166
- if (lastHash != null && lastHash != hash) {
160
+ if (needsLayerSaving || ( lastHash != null && lastHash != hash) ) {
167
161
drawPaths ();
168
162
}
169
163
lastHash = hash;
164
+ needsLayerSaving = polyline.color.opacity < 1.0 ||
165
+ (polyline.gradientColors? .any ((c) => c.opacity < 1.0 ) ?? false );
170
166
171
167
late final double strokeWidth;
172
168
if (polyline.useStrokeWidthInMeter) {
@@ -200,30 +196,30 @@ class PolylinePainter extends CustomPainter {
200
196
: paint.color = polyline.color;
201
197
}
202
198
203
- if (polyline.borderColor != null ) {
204
- filterPaint = Paint ()
205
- ..color = polyline.borderColor! .withAlpha (255 )
206
- ..strokeWidth = strokeWidth
207
- ..strokeCap = polyline.strokeCap
208
- ..strokeJoin = polyline.strokeJoin
209
- ..style = isDotted ? PaintingStyle .fill : PaintingStyle .stroke
210
- ..blendMode = BlendMode .dstOut;
211
- }
212
-
213
- if (polyline.borderStrokeWidth > 0.0 ) {
199
+ if (polyline.borderColor != null && polyline.borderStrokeWidth > 0.0 ) {
200
+ // Outlined lines are drawn by drawing a thicker path underneath, then
201
+ // stenciling the middle (in case the line fill is transparent), and
202
+ // finally drawing the line fill.
214
203
borderPaint = Paint ()
215
204
..color = polyline.borderColor ?? const Color (0x00000000 )
216
205
..strokeWidth = strokeWidth + polyline.borderStrokeWidth
217
206
..strokeCap = polyline.strokeCap
218
207
..strokeJoin = polyline.strokeJoin
219
208
..style = isDotted ? PaintingStyle .fill : PaintingStyle .stroke
220
209
..blendMode = BlendMode .srcOver;
210
+
211
+ filterPaint = Paint ()
212
+ ..color = polyline.borderColor! .withAlpha (255 )
213
+ ..strokeWidth = strokeWidth
214
+ ..strokeCap = polyline.strokeCap
215
+ ..strokeJoin = polyline.strokeJoin
216
+ ..style = isDotted ? PaintingStyle .fill : PaintingStyle .stroke
217
+ ..blendMode = BlendMode .dstOut;
221
218
}
222
219
223
220
final radius = paint.strokeWidth / 2 ;
224
221
final borderRadius = (borderPaint? .strokeWidth ?? 0 ) / 2 ;
225
222
226
- if (saveLayers) canvas.saveLayer (rect, Paint ());
227
223
if (isDotted) {
228
224
final spacing = strokeWidth * 1.5 ;
229
225
if (borderPaint != null && filterPaint != null ) {
@@ -238,7 +234,6 @@ class PolylinePainter extends CustomPainter {
238
234
}
239
235
_paintLine (path, offsets);
240
236
}
241
- if (saveLayers) canvas.restore ();
242
237
}
243
238
244
239
drawPaths ();
0 commit comments