diff --git a/src/Skia/Avalonia.Skia/GeometryImpl.cs b/src/Skia/Avalonia.Skia/GeometryImpl.cs
index 879b18742e..e8b5795f60 100644
--- a/src/Skia/Avalonia.Skia/GeometryImpl.cs
+++ b/src/Skia/Avalonia.Skia/GeometryImpl.cs
@@ -11,9 +11,20 @@ namespace Avalonia.Skia
internal abstract class GeometryImpl : IGeometryImpl
{
private PathCache _pathCache;
-
+
///
public abstract Rect Bounds { get; }
+
+ ///
+ public double ContourLength
+ {
+ get
+ {
+ if (EffectivePath is null) return 0;
+ return new SKPathMeasure(EffectivePath).Length;
+ }
+ }
+
public abstract SKPath EffectivePath { get; }
///
@@ -103,6 +114,36 @@ namespace Avalonia.Skia
{
return new TransformedGeometryImpl(this, transform);
}
+
+ ///
+ public bool TryGetPointAtDistance(double distance, out Point point)
+ {
+ if (EffectivePath is null)
+ {
+ point = new Point();
+ return false;
+ }
+
+ var res = new SKPathMeasure(EffectivePath).GetPosition((float)distance, out var skPoint);
+ point = new Point(skPoint.X, skPoint.Y);
+ return res;
+ }
+
+ ///
+ public bool TryGetPointAndTangentAtDistance(double distance, out Point point, out Point tangent)
+ {
+ if (EffectivePath is null)
+ {
+ point = new Point();
+ tangent = new Point();
+ return false;
+ }
+
+ var res = new SKPathMeasure(EffectivePath).GetPositionAndTangent((float)distance, out var skPoint, out var skTangent);
+ point = new Point(skPoint.X, skPoint.Y);
+ tangent = new Point(skTangent.X, skTangent.Y);
+ return res;
+ }
///
/// Invalidate all caches. Call after chaining path contents.