1use crate::color::AbsoluteColor;
8use crate::context::QuirksMode;
9use crate::custom_properties::CssEnvironment;
10use crate::font_metrics::FontMetrics;
11use crate::logical_geometry::WritingMode;
12use crate::media_queries::MediaType;
13use crate::properties::style_structs::Font;
14use crate::properties::ComputedValues;
15use crate::queries::values::PrefersColorScheme;
16use crate::values::computed::font::GenericFontFamily;
17use crate::values::computed::{CSSPixelLength, Length, LineHeight, NonNegativeLength};
18use crate::values::specified::color::{ColorSchemeFlags, ForcedColors, SystemColor};
19use crate::values::specified::font::{
20 QueryFontMetricsFlags, FONT_MEDIUM_CAP_PX, FONT_MEDIUM_CH_PX, FONT_MEDIUM_EX_PX,
21 FONT_MEDIUM_IC_PX, FONT_MEDIUM_LINE_HEIGHT_PX, FONT_MEDIUM_PX,
22};
23use crate::values::specified::ViewportVariant;
24use crate::values::KeyframesName;
25use app_units::{Au, AU_PER_PX};
26use euclid::default::Size2D as UntypedSize2D;
27use euclid::{Scale, SideOffsets2D, Size2D};
28use malloc_size_of_derive::MallocSizeOf;
29use mime::Mime;
30use parking_lot::RwLock;
31use servo_arc::Arc;
32use std::fmt::Debug;
33use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
34use style_traits::{CSSPixel, DevicePixel};
35
36use crate::device::Device;
37
38pub trait FontMetricsProvider: Debug + Sync {
41 fn query_font_metrics(
43 &self,
44 vertical: bool,
45 font: &Font,
46 base_size: CSSPixelLength,
47 flags: QueryFontMetricsFlags,
48 ) -> FontMetrics;
49 fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length;
51}
52
53#[derive(Debug, MallocSizeOf)]
54pub(super) struct ExtraDeviceData {
55 media_type: MediaType,
57 viewport_size: Size2D<f32, CSSPixel>,
59 device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
61 #[ignore_malloc_size_of = "Pure stack type"]
63 quirks_mode: QuirksMode,
64 #[ignore_malloc_size_of = "Pure stack type"]
66 prefers_color_scheme: PrefersColorScheme,
67 #[ignore_malloc_size_of = "Owned by embedder"]
69 font_metrics_provider: Box<dyn FontMetricsProvider>,
70}
71
72impl Device {
73 pub fn new(
75 media_type: MediaType,
76 quirks_mode: QuirksMode,
77 viewport_size: Size2D<f32, CSSPixel>,
78 device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
79 font_metrics_provider: Box<dyn FontMetricsProvider>,
80 default_values: Arc<ComputedValues>,
81 prefers_color_scheme: PrefersColorScheme,
82 ) -> Device {
83 let root_style = RwLock::new(Arc::clone(&default_values));
84 Device {
85 root_style,
86 root_font_size: AtomicU32::new(FONT_MEDIUM_PX.to_bits()),
87 root_line_height: AtomicU32::new(FONT_MEDIUM_LINE_HEIGHT_PX.to_bits()),
88 root_font_metrics_ex: AtomicU32::new(FONT_MEDIUM_EX_PX.to_bits()),
89 root_font_metrics_cap: AtomicU32::new(FONT_MEDIUM_CAP_PX.to_bits()),
90 root_font_metrics_ch: AtomicU32::new(FONT_MEDIUM_CH_PX.to_bits()),
91 root_font_metrics_ic: AtomicU32::new(FONT_MEDIUM_IC_PX.to_bits()),
92 used_root_font_size: AtomicBool::new(false),
93 used_root_line_height: AtomicBool::new(false),
94 used_root_font_metrics: RwLock::new(false),
95 used_font_metrics: AtomicBool::new(false),
96 used_viewport_size: AtomicBool::new(false),
97 used_dynamic_viewport_size: AtomicBool::new(false),
98 environment: CssEnvironment,
99 default_values,
100 extra: ExtraDeviceData {
101 media_type,
102 viewport_size,
103 device_pixel_ratio,
104 quirks_mode,
105 prefers_color_scheme,
106 font_metrics_provider,
107 },
108 }
109 }
110
111 pub fn calc_line_height(
115 &self,
116 font: &crate::properties::style_structs::Font,
117 _writing_mode: WritingMode,
118 _element: Option<()>,
119 ) -> NonNegativeLength {
120 (match font.line_height {
121 LineHeight::Normal => CSSPixelLength::new(0.),
123 LineHeight::Number(number) => font.font_size.computed_size() * number.0,
124 LineHeight::Length(length) => length.0,
125 })
126 .into()
127 }
128
129 pub fn quirks_mode(&self) -> QuirksMode {
131 self.extra.quirks_mode
132 }
133
134 pub fn set_body_text_color(&self, _color: AbsoluteColor) {
138 }
140
141 pub fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length {
143 self.extra
144 .font_metrics_provider
145 .base_size_for_generic(generic)
146 }
147
148 pub fn animation_name_may_be_referenced(&self, _: &KeyframesName) -> bool {
150 true
152 }
153
154 pub fn viewport_size(&self) -> Size2D<f32, CSSPixel> {
156 self.extra.viewport_size
157 }
158
159 pub fn set_viewport_size(&mut self, viewport_size: Size2D<f32, CSSPixel>) {
165 self.extra.viewport_size = viewport_size;
166 }
167
168 #[inline]
171 pub fn au_viewport_size(&self) -> UntypedSize2D<Au> {
172 Size2D::new(
173 Au::from_f32_px(self.extra.viewport_size.width),
174 Au::from_f32_px(self.extra.viewport_size.height),
175 )
176 }
177
178 pub fn au_viewport_size_for_viewport_unit_resolution(
180 &self,
181 _: ViewportVariant,
182 ) -> UntypedSize2D<Au> {
183 self.used_viewport_size.store(true, Ordering::Relaxed);
184 self.au_viewport_size()
187 }
188
189 pub fn app_units_per_device_pixel(&self) -> i32 {
191 (AU_PER_PX as f32 / self.extra.device_pixel_ratio.0) as i32
192 }
193
194 pub fn device_pixel_ratio_ignoring_full_zoom(&self) -> Scale<f32, CSSPixel, DevicePixel> {
196 self.extra.device_pixel_ratio
197 }
198
199 pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
201 self.extra.device_pixel_ratio
202 }
203
204 pub fn set_device_pixel_ratio(
210 &mut self,
211 device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
212 ) {
213 self.extra.device_pixel_ratio = device_pixel_ratio;
214 }
215
216 pub fn scrollbar_inline_size(&self) -> CSSPixelLength {
218 CSSPixelLength::new(0.0)
220 }
221
222 pub fn query_font_metrics(
224 &self,
225 vertical: bool,
226 font: &Font,
227 base_size: CSSPixelLength,
228 flags: QueryFontMetricsFlags,
229 track_usage: bool,
230 ) -> FontMetrics {
231 if track_usage {
232 self.used_font_metrics.store(true, Ordering::Relaxed);
233 }
234 self.extra
235 .font_metrics_provider
236 .query_font_metrics(vertical, font, base_size, flags)
237 }
238
239 pub fn media_type(&self) -> MediaType {
241 self.extra.media_type.clone()
242 }
243
244 pub fn forced_colors(&self) -> ForcedColors {
246 ForcedColors::None
247 }
248
249 pub fn default_background_color(&self) -> AbsoluteColor {
251 AbsoluteColor::WHITE
252 }
253
254 pub fn default_color(&self) -> AbsoluteColor {
256 AbsoluteColor::BLACK
257 }
258
259 pub fn set_color_scheme(&mut self, new_color_scheme: PrefersColorScheme) {
265 self.extra.prefers_color_scheme = new_color_scheme;
266 }
267
268 pub fn color_scheme(&self) -> PrefersColorScheme {
270 self.extra.prefers_color_scheme
271 }
272
273 pub(crate) fn is_dark_color_scheme(&self, _: ColorSchemeFlags) -> bool {
274 false
275 }
276
277 pub(crate) fn system_color(
278 &self,
279 system_color: SystemColor,
280 color_scheme_flags: ColorSchemeFlags,
281 ) -> AbsoluteColor {
282 fn srgb(r: u8, g: u8, b: u8) -> AbsoluteColor {
283 AbsoluteColor::srgb_legacy(r, g, b, 1f32)
284 }
285
286 if self.is_dark_color_scheme(color_scheme_flags) {
289 match system_color {
291 SystemColor::Accentcolor => srgb(10, 132, 255),
292 SystemColor::Accentcolortext => srgb(255, 255, 255),
293 SystemColor::Activetext => srgb(255, 0, 0),
294 SystemColor::Linktext => srgb(158, 158, 255),
295 SystemColor::Visitedtext => srgb(208, 173, 240),
296 SystemColor::Buttonborder
297 | SystemColor::Activeborder
299 | SystemColor::Inactiveborder
300 | SystemColor::Threeddarkshadow
301 | SystemColor::Threedshadow
302 | SystemColor::Windowframe => srgb(255, 255, 255),
303 SystemColor::Buttonface
304 | SystemColor::Buttonhighlight
306 | SystemColor::Buttonshadow
307 | SystemColor::Threedface
308 | SystemColor::Threedhighlight
309 | SystemColor::Threedlightshadow => srgb(107, 107, 107),
310 SystemColor::Buttontext => srgb(245, 245, 245),
311 SystemColor::Canvas
312 | SystemColor::Activecaption
314 | SystemColor::Appworkspace
315 | SystemColor::Background
316 | SystemColor::Inactivecaption
317 | SystemColor::Infobackground
318 | SystemColor::Menu
319 | SystemColor::Scrollbar
320 | SystemColor::Window => srgb(30, 30, 30),
321 SystemColor::Canvastext
322 | SystemColor::Captiontext
324 | SystemColor::Infotext
325 | SystemColor::Menutext
326 | SystemColor::Windowtext => srgb(232, 232, 232),
327 SystemColor::Field => srgb(45, 45, 45),
328 SystemColor::Fieldtext => srgb(240, 240, 240),
329 SystemColor::Graytext
330 | SystemColor::Inactivecaptiontext => srgb(155, 155, 155),
332 SystemColor::Highlight => srgb(38, 79, 120),
333 SystemColor::Highlighttext => srgb(255, 255, 255),
334 SystemColor::Mark => srgb(102, 92, 0),
335 SystemColor::Marktext => srgb(255, 255, 255),
336 SystemColor::Selecteditem => srgb(153, 200, 255),
337 SystemColor::Selecteditemtext => srgb(59, 59, 59),
338 }
339 } else {
340 match system_color {
341 SystemColor::Accentcolor => srgb(0, 102, 204),
342 SystemColor::Accentcolortext => srgb(255, 255, 255),
343 SystemColor::Activetext => srgb(238, 0, 0),
344 SystemColor::Linktext => srgb(0, 0, 238),
345 SystemColor::Visitedtext => srgb(85, 26, 139),
346 SystemColor::Buttonborder
347 | SystemColor::Activeborder
349 | SystemColor::Inactiveborder
350 | SystemColor::Threeddarkshadow
351 | SystemColor::Threedshadow
352 | SystemColor::Windowframe => srgb(169, 169, 169),
353 SystemColor::Buttonface
354 | SystemColor::Buttonhighlight
356 | SystemColor::Buttonshadow
357 | SystemColor::Threedface
358 | SystemColor::Threedhighlight
359 | SystemColor::Threedlightshadow => srgb(220, 220, 220),
360 SystemColor::Buttontext => srgb(0, 0, 0),
361 SystemColor::Canvas
362 | SystemColor::Activecaption
364 | SystemColor::Appworkspace
365 | SystemColor::Background
366 | SystemColor::Inactivecaption
367 | SystemColor::Infobackground
368 | SystemColor::Menu
369 | SystemColor::Scrollbar
370 | SystemColor::Window => srgb(255, 255, 255),
371 SystemColor::Canvastext
372 | SystemColor::Captiontext
374 | SystemColor::Infotext
375 | SystemColor::Menutext
376 | SystemColor::Windowtext => srgb(0, 0, 0),
377 SystemColor::Field => srgb(255, 255, 255),
378 SystemColor::Fieldtext => srgb(0, 0, 0),
379 SystemColor::Graytext
380 | SystemColor::Inactivecaptiontext => srgb(109, 109, 109),
382 SystemColor::Highlight => srgb(0, 65, 198),
383 SystemColor::Highlighttext => srgb(0, 0, 0),
384 SystemColor::Mark => srgb(255, 235, 59),
385 SystemColor::Marktext => srgb(0, 0, 0),
386 SystemColor::Selecteditem => srgb(0, 102, 204),
387 SystemColor::Selecteditemtext => srgb(255, 255, 255),
388 }
389 }
390 }
391
392 pub fn safe_area_insets(&self) -> SideOffsets2D<f32, CSSPixel> {
394 SideOffsets2D::zero()
395 }
396
397 pub fn is_supported_mime_type(&self, mime_type: &str) -> bool {
399 match mime_type.parse::<Mime>() {
400 Ok(m) => {
401 m == mime::IMAGE_BMP
404 || m == mime::IMAGE_GIF
405 || m == mime::IMAGE_PNG
406 || m == mime::IMAGE_JPEG
407 || m == "image/x-icon"
408 || m == "image/webp"
409 },
410 _ => false,
411 }
412 }
413
414 #[inline]
416 pub fn chrome_rules_enabled_for_document(&self) -> bool {
417 false
418 }
419}