skia_safe/modules/paragraph/
paragraph_style.rs1use std::fmt;
2
3use skia_bindings as sb;
4
5use super::{FontFamilies, TextAlign, TextDirection, TextStyle};
6use crate::{
7 interop::{self, AsStr, FromStrs, SetStr},
8 modules::paragraph::TextHeightBehavior,
9 prelude::*,
10 scalar, FontStyle,
11};
12
13pub type StrutStyle = Handle<sb::skia_textlayout_StrutStyle>;
14unsafe_send_sync!(StrutStyle);
15
16impl NativeDrop for sb::skia_textlayout_StrutStyle {
17 fn drop(&mut self) {
18 unsafe { sb::C_StrutStyle_destruct(self) }
19 }
20}
21
22impl NativeClone for sb::skia_textlayout_StrutStyle {
23 fn clone(&self) -> Self {
24 construct(|ss| unsafe { sb::C_StrutStyle_CopyConstruct(ss, self) })
25 }
26}
27
28impl NativePartialEq for sb::skia_textlayout_StrutStyle {
29 fn eq(&self, rhs: &Self) -> bool {
30 unsafe { sb::C_StrutStyle_equals(self, rhs) }
31 }
32}
33
34impl Default for StrutStyle {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39
40impl fmt::Debug for StrutStyle {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 f.debug_struct("StrutStyle")
43 .field("font_families", &self.font_families())
44 .field("font_style", &self.font_style())
45 .field("font_size", &self.font_size())
46 .field("height", &self.height())
47 .field("leading", &self.leading())
48 .field("strut_enabled", &self.strut_enabled())
49 .field("force_strut_height", &self.force_strut_height())
50 .field("height_override", &self.height_override())
51 .field("half_leading", &self.half_leading())
52 .finish()
53 }
54}
55
56impl StrutStyle {
57 pub fn new() -> Self {
58 StrutStyle::construct(|ss| unsafe { sb::C_StrutStyle_Construct(ss) })
59 }
60
61 pub fn font_families(&self) -> FontFamilies {
62 unsafe {
63 let mut count = 0;
64 let ptr = sb::C_StrutStyle_getFontFamilies(self.native(), &mut count);
65 FontFamilies(safer::from_raw_parts(ptr, count))
66 }
67 }
68
69 pub fn set_font_families(&mut self, families: &[impl AsRef<str>]) -> &mut Self {
70 let families: Vec<interop::String> = FromStrs::from_strs(families);
71 let families = families.native();
72 unsafe {
73 sb::C_StrutStyle_setFontFamilies(self.native_mut(), families.as_ptr(), families.len());
74 }
75 self
76 }
77
78 pub fn font_style(&self) -> FontStyle {
79 FontStyle::from_native_c(self.native().fFontStyle)
80 }
81
82 pub fn set_font_style(&mut self, font_style: FontStyle) -> &mut Self {
83 self.native_mut().fFontStyle = font_style.into_native();
84 self
85 }
86
87 pub fn font_size(&self) -> scalar {
88 self.native().fFontSize
89 }
90
91 pub fn set_font_size(&mut self, font_size: scalar) -> &mut Self {
92 self.native_mut().fFontSize = font_size;
93 self
94 }
95
96 pub fn set_height(&mut self, height: scalar) -> &mut Self {
97 self.native_mut().fHeight = height;
98 self
99 }
100
101 pub fn height(&self) -> scalar {
102 self.native().fHeight
103 }
104
105 pub fn set_leading(&mut self, leading: scalar) -> &mut Self {
106 self.native_mut().fLeading = leading;
107 self
108 }
109
110 pub fn leading(&self) -> scalar {
111 self.native().fLeading
112 }
113
114 pub fn strut_enabled(&self) -> bool {
115 self.native().fEnabled
116 }
117
118 pub fn set_strut_enabled(&mut self, enabled: bool) -> &mut Self {
119 self.native_mut().fEnabled = enabled;
120 self
121 }
122
123 pub fn force_strut_height(&self) -> bool {
124 self.native().fForceHeight
125 }
126
127 pub fn set_force_strut_height(&mut self, force_height: bool) -> &mut Self {
128 self.native_mut().fForceHeight = force_height;
129 self
130 }
131
132 pub fn height_override(&self) -> bool {
133 self.native().fHeightOverride
134 }
135
136 pub fn set_height_override(&mut self, height_override: bool) -> &mut Self {
137 self.native_mut().fHeightOverride = height_override;
138 self
139 }
140
141 pub fn half_leading(&self) -> bool {
142 self.native().fHalfLeading
143 }
144
145 pub fn set_half_leading(&mut self, half_leading: bool) -> &mut Self {
146 self.native_mut().fHalfLeading = half_leading;
147 self
148 }
149}
150
151pub type ParagraphStyle = RefHandle<sb::skia_textlayout_ParagraphStyle>;
153unsafe_send_sync!(ParagraphStyle);
154
155impl NativeDrop for sb::skia_textlayout_ParagraphStyle {
156 fn drop(&mut self) {
157 unsafe { sb::C_ParagraphStyle_delete(self) }
158 }
159}
160
161impl Clone for ParagraphStyle {
162 fn clone(&self) -> Self {
163 Self::from_ptr(unsafe { sb::C_ParagraphStyle_newCopy(self.native()) }).unwrap()
164 }
165}
166
167impl NativePartialEq for sb::skia_textlayout_ParagraphStyle {
168 fn eq(&self, rhs: &Self) -> bool {
169 unsafe { sb::C_ParagraphStyle_Equals(self, rhs) }
170 }
171}
172
173impl Default for ParagraphStyle {
174 fn default() -> Self {
175 Self::new()
176 }
177}
178
179impl fmt::Debug for ParagraphStyle {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 f.debug_struct("ParagraphStyle")
182 .field("strut_style", &self.strut_style())
183 .field("text_style", &self.text_style())
184 .field("text_direction", &self.text_direction())
185 .field("text_align", &self.text_align())
186 .field("max_lines", &self.max_lines())
187 .field("ellipsis", &self.ellipsis())
188 .field("height", &self.height())
189 .field("text_height_behavior", &self.text_height_behavior())
190 .field("unlimited_lines", &self.unlimited_lines())
191 .field("ellipsized", &self.ellipsized())
192 .field("effective_align", &self.effective_align())
193 .field("hinting_is_on", &self.hinting_is_on())
194 .field("replace_tab_characters", &self.replace_tab_characters())
195 .field("fake_missing_font_styles", &self.fake_missing_font_styles())
196 .field(
197 "letter_spacing_by_css_spec",
198 &self.letter_spacing_by_css_spec(),
199 )
200 .finish()
201 }
202}
203
204impl ParagraphStyle {
205 pub fn new() -> Self {
206 Self::from_ptr(unsafe { sb::C_ParagraphStyle_new() }).unwrap()
207 }
208
209 pub fn strut_style(&self) -> &StrutStyle {
210 StrutStyle::from_native_ref(&self.native().fStrutStyle)
211 }
212
213 pub fn set_strut_style(&mut self, strut_style: StrutStyle) -> &mut Self {
214 self.native_mut().fStrutStyle.replace_with(strut_style);
215 self
216 }
217
218 pub fn text_style(&self) -> &TextStyle {
219 TextStyle::from_native_ref(&self.native().fDefaultTextStyle)
220 }
221
222 pub fn set_text_style(&mut self, text_style: &TextStyle) -> &mut Self {
223 self.native_mut()
225 .fDefaultTextStyle
226 .replace_with(text_style.clone());
227 self
228 }
229
230 pub fn text_direction(&self) -> TextDirection {
231 self.native().fTextDirection
232 }
233
234 pub fn set_text_direction(&mut self, direction: TextDirection) -> &mut Self {
235 self.native_mut().fTextDirection = direction;
236 self
237 }
238
239 pub fn text_align(&self) -> TextAlign {
240 self.native().fTextAlign
241 }
242
243 pub fn set_text_align(&mut self, align: TextAlign) -> &mut Self {
244 self.native_mut().fTextAlign = align;
245 self
246 }
247
248 pub fn max_lines(&self) -> Option<usize> {
249 match self.native().fLinesLimit {
250 std::usize::MAX => None,
251 lines => Some(lines),
252 }
253 }
254
255 pub fn set_max_lines(&mut self, lines: impl Into<Option<usize>>) -> &mut Self {
256 self.native_mut().fLinesLimit = lines.into().unwrap_or(usize::MAX);
257 self
258 }
259
260 pub fn ellipsis(&self) -> &str {
263 self.native().fEllipsis.as_str()
264 }
265
266 pub fn set_ellipsis(&mut self, ellipsis: impl AsRef<str>) -> &mut Self {
267 self.native_mut().fEllipsis.set_str(ellipsis);
268 self
269 }
270
271 pub fn height(&self) -> scalar {
272 self.native().fHeight
273 }
274
275 pub fn set_height(&mut self, height: scalar) -> &mut Self {
276 self.native_mut().fHeight = height;
277 self
278 }
279
280 pub fn text_height_behavior(&self) -> TextHeightBehavior {
281 self.native().fTextHeightBehavior
282 }
283
284 pub fn set_text_height_behavior(&mut self, v: TextHeightBehavior) -> &mut Self {
285 self.native_mut().fTextHeightBehavior = v;
286 self
287 }
288
289 pub fn unlimited_lines(&self) -> bool {
290 self.max_lines().is_none()
291 }
292
293 pub fn ellipsized(&self) -> bool {
294 unsafe { sb::C_ParagraphStyle_ellipsized(self.native()) }
295 }
296
297 pub fn effective_align(&self) -> TextAlign {
298 unsafe { self.native().effective_align() }
299 }
300
301 pub fn hinting_is_on(&self) -> bool {
302 self.native().fHintingIsOn
303 }
304
305 pub fn turn_hinting_off(&mut self) -> &mut Self {
306 self.native_mut().fHintingIsOn = false;
307 self
308 }
309
310 pub fn fake_missing_font_styles(&self) -> bool {
311 self.native().fFakeMissingFontStyles
312 }
313
314 pub fn set_fake_missing_font_styles(&mut self, value: bool) -> &mut Self {
315 self.native_mut().fFakeMissingFontStyles = value;
316 self
317 }
318
319 pub fn replace_tab_characters(&self) -> bool {
320 self.native().fReplaceTabCharacters
321 }
322
323 pub fn set_replace_tab_characters(&mut self, value: bool) -> &mut Self {
324 self.native_mut().fReplaceTabCharacters = value;
325 self
326 }
327
328 pub fn apply_rounding_hack(&self) -> bool {
329 self.native().fApplyRoundingHack
330 }
331
332 pub fn set_apply_rounding_hack(&mut self, value: bool) -> &mut Self {
333 self.native_mut().fApplyRoundingHack = value;
334 self
335 }
336
337 pub fn letter_spacing_by_css_spec(&self) -> bool {
338 self.native().fLetterSpacingByCSSSpec
339 }
340
341 pub fn set_letter_spacing_by_css_spec(&mut self, value: bool) -> &mut Self {
342 self.native_mut().fLetterSpacingByCSSSpec = value;
343 self
344 }
345}
346
347#[cfg(test)]
348mod tests {
349 use super::ParagraphStyle;
350
351 #[test]
353 fn paragraph_style_supports_equality() {
354 let a = ParagraphStyle::default();
355 let b = ParagraphStyle::default();
356 assert_eq!(a, b)
357 }
358}