1#[derive(Debug, Clone)]
3pub struct Viewport {
4 pub width: u32,
6 pub height: u32,
8 pub device_scale_factor: f64,
11 pub is_mobile: bool,
13 pub has_touch: bool,
15 pub is_landscape: bool,
17}
18
19impl Default for Viewport {
20 fn default() -> Self {
21 Self {
22 width: 800,
23 height: 600,
24 device_scale_factor: 1.0,
25 is_mobile: false,
26 has_touch: false,
27 is_landscape: false,
28 }
29 }
30}
31
32impl Viewport {
33 pub fn new(width: u32, height: u32) -> Self {
35 Self {
36 width,
37 height,
38 ..Default::default()
39 }
40 }
41
42 pub fn builder() -> ViewportBuilder {
44 ViewportBuilder::default()
45 }
46
47 pub fn with_device_scale_factor(mut self, factor: f64) -> Self {
48 self.device_scale_factor = factor;
49 self
50 }
51
52 pub fn with_mobile(mut self, is_mobile: bool) -> Self {
53 self.is_mobile = is_mobile;
54 self
55 }
56
57 pub fn with_touch(mut self, has_touch: bool) -> Self {
58 self.has_touch = has_touch;
59 self
60 }
61
62 pub fn with_landscape(mut self, is_landscape: bool) -> Self {
63 self.is_landscape = is_landscape;
64 self
65 }
66}
67
68#[derive(Debug, Clone, Default)]
70pub struct ViewportBuilder {
71 width: Option<u32>,
72 height: Option<u32>,
73 device_scale_factor: Option<f64>,
74 is_mobile: Option<bool>,
75 has_touch: Option<bool>,
76 is_landscape: Option<bool>,
77}
78
79impl ViewportBuilder {
80 pub fn width(mut self, width: u32) -> Self {
81 self.width = Some(width);
82 self
83 }
84
85 pub fn height(mut self, height: u32) -> Self {
86 self.height = Some(height);
87 self
88 }
89
90 pub fn device_scale_factor(mut self, factor: f64) -> Self {
91 self.device_scale_factor = Some(factor);
92 self
93 }
94
95 pub fn is_mobile(mut self, mobile: bool) -> Self {
96 self.is_mobile = Some(mobile);
97 self
98 }
99
100 pub fn has_touch(mut self, touch: bool) -> Self {
101 self.has_touch = Some(touch);
102 self
103 }
104
105 pub fn is_landscape(mut self, landscape: bool) -> Self {
106 self.is_landscape = Some(landscape);
107 self
108 }
109
110 pub fn build(self) -> Viewport {
111 let default = Viewport::default();
112 Viewport {
113 width: self.width.unwrap_or(default.width),
114 height: self.height.unwrap_or(default.height),
115 device_scale_factor: self
116 .device_scale_factor
117 .unwrap_or(default.device_scale_factor),
118 is_mobile: self.is_mobile.unwrap_or(default.is_mobile),
119 has_touch: self.has_touch.unwrap_or(default.has_touch),
120 is_landscape: self.is_landscape.unwrap_or(default.is_landscape),
121 }
122 }
123}
124
125#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
127pub enum ImageFormat {
128 #[default]
129 Jpeg,
130 Png,
131 WebP,
132}
133
134impl ImageFormat {
135 pub fn as_str(&self) -> &'static str {
136 match self {
137 ImageFormat::Jpeg => "jpeg",
138 ImageFormat::Png => "png",
139 ImageFormat::WebP => "webp",
140 }
141 }
142}
143
144#[derive(Debug, Clone, Copy)]
146pub struct ClipRegion {
147 pub x: f64,
148 pub y: f64,
149 pub width: f64,
150 pub height: f64,
151 pub scale: f64,
152}
153
154impl ClipRegion {
155 pub fn new(x: f64, y: f64, width: f64, height: f64) -> Self {
156 Self {
157 x,
158 y,
159 width,
160 height,
161 scale: 1.0,
162 }
163 }
164
165 pub fn with_scale(mut self, scale: f64) -> Self {
166 self.scale = scale;
167 self
168 }
169}
170
171#[derive(Debug, Clone, Default)]
173pub struct CaptureOptions {
174 pub(crate) format: ImageFormat,
175 pub(crate) quality: Option<u8>,
176 pub(crate) viewport: Option<Viewport>,
177 pub(crate) full_page: bool,
178 pub(crate) omit_background: bool,
179 pub(crate) clip: Option<ClipRegion>,
180}
181
182impl CaptureOptions {
183 pub fn new() -> Self {
184 Self::default()
185 }
186
187 pub fn with_format(mut self, format: ImageFormat) -> Self {
188 self.format = format;
189 self
190 }
191
192 pub fn with_quality(mut self, quality: u8) -> Self {
193 self.quality = Some(quality.min(100));
194 self
195 }
196
197 pub fn with_viewport(mut self, viewport: Viewport) -> Self {
198 self.viewport = Some(viewport);
199 self
200 }
201
202 pub fn with_full_page(mut self, full_page: bool) -> Self {
203 self.full_page = full_page;
204 self
205 }
206
207 pub fn with_omit_background(mut self, omit: bool) -> Self {
208 self.omit_background = omit;
209 self
210 }
211
212 pub fn with_clip(mut self, clip: ClipRegion) -> Self {
213 self.clip = Some(clip);
214 self
215 }
216
217 pub fn raw_png() -> Self {
218 Self::new().with_format(ImageFormat::Png)
219 }
220
221 pub fn high_quality_jpeg() -> Self {
222 Self::new().with_format(ImageFormat::Jpeg).with_quality(95)
223 }
224
225 pub fn hidpi() -> Self {
226 Self::new().with_viewport(Viewport::default().with_device_scale_factor(2.0))
227 }
228
229 pub fn ultra_hidpi() -> Self {
230 Self::new().with_viewport(Viewport::default().with_device_scale_factor(3.0))
231 }
232
233 #[deprecated(since = "0.2.0", note = "Use `with_format()` instead")]
234 pub fn with_raw_png(mut self, raw: bool) -> Self {
235 self.format = if raw {
236 ImageFormat::Png
237 } else {
238 ImageFormat::Jpeg
239 };
240 self
241 }
242}