diff --git a/components/layout/block.rs b/components/layout/block.rs index 6887895f06b..1fd17ad5e63 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -436,7 +436,7 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> { } let AbsoluteAssignBSizesTraversal(ref ctx) = *self; - block_flow.calculate_abs_block_size_and_margins(*ctx); + block_flow.calculate_absolute_block_size_and_margins(*ctx); } } @@ -631,7 +631,7 @@ impl BlockFlow { } } - /// Compute the used value of inline-size for this Block. + /// Compute the actual inline size and position for this block. pub fn compute_used_inline_size(&mut self, ctx: &LayoutContext, containing_block_inline_size: Au) { @@ -686,7 +686,7 @@ impl BlockFlow { /// reference the CB. #[inline] pub fn containing_block_size(&mut self, viewport_size: Size2D) -> LogicalSize { - assert!(self.is_absolutely_positioned()); + debug_assert!(self.is_absolutely_positioned()); if self.is_fixed() { // Initial containing block is the CB for the root LogicalSize::from_physical(self.base.writing_mode, viewport_size) @@ -1062,6 +1062,7 @@ impl BlockFlow { let margin_offset = LogicalPoint::new(writing_mode, Au(0), self.fragment.margin.block_start); + self.base.position = self.base.position.translate(&float_offset).translate(&margin_offset); } @@ -1071,9 +1072,9 @@ impl BlockFlow { /// The layout for its in-flow children has been done during normal layout. /// This is just the calculation of: /// + block-size for the flow - /// + y-coordinate of the flow wrt its Containing Block. + /// + position in the block direction of the flow with respect to its Containing Block. /// + block-size, vertical margins, and y-coordinate for the flow's box. - fn calculate_abs_block_size_and_margins(&mut self, ctx: &LayoutContext) { + fn calculate_absolute_block_size_and_margins(&mut self, ctx: &LayoutContext) { let containing_block_block_size = self.containing_block_size(ctx.shared.screen_size).block; let static_b_offset = self.static_b_offset; @@ -1098,11 +1099,13 @@ impl BlockFlow { let block_end; { let position = self.fragment.style().logical_position(); - block_start = MaybeAuto::from_style(position.block_start, containing_block_block_size); + block_start = MaybeAuto::from_style(position.block_start, + containing_block_block_size); block_end = MaybeAuto::from_style(position.block_end, containing_block_block_size); } - let available_block_size = containing_block_block_size - self.fragment.border_padding.block_start_end(); + let available_block_size = containing_block_block_size - + self.fragment.border_padding.block_start_end(); if self.is_replaced_content() { // Calculate used value of block-size just like we do for inline replaced elements. // TODO: Pass in the containing block block-size when Fragment's @@ -1348,6 +1351,8 @@ impl BlockFlow { /// on the floats we could see at the time of inline-size assignment. The job of this function, /// therefore, is not only to assign the final size but also to perform the layout again for /// this block formatting context if our speculation was wrong. + /// + /// FIXME(pcwalton): This code is not incremental-reflow-safe (i.e. not idempotent). fn assign_inline_position_for_formatting_context(&mut self) { debug_assert!(self.formatting_context_type() != NonformattingContext); @@ -1611,19 +1616,18 @@ impl Flow for BlockFlow { } if self.is_absolutely_positioned() { - let position_start = self.base.position.start.to_physical( - self.base.writing_mode, container_size); - self.base - .absolute_position_info - .absolute_containing_block_position = if self.is_fixed() { - // The viewport is initially at (0, 0). - position_start - } else { - // Absolute position of the containing block + position of absolute flow w/r/t the - // containing block. - self.base.absolute_position_info.absolute_containing_block_position - + position_start - }; + let position_start = self.base.position.start.to_physical(self.base.writing_mode, + container_size); + self.base.absolute_position_info.absolute_containing_block_position = + if self.is_fixed() { + // The viewport is initially at (0, 0). + position_start + } else { + // Absolute position of the containing block + position of absolute + // flow w.r.t. the containing block. + self.base.absolute_position_info.absolute_containing_block_position + + position_start + }; // Set the absolute position, which will be passed down later as part // of containing block details for absolute descendants. @@ -1929,9 +1933,9 @@ pub trait ISizeAndMarginsComputer { /// Solve the inline-size and margins constraints for this block flow. fn solve_inline_size_constraints(&self, - block: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution; + block: &mut BlockFlow, + input: &ISizeConstraintInput) + -> ISizeConstraintSolution; fn initial_computed_inline_size(&self, block: &mut BlockFlow, @@ -1957,16 +1961,14 @@ pub trait ISizeAndMarginsComputer { /// CSS Section 10.4: Minimum and Maximum inline-sizes fn compute_used_inline_size(&self, block: &mut BlockFlow, - ctx: &LayoutContext, + layout_context: &LayoutContext, parent_flow_inline_size: Au) { let mut input = self.compute_inline_size_constraint_inputs(block, parent_flow_inline_size, - ctx); + layout_context); - let containing_block_inline_size = self.containing_block_inline_size( - block, - parent_flow_inline_size, - ctx); + let containing_block_inline_size = + self.containing_block_inline_size(block, parent_flow_inline_size, layout_context); let mut solution = self.solve_inline_size_constraints(block, &input); @@ -2005,9 +2007,9 @@ pub trait ISizeAndMarginsComputer { /// available_inline-size /// where available_inline-size = CB inline-size - (horizontal border + padding) fn solve_block_inline_size_constraints(&self, - _: &mut BlockFlow, - input: &ISizeConstraintInput) - -> ISizeConstraintSolution { + _: &mut BlockFlow, + input: &ISizeConstraintInput) + -> ISizeConstraintSolution { let (computed_inline_size, inline_start_margin, inline_end_margin, available_inline_size) = (input.computed_inline_size, input.inline_start_margin, diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 424826f5d8c..7a3c3c7f133 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -1192,11 +1192,11 @@ pub trait FlowConstructionUtils { fn add_new_child(&mut self, new_child: FlowRef); /// Finishes a flow. Once a flow is finished, no more child flows or boxes may be added to it. - /// This will normally run the bubble-inline-sizes (minimum and preferred -- i.e. intrinsic -- inline-size) - /// calculation, unless the global `bubble_inline-sizes_separately` flag is on. + /// This will normally run the bubble-inline-sizes (minimum and preferred -- i.e. intrinsic -- + /// inline-size) calculation, unless the global `bubble_inline-sizes_separately` flag is on. /// - /// All flows must be finished at some point, or they will not have their intrinsic inline-sizes - /// properly computed. (This is not, however, a memory safety problem.) + /// All flows must be finished at some point, or they will not have their intrinsic inline- + /// sizes properly computed. (This is not, however, a memory safety problem.) fn finish(&mut self); } @@ -1217,8 +1217,8 @@ impl FlowConstructionUtils for FlowRef { } /// Finishes a flow. Once a flow is finished, no more child flows or fragments may be added to - /// it. This will normally run the bubble-inline-sizes (minimum and preferred -- i.e. intrinsic -- - /// inline-size) calculation, unless the global `bubble_inline-sizes_separately` flag is on. + /// it. This will normally run the bubble-inline-sizes (minimum and preferred -- i.e. intrinsic + /// -- inline-size) calculation, unless the global `bubble_inline-sizes_separately` flag is on. /// /// All flows must be finished at some point, or they will not have their intrinsic inline-sizes /// properly computed. (This is not, however, a memory safety problem.) diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index 2c30e9d8fd2..f41193400a2 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -// High-level interface to CSS selector matching. +//! High-level interface to CSS selector matching. use css::node_style::StyledNode; use util::{LayoutDataAccess, LayoutDataWrapper}; @@ -550,20 +550,20 @@ impl<'ln> MatchMethods for LayoutNode<'ln> { applicable_declarations_cache, applicable_declarations.normal_shareable); if applicable_declarations.before.len() > 0 { - self.cascade_node_pseudo_element( - Some(layout_data.shared_data.style.as_ref().unwrap()), - applicable_declarations.before.as_slice(), - &mut layout_data.data.before_style, - applicable_declarations_cache, - false); + self.cascade_node_pseudo_element( + Some(layout_data.shared_data.style.as_ref().unwrap()), + applicable_declarations.before.as_slice(), + &mut layout_data.data.before_style, + applicable_declarations_cache, + false); } if applicable_declarations.after.len() > 0 { - self.cascade_node_pseudo_element( - Some(layout_data.shared_data.style.as_ref().unwrap()), - applicable_declarations.after.as_slice(), - &mut layout_data.data.after_style, - applicable_declarations_cache, - false); + self.cascade_node_pseudo_element( + Some(layout_data.shared_data.style.as_ref().unwrap()), + applicable_declarations.after.as_slice(), + &mut layout_data.data.after_style, + applicable_declarations_cache, + false); } } } diff --git a/components/layout/css/node_util.rs b/components/layout/css/node_util.rs index c5268abf169..80144d50022 100644 --- a/components/layout/css/node_util.rs +++ b/components/layout/css/node_util.rs @@ -6,6 +6,7 @@ use incremental::RestyleDamage; use util::LayoutDataAccess; use wrapper::ThreadSafeLayoutNode; use wrapper::{After, Before, Normal}; + use std::mem; use style::ComputedValues; use sync::Arc; diff --git a/components/layout/floats.rs b/components/layout/floats.rs index e531fc49798..7a212c5e295 100644 --- a/components/layout/floats.rs +++ b/components/layout/floats.rs @@ -216,7 +216,7 @@ impl Floats { let mut r_block_start = None; let mut r_block_end = None; - // Find the float collisions for the given vertical range. + // Find the float collisions for the given range in the block direction. for float in list.floats.iter() { debug!("available_rect: Checking for collision against float"); let float_pos = float.bounds.start; diff --git a/components/layout/flow.rs b/components/layout/flow.rs index 81f06de9094..0d2ac4f5c94 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -765,10 +765,11 @@ pub struct BaseFlow { /// Any layers that we're bubbling up, in a linked list. pub layers: DList, + /// The writing mode for this flow. + pub writing_mode: WritingMode, + /// Various flags for flows, tightly packed to save space. pub flags: FlowFlags, - - pub writing_mode: WritingMode, } impl fmt::Show for BaseFlow { @@ -824,9 +825,7 @@ impl BaseFlow { intrinsic_inline_sizes: IntrinsicISizes::new(), position: LogicalRect::zero(writing_mode), overflow: LogicalRect::zero(writing_mode), - parallel: FlowParallelInfo::new(), - floats: Floats::new(writing_mode), collapsible_margins: CollapsibleMargins::new(), abs_position: Zero::zero(), diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index d35aed10bcd..fcaf3051019 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -250,7 +250,8 @@ impl LayoutTask { font_cache_task: FontCacheTask, time_profiler_chan: TimeProfilerChan) -> LayoutTask { - let local_image_cache = Arc::new(Mutex::new(LocalImageCache::new(image_cache_task.clone()))); + let local_image_cache = + Arc::new(Mutex::new(LocalImageCache::new(image_cache_task.clone()))); let screen_size = Size2D(Au(0), Au(0)); let device = Device::new(Screen, opts::get().initial_window_size.as_f32()); let parallel_traversal = if opts::get().layout_threads != 1 { @@ -297,12 +298,11 @@ impl LayoutTask { } // Create a layout context for use in building display lists, hit testing, &c. - fn build_shared_layout_context( - &self, - rw_data: &LayoutTaskData, - reflow_root: &LayoutNode, - url: &Url) - -> SharedLayoutContext { + fn build_shared_layout_context(&self, + rw_data: &LayoutTaskData, + reflow_root: &LayoutNode, + url: &Url) + -> SharedLayoutContext { SharedLayoutContext { image_cache: rw_data.local_image_cache.clone(), screen_size: rw_data.screen_size.clone(), @@ -318,7 +318,9 @@ impl LayoutTask { } /// Receives and dispatches messages from the script and constellation tasks - fn handle_request<'a>(&'a self, possibly_locked_rw_data: &mut Option>) -> bool { + fn handle_request<'a>(&'a self, + possibly_locked_rw_data: &mut Option>) + -> bool { enum PortToRead { Pipeline, Script, @@ -343,8 +345,12 @@ impl LayoutTask { }; match port_to_read { - Pipeline => match self.pipeline_port.recv() { - layout_traits::ExitNowMsg => self.handle_script_request(ExitNowMsg, possibly_locked_rw_data), + Pipeline => { + match self.pipeline_port.recv() { + layout_traits::ExitNowMsg => { + self.handle_script_request(ExitNowMsg, possibly_locked_rw_data) + } + } }, Script => { let msg = self.port.recv(); @@ -359,17 +365,20 @@ impl LayoutTask { /// If you do not wish RPCs to remain blocked, just drop the `RWGuard` /// returned from this function. If you _do_ wish for them to remain blocked, /// use `return_rw_data`. - fn lock_rw_data<'a>(&'a self, possibly_locked_rw_data: &mut Option>) -> RWGuard<'a> { + fn lock_rw_data<'a>(&'a self, + possibly_locked_rw_data: &mut Option>) + -> RWGuard<'a> { match possibly_locked_rw_data.take() { None => Used(self.rw_data.lock()), Some(x) => Held(x), } } - /// If no reflow has ever been trigger, this will keep the lock, locked + /// If no reflow has ever been triggered, this will keep the lock, locked /// (and saved in `possibly_locked_rw_data`). If it has been, the lock will /// be unlocked. - fn return_rw_data<'a>(possibly_locked_rw_data: &mut Option>, rw_data: RWGuard<'a>) { + fn return_rw_data<'a>(possibly_locked_rw_data: &mut Option>, + rw_data: RWGuard<'a>) { match rw_data { Used(x) => drop(x), Held(x) => *possibly_locked_rw_data = Some(x), @@ -377,20 +386,23 @@ impl LayoutTask { } /// Receives and dispatches messages from the script task. - fn handle_script_request<'a>(&'a self, request: Msg, possibly_locked_rw_data: &mut Option>) -> bool { + fn handle_script_request<'a>(&'a self, + request: Msg, + possibly_locked_rw_data: &mut Option>) + -> bool { match request { AddStylesheetMsg(sheet) => self.handle_add_stylesheet(sheet, possibly_locked_rw_data), LoadStylesheetMsg(url) => self.handle_load_stylesheet(url, possibly_locked_rw_data), GetRPCMsg(response_chan) => { - response_chan.send( - box LayoutRPCImpl( - self.rw_data.clone()) as Box); + response_chan.send(box LayoutRPCImpl(self.rw_data.clone()) as + Box); }, ReflowMsg(data) => { - profile(time::LayoutPerformCategory, Some((&data.url, data.iframe, self.first_reflow.get())), - self.time_profiler_chan.clone(), || { - self.handle_reflow(&*data, possibly_locked_rw_data); - }); + profile(time::LayoutPerformCategory, + Some((&data.url, data.iframe, self.first_reflow.get())), + self.time_profiler_chan.clone(), + || self.handle_reflow(&*data, possibly_locked_rw_data)); }, ReapLayoutDataMsg(dead_layout_data) => { unsafe { @@ -415,7 +427,9 @@ impl LayoutTask { /// Enters a quiescent state in which no new messages except for `ReapLayoutDataMsg` will be /// processed until an `ExitNowMsg` is received. A pong is immediately sent on the given /// response channel. - fn prepare_to_exit<'a>(&'a self, response_chan: Sender<()>, possibly_locked_rw_data: &mut Option>) { + fn prepare_to_exit<'a>(&'a self, + response_chan: Sender<()>, + possibly_locked_rw_data: &mut Option>) { response_chan.send(()); loop { match self.port.recv() { @@ -455,7 +469,10 @@ impl LayoutTask { response_port.recv() } - fn handle_load_stylesheet<'a>(&'a self, url: Url, possibly_locked_rw_data: &mut Option>) { + fn handle_load_stylesheet<'a>(&'a self, + url: Url, + possibly_locked_rw_data: + &mut Option>) { // TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding let environment_encoding = UTF_8 as EncodingRef; @@ -463,11 +480,17 @@ impl LayoutTask { let protocol_encoding_label = metadata.charset.as_ref().map(|s| s.as_slice()); let final_url = metadata.final_url; - let sheet = Stylesheet::from_bytes_iter(iter, final_url, protocol_encoding_label, Some(environment_encoding)); + let sheet = Stylesheet::from_bytes_iter(iter, + final_url, + protocol_encoding_label, + Some(environment_encoding)); self.handle_add_stylesheet(sheet, possibly_locked_rw_data); } - fn handle_add_stylesheet<'a>(&'a self, sheet: Stylesheet, possibly_locked_rw_data: &mut Option>) { + fn handle_add_stylesheet<'a>(&'a self, + sheet: Stylesheet, + possibly_locked_rw_data: + &mut Option>) { // Find all font-face rules and notify the font cache of them. // GWTODO: Need to handle unloading web fonts (when we handle unloading stylesheets!) iter_font_face_rules(&sheet, &self.device, |family, src| { @@ -566,11 +589,15 @@ impl LayoutTask { } /// The high-level routine that performs layout tasks. - fn handle_reflow<'a>(&'a self, data: &Reflow, possibly_locked_rw_data: &mut Option>) { + fn handle_reflow<'a>(&'a self, + data: &Reflow, + possibly_locked_rw_data: &mut Option>) { // FIXME: Isolate this transmutation into a "bridge" module. // FIXME(rust#16366): The following line had to be moved because of a // rustc bug. It should be in the next unsafe block. - let mut node: JS = unsafe { JS::from_trusted_node_address(data.document_root) }; + let mut node: JS = unsafe { + JS::from_trusted_node_address(data.document_root) + }; let node: &mut LayoutNode = unsafe { mem::transmute(&mut node) }; @@ -599,11 +626,9 @@ impl LayoutTask { rw_data.screen_size = current_screen_size; // Create a layout context for use throughout the following passes. - let mut shared_layout_ctx = - self.build_shared_layout_context( - rw_data.deref(), - node, - &data.url); + let mut shared_layout_ctx = self.build_shared_layout_context(rw_data.deref(), + node, + &data.url); // Handle conditions where the entire flow tree is invalid. let needs_dirtying = rw_data.stylesheet_dirty; @@ -664,8 +689,10 @@ impl LayoutTask { // Perform the primary layout passes over the flow tree to compute the locations of all // the boxes. - profile(time::LayoutMainCategory, Some((&data.url, data.iframe, self.first_reflow.get())), - self.time_profiler_chan.clone(), || { + profile(time::LayoutMainCategory, + Some((&data.url, data.iframe, self.first_reflow.get())), + self.time_profiler_chan.clone(), + || { let rw_data = rw_data.deref_mut(); match rw_data.parallel_traversal { None => { @@ -674,7 +701,10 @@ impl LayoutTask { } Some(_) => { // Parallel mode. - self.solve_constraints_parallel(data, rw_data, &mut layout_root, &mut shared_layout_ctx) + self.solve_constraints_parallel(data, + rw_data, + &mut layout_root, + &mut shared_layout_ctx); } } }); @@ -682,28 +712,31 @@ impl LayoutTask { // Build the display list if necessary, and send it to the renderer. if data.goal == ReflowForDisplay { let writing_mode = flow::base(layout_root.deref()).writing_mode; - profile(time::LayoutDispListBuildCategory, Some((&data.url, data.iframe, self.first_reflow.get())), self.time_profiler_chan.clone(), || { - shared_layout_ctx.dirty = flow::base(layout_root.deref()).position.to_physical( - writing_mode, rw_data.screen_size); + profile(time::LayoutDispListBuildCategory, + Some((&data.url, data.iframe, self.first_reflow.get())), + self.time_profiler_chan.clone(), + || { + shared_layout_ctx.dirty = + flow::base(layout_root.deref()).position.to_physical(writing_mode, + rw_data.screen_size); flow::mut_base(layout_root.deref_mut()).abs_position = - LogicalPoint::zero(writing_mode).to_physical(writing_mode, rw_data.screen_size); + LogicalPoint::zero(writing_mode).to_physical(writing_mode, + rw_data.screen_size); let rw_data = rw_data.deref_mut(); match rw_data.parallel_traversal { None => { - sequential::build_display_list_for_subtree( - &mut layout_root, - &shared_layout_ctx); + sequential::build_display_list_for_subtree(&mut layout_root, + &shared_layout_ctx); } Some(ref mut traversal) => { - parallel::build_display_list_for_subtree( - &mut layout_root, - &data.url, - data.iframe, - self.first_reflow.get(), - self.time_profiler_chan.clone(), - &shared_layout_ctx, - traversal); + parallel::build_display_list_for_subtree(&mut layout_root, + &data.url, + data.iframe, + self.first_reflow.get(), + self.time_profiler_chan.clone(), + &shared_layout_ctx, + traversal); } } diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 20f41ff58cb..57afc925918 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -37,7 +37,9 @@ pub fn traverse_dom_preorder(root: LayoutNode, pub fn traverse_flow_tree_preorder(root: &mut FlowRef, shared_layout_context: &SharedLayoutContext) { - fn doit(flow: &mut Flow, assign_inline_sizes: AssignISizes, assign_block_sizes: AssignBSizesAndStoreOverflow) { + fn doit(flow: &mut Flow, + assign_inline_sizes: AssignISizes, + assign_block_sizes: AssignBSizesAndStoreOverflow) { if assign_inline_sizes.should_process(flow) { assign_inline_sizes.process(flow); } @@ -68,7 +70,9 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef, pub fn build_display_list_for_subtree(root: &mut FlowRef, shared_layout_context: &SharedLayoutContext) { - fn doit(flow: &mut Flow, compute_absolute_positions: ComputeAbsolutePositions, build_display_list: BuildDisplayList) { + fn doit(flow: &mut Flow, + compute_absolute_positions: ComputeAbsolutePositions, + build_display_list: BuildDisplayList) { if compute_absolute_positions.should_process(flow) { compute_absolute_positions.process(flow); }