skia_safe/core/
strike_ref.rs1use std::fmt;
2
3use skia_bindings as sb;
4
5use crate::{GlyphId, Rect, prelude::*, scalar};
6
7pub type StrikeRef = Handle<sb::SkStrikeRef>;
8unsafe_send_sync!(StrikeRef);
9
10impl NativeDrop for sb::SkStrikeRef {
11 fn drop(&mut self) {
12 unsafe { sb::C_SkStrikeRef_destruct(self) }
13 }
14}
15
16impl NativeClone for sb::SkStrikeRef {
17 fn clone(&self) -> Self {
18 construct(|s| unsafe { sb::C_SkStrikeRef_CopyConstruct(s, self) })
19 }
20}
21
22impl fmt::Debug for StrikeRef {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 f.debug_struct("StrikeRef").finish()
25 }
26}
27
28impl StrikeRef {
29 pub fn get_width(&self, glyph: GlyphId) -> scalar {
30 unsafe { sb::C_SkStrikeRef_getWidth(self.native(), glyph) }
31 }
32
33 pub fn get_widths(&self, glyphs: &[GlyphId], widths: &mut [scalar]) {
34 assert_eq!(glyphs.len(), widths.len());
35 unsafe {
36 sb::C_SkStrikeRef_getWidths(
37 self.native(),
38 glyphs.as_ptr(),
39 glyphs.len(),
40 widths.as_mut_ptr(),
41 widths.len(),
42 )
43 }
44 }
45
46 pub fn get_widths_bounds(
47 &self,
48 glyphs: &[GlyphId],
49 mut widths: Option<&mut [scalar]>,
50 mut bounds: Option<&mut [Rect]>,
51 ) {
52 let count = glyphs.len();
53
54 {
55 if let Some(slice) = &widths {
56 assert_eq!(count, slice.len())
57 };
58 if let Some(slice) = &bounds {
59 assert_eq!(count, slice.len())
60 };
61 }
62
63 let widths_ptr = widths.as_ptr_or_null_mut();
64 let widths_count = widths.map_or(0, |slice| slice.len());
65 let bounds_ptr = bounds.native_mut().as_ptr_or_null_mut();
66 let bounds_count = bounds.map_or(0, |slice| slice.len());
67
68 unsafe {
69 sb::C_SkStrikeRef_getWidthsBounds(
70 self.native(),
71 glyphs.as_ptr(),
72 count,
73 widths_ptr,
74 widths_count,
75 bounds_ptr,
76 bounds_count,
77 )
78 }
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use crate::{Font, FontMgr, FontStyle};
85
86 #[test]
87 fn strike_ref_widths_match_font_widths() {
88 let font_mgr = FontMgr::new();
89 let typeface = font_mgr
90 .legacy_make_typeface(None, FontStyle::normal())
91 .unwrap();
92 let font = Font::new(typeface, 14.0);
93 let glyphs = font.text_to_glyphs_vec("StrikeRef");
94 assert!(!glyphs.is_empty());
95
96 let strike_ref = font.make_strike_ref();
97
98 let mut font_widths = vec![0.0; glyphs.len()];
99 font.get_widths(&glyphs, &mut font_widths);
100
101 let mut strike_widths = vec![0.0; glyphs.len()];
102 strike_ref.get_widths(&glyphs, &mut strike_widths);
103
104 assert_eq!(strike_widths, font_widths);
105 assert_eq!(strike_ref.get_width(glyphs[0]), font_widths[0]);
106
107 let mut font_bounds = vec![Default::default(); glyphs.len()];
108 let mut strike_bounds = vec![Default::default(); glyphs.len()];
109 font.get_widths_bounds(&glyphs, None, Some(&mut font_bounds), None);
110 strike_ref.get_widths_bounds(&glyphs, None, Some(&mut strike_bounds));
111
112 assert_eq!(strike_bounds, font_bounds);
113 }
114}