skia_safe/core/
stroke_rec.rs1use crate::{paint, prelude::*, scalar, Paint, Path};
2use skia_bindings::{self as sb, SkStrokeRec};
3use std::fmt;
4
5pub use sb::SkStrokeRec_InitStyle as InitStyle;
6variant_name!(InitStyle::Hairline);
7
8pub use sb::SkStrokeRec_Style as Style;
9variant_name!(Style::Stroke);
10
11pub type StrokeRec = Handle<SkStrokeRec>;
12unsafe_send_sync!(StrokeRec);
13
14impl NativeDrop for SkStrokeRec {
15 fn drop(&mut self) {
16 unsafe { sb::C_SkStrokeRec_destruct(self) };
17 }
18}
19
20impl NativeClone for SkStrokeRec {
21 fn clone(&self) -> Self {
22 let mut copy = StrokeRec::new_hairline();
23 unsafe { sb::C_SkStrokeRec_copy(self, copy.native_mut()) }
24 *copy.native()
25 }
26}
27
28impl fmt::Debug for StrokeRec {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 f.debug_struct("StrokeRec")
31 .field("style", &self.style())
32 .field("width", &self.width())
33 .field("miter", &self.miter())
34 .field("cap", &self.cap())
35 .field("join", &self.join())
36 .field("res_scale", &self.res_scale())
37 .finish()
38 }
39}
40
41impl StrokeRec {
42 pub fn new(init_style: InitStyle) -> Self {
43 Self::from_native_c(unsafe { SkStrokeRec::new(init_style) })
44 }
45
46 pub fn new_hairline() -> Self {
48 Self::new(InitStyle::Hairline)
49 }
50
51 pub fn new_fill() -> Self {
53 Self::new(InitStyle::Fill)
54 }
55
56 pub fn from_paint(
57 paint: &Paint,
58 style: impl Into<Option<paint::Style>>,
59 res_scale: impl Into<Option<scalar>>,
60 ) -> Self {
61 let res_scale = res_scale.into().unwrap_or(1.0);
62 Self::from_native_c(unsafe {
63 match style.into() {
64 Some(style) => SkStrokeRec::new1(paint.native(), style, res_scale),
65 None => SkStrokeRec::new2(paint.native(), res_scale),
66 }
67 })
68 }
69
70 pub fn style(&self) -> Style {
71 unsafe { self.native().getStyle() }
72 }
73
74 pub fn width(&self) -> scalar {
75 self.native().fWidth
76 }
77
78 pub fn miter(&self) -> scalar {
79 self.native().fMiterLimit
80 }
81
82 pub fn cap(&self) -> paint::Cap {
83 unsafe { sb::C_SkStrokeRec_getCap(self.native()) }
84 }
85
86 pub fn join(&self) -> paint::Join {
87 unsafe { sb::C_SkStrokeRec_getJoin(self.native()) }
88 }
89
90 pub fn is_hairline_style(&self) -> bool {
91 self.style() == Style::Hairline
92 }
93
94 pub fn is_fill_style(&self) -> bool {
95 self.style() == Style::Fill
96 }
97
98 pub fn set_fill_style(&mut self) -> &mut Self {
99 unsafe { self.native_mut().setFillStyle() }
100 self
101 }
102
103 pub fn set_hairline_style(&mut self) -> &mut Self {
104 unsafe { self.native_mut().setHairlineStyle() }
105 self
106 }
107
108 pub fn set_stroke_style(
109 &mut self,
110 width: scalar,
111 stroke_and_fill: impl Into<Option<bool>>,
112 ) -> &mut Self {
113 let stroke_and_fill = stroke_and_fill.into().unwrap_or(false);
114 unsafe { self.native_mut().setStrokeStyle(width, stroke_and_fill) }
115 self
116 }
117
118 pub fn set_stroke_params(
119 &mut self,
120 cap: paint::Cap,
121 join: paint::Join,
122 miter_limit: scalar,
123 ) -> &mut Self {
124 let native = self.native_mut();
125 native.set_fCap(cap as _);
126 native.set_fJoin(join as _);
127 native.fMiterLimit = miter_limit;
128 self
129 }
130
131 pub fn res_scale(&self) -> scalar {
132 self.native().fResScale
133 }
134
135 pub fn set_res_scale(&mut self, rs: scalar) {
136 debug_assert!(rs > 0.0 && rs.is_finite());
137 self.native_mut().fResScale = rs;
138 }
139
140 pub fn need_to_apply(&self) -> bool {
141 let style = self.style();
142 style == Style::Stroke || style == Style::StrokeAndFill
143 }
144
145 pub fn apply_to_path(&self, dst: &mut Path, src: &Path) -> bool {
146 unsafe { self.native().applyToPath(dst.native_mut(), src.native()) }
147 }
148
149 pub fn apply_to_path_inplace(&self, path: &mut Path) -> bool {
150 unsafe { self.native().applyToPath(path.native_mut(), path.native()) }
151 }
152
153 pub fn apply_to_paint(&self, paint: &mut Paint) {
154 unsafe { self.native().applyToPaint(paint.native_mut()) }
155 }
156
157 pub fn inflation_radius(&self) -> scalar {
158 unsafe { self.native().getInflationRadius() }
159 }
160
161 pub fn inflation_radius_from_paint_and_style(paint: &Paint, style: paint::Style) -> scalar {
162 unsafe { SkStrokeRec::GetInflationRadius(paint.native(), style) }
163 }
164
165 pub fn inflation_radius_from_params(
166 join: paint::Join,
167 miter_limit: scalar,
168 cap: paint::Cap,
169 stroke_width: scalar,
170 ) -> scalar {
171 unsafe { SkStrokeRec::GetInflationRadius1(join, miter_limit, cap, stroke_width) }
172 }
173
174 pub fn has_equal_effect(&self, other: &StrokeRec) -> bool {
175 unsafe { sb::C_SkStrokeRec_hasEqualEffect(self.native(), other.native()) }
176 }
177}