diff --git a/lib/src/layer/misc/line_patterns/pixel_hiker.dart b/lib/src/layer/misc/line_patterns/pixel_hiker.dart index f0e719f08..f0c7baa4c 100644 --- a/lib/src/layer/misc/line_patterns/pixel_hiker.dart +++ b/lib/src/layer/misc/line_patterns/pixel_hiker.dart @@ -237,6 +237,45 @@ class DashedPixelHiker extends _PixelHiker { } } +/// Pixel hiker that lists the visible solid segments to display on the way. +@internal +class SolidPixelHiker extends _PixelHiker { + /// Standard Solid Pixel Hiker constructor. + SolidPixelHiker({ + required super.offsets, + required super.closePath, + required super.canvasSize, + }) : super( + segmentValues: [], + patternFit: PatternFit.none, + ); + + /// Returns all visible segments. + List getAllVisibleSegments() { + final List result = []; + + if (offsets.length < 2) { + return result; + } + + for (int i = 0; i < offsets.length - 1 + (closePath ? 1 : 0); i++) { + final VisibleSegment? visibleSegment = VisibleSegment.getVisibleSegment( + offsets[i], + offsets[(i + 1) % offsets.length], + canvasSize, + ); + if (visibleSegment != null) { + result.add(visibleSegment); + } + } + + return result; + } + + @override + double getFactor() => 1; +} + /// Pixel hiker that lists the visible items on the way. sealed class _PixelHiker { _PixelHiker({ @@ -253,6 +292,13 @@ sealed class _PixelHiker { final List offsets; final bool closePath; + + /// List of segments' lengths. + /// + /// Expected number of items: + /// * empty for "solid" + /// * > 0 and even for "dashed": (dash size _ space size) * n + /// * only 1 item for "dotted": the size of the space final List segmentValues; final Size canvasSize; final PatternFit patternFit; @@ -290,6 +336,9 @@ sealed class _PixelHiker { @protected void nextSegment() { + if (segmentValues.isEmpty) { + return; + } _segmentIndex = (_segmentIndex + 1) % segmentValues.length; _remaining = segmentValues[_segmentIndex]; } @@ -305,7 +354,7 @@ sealed class _PixelHiker { @protected Offset getIntermediateOffset(final Offset offsetA, final Offset offsetB) { final segmentDistance = getDistance(offsetA, offsetB); - if (_remaining >= segmentDistance) { + if (segmentValues.isEmpty || _remaining >= segmentDistance) { _used = segmentDistance; return offsetB; } diff --git a/lib/src/layer/polygon_layer/painter.dart b/lib/src/layer/polygon_layer/painter.dart index 4937a90c8..c665a6bee 100644 --- a/lib/src/layer/polygon_layer/painter.dart +++ b/lib/src/layer/polygon_layer/painter.dart @@ -315,9 +315,20 @@ class _PolygonPainter extends CustomPainter { Canvas canvas, Paint paint, ) { + final isSolid = polygon.pattern == const StrokePattern.solid(); final isDashed = polygon.pattern.segments != null; final isDotted = polygon.pattern.spacingFactor != null; - if (isDotted) { + if (isSolid) { + final SolidPixelHiker hiker = SolidPixelHiker( + offsets: offsets, + closePath: true, + canvasSize: canvasSize, + ); + for (final visibleSegment in hiker.getAllVisibleSegments()) { + path.moveTo(visibleSegment.begin.dx, visibleSegment.begin.dy); + path.lineTo(visibleSegment.end.dx, visibleSegment.end.dy); + } + } else if (isDotted) { final DottedPixelHiker hiker = DottedPixelHiker( offsets: offsets, stepLength: polygon.borderStrokeWidth * polygon.pattern.spacingFactor!, @@ -341,8 +352,6 @@ class _PolygonPainter extends CustomPainter { path.moveTo(visibleSegment.begin.dx, visibleSegment.begin.dy); path.lineTo(visibleSegment.end.dx, visibleSegment.end.dy); } - } else { - _addLineToPath(path, offsets); } } @@ -366,10 +375,6 @@ class _PolygonPainter extends CustomPainter { } } - void _addLineToPath(Path path, List offsets) { - path.addPolygon(offsets, true); - } - ({Offset min, Offset max}) _getBounds(Offset origin, Polygon polygon) { final bBox = polygon.boundingBox; return ( diff --git a/lib/src/layer/polyline_layer/painter.dart b/lib/src/layer/polyline_layer/painter.dart index 1f7958384..58f5e7bac 100644 --- a/lib/src/layer/polyline_layer/painter.dart +++ b/lib/src/layer/polyline_layer/painter.dart @@ -159,6 +159,7 @@ class _PolylinePainter extends CustomPainter { strokeWidth = polyline.strokeWidth; } + final isSolid = polyline.pattern == const StrokePattern.solid(); final isDashed = polyline.pattern.segments != null; final isDotted = polyline.pattern.spacingFactor != null; @@ -207,7 +208,19 @@ class _PolylinePainter extends CustomPainter { paths.add(filterPath); } paths.add(path); - if (isDotted) { + if (isSolid) { + final SolidPixelHiker hiker = SolidPixelHiker( + offsets: offsets, + closePath: false, + canvasSize: size, + ); + for (final visibleSegment in hiker.getAllVisibleSegments()) { + for (final path in paths) { + path.moveTo(visibleSegment.begin.dx, visibleSegment.begin.dy); + path.lineTo(visibleSegment.end.dx, visibleSegment.end.dy); + } + } + } else if (isDotted) { final DottedPixelHiker hiker = DottedPixelHiker( offsets: offsets, stepLength: strokeWidth * polyline.pattern.spacingFactor!, @@ -244,12 +257,6 @@ class _PolylinePainter extends CustomPainter { path.lineTo(visibleSegment.end.dx, visibleSegment.end.dy); } } - } else { - if (offsets.isNotEmpty) { - for (final path in paths) { - path.addPolygon(offsets, false); - } - } } }