skia_safe/core/
path_effect.rs

1use crate::{prelude::*, Matrix, NativeFlattenable, Path, Rect, StrokeRec};
2use sb::SkPathEffect_INHERITED;
3use skia_bindings::{self as sb, SkFlattenable, SkPathEffect, SkRefCntBase};
4use std::fmt;
5
6pub type PathEffect = RCHandle<SkPathEffect>;
7unsafe_send_sync!(PathEffect);
8require_type_equality!(SkPathEffect_INHERITED, SkFlattenable);
9
10impl NativeBase<SkRefCntBase> for SkPathEffect {}
11impl NativeBase<SkFlattenable> for SkPathEffect {}
12
13impl NativeRefCountedBase for SkPathEffect {
14    type Base = SkRefCntBase;
15}
16
17impl 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 _, data.len()) }
24    }
25}
26
27impl fmt::Debug for PathEffect {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        f.debug_struct("PathEffect")
30            .field("needs_ctm", &self.needs_ctm())
31            .finish()
32    }
33}
34
35impl 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}