1 | use crate::{prelude::*, Matrix, NativeFlattenable, Path, Rect, StrokeRec}; |
2 | use sb::SkPathEffect_INHERITED; |
3 | use skia_bindings::{self as sb, SkFlattenable, SkPathEffect, SkRefCntBase}; |
4 | use std::fmt; |
5 | |
6 | pub type PathEffect = RCHandle<SkPathEffect>; |
7 | unsafe_send_sync!(PathEffect); |
8 | require_type_equality!(SkPathEffect_INHERITED, SkFlattenable); |
9 | |
10 | impl NativeBase<SkRefCntBase> for SkPathEffect {} |
11 | impl NativeBase<SkFlattenable> for SkPathEffect {} |
12 | |
13 | impl NativeRefCountedBase for SkPathEffect { |
14 | type Base = SkRefCntBase; |
15 | } |
16 | |
17 | impl NativeFlattenable for SkPathEffect { |
18 | fn native_flattenable(&self) -> &SkFlattenable { |
19 | self.base() |
20 | } |
21 | |
22 | fn native_deserialize(data: &[u8]) -> *mut Self { |
23 | unsafe { sb::C_SkPathEffect_Deserialize(data.as_ptr() as _, length:data.len()) } |
24 | } |
25 | } |
26 | |
27 | impl fmt::Debug for PathEffect { |
28 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
29 | f&mut DebugStruct<'_, '_>.debug_struct("PathEffect" ) |
30 | .field(name:"needs_ctm" , &self.needs_ctm()) |
31 | .finish() |
32 | } |
33 | } |
34 | |
35 | impl PathEffect { |
36 | pub fn sum(first: impl Into<PathEffect>, second: impl Into<PathEffect>) -> PathEffect { |
37 | PathEffect::from_ptr(unsafe { |
38 | sb::C_SkPathEffect_MakeSum(first.into().into_ptr(), second.into().into_ptr()) |
39 | }) |
40 | .unwrap() |
41 | } |
42 | |
43 | pub fn compose(first: impl Into<PathEffect>, second: impl Into<PathEffect>) -> PathEffect { |
44 | PathEffect::from_ptr(unsafe { |
45 | sb::C_SkPathEffect_MakeCompose(first.into().into_ptr(), second.into().into_ptr()) |
46 | }) |
47 | .unwrap() |
48 | } |
49 | |
50 | pub fn filter_path( |
51 | &self, |
52 | src: &Path, |
53 | stroke_rec: &StrokeRec, |
54 | cull_rect: impl AsRef<Rect>, |
55 | ) -> Option<(Path, StrokeRec)> { |
56 | let mut dst = Path::default(); |
57 | let mut stroke_rec_r = stroke_rec.clone(); |
58 | self.filter_path_inplace(&mut dst, src, &mut stroke_rec_r, cull_rect) |
59 | .if_true_some((dst, stroke_rec_r)) |
60 | } |
61 | |
62 | pub fn filter_path_inplace( |
63 | &self, |
64 | dst: &mut Path, |
65 | src: &Path, |
66 | stroke_rec: &mut StrokeRec, |
67 | cull_rect: impl AsRef<Rect>, |
68 | ) -> bool { |
69 | unsafe { |
70 | self.native().filterPath( |
71 | dst.native_mut(), |
72 | src.native(), |
73 | stroke_rec.native_mut(), |
74 | cull_rect.as_ref().native(), |
75 | ) |
76 | } |
77 | } |
78 | |
79 | pub fn filter_path_inplace_with_matrix( |
80 | &self, |
81 | dst: &mut Path, |
82 | src: &Path, |
83 | stroke_rec: &mut StrokeRec, |
84 | cull_rect: impl AsRef<Rect>, |
85 | ctm: &Matrix, |
86 | ) -> bool { |
87 | unsafe { |
88 | self.native().filterPath1( |
89 | dst.native_mut(), |
90 | src.native(), |
91 | stroke_rec.native_mut(), |
92 | cull_rect.as_ref().native(), |
93 | ctm.native(), |
94 | ) |
95 | } |
96 | } |
97 | |
98 | pub fn needs_ctm(&self) -> bool { |
99 | unsafe { self.native().needsCTM() } |
100 | } |
101 | } |
102 | |