diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs index 5b801c1fd7a..f6466e99844 100644 --- a/components/layout_2020/flow/root.rs +++ b/components/layout_2020/flow/root.rs @@ -18,7 +18,8 @@ use crate::replaced::ReplacedContent; use crate::sizing::ContentSizesRequest; use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside}; use crate::DefiniteContainingBlock; -use euclid::Size2D; +use app_units::Au; +use euclid::default::{Point2D, Rect, Size2D}; use gfx_traits::print_tree::PrintTree; use script_layout_interface::wrapper_traits::LayoutNode; use servo_arc::Arc; @@ -35,6 +36,9 @@ pub struct FragmentTreeRoot { /// The scrollable overflow of the root of the fragment tree. scrollable_overflow: physical::Rect, + + /// The axis-aligned bounding box of the border box of all child fragments + bounding_box_of_border_boxes: physical::Rect, } impl BoxTreeRoot { @@ -165,9 +169,32 @@ impl BoxTreeRoot { acc.axis_aligned_bounding_box(&child_overflow) }); + let containing_block = physical::Rect::zero(); + let bounding_box_of_border_boxes = + independent_layout + .fragments + .iter() + .fold(physical::Rect::zero(), |acc, child| { + acc.axis_aligned_bounding_box(&match child { + Fragment::Box(fragment) => fragment + .border_rect() + .to_physical(fragment.style.writing_mode, &containing_block), + Fragment::Anonymous(fragment) => { + fragment.rect.to_physical(fragment.mode, &containing_block) + }, + Fragment::Text(fragment) => fragment + .rect + .to_physical(fragment.parent_style.writing_mode, &containing_block), + Fragment::Image(fragment) => fragment + .rect + .to_physical(fragment.style.writing_mode, &containing_block), + }) + }); + FragmentTreeRoot { children: independent_layout.fragments, scrollable_overflow, + bounding_box_of_border_boxes, } } } @@ -206,4 +233,16 @@ impl FragmentTreeRoot { self.scrollable_overflow.size.y.px(), )) } + + pub fn bounding_box_of_border_boxes(&self) -> Rect { + let origin = Point2D::new( + Au::from_f32_px(self.bounding_box_of_border_boxes.top_left.x.px()), + Au::from_f32_px(self.bounding_box_of_border_boxes.top_left.y.px()), + ); + let size = Size2D::new( + Au::from_f32_px(self.bounding_box_of_border_boxes.size.x.px()), + Au::from_f32_px(self.bounding_box_of_border_boxes.size.y.px()), + ); + Rect::new(origin, size) + } } diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs index 1317759b33b..0a7225c3b3c 100644 --- a/components/layout_2020/query.rs +++ b/components/layout_2020/query.rs @@ -5,6 +5,7 @@ //! Utilities for querying the layout, as needed by the layout thread. use crate::context::LayoutContext; +use crate::flow::FragmentTreeRoot; use app_units::Au; use euclid::default::{Point2D, Rect}; use euclid::Size2D; @@ -163,8 +164,15 @@ impl LayoutRPC for LayoutRPCImpl { } } -pub fn process_content_box_request(_requested_node: OpaqueNode) -> Option> { - None +pub fn process_content_box_request( + _requested_node: OpaqueNode, + fragment_tree_root: Option<&FragmentTreeRoot>, +) -> Option> { + let fragment_tree_root = match fragment_tree_root { + Some(fragment_tree_root) => fragment_tree_root, + None => return None, + }; + Some(fragment_tree_root.bounding_box_of_border_boxes()) } pub fn process_content_boxes_request(_requested_node: OpaqueNode) -> Vec> { diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index b221774390f..295cdabda4e 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -46,7 +46,7 @@ use layout::query::{ process_text_index_request, }; use layout::traversal::RecalcStyle; -use layout::BoxTreeRoot; +use layout::{BoxTreeRoot, FragmentTreeRoot}; use layout_traits::LayoutThreadFactory; use libc::c_void; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; @@ -172,10 +172,10 @@ pub struct LayoutThread { outstanding_web_fonts: Arc, /// The root of the box tree. - box_tree_root: RefCell>, + box_tree_root: RefCell>, /// The root of the fragment tree. - fragment_tree_root: RefCell>, + fragment_tree_root: RefCell>, /// The document-specific shared lock used for author-origin stylesheets document_shared_lock: Option, @@ -1218,7 +1218,10 @@ impl LayoutThread { match *reflow_goal { ReflowGoal::LayoutQuery(ref querymsg, _) => match querymsg { &QueryMsg::ContentBoxQuery(node) => { - rw_data.content_box_response = process_content_box_request(node); + rw_data.content_box_response = process_content_box_request( + node, + (&*self.fragment_tree_root.borrow()).as_ref(), + ); }, &QueryMsg::ContentBoxesQuery(node) => { rw_data.content_boxes_response = process_content_boxes_request(node); @@ -1355,7 +1358,7 @@ impl LayoutThread { fn perform_post_style_recalc_layout_passes( &self, - fragment_tree: &layout::FragmentTreeRoot, + fragment_tree: &FragmentTreeRoot, reflow_goal: &ReflowGoal, document: Option<&ServoLayoutDocument>, context: &mut LayoutContext,