cairo/font/
scaled_font.rs
1use std::{ffi::CString, mem::MaybeUninit, ptr};
4
5#[cfg(feature = "use_glib")]
6use glib::translate::*;
7
8use crate::{
9 ffi, utils::status_to_result, Error, FontExtents, FontFace, FontOptions, FontType, Glyph,
10 Matrix, TextCluster, TextExtents,
11};
12
13#[cfg(feature = "use_glib")]
14glib::wrapper! {
15 #[derive(Debug)]
16 #[doc(alias = "cairo_scaled_font_t")]
17 pub struct ScaledFont(Shared<ffi::cairo_scaled_font_t>);
18
19 match fn {
20 ref => |ptr| ffi::cairo_scaled_font_reference(ptr),
21 unref => |ptr| ffi::cairo_scaled_font_destroy(ptr),
22 type_ => || ffi::gobject::cairo_gobject_scaled_font_get_type(),
23 }
24}
25
26#[cfg(not(feature = "use_glib"))]
27#[derive(Debug)]
28#[doc(alias = "cairo_scaled_font_t")]
29pub struct ScaledFont(ptr::NonNull<ffi::cairo_scaled_font_t>);
30
31impl ScaledFont {
32 #[doc(alias = "cairo_scaled_font_create")]
33 pub fn new(
34 font_face: &FontFace,
35 font_matrix: &Matrix,
36 ctm: &Matrix,
37 options: &FontOptions,
38 ) -> Result<ScaledFont, Error> {
39 let scaled_font: ScaledFont = unsafe {
40 ScaledFont::from_raw_full(ffi::cairo_scaled_font_create(
41 font_face.to_raw_none(),
42 font_matrix.ptr(),
43 ctm.ptr(),
44 options.to_raw_none(),
45 ))
46 };
47 let status = unsafe { ffi::cairo_scaled_font_status(scaled_font.to_raw_none()) };
48 status_to_result(status)?;
49
50 Ok(scaled_font)
51 }
52
53 #[cfg(feature = "use_glib")]
54 #[inline]
55 pub fn to_raw_none(&self) -> *mut ffi::cairo_scaled_font_t {
56 self.to_glib_none().0
57 }
58
59 #[cfg(not(feature = "use_glib"))]
60 #[inline]
61 pub fn to_raw_none(&self) -> *mut ffi::cairo_scaled_font_t {
62 self.0.as_ptr()
63 }
64
65 #[cfg(not(feature = "use_glib"))]
66 #[inline]
67 pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont {
68 debug_assert!(!ptr.is_null());
69 ScaledFont(ptr::NonNull::new_unchecked(ptr))
70 }
71
72 #[cfg(feature = "use_glib")]
73 #[inline]
74 pub unsafe fn from_raw_full(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont {
75 from_glib_full(ptr)
76 }
77
78 #[cfg(feature = "use_glib")]
79 #[inline]
80 pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont {
81 from_glib_none(ptr)
82 }
83
84 #[cfg(not(feature = "use_glib"))]
85 #[inline]
86 pub unsafe fn from_raw_none(ptr: *mut ffi::cairo_scaled_font_t) -> ScaledFont {
87 debug_assert!(!ptr.is_null());
88 ffi::cairo_scaled_font_reference(ptr);
89 ScaledFont(ptr::NonNull::new_unchecked(ptr))
90 }
91
92 #[doc(alias = "cairo_scaled_font_get_type")]
93 #[doc(alias = "get_type")]
94 pub fn type_(&self) -> FontType {
95 unsafe { FontType::from(ffi::cairo_scaled_font_get_type(self.to_raw_none())) }
96 }
97
98 #[doc(alias = "cairo_scaled_font_get_reference_count")]
99 #[doc(alias = "get_reference_count")]
100 pub fn reference_count(&self) -> usize {
101 unsafe { ffi::cairo_scaled_font_get_reference_count(self.to_raw_none()) as usize }
102 }
103
104 #[doc(alias = "cairo_scaled_font_extents")]
105 pub fn extents(&self) -> FontExtents {
106 let mut extents = MaybeUninit::<FontExtents>::uninit();
107
108 unsafe {
109 ffi::cairo_scaled_font_extents(self.to_raw_none(), extents.as_mut_ptr() as *mut _);
110 extents.assume_init()
111 }
112 }
113
114 #[doc(alias = "cairo_scaled_font_text_extents")]
115 pub fn text_extents(&self, text: &str) -> TextExtents {
116 let mut extents = MaybeUninit::<TextExtents>::uninit();
117
118 let text = CString::new(text).unwrap();
119 unsafe {
120 ffi::cairo_scaled_font_text_extents(
121 self.to_raw_none(),
122 text.as_ptr(),
123 extents.as_mut_ptr() as *mut _,
124 );
125 extents.assume_init()
126 }
127 }
128
129 #[doc(alias = "cairo_scaled_font_glyph_extents")]
130 pub fn glyph_extents(&self, glyphs: &[Glyph]) -> TextExtents {
131 let mut extents = MaybeUninit::<TextExtents>::uninit();
132
133 unsafe {
134 ffi::cairo_scaled_font_glyph_extents(
135 self.to_raw_none(),
136 glyphs.as_ptr() as *const _,
137 glyphs.len() as _,
138 extents.as_mut_ptr() as *mut _,
139 );
140 extents.assume_init()
141 }
142 }
143
144 #[doc(alias = "cairo_scaled_font_text_to_glyphs")]
145 pub fn text_to_glyphs(
146 &self,
147 x: f64,
148 y: f64,
149 text: &str,
150 ) -> Result<(Vec<Glyph>, Vec<TextCluster>), Error> {
151 unsafe {
156 let mut glyphs_ptr: *mut Glyph = ptr::null_mut();
157 let mut glyph_count = 0i32;
158 let mut clusters_ptr: *mut TextCluster = ptr::null_mut();
159 let mut cluster_count = 0i32;
160 let mut cluster_flags = 0i32;
161 let text_length = text.len() as i32;
162 let text = CString::new(text).unwrap();
163
164 let status = ffi::cairo_scaled_font_text_to_glyphs(
165 self.to_raw_none(),
166 x,
167 y,
168 text.as_ptr(),
169 text_length,
170 &mut glyphs_ptr as *mut *mut Glyph as *mut _,
171 &mut glyph_count,
172 &mut clusters_ptr as *mut *mut TextCluster as *mut _,
173 &mut cluster_count,
174 &mut cluster_flags,
175 );
176 status_to_result(status)?;
177
178 let glyph_count = glyph_count as usize;
179 let glyphs: Vec<Glyph> = {
180 let mut glyphs: Vec<Glyph> = Vec::with_capacity(glyph_count);
181
182 ptr::copy(glyphs_ptr, glyphs.as_mut_ptr(), glyph_count);
183
184 glyphs.set_len(glyph_count);
185
186 glyphs
187 };
188
189 let cluster_count = cluster_count as usize;
190 let clusters: Vec<TextCluster> = {
191 let mut clusters = Vec::with_capacity(cluster_count);
192
193 ptr::copy(clusters_ptr, clusters.as_mut_ptr(), cluster_count);
194
195 clusters.set_len(cluster_count);
196
197 clusters
198 };
199
200 ffi::cairo_glyph_free(glyphs_ptr as _);
201 ffi::cairo_text_cluster_free(clusters_ptr as _);
202
203 Ok((glyphs, clusters))
204 }
205 }
206
207 #[doc(alias = "cairo_scaled_font_get_font_face")]
208 #[doc(alias = "get_font_face")]
209 pub fn font_face(&self) -> FontFace {
210 unsafe { FontFace::from_raw_none(ffi::cairo_scaled_font_get_font_face(self.to_raw_none())) }
211 }
212
213 #[doc(alias = "cairo_scaled_font_get_font_options")]
214 #[doc(alias = "get_font_options")]
215 pub fn font_options(&self) -> Result<FontOptions, Error> {
216 let options = FontOptions::new()?;
217
218 unsafe {
219 ffi::cairo_scaled_font_get_font_options(self.to_raw_none(), options.to_raw_none())
220 }
221
222 Ok(options)
223 }
224
225 #[doc(alias = "cairo_scaled_font_get_font_matrix")]
226 #[doc(alias = "get_font_matrix")]
227 pub fn font_matrix(&self) -> Matrix {
228 let mut matrix = Matrix::null();
229
230 unsafe { ffi::cairo_scaled_font_get_font_matrix(self.to_raw_none(), matrix.mut_ptr()) }
231
232 matrix
233 }
234
235 #[doc(alias = "cairo_scaled_font_get_ctm")]
236 #[doc(alias = "get_ctm")]
237 pub fn ctm(&self) -> Matrix {
238 let mut matrix = Matrix::null();
239
240 unsafe { ffi::cairo_scaled_font_get_ctm(self.to_raw_none(), matrix.mut_ptr()) }
241
242 matrix
243 }
244
245 #[doc(alias = "cairo_scaled_font_get_scale_matrix")]
246 #[doc(alias = "get_scale_matrix")]
247 pub fn scale_matrix(&self) -> Matrix {
248 let mut matrix = Matrix::null();
249
250 unsafe { ffi::cairo_scaled_font_get_scale_matrix(self.to_raw_none(), matrix.mut_ptr()) }
251
252 matrix
253 }
254
255 #[doc(alias = "cairo_scaled_font_status")]
256 pub fn status(&self) -> Result<(), Error> {
257 let status = unsafe { ffi::cairo_scaled_font_status(self.to_raw_none()) };
258 status_to_result(status)
259 }
260
261 user_data_methods! {
262 ffi::cairo_scaled_font_get_user_data,
263 ffi::cairo_scaled_font_set_user_data,
264 }
265}
266
267#[cfg(not(feature = "use_glib"))]
268impl Drop for ScaledFont {
269 #[inline]
270 fn drop(&mut self) {
271 unsafe {
272 ffi::cairo_scaled_font_destroy(self.to_raw_none());
273 }
274 }
275}
276
277#[cfg(not(feature = "use_glib"))]
278impl Clone for ScaledFont {
279 #[inline]
280 fn clone(&self) -> ScaledFont {
281 unsafe { ScaledFont::from_raw_none(self.to_raw_none()) }
282 }
283}