layout/display_list/
largest_contenful_paint_candidate_collector.rs1use compositing_traits::largest_contentful_paint_candidate::{
6 LCPCandidate, LCPCandidateID, LargestContentfulPaintType,
7};
8use euclid::Rect;
9use servo_geometry::{FastLayoutTransform, au_rect_to_f32_rect, f32_rect_to_au_rect};
10use webrender_api::units::{LayoutRect, LayoutSize};
11
12use crate::query::transform_au_rectangle;
13
14pub(crate) struct LargestContentfulPaintCandidateCollector {
15 pub lcp_candidate: Option<LCPCandidate>,
17 pub viewport_rect: LayoutRect,
19 pub did_lcp_candidate_update: bool,
22}
23
24impl LargestContentfulPaintCandidateCollector {
25 pub fn new(viewport_size: LayoutSize) -> Self {
26 Self {
27 lcp_candidate: None,
28 viewport_rect: LayoutRect::from_size(viewport_size),
29 did_lcp_candidate_update: true,
30 }
31 }
32
33 pub fn add_or_update_candidate(
34 &mut self,
35 lcp_type: LargestContentfulPaintType,
36 lcp_candidate_id: LCPCandidateID,
37 clip_rect: LayoutRect,
38 bounds: LayoutRect,
39 transform: FastLayoutTransform,
40 ) {
41 let clipped_rect = bounds
42 .intersection(&clip_rect)
43 .unwrap_or(LayoutRect::zero());
44 let transformed_rect = transform_au_rectangle(
45 f32_rect_to_au_rect(clipped_rect.to_rect().to_untyped()),
46 transform,
47 )
48 .unwrap_or_default();
49 let transformed_rect = au_rect_to_f32_rect(transformed_rect);
50 let visual_rect = transformed_rect
51 .intersection(&self.viewport_rect.to_rect().to_untyped())
52 .unwrap_or(Rect::zero());
53 let area = visual_rect.size.width * visual_rect.size.height;
54 if area == 0.0 {
55 return;
56 }
57
58 self.update_candidate(LCPCandidate::new(lcp_candidate_id, lcp_type, area as usize));
59 }
60
61 fn update_candidate(&mut self, candidate: LCPCandidate) {
62 if let Some(ref mut latest_candidate) = self.lcp_candidate {
63 if candidate.area > latest_candidate.area {
64 *latest_candidate = candidate;
65 self.did_lcp_candidate_update = true;
66 }
67 } else {
68 self.lcp_candidate = Some(candidate);
69 }
70 }
71
72 pub fn largest_contentful_paint(&self) -> Option<LCPCandidate> {
73 self.lcp_candidate
74 }
75}