screencapturekit/stream/configuration/dimensions.rs
1//! Dimension and scaling configuration for stream capture
2//!
3//! This module provides methods to configure the output dimensions, scaling behavior,
4//! and source/destination rectangles for captured streams.
5
6use crate::cg::CGRect;
7
8use super::internal::SCStreamConfiguration;
9
10impl SCStreamConfiguration {
11 /// Set the output width in pixels
12 ///
13 /// The width determines the width of captured frames.
14 ///
15 /// # Examples
16 ///
17 /// ```
18 /// use screencapturekit::prelude::*;
19 ///
20 /// let mut config = SCStreamConfiguration::default();
21 /// config.set_width(1920);
22 /// assert_eq!(config.get_width(), 1920);
23 /// ```
24 pub fn set_width(&mut self, width: u32) {
25 // FFI expects isize; u32 may wrap on 32-bit platforms (acceptable)
26 #[allow(clippy::cast_possible_wrap)]
27 unsafe {
28 crate::ffi::sc_stream_configuration_set_width(self.as_ptr(), width as isize);
29 }
30 }
31
32 /// Get the configured output width in pixels
33 ///
34 /// # Examples
35 ///
36 /// ```
37 /// use screencapturekit::prelude::*;
38 ///
39 /// let mut config = SCStreamConfiguration::default();
40 /// config.set_width(1920);
41 /// assert_eq!(config.get_width(), 1920);
42 /// ```
43 pub fn get_width(&self) -> u32 {
44 // FFI returns isize but width is always positive and fits in u32
45 #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
46 unsafe {
47 crate::ffi::sc_stream_configuration_get_width(self.as_ptr()) as u32
48 }
49 }
50
51 /// Set the output height in pixels
52 ///
53 /// The height determines the height of captured frames.
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use screencapturekit::prelude::*;
59 ///
60 /// let mut config = SCStreamConfiguration::default();
61 /// config.set_height(1080);
62 /// assert_eq!(config.get_height(), 1080);
63 /// ```
64 pub fn set_height(&mut self, height: u32) {
65 // FFI expects isize; u32 may wrap on 32-bit platforms (acceptable)
66 #[allow(clippy::cast_possible_wrap)]
67 unsafe {
68 crate::ffi::sc_stream_configuration_set_height(self.as_ptr(), height as isize);
69 }
70 }
71
72 /// Get the configured output height in pixels
73 ///
74 /// # Examples
75 ///
76 /// ```
77 /// use screencapturekit::prelude::*;
78 ///
79 /// let mut config = SCStreamConfiguration::default();
80 /// config.set_height(1080);
81 /// assert_eq!(config.get_height(), 1080);
82 /// ```
83 pub fn get_height(&self) -> u32 {
84 // FFI returns isize but height is always positive and fits in u32
85 #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
86 unsafe {
87 crate::ffi::sc_stream_configuration_get_height(self.as_ptr()) as u32
88 }
89 }
90
91 /// Enable or disable scaling to fit the output dimensions
92 ///
93 /// When enabled, the source content will be scaled to fit within the
94 /// configured width and height, potentially changing aspect ratio.
95 ///
96 /// # Examples
97 ///
98 /// ```
99 /// use screencapturekit::prelude::*;
100 ///
101 /// let mut config = SCStreamConfiguration::default();
102 /// config.set_scales_to_fit(true);
103 /// assert!(config.get_scales_to_fit());
104 /// ```
105 pub fn set_scales_to_fit(&mut self, scales_to_fit: bool) {
106 unsafe {
107 crate::ffi::sc_stream_configuration_set_scales_to_fit(self.as_ptr(), scales_to_fit);
108 }
109 }
110
111 /// Check if scaling to fit is enabled
112 pub fn get_scales_to_fit(&self) -> bool {
113 unsafe { crate::ffi::sc_stream_configuration_get_scales_to_fit(self.as_ptr()) }
114 }
115
116 /// Set the source rectangle to capture
117 ///
118 /// Defines which portion of the source content to capture. Coordinates are
119 /// relative to the source content's coordinate system.
120 ///
121 /// # Examples
122 ///
123 /// ```
124 /// use screencapturekit::prelude::*;
125 /// use screencapturekit::cg::CGRect;
126 ///
127 /// // Capture only top-left quarter of screen
128 /// let rect = CGRect::new(0.0, 0.0, 960.0, 540.0);
129 /// let mut config = SCStreamConfiguration::default();
130 /// config.set_source_rect(rect);
131 /// ```
132 pub fn set_source_rect(&mut self, source_rect: CGRect) {
133 unsafe {
134 crate::ffi::sc_stream_configuration_set_source_rect(
135 self.as_ptr(),
136 source_rect.x,
137 source_rect.y,
138 source_rect.width,
139 source_rect.height,
140 );
141 }
142 }
143
144 /// Get the configured source rectangle
145 pub fn get_source_rect(&self) -> CGRect {
146 unsafe {
147 let mut x = 0.0;
148 let mut y = 0.0;
149 let mut width = 0.0;
150 let mut height = 0.0;
151 crate::ffi::sc_stream_configuration_get_source_rect(
152 self.as_ptr(),
153 &mut x,
154 &mut y,
155 &mut width,
156 &mut height,
157 );
158 CGRect::new(x, y, width, height)
159 }
160 }
161
162 /// Set the destination rectangle for captured content
163 ///
164 /// Defines where the captured content will be placed in the output frame.
165 /// Useful for picture-in-picture or multi-source compositions.
166 ///
167 /// # Examples
168 ///
169 /// ```
170 /// use screencapturekit::prelude::*;
171 /// use screencapturekit::cg::CGRect;
172 ///
173 /// // Place captured content in top-left corner
174 /// let rect = CGRect::new(0.0, 0.0, 640.0, 480.0);
175 /// let mut config = SCStreamConfiguration::default();
176 /// config.set_destination_rect(rect);
177 /// ```
178 pub fn set_destination_rect(&mut self, destination_rect: CGRect) {
179 unsafe {
180 crate::ffi::sc_stream_configuration_set_destination_rect(
181 self.as_ptr(),
182 destination_rect.x,
183 destination_rect.y,
184 destination_rect.width,
185 destination_rect.height,
186 );
187 }
188 }
189
190 /// Get the configured destination rectangle
191 pub fn get_destination_rect(&self) -> CGRect {
192 unsafe {
193 let mut x = 0.0;
194 let mut y = 0.0;
195 let mut width = 0.0;
196 let mut height = 0.0;
197 crate::ffi::sc_stream_configuration_get_destination_rect(
198 self.as_ptr(),
199 &mut x,
200 &mut y,
201 &mut width,
202 &mut height,
203 );
204 CGRect::new(x, y, width, height)
205 }
206 }
207
208 /// Preserve aspect ratio when scaling
209 ///
210 /// When enabled, the content will be scaled while maintaining its original
211 /// aspect ratio, potentially adding letterboxing or pillarboxing.
212 ///
213 /// Note: This property requires macOS 14.0+. On older versions, the setter
214 /// is a no-op and the getter returns `false`.
215 ///
216 /// # Examples
217 ///
218 /// ```
219 /// use screencapturekit::prelude::*;
220 ///
221 /// let mut config = SCStreamConfiguration::default();
222 /// config.set_preserves_aspect_ratio(true);
223 /// // Returns true on macOS 14.0+, false on older versions
224 /// let _ = config.get_preserves_aspect_ratio();
225 /// ```
226 pub fn set_preserves_aspect_ratio(&mut self, preserves_aspect_ratio: bool) {
227 unsafe {
228 crate::ffi::sc_stream_configuration_set_preserves_aspect_ratio(
229 self.as_ptr(),
230 preserves_aspect_ratio,
231 );
232 }
233 }
234
235 /// Check if aspect ratio preservation is enabled
236 pub fn get_preserves_aspect_ratio(&self) -> bool {
237 unsafe { crate::ffi::sc_stream_configuration_get_preserves_aspect_ratio(self.as_ptr()) }
238 }
239
240 /// Preserve aspect ratio when scaling (alternative API)
241 ///
242 /// This is an alternative to `set_preserves_aspect_ratio` for compatibility.
243 pub fn set_preserve_aspect_ratio(&mut self, preserve_aspect_ratio: bool) {
244 unsafe {
245 crate::ffi::sc_stream_configuration_set_preserve_aspect_ratio(
246 self.as_ptr(),
247 preserve_aspect_ratio,
248 );
249 }
250 }
251
252 /// Check if aspect ratio preservation is enabled (alternative API)
253 pub fn get_preserve_aspect_ratio(&self) -> bool {
254 unsafe { crate::ffi::sc_stream_configuration_get_preserve_aspect_ratio(self.as_ptr()) }
255 }
256
257 /// Enable or disable increased resolution for Retina displays
258 ///
259 /// When enabled, the captured content will be scaled up to match the backing
260 /// scale factor of Retina displays, providing higher quality output.
261 /// Available on macOS 13.0+
262 ///
263 /// # Examples
264 ///
265 /// ```
266 /// use screencapturekit::prelude::*;
267 ///
268 /// let mut config = SCStreamConfiguration::default();
269 /// config.set_increase_resolution_for_retina_displays(true);
270 /// // Note: Getter may not return the set value on all macOS versions
271 /// let _ = config.get_increase_resolution_for_retina_displays();
272 /// ```
273 pub fn set_increase_resolution_for_retina_displays(&mut self, increase_resolution: bool) {
274 unsafe {
275 crate::ffi::sc_stream_configuration_set_increase_resolution_for_retina_displays(
276 self.as_ptr(),
277 increase_resolution,
278 );
279 }
280 }
281
282 /// Check if increased resolution for Retina displays is enabled
283 pub fn get_increase_resolution_for_retina_displays(&self) -> bool {
284 unsafe {
285 crate::ffi::sc_stream_configuration_get_increase_resolution_for_retina_displays(
286 self.as_ptr(),
287 )
288 }
289 }
290}