Skip to main content

path_kit/
stroke_rec.rs

1//! 描边参数。Stroke parameters for path outlining.
2
3use crate::path::Path;
4use crate::pathkit;
5
6/// 描边样式。Stroke style.
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub enum StrokeStyle {
9    /// 极细线 / Hairline (1 pixel)
10    Hairline,
11    /// 填充 / Fill (no stroke)
12    Fill,
13    /// 描边 / Stroke with width
14    Stroke { width: f32, stroke_and_fill: bool },
15    /// 描边+填充 / Stroke and fill
16    StrokeAndFill { width: f32 },
17}
18
19/// 描边参数,描述如何将路径转为描边轮廓。
20/// Stroke parameters - describes how to expand a path to a stroke outline.
21///
22/// 用于 `apply_to_path` 将路径转换为描边后的填充路径。
23/// Used with `apply_to_path` to convert a path to its stroked fill equivalent.
24pub struct StrokeRec {
25    inner: pathkit::SkStrokeRec,
26}
27
28impl StrokeRec {
29    /// 创建填充样式(无描边)。Creates fill style (no stroke).
30    pub fn new_fill() -> Self {
31        Self {
32            inner: unsafe {
33                pathkit::SkStrokeRec::new(pathkit::SkStrokeRec_InitStyle::kFill_InitStyle)
34            },
35        }
36    }
37
38    /// 创建极细线样式。Creates hairline style (1-pixel stroke).
39    pub fn new_hairline() -> Self {
40        Self {
41            inner: unsafe {
42                pathkit::SkStrokeRec::new(pathkit::SkStrokeRec_InitStyle::kHairline_InitStyle)
43            },
44        }
45    }
46
47    /// 创建描边样式。Creates stroke style with given width.
48    pub fn new_stroke(width: f32, stroke_and_fill: bool) -> Self {
49        let mut rec = Self::new_hairline();
50        unsafe {
51            rec.inner.setStrokeStyle(width, stroke_and_fill);
52        }
53        rec
54    }
55
56    /// 设置为填充样式。Sets to fill style.
57    pub fn set_fill(&mut self) {
58        unsafe {
59            self.inner.setFillStyle();
60        }
61    }
62
63    /// 设置为极细线。Sets to hairline style.
64    pub fn set_hairline(&mut self) {
65        unsafe {
66            self.inner.setHairlineStyle();
67        }
68    }
69
70    /// 设置描边宽度。Sets stroke width (width=0 may switch to fill/hairline).
71    pub fn set_stroke_style(&mut self, width: f32, stroke_and_fill: bool) {
72        unsafe {
73            self.inner.setStrokeStyle(width, stroke_and_fill);
74        }
75    }
76
77    /// 当前样式。Returns current style (hairline/fill/stroke).
78    pub fn style(&self) -> StrokeStyle {
79        let raw = unsafe { self.inner.getStyle() };
80        match raw {
81            pathkit::SkStrokeRec_Style::kHairline_Style => StrokeStyle::Hairline,
82            pathkit::SkStrokeRec_Style::kFill_Style => StrokeStyle::Fill,
83            pathkit::SkStrokeRec_Style::kStroke_Style => StrokeStyle::Stroke {
84                width: self.inner.fWidth,
85                stroke_and_fill: false,
86            },
87            pathkit::SkStrokeRec_Style::kStrokeAndFill_Style => StrokeStyle::StrokeAndFill {
88                width: self.inner.fWidth,
89            },
90            _ => StrokeStyle::Fill,
91        }
92    }
93
94    /// 描边宽度。Returns stroke width.
95    pub fn width(&self) -> f32 {
96        self.inner.fWidth
97    }
98
99    /// 膨胀半径(用于边界计算)。Inflation radius for bounds.
100    pub fn inflation_radius(&self) -> f32 {
101        unsafe { self.inner.getInflationRadius() }
102    }
103
104    /// 将描边参数应用到路径,返回描边后的填充路径。
105    /// Applies stroke to path, returning the stroked outline as a fill path.
106    ///
107    /// 若样式为 fill/hairline 则返回 None。
108    /// Returns None if style is fill or hairline (no expansion).
109    pub fn apply_to_path(&self, path: &Path) -> Option<Path> {
110        let mut dst = Path::new();
111        let ok = unsafe {
112            pathkit::SkStrokeRec_applyToPath(
113                &self.inner as *const _,
114                dst.as_raw_mut() as *mut _,
115                path.as_raw() as *const _,
116            )
117        };
118        if ok {
119            Some(dst)
120        } else {
121            None
122        }
123    }
124
125    /// 内部 SkStrokeRec 引用(仅 crate 内使用,如 PathEffect filterPath)。Internal use only.
126    #[allow(dead_code)]
127    pub(crate) fn as_raw(&self) -> &pathkit::SkStrokeRec {
128        &self.inner
129    }
130
131    /// 内部 SkStrokeRec 可变引用(仅 crate 内使用,如 PathEffect filterPath)。Internal use only.
132    #[allow(dead_code)]
133    pub(crate) fn as_raw_mut(&mut self) -> &mut pathkit::SkStrokeRec {
134        &mut self.inner
135    }
136}
137
138impl Default for StrokeRec {
139    fn default() -> Self {
140        Self::new_fill()
141    }
142}