From 4ef47bfdb05d04e5f4be199da7c3e47893dfe5fa Mon Sep 17 00:00:00 2001 From: Jumar Macato Date: Fri, 19 Mar 2021 12:14:03 +0800 Subject: [PATCH] Add TryGetSegment --- .../HeadlessPlatformRenderInterface.cs | 6 +++++ .../Platform/IGeometryImpl.cs | 13 +++++++++++ src/Skia/Avalonia.Skia/GeometryImpl.cs | 22 +++++++++++++++++++ .../Avalonia.Direct2D1/Media/GeometryImpl.cs | 9 ++++++++ .../MockStreamGeometryImpl.cs | 6 +++++ .../VisualTree/MockRenderInterface.cs | 5 +++++ 6 files changed, 61 insertions(+) diff --git a/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs index 48c46f50a1..1563c66a96 100644 --- a/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs +++ b/src/Avalonia.Headless/HeadlessPlatformRenderInterface.cs @@ -142,6 +142,12 @@ namespace Avalonia.Headless tangent = new Point(); return false; } + + public bool TryGetSegment(float startDistance, float stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry) + { + segmentGeometry = null; + return false; + } } class HeadlessTransformedGeometryStub : HeadlessGeometryStub, ITransformedGeometryImpl diff --git a/src/Avalonia.Visuals/Platform/IGeometryImpl.cs b/src/Avalonia.Visuals/Platform/IGeometryImpl.cs index c61e6c6112..33092ca2b4 100644 --- a/src/Avalonia.Visuals/Platform/IGeometryImpl.cs +++ b/src/Avalonia.Visuals/Platform/IGeometryImpl.cs @@ -73,5 +73,18 @@ namespace Avalonia.Platform /// The tangent in the specified distance. /// If there's valid point and tangent at the specified distance. bool TryGetPointAndTangentAtDistance(double distance, out Point point, out Point tangent); + + /// + /// Attempts to get the corresponding path segment + /// given by the two distances specified. + /// Imagine it like snipping a part of the current + /// geometry. + /// + /// The contour distance to start snipping from. + /// The contour distance to stop snipping to. + /// If ture, the resulting snipped path will start with a BeginFigure call. + /// The resulting snipped path. + /// If the snipping operation is successful. + bool TryGetSegment (float startDistance, float stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry); } } diff --git a/src/Skia/Avalonia.Skia/GeometryImpl.cs b/src/Skia/Avalonia.Skia/GeometryImpl.cs index 8b4ba66cf6..0884399f4e 100644 --- a/src/Skia/Avalonia.Skia/GeometryImpl.cs +++ b/src/Skia/Avalonia.Skia/GeometryImpl.cs @@ -138,6 +138,28 @@ namespace Avalonia.Skia return res; } + public bool TryGetSegment(float startDistance, float stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry) + { + if (_pathCache.CachePathMeasure is null) + { + segmentGeometry = null; + return false; + } + + segmentGeometry = null; + + SKPath _skPathSegment = null; + + var res = _pathCache.CachePathMeasure.GetSegment(startDistance, stopDistance, _skPathSegment, startOnBeginFigure); + + if (res) + { + segmentGeometry = new StreamGeometryImpl(_skPathSegment); + } + + return res; + } + /// /// Invalidate all caches. Call after chaining path contents. /// diff --git a/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs index 81c21c8648..e03c049ec2 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs @@ -82,6 +82,15 @@ namespace Avalonia.Direct2D1.Media return false; } + public bool TryGetSegment(float startDistance, float stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry) + { + // Direct2D doesnt have this too sadly. + Logger.TryGet(LogEventLevel.Warning, LogArea.Visual)?.Log(this, "TryGetSegment is not available in Direct2D."); + + segmentGeometry = null; + return false; + } + protected virtual Geometry GetSourceGeometry() => Geometry; } } diff --git a/tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs b/tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs index 4e66eaeb24..dfe2021cc2 100644 --- a/tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs +++ b/tests/Avalonia.UnitTests/MockStreamGeometryImpl.cs @@ -84,6 +84,12 @@ namespace Avalonia.UnitTests return false; } + public bool TryGetSegment(float startDistance, float stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry) + { + segmentGeometry = null; + return false; + } + class MockStreamGeometryContext : IStreamGeometryContextImpl { private List points = new List(); diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs index bb6301365a..666ac75c4b 100644 --- a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs +++ b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs @@ -163,6 +163,11 @@ namespace Avalonia.Visuals.UnitTests.VisualTree throw new NotImplementedException(); } + public bool TryGetSegment(float startDistance, float stopDistance, bool startOnBeginFigure, out IGeometryImpl segmentGeometry) + { + throw new NotImplementedException(); + } + class MockStreamGeometryContext : IStreamGeometryContextImpl { private List points = new List();