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::servo::media_features::PointerCapabilities;
17use crate::values::computed::font::GenericFontFamily;
18use crate::values::computed::{CSSPixelLength, Length, LineHeight, NonNegativeLength};
19use crate::values::specified::color::{ColorSchemeFlags, ForcedColors, SystemColor};
20use crate::values::specified::font::{
21 QueryFontMetricsFlags, FONT_MEDIUM_CAP_PX, FONT_MEDIUM_CH_PX, FONT_MEDIUM_EX_PX,
22 FONT_MEDIUM_IC_PX, FONT_MEDIUM_LINE_HEIGHT_PX, FONT_MEDIUM_PX,
23};
24use crate::values::specified::ViewportVariant;
25use crate::values::KeyframesName;
26use app_units::{Au, AU_PER_PX};
27use euclid::default::Size2D as UntypedSize2D;
28use euclid::{Scale, SideOffsets2D, Size2D};
29use malloc_size_of_derive::MallocSizeOf;
30use mime::Mime;
31use parking_lot::RwLock;
32use servo_arc::Arc;
33use std::fmt::Debug;
34use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
35use style_traits::{CSSPixel, DevicePixel};
36
37use crate::device::Device;
38
39pub trait FontMetricsProvider: Debug + Sync {
42 fn query_font_metrics(
44 &self,
45 vertical: bool,
46 font: &Font,
47 base_size: CSSPixelLength,
48 flags: QueryFontMetricsFlags,
49 ) -> FontMetrics;
50 fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length;
52}
53
54#[derive(Debug, MallocSizeOf)]
55pub(super) struct ExtraDeviceData {
56 media_type: MediaType,
58 viewport_size: Size2D<f32, CSSPixel>,
60 device_size: Size2D<f32, DevicePixel>,
62 device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
64 #[ignore_malloc_size_of = "Pure stack type"]
66 quirks_mode: QuirksMode,
67 #[ignore_malloc_size_of = "Pure stack type"]
69 prefers_color_scheme: PrefersColorScheme,
70 #[ignore_malloc_size_of = "Pure stack type"]
72 primary_pointer_capabilities: PointerCapabilities,
73 #[ignore_malloc_size_of = "Pure stack type"]
75 all_pointer_capabilities: PointerCapabilities,
76 #[ignore_malloc_size_of = "Owned by embedder"]
78 font_metrics_provider: Box<dyn FontMetricsProvider>,
79}
80
81impl Device {
82 pub fn new(
84 media_type: MediaType,
85 quirks_mode: QuirksMode,
86 viewport_size: Size2D<f32, CSSPixel>,
87 device_size: Size2D<f32, DevicePixel>,
88 device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
89 font_metrics_provider: Box<dyn FontMetricsProvider>,
90 default_values: Arc<ComputedValues>,
91 prefers_color_scheme: PrefersColorScheme,
92 primary_pointer_capabilities: PointerCapabilities,
93 all_pointer_capabilities: PointerCapabilities,
94 ) -> Device {
95 let root_style = RwLock::new(Arc::clone(&default_values));
96 Device {
97 root_style,
98 root_font_size: AtomicU32::new(FONT_MEDIUM_PX.to_bits()),
99 root_line_height: AtomicU32::new(FONT_MEDIUM_LINE_HEIGHT_PX.to_bits()),
100 root_font_metrics_ex: AtomicU32::new(FONT_MEDIUM_EX_PX.to_bits()),
101 root_font_metrics_cap: AtomicU32::new(FONT_MEDIUM_CAP_PX.to_bits()),
102 root_font_metrics_ch: AtomicU32::new(FONT_MEDIUM_CH_PX.to_bits()),
103 root_font_metrics_ic: AtomicU32::new(FONT_MEDIUM_IC_PX.to_bits()),
104 used_root_font_size: AtomicBool::new(false),
105 used_root_line_height: AtomicBool::new(false),
106 used_root_font_metrics: RwLock::new(false),
107 used_font_metrics: AtomicBool::new(false),
108 used_viewport_size: AtomicBool::new(false),
109 used_dynamic_viewport_size: AtomicBool::new(false),
110 environment: CssEnvironment,
111 default_values,
112 body_text_color: AtomicU32::new(AbsoluteColor::BLACK.to_nscolor()),
113 extra: ExtraDeviceData {
114 media_type,
115 viewport_size,
116 device_size,
117 device_pixel_ratio,
118 quirks_mode,
119 prefers_color_scheme,
120 primary_pointer_capabilities,
121 all_pointer_capabilities,
122 font_metrics_provider,
123 },
124 }
125 }
126
127 pub fn calc_line_height(
131 &self,
132 font: &crate::properties::style_structs::Font,
133 _writing_mode: WritingMode,
134 _element: Option<()>,
135 ) -> NonNegativeLength {
136 (match font.line_height {
137 LineHeight::Normal => CSSPixelLength::new(0.),
139 LineHeight::Number(number) => font.font_size.computed_size() * number.0,
140 LineHeight::Length(length) => length.0,
141 })
142 .into()
143 }
144
145 pub fn quirks_mode(&self) -> QuirksMode {
147 self.extra.quirks_mode
148 }
149
150 pub fn base_size_for_generic(&self, generic: GenericFontFamily) -> Length {
152 self.extra
153 .font_metrics_provider
154 .base_size_for_generic(generic)
155 }
156
157 pub fn animation_name_may_be_referenced(&self, _: &KeyframesName) -> bool {
159 true
161 }
162
163 pub fn viewport_size(&self) -> Size2D<f32, CSSPixel> {
165 self.extra.viewport_size
166 }
167
168 pub fn set_viewport_size(&mut self, viewport_size: Size2D<f32, CSSPixel>) {
174 self.extra.viewport_size = viewport_size;
175 }
176
177 #[inline]
180 pub fn au_viewport_size(&self) -> UntypedSize2D<Au> {
181 Size2D::new(
182 Au::from_f32_px(self.extra.viewport_size.width),
183 Au::from_f32_px(self.extra.viewport_size.height),
184 )
185 }
186
187 pub fn au_viewport_size_for_viewport_unit_resolution(
189 &self,
190 _: ViewportVariant,
191 ) -> UntypedSize2D<Au> {
192 self.used_viewport_size.store(true, Ordering::Relaxed);
193 self.au_viewport_size()
196 }
197
198 pub fn app_units_per_device_pixel(&self) -> i32 {
200 (AU_PER_PX as f32 / self.extra.device_pixel_ratio.0) as i32
201 }
202
203 pub fn device_pixel_ratio_ignoring_full_zoom(&self) -> Scale<f32, CSSPixel, DevicePixel> {
205 self.extra.device_pixel_ratio
206 }
207
208 pub fn device_pixel_ratio(&self) -> Scale<f32, CSSPixel, DevicePixel> {
210 self.extra.device_pixel_ratio
211 }
212
213 pub fn set_device_pixel_ratio(
219 &mut self,
220 device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
221 ) {
222 self.extra.device_pixel_ratio = device_pixel_ratio;
223 }
224
225 pub fn set_device_size(&mut self, device_size: Size2D<f32, DevicePixel>) {
231 self.extra.device_size = device_size;
232 }
233
234 #[inline]
236 pub fn device_size(&self) -> Size2D<f32, DevicePixel> {
237 self.extra.device_size
238 }
239
240 pub fn scrollbar_inline_size(&self) -> CSSPixelLength {
242 CSSPixelLength::new(0.0)
244 }
245
246 pub fn query_font_metrics(
248 &self,
249 vertical: bool,
250 font: &Font,
251 base_size: CSSPixelLength,
252 flags: QueryFontMetricsFlags,
253 track_usage: bool,
254 ) -> FontMetrics {
255 if track_usage {
256 self.used_font_metrics.store(true, Ordering::Relaxed);
257 }
258 self.extra
259 .font_metrics_provider
260 .query_font_metrics(vertical, font, base_size, flags)
261 }
262
263 pub fn media_type(&self) -> MediaType {
265 self.extra.media_type.clone()
266 }
267
268 pub fn forced_colors(&self) -> ForcedColors {
270 ForcedColors::None
271 }
272
273 pub fn default_background_color(&self) -> AbsoluteColor {
275 AbsoluteColor::WHITE
276 }
277
278 pub fn default_color(&self) -> AbsoluteColor {
280 AbsoluteColor::BLACK
281 }
282
283 pub fn set_color_scheme(&mut self, new_color_scheme: PrefersColorScheme) {
289 self.extra.prefers_color_scheme = new_color_scheme;
290 }
291
292 pub fn color_scheme(&self) -> PrefersColorScheme {
294 self.extra.prefers_color_scheme
295 }
296
297 pub fn set_primary_pointer_capabilities(&mut self, capabilities: PointerCapabilities) {
303 self.extra.primary_pointer_capabilities = capabilities;
304 }
305
306 pub fn primary_pointer_capabilities(&self) -> PointerCapabilities {
308 self.extra.primary_pointer_capabilities
309 }
310
311 pub fn set_all_pointer_capabilities(&mut self, capabilities: PointerCapabilities) {
317 self.extra.all_pointer_capabilities = capabilities;
318 }
319
320 pub fn all_pointer_capabilities(&self) -> PointerCapabilities {
322 self.extra.all_pointer_capabilities
323 }
324
325 pub(crate) fn is_dark_color_scheme(&self, _: ColorSchemeFlags) -> bool {
326 false
327 }
328
329 pub(crate) fn system_color(
330 &self,
331 system_color: SystemColor,
332 color_scheme_flags: ColorSchemeFlags,
333 ) -> AbsoluteColor {
334 fn srgb(r: u8, g: u8, b: u8) -> AbsoluteColor {
335 AbsoluteColor::srgb_legacy(r, g, b, 1f32)
336 }
337
338 if self.is_dark_color_scheme(color_scheme_flags) {
341 match system_color {
343 SystemColor::Accentcolor => srgb(10, 132, 255),
344 SystemColor::Accentcolortext => srgb(255, 255, 255),
345 SystemColor::Activetext => srgb(255, 0, 0),
346 SystemColor::Linktext => srgb(158, 158, 255),
347 SystemColor::Visitedtext => srgb(208, 173, 240),
348 SystemColor::Buttonborder
349 | SystemColor::Activeborder
351 | SystemColor::Inactiveborder
352 | SystemColor::Threeddarkshadow
353 | SystemColor::Threedshadow
354 | SystemColor::Windowframe => srgb(255, 255, 255),
355 SystemColor::Buttonface
356 | SystemColor::Buttonhighlight
358 | SystemColor::Buttonshadow
359 | SystemColor::Threedface
360 | SystemColor::Threedhighlight
361 | SystemColor::Threedlightshadow => srgb(107, 107, 107),
362 SystemColor::Buttontext => srgb(245, 245, 245),
363 SystemColor::Canvas
364 | SystemColor::Activecaption
366 | SystemColor::Appworkspace
367 | SystemColor::Background
368 | SystemColor::Inactivecaption
369 | SystemColor::Infobackground
370 | SystemColor::Menu
371 | SystemColor::Scrollbar
372 | SystemColor::Window => srgb(30, 30, 30),
373 SystemColor::Canvastext
374 | SystemColor::Captiontext
376 | SystemColor::Infotext
377 | SystemColor::Menutext
378 | SystemColor::Windowtext => srgb(232, 232, 232),
379 SystemColor::Field => srgb(45, 45, 45),
380 SystemColor::Fieldtext => srgb(240, 240, 240),
381 SystemColor::Graytext
382 | SystemColor::Inactivecaptiontext => srgb(155, 155, 155),
384 SystemColor::Highlight => srgb(38, 79, 120),
385 SystemColor::Highlighttext => srgb(255, 255, 255),
386 SystemColor::Mark => srgb(102, 92, 0),
387 SystemColor::Marktext => srgb(255, 255, 255),
388 SystemColor::Selecteditem => srgb(153, 200, 255),
389 SystemColor::Selecteditemtext => srgb(59, 59, 59),
390 }
391 } else {
392 match system_color {
393 SystemColor::Accentcolor => srgb(0, 102, 204),
394 SystemColor::Accentcolortext => srgb(255, 255, 255),
395 SystemColor::Activetext => srgb(238, 0, 0),
396 SystemColor::Linktext => srgb(0, 0, 238),
397 SystemColor::Visitedtext => srgb(85, 26, 139),
398 SystemColor::Buttonborder
399 | SystemColor::Activeborder
401 | SystemColor::Inactiveborder
402 | SystemColor::Threeddarkshadow
403 | SystemColor::Threedshadow
404 | SystemColor::Windowframe => srgb(169, 169, 169),
405 SystemColor::Buttonface
406 | SystemColor::Buttonhighlight
408 | SystemColor::Buttonshadow
409 | SystemColor::Threedface
410 | SystemColor::Threedhighlight
411 | SystemColor::Threedlightshadow => srgb(220, 220, 220),
412 SystemColor::Buttontext => srgb(0, 0, 0),
413 SystemColor::Canvas
414 | SystemColor::Activecaption
416 | SystemColor::Appworkspace
417 | SystemColor::Background
418 | SystemColor::Inactivecaption
419 | SystemColor::Infobackground
420 | SystemColor::Menu
421 | SystemColor::Scrollbar
422 | SystemColor::Window => srgb(255, 255, 255),
423 SystemColor::Canvastext
424 | SystemColor::Captiontext
426 | SystemColor::Infotext
427 | SystemColor::Menutext
428 | SystemColor::Windowtext => srgb(0, 0, 0),
429 SystemColor::Field => srgb(255, 255, 255),
430 SystemColor::Fieldtext => srgb(0, 0, 0),
431 SystemColor::Graytext
432 | SystemColor::Inactivecaptiontext => srgb(109, 109, 109),
434 SystemColor::Highlight => srgb(0, 65, 198),
435 SystemColor::Highlighttext => srgb(0, 0, 0),
436 SystemColor::Mark => srgb(255, 235, 59),
437 SystemColor::Marktext => srgb(0, 0, 0),
438 SystemColor::Selecteditem => srgb(0, 102, 204),
439 SystemColor::Selecteditemtext => srgb(255, 255, 255),
440 }
441 }
442 }
443
444 pub fn safe_area_insets(&self) -> SideOffsets2D<f32, CSSPixel> {
446 SideOffsets2D::zero()
447 }
448
449 pub fn is_supported_mime_type(&self, mime_type: &str) -> bool {
451 match mime_type.parse::<Mime>() {
452 Ok(m) => {
453 m == mime::IMAGE_BMP
456 || m == mime::IMAGE_GIF
457 || m == mime::IMAGE_PNG
458 || m == mime::IMAGE_JPEG
459 || m == "image/x-icon"
460 || m == "image/webp"
461 },
462 _ => false,
463 }
464 }
465
466 #[inline]
468 pub fn chrome_rules_enabled_for_document(&self) -> bool {
469 false
470 }
471}