auto merge of #3837 : pcwalton/servo/layout-formatting-cleanups, r=metajack

These should have no effect on functionality.

r? @metajack
This commit is contained in:
bors-servo 2014-10-28 17:21:48 -06:00
commit 4bdd9a5ec0
8 changed files with 147 additions and 108 deletions

View file

@ -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<Au>) -> LogicalSize<Au> {
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,16 +1616,15 @@ 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() {
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.
// 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
};
@ -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);

View file

@ -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.)

View file

@ -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};

View file

@ -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;

View file

@ -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;

View file

@ -765,10 +765,11 @@ pub struct BaseFlow {
/// Any layers that we're bubbling up, in a linked list.
pub layers: DList<RenderLayer>,
/// 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(),

View file

@ -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,8 +298,7 @@ impl LayoutTask {
}
// Create a layout context for use in building display lists, hit testing, &c.
fn build_shared_layout_context(
&self,
fn build_shared_layout_context(&self,
rw_data: &LayoutTaskData,
reflow_root: &LayoutNode,
url: &Url)
@ -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<MutexGuard<'a, LayoutTaskData>>) -> bool {
fn handle_request<'a>(&'a self,
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>)
-> 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<MutexGuard<'a, LayoutTaskData>>) -> RWGuard<'a> {
fn lock_rw_data<'a>(&'a self,
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>)
-> 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<MutexGuard<'a, LayoutTaskData>>, rw_data: RWGuard<'a>) {
fn return_rw_data<'a>(possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>,
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<MutexGuard<'a, LayoutTaskData>>) -> bool {
fn handle_script_request<'a>(&'a self,
request: Msg,
possibly_locked_rw_data: &mut Option<MutexGuard<'a,
LayoutTaskData>>)
-> 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<LayoutRPC + Send>);
response_chan.send(box LayoutRPCImpl(self.rw_data.clone()) as
Box<LayoutRPC + Send>);
},
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<MutexGuard<'a, LayoutTaskData>>) {
fn prepare_to_exit<'a>(&'a self,
response_chan: Sender<()>,
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
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<MutexGuard<'a, LayoutTaskData>>) {
fn handle_load_stylesheet<'a>(&'a self,
url: Url,
possibly_locked_rw_data:
&mut Option<MutexGuard<'a, LayoutTaskData>>) {
// 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<MutexGuard<'a, LayoutTaskData>>) {
fn handle_add_stylesheet<'a>(&'a self,
sheet: Stylesheet,
possibly_locked_rw_data:
&mut Option<MutexGuard<'a, LayoutTaskData>>) {
// 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<MutexGuard<'a, LayoutTaskData>>) {
fn handle_reflow<'a>(&'a self,
data: &Reflow,
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) {
// 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<Node> = unsafe { JS::from_trusted_node_address(data.document_root) };
let mut node: JS<Node> = unsafe {
JS::from_trusted_node_address(data.document_root)
};
let node: &mut LayoutNode = unsafe {
mem::transmute(&mut node)
};
@ -599,9 +626,7 @@ 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(),
let mut shared_layout_ctx = self.build_shared_layout_context(rw_data.deref(),
node,
&data.url);
@ -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,22 +712,25 @@ 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,
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,
parallel::build_display_list_for_subtree(&mut layout_root,
&data.url,
data.iframe,
self.first_reflow.get(),

View file

@ -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);
}