1 module skia.SKPathMeasure;
2 
3 import skia.Definitions;
4 import skia.MathTypes;
5 import skia.SKMatrix;
6 import skia.SKObject;
7 import skia.SKPath;
8 import skia.SkiaApi;
9 import skia.Exceptions;
10 
11 /**
12  * 
13  */
14 class SKPathMeasure : SKObject, ISKSkipObjectRegistration {
15 	this(void* handle, bool owns) {
16 		super(handle, owns);
17 	}
18 
19 	this() {
20 		this(SkiaApi.sk_pathmeasure_new(), true);
21 		if (Handle is null) {
22 			throw new InvalidOperationException("Unable to create a new SKPathMeasure instance.");
23 		}
24 	}
25 
26 	this(SKPath path, bool forceClosed = false, float resScale = 1) {
27 		super(null, true);
28 		if (path is null)
29 			throw new ArgumentNullException(path.stringof);
30 
31 		Handle = SkiaApi.sk_pathmeasure_new_with_path(cast(sk_path_t*)path.Handle, forceClosed, resScale);
32 
33 		if (Handle is null) {
34 			throw new InvalidOperationException("Unable to create a new SKPathMeasure instance.");
35 		}
36 	}
37 
38 	protected override void Dispose(bool disposing) {
39 		return super.Dispose(disposing);
40 	}
41 
42   override void Dispose()
43   {
44     return super.Dispose();
45   }
46 
47 	protected override void DisposeNative() {
48 		return SkiaApi.sk_pathmeasure_destroy(cast(sk_pathmeasure_t*)Handle);
49 	}
50 
51 	// properties
52 
53 	float Length() {
54 		return SkiaApi.sk_pathmeasure_get_length(cast(sk_pathmeasure_t*)Handle);
55 	}
56 
57 	bool IsClosed() {
58 		return SkiaApi.sk_pathmeasure_is_closed(cast(sk_pathmeasure_t*)Handle);
59 	}
60 
61 	// SetPath
62 
63 	void SetPath(SKPath path) {
64 		return SetPath(path, false);
65 	}
66 
67 	void SetPath(SKPath path, bool forceClosed) {
68 		SkiaApi.sk_pathmeasure_set_path(cast(sk_pathmeasure_t*)Handle, 
69 			cast(sk_path_t*)(path is null ? null : path.Handle), forceClosed);
70 	}
71 
72 	// GetPositionAndTangent
73 
74 	bool GetPositionAndTangent(float distance, out SKPoint position, out SKPoint tangent) {
75 		SKPoint* p = &position;
76 		SKPoint* t = &tangent;
77 		return SkiaApi.sk_pathmeasure_get_pos_tan(cast(sk_pathmeasure_t*)Handle, distance, p, t);
78 	}
79 
80 	// GetPosition
81 
82 	SKPoint GetPosition(float distance) {
83 		SKPoint position;
84 		if (!GetPosition(distance, position))
85 			position = SKPoint.Empty;
86 		return position;
87 	}
88 
89 	bool GetPosition(float distance, ref SKPoint position) {
90 		SKPoint* p = &position;
91 		return SkiaApi.sk_pathmeasure_get_pos_tan(cast(sk_pathmeasure_t*)Handle, distance, p, null);
92 	}
93 
94 	// GetTangent
95 
96 	SKPoint GetTangent(float distance) {
97 		SKPoint tangent;
98 		if (!GetTangent(distance, tangent))
99 			tangent = SKPoint.Empty;
100 		return tangent;
101 	}
102 
103 	bool GetTangent(float distance, out SKPoint tangent) {
104 		SKPoint* t = &tangent;
105 		return SkiaApi.sk_pathmeasure_get_pos_tan(cast(sk_pathmeasure_t*)Handle, distance, null, t);
106 	}
107 
108 	// GetMatrix
109 
110 	SKMatrix GetMatrix(float distance, SKPathMeasureMatrixFlags flags) {
111 		SKMatrix matrix;
112 		if (!GetMatrix(distance, matrix, flags))
113 			matrix = SKMatrix.Empty;
114 		return matrix;
115 	}
116 
117 	bool GetMatrix(float distance, out SKMatrix matrix, SKPathMeasureMatrixFlags flags) {
118 		SKMatrix* m = &matrix;
119 		return SkiaApi.sk_pathmeasure_get_matrix(cast(sk_pathmeasure_t*)Handle, distance, m, flags);
120 	}
121 
122 	// GetSegment
123 
124 	bool GetSegment(float start, float stop, SKPath dst, bool startWithMoveTo) {
125 		if (dst is null)
126 			throw new ArgumentNullException(dst.stringof);
127 		return SkiaApi.sk_pathmeasure_get_segment(cast(sk_pathmeasure_t*)Handle, start, stop,
128 				cast(sk_path_t*)dst.Handle, startWithMoveTo);
129 	}
130 
131 	SKPath GetSegment(float start, float stop, bool startWithMoveTo) {
132 		auto dst = new SKPath();
133 		if (!GetSegment(start, stop, dst, startWithMoveTo)) {
134 			dst.Dispose();
135 			dst = null;
136 		}
137 		return dst;
138 	}
139 
140 	// NextContour
141 
142 	bool NextContour() {
143 		return SkiaApi.sk_pathmeasure_next_contour(cast(sk_pathmeasure_t*)Handle);
144 	}
145 }