зеркало из https://github.com/mono/SkiaSharp.git
Added SKPathMeasure to the C# API
This commit is contained in:
Родитель
7fa8a4aac1
Коммит
9c2d2697a2
|
@ -21,6 +21,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)SKDocument.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKPathEffect.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)GRContext.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKPathMeasure.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKSurface.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKCanvas.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)SKShader.cs" />
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
//
|
||||
// Bindings for SKPathMeasure
|
||||
//
|
||||
// Author:
|
||||
// Matthew Leibowitz
|
||||
//
|
||||
// Copyright 2016 Xamarin Inc
|
||||
//
|
||||
using System;
|
||||
|
||||
namespace SkiaSharp
|
||||
{
|
||||
public class SKPathMeasure : SKObject
|
||||
{
|
||||
[Flags]
|
||||
public enum MatrixFlags {
|
||||
GetPosition = 0x01,
|
||||
GetTangent = 0x02,
|
||||
GetPositionAndTangent = GetPosition | GetTangent,
|
||||
}
|
||||
|
||||
[Preserve]
|
||||
internal SKPathMeasure (IntPtr handle, bool owns)
|
||||
: base (handle, owns)
|
||||
{
|
||||
}
|
||||
|
||||
public SKPathMeasure ()
|
||||
: this (SkiaApi.sk_pathmeasure_new (), true)
|
||||
{
|
||||
if (Handle == IntPtr.Zero) {
|
||||
throw new InvalidOperationException ("Unable to create a new SKPathMeasure instance.");
|
||||
}
|
||||
}
|
||||
|
||||
public SKPathMeasure (SKPath path, bool forceClosed = false, float resScale = 1)
|
||||
: this (SkiaApi.sk_pathmeasure_new_with_path (path == null ? IntPtr.Zero : path.Handle, forceClosed, resScale), true)
|
||||
{
|
||||
if (Handle == IntPtr.Zero) {
|
||||
throw new InvalidOperationException ("Unable to create a new SKPathMeasure instance.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (Handle != IntPtr.Zero && OwnsHandle) {
|
||||
SkiaApi.sk_pathmeasure_destroy (Handle);
|
||||
}
|
||||
|
||||
base.Dispose (disposing);
|
||||
}
|
||||
|
||||
public float Length {
|
||||
get {
|
||||
return SkiaApi.sk_pathmeasure_get_length (Handle);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsClosed {
|
||||
get {
|
||||
return SkiaApi.sk_pathmeasure_is_closed (Handle);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPath (SKPath path, bool forceClosed)
|
||||
{
|
||||
SkiaApi.sk_pathmeasure_set_path (Handle, path == null ? IntPtr.Zero : path.Handle, forceClosed);
|
||||
}
|
||||
|
||||
public bool GetPositionAndTangent (float distance, out SKPoint position, out SKPoint tangent)
|
||||
{
|
||||
return SkiaApi.sk_pathmeasure_get_pos_tan (Handle, distance, out position, out tangent);
|
||||
}
|
||||
|
||||
public bool GetPosition (float distance, out SKPoint position)
|
||||
{
|
||||
return SkiaApi.sk_pathmeasure_get_pos_tan (Handle, distance, out position, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public bool GetTangent (float distance, out SKPoint tangent)
|
||||
{
|
||||
return SkiaApi.sk_pathmeasure_get_pos_tan (Handle, distance, IntPtr.Zero, out tangent);
|
||||
}
|
||||
|
||||
public bool GetMatrix (float distance, out SKMatrix matrix, MatrixFlags flags)
|
||||
{
|
||||
return SkiaApi.sk_pathmeasure_get_matrix (Handle, distance, out matrix, flags);
|
||||
}
|
||||
|
||||
public bool GetSegment (float start, float stop, SKPath dst, bool startWithMoveTo)
|
||||
{
|
||||
if (dst == null)
|
||||
throw new ArgumentNullException (nameof (dst));
|
||||
return SkiaApi.sk_pathmeasure_get_segment (Handle, start, stop, dst.Handle, startWithMoveTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@ using sk_document_t = System.IntPtr;
|
|||
using sk_colorspace_t = System.IntPtr;
|
||||
using sk_path_iterator_t = System.IntPtr;
|
||||
using sk_path_effect_t = System.IntPtr;
|
||||
using sk_pathmeasure_t = System.IntPtr;
|
||||
using sk_pixelref_factory_t = System.IntPtr;
|
||||
using sk_colortable_t = System.IntPtr;
|
||||
using gr_context_t = System.IntPtr;
|
||||
|
@ -504,6 +505,38 @@ namespace SkiaSharp
|
|||
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static int sk_path_convert_conic_to_quads(ref SKPoint p0, ref SKPoint p1, ref SKPoint p2, float w, [Out] SKPoint[] pts, int pow2);
|
||||
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_pathmeasure_t sk_pathmeasure_new();
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static sk_pathmeasure_t sk_pathmeasure_new_with_path(sk_path_t path, bool forceClosed, float resScale);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void sk_pathmeasure_destroy(sk_pathmeasure_t pathMeasure);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static void sk_pathmeasure_set_path(sk_pathmeasure_t pathMeasure, sk_path_t path, bool forceClosed);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
public extern static float sk_pathmeasure_get_length(sk_pathmeasure_t pathMeasure);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_pathmeasure_get_pos_tan(sk_pathmeasure_t pathMeasure, float distance, out SKPoint position, out SKPoint tangent);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_pathmeasure_get_pos_tan(sk_pathmeasure_t pathMeasure, float distance, IntPtr positionZero, out SKPoint tangent);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_pathmeasure_get_pos_tan(sk_pathmeasure_t pathMeasure, float distance, out SKPoint position, IntPtr tangentZero);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_pathmeasure_get_matrix(sk_pathmeasure_t pathMeasure, float distance, out SKMatrix matrix, SKPathMeasure.MatrixFlags flags);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_pathmeasure_get_segment(sk_pathmeasure_t pathMeasure, float start, float stop, sk_path_t dst, bool startWithMoveTo);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_pathmeasure_is_closed(sk_pathmeasure_t pathMeasure);
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
public extern static bool sk_pathmeasure_next_contour(sk_pathmeasure_t pathMeasure);
|
||||
|
||||
// path ops
|
||||
[DllImport(SKIA, CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I1)]
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 801831b60769f40f1fc606feb9ad624c7d12d9e3
|
||||
Subproject commit b1d9ddd8bacc8464f93583c314799d910b056ab3
|
|
@ -0,0 +1,61 @@
|
|||
using SkiaSharp;
|
||||
|
||||
namespace SkiaSharpSample.Samples
|
||||
{
|
||||
[Preserve(AllMembers = true)]
|
||||
public class PathMeasureSample : SampleBase
|
||||
{
|
||||
[Preserve]
|
||||
public PathMeasureSample()
|
||||
{
|
||||
}
|
||||
|
||||
public override string Title => "Path Measure";
|
||||
|
||||
public override SampleCategories Category => SampleCategories.Paths;
|
||||
|
||||
protected override void OnDrawSample(SKCanvas canvas, int width, int height)
|
||||
{
|
||||
canvas.Clear(SKColors.White);
|
||||
|
||||
using (SKPaint paint = new SKPaint())
|
||||
using (SKPath path = new SKPath())
|
||||
{
|
||||
paint.Style = SKPaintStyle.Stroke;
|
||||
paint.StrokeWidth = 10;
|
||||
paint.IsAntialias = true;
|
||||
paint.StrokeCap = SKStrokeCap.Round;
|
||||
paint.StrokeJoin = SKStrokeJoin.Round;
|
||||
|
||||
path.MoveTo(20, 20);
|
||||
path.LineTo(400, 50);
|
||||
path.LineTo(80, 100);
|
||||
path.LineTo(300, 150);
|
||||
|
||||
paint.Color = SampleMedia.Colors.XamarinDarkBlue;
|
||||
canvas.DrawPath(path, paint);
|
||||
|
||||
using (var measure = new SKPathMeasure(path, false))
|
||||
using (var dst = new SKPath())
|
||||
{
|
||||
var length = measure.Length;
|
||||
|
||||
dst.Reset();
|
||||
measure.GetSegment(length * 0.05f, length * 0.2f, dst, true);
|
||||
paint.Color = SampleMedia.Colors.XamarinPurple;
|
||||
canvas.DrawPath(dst, paint);
|
||||
|
||||
dst.Reset();
|
||||
measure.GetSegment(length * 0.2f, length * 0.8f, dst, true);
|
||||
paint.Color = SampleMedia.Colors.XamarinGreen;
|
||||
canvas.DrawPath(dst, paint);
|
||||
|
||||
dst.Reset();
|
||||
measure.GetSegment(length * 0.8f, length * 0.95f, dst, true);
|
||||
paint.Color = SampleMedia.Colors.XamarinLightBlue;
|
||||
canvas.DrawPath(dst, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)SampleMedia.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Samples\BitmapSubsetDecoderSample.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Samples\ManipulatedBitmapShaderSample.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Samples\PathMeasureSample.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Samples\PathConicToQuadsSample.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Samples\XamagonSample.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Samples\TextSample.cs" />
|
||||
|
|
|
@ -211,5 +211,28 @@ namespace SkiaSharp.Tests
|
|||
Assert.AreEqual (14.185303f, tightBounds.Bottom, EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MeasuringSegementsWorks ()
|
||||
{
|
||||
const float EPSILON = 0.000001f;
|
||||
|
||||
using (SKPath path = new SKPath ())
|
||||
{
|
||||
path.MoveTo (10f, 10f);
|
||||
path.LineTo (110f, 10f);
|
||||
|
||||
var measure = new SKPathMeasure (path);
|
||||
|
||||
Assert.AreEqual (100f, measure.Length, EPSILON);
|
||||
|
||||
var segment = new SKPath ();
|
||||
var result = measure.GetSegment (20, 50, segment, true);
|
||||
Assert.IsTrue (result);
|
||||
Assert.AreEqual (2, segment.PointCount);
|
||||
Assert.AreEqual (new SKPoint (30, 10), segment.Points [0]);
|
||||
Assert.AreEqual (new SKPoint (60, 10), segment.Points [1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче