mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Auto merge of #7313 - pcwalton:position-relative-percentage-overflow, r=mbrubeck
layout: Make overflow calculation take relative percentages into account. This necessitated changing overflow to be calculated by the parent flow if relatively positioned children are present. That is because the overflow regions cannot be calculated without knowing relative offsets, which themselves cannot be calculated without knowing the parent size (because of percentages). To accomplish this without sacrificing parallelism in the non-relative case, this patch splits overflow into "early" and "late" computation. Late overflow computation cannot be parallelized across children, while early overflow computation can. Makes the "Apple Music" text show up over the full-bleed promotional background on apple.com. r? @SimonSapin -- would appreciate a look over the iframe test case that was changed. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7313) <!-- Reviewable:end -->
This commit is contained in:
commit
dcaf66397a
19 changed files with 223 additions and 108 deletions
|
@ -36,10 +36,10 @@ use flow::{CLEARS_LEFT, CLEARS_RIGHT};
|
|||
use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
|
||||
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS, INLINE_POSITION_IS_STATIC};
|
||||
use flow::{IS_ABSOLUTELY_POSITIONED};
|
||||
use flow::{ImmutableFlowUtils, MutableFlowUtils, OpaqueFlow, PreorderFlowTraversal};
|
||||
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, MutableFlowUtils, OpaqueFlow};
|
||||
use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
|
||||
use flow::{PostorderFlowTraversal, mut_base};
|
||||
use flow::{self, AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow};
|
||||
use flow::{PostorderFlowTraversal, PreorderFlowTraversal, mut_base};
|
||||
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, ForceNonfloatedFlag, FlowClass, Flow};
|
||||
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, HAS_LAYER};
|
||||
use fragment::{SpecificFragmentInfo};
|
||||
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
|
||||
|
@ -485,7 +485,7 @@ impl<'a> PostorderFlowTraversal for AbsoluteStoreOverflowTraversal<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
flow.store_overflow(self.layout_context);
|
||||
flow.early_store_overflow(self.layout_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -959,6 +959,19 @@ impl BlockFlow {
|
|||
//
|
||||
// FIXME(pcwalton): This looks not idempotent. Is it?
|
||||
self.fragment.border_box.size.block = block_size;
|
||||
}
|
||||
|
||||
// Write in the size of the relative containing block for children. (This information
|
||||
// is also needed to handle RTL.)
|
||||
for kid in self.base.child_iter() {
|
||||
flow::mut_base(kid).early_absolute_position_info = EarlyAbsolutePositionInfo {
|
||||
relative_containing_block_size: self.fragment.content_box().size,
|
||||
relative_containing_block_mode: self.fragment.style().writing_mode,
|
||||
};
|
||||
kid.late_store_overflow(layout_context)
|
||||
}
|
||||
|
||||
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1730,7 +1743,7 @@ impl Flow for BlockFlow {
|
|||
self.base.thread_id = parent_thread_id;
|
||||
if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
|
||||
self.assign_block_size(layout_context);
|
||||
self.store_overflow(layout_context);
|
||||
(self as &mut Flow).early_store_overflow(layout_context);
|
||||
// Don't remove the restyle damage; `assign_block_size` decides whether that is
|
||||
// appropriate (which in the case of e.g. absolutely-positioned flows, it is not).
|
||||
}
|
||||
|
@ -1775,7 +1788,7 @@ impl Flow for BlockFlow {
|
|||
|
||||
fn compute_absolute_position(&mut self, layout_context: &LayoutContext) {
|
||||
if (self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
|
||||
self.base.absolute_position_info.layers_needed_for_positioned_flows) ||
|
||||
self.base.late_absolute_position_info.layers_needed_for_positioned_flows) ||
|
||||
self.base.flags.contains(NEEDS_LAYER) {
|
||||
self.fragment.flags.insert(HAS_LAYER)
|
||||
}
|
||||
|
@ -1816,7 +1829,7 @@ impl Flow for BlockFlow {
|
|||
// Absolute position of the containing block + position of absolute
|
||||
// flow w.r.t. the containing block.
|
||||
self.base
|
||||
.absolute_position_info
|
||||
.late_absolute_position_info
|
||||
.stacking_relative_position_of_absolute_containing_block + position_start
|
||||
};
|
||||
|
||||
|
@ -1842,13 +1855,13 @@ impl Flow for BlockFlow {
|
|||
// other hand, is only established if we are positioned.
|
||||
let relative_offset =
|
||||
self.fragment.relative_position(&self.base
|
||||
.absolute_position_info
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_size);
|
||||
if self.contains_positioned_fragments() {
|
||||
let border_box_origin = (self.fragment.border_box -
|
||||
self.fragment.style.logical_border_width()).start;
|
||||
self.base
|
||||
.absolute_position_info
|
||||
.late_absolute_position_info
|
||||
.stacking_relative_position_of_absolute_containing_block =
|
||||
self.base.stacking_relative_position +
|
||||
(border_box_origin + relative_offset).to_physical(self.base.writing_mode,
|
||||
|
@ -1875,14 +1888,12 @@ impl Flow for BlockFlow {
|
|||
}
|
||||
} else {
|
||||
self.base
|
||||
.absolute_position_info
|
||||
.late_absolute_position_info
|
||||
.stacking_relative_position_of_absolute_containing_block
|
||||
};
|
||||
let absolute_position_info_for_children = AbsolutePositionInfo {
|
||||
let late_absolute_position_info_for_children = LateAbsolutePositionInfo {
|
||||
stacking_relative_position_of_absolute_containing_block:
|
||||
stacking_relative_position_of_absolute_containing_block_for_children,
|
||||
relative_containing_block_size: self.fragment.content_box().size,
|
||||
relative_containing_block_mode: self.base.writing_mode,
|
||||
layers_needed_for_positioned_flows: self.base
|
||||
.flags
|
||||
.contains(LAYERS_NEEDED_FOR_DESCENDANTS),
|
||||
|
@ -1934,10 +1945,10 @@ impl Flow for BlockFlow {
|
|||
self.fragment
|
||||
.stacking_relative_border_box(&self.base.stacking_relative_position,
|
||||
&self.base
|
||||
.absolute_position_info
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_size,
|
||||
self.base
|
||||
.absolute_position_info
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_mode,
|
||||
CoordinateSystem::Own);
|
||||
let clip = self.fragment.clipping_region_for_children(
|
||||
|
@ -1985,7 +1996,8 @@ impl Flow for BlockFlow {
|
|||
}
|
||||
}
|
||||
|
||||
flow::mut_base(kid).absolute_position_info = absolute_position_info_for_children;
|
||||
flow::mut_base(kid).late_absolute_position_info =
|
||||
late_absolute_position_info_for_children;
|
||||
flow::mut_base(kid).clip = clip.clone();
|
||||
flow::mut_base(kid).stacking_relative_position_of_display_port =
|
||||
stacking_relative_position_of_display_port_for_children;
|
||||
|
@ -2056,7 +2068,9 @@ impl Flow for BlockFlow {
|
|||
}
|
||||
|
||||
fn compute_overflow(&self) -> Rect<Au> {
|
||||
self.fragment.compute_overflow()
|
||||
self.fragment.compute_overflow(&self.base
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_size)
|
||||
}
|
||||
|
||||
fn iterate_through_fragment_border_boxes(&self,
|
||||
|
@ -2072,10 +2086,10 @@ impl Flow for BlockFlow {
|
|||
&self.fragment
|
||||
.stacking_relative_border_box(&self.base.stacking_relative_position,
|
||||
&self.base
|
||||
.absolute_position_info
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_size,
|
||||
self.base
|
||||
.absolute_position_info
|
||||
.early_absolute_position_info
|
||||
.relative_containing_block_mode,
|
||||
CoordinateSystem::Own)
|
||||
.translate(stacking_context_position));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue