layout: Implement z-index.

This commit is contained in:
Patrick Walton 2014-10-02 14:11:04 -07:00
parent eff0de0ce1
commit 01c90d8d6a
9 changed files with 81 additions and 18 deletions

View file

@ -1239,11 +1239,10 @@ impl BlockFlow {
if !self.base.absolute_position_info.layers_needed_for_positioned_flows &&
!self.base.flags.needs_layer() {
// We didn't need a layer.
//
// TODO(#781, pcwalton): `z-index`.
self.base.display_list =
mem::replace(&mut self.base.display_list,
DisplayList::new()).flatten(PositionedDescendantStackingLevel(0));
let z_index = self.fragment.style().get_box().z_index.number_or_zero();
let level = PositionedDescendantStackingLevel(z_index);
self.base.display_list = mem::replace(&mut self.base.display_list,
DisplayList::new()).flatten(level);
return
}

View file

@ -330,12 +330,17 @@ impl<'a> FlowConstructor<'a> {
{
let inline_flow = inline_flow_ref.get_mut().as_inline();
// We must scan for runs before computing minimum ascent and descent because scanning
// for runs might collapse so much whitespace away that only hypothetical fragments
// remain. In that case the inline flow will compute its ascent and descent to be zero.
TextRunScanner::new().scan_for_runs(self.layout_context.font_context(), inline_flow);
let (ascent, descent) =
inline_flow.compute_minimum_ascent_and_descent(self.layout_context.font_context(),
&**node.style());
inline_flow.minimum_block_size_above_baseline = ascent;
inline_flow.minimum_depth_below_baseline = descent;
TextRunScanner::new().scan_for_runs(self.layout_context.font_context(), inline_flow);
}
inline_flow_ref.finish(self.layout_context);

View file

@ -1701,13 +1701,13 @@ impl Fragment {
&font_style);
InlineMetrics::from_block_height(&font_metrics, block_flow.base.position.size.block)
}
InlineAbsoluteHypotheticalFragment(ref info) => {
// See CSS 2.1 § 10.8.1.
let block_flow = info.flow_ref.get().as_immutable_block();
let font_style = text::computed_style_to_font_style(&*self.style);
let font_metrics = text::font_metrics_for_style(layout_context.font_context(),
&font_style);
InlineMetrics::from_block_height(&font_metrics, block_flow.base.position.size.block)
InlineAbsoluteHypotheticalFragment(_) => {
// Hypothetical boxes take up no space.
InlineMetrics {
block_size_above_baseline: Au(0),
depth_below_baseline: Au(0),
ascent: Au(0),
}
}
_ => {
InlineMetrics {
@ -1719,6 +1719,14 @@ impl Fragment {
}
}
/// Returns true if this fragment is a hypothetical box. See CSS 2.1 § 10.3.7.
pub fn is_hypothetical(&self) -> bool {
match self.specific {
InlineAbsoluteHypotheticalFragment(_) => true,
_ => false,
}
}
/// Returns true if this fragment can merge with another adjacent fragment or false otherwise.
pub fn can_merge_with_fragment(&self, other: &Fragment) -> bool {
match (&self.specific, &other.specific) {

View file

@ -943,7 +943,14 @@ impl InlineFlow {
/// `style` is the style of the block.
pub fn compute_minimum_ascent_and_descent(&self,
font_context: &mut FontContext,
style: &ComputedValues) -> (Au, Au) {
style: &ComputedValues)
-> (Au, Au) {
// As a special case, if this flow contains only hypothetical fragments, then the entire
// flow is hypothetical and takes up no space. See CSS 2.1 § 10.3.7.
if self.fragments.fragments.iter().all(|fragment| fragment.is_hypothetical()) {
return (Au(0), Au(0))
}
let font_style = text::computed_style_to_font_style(style);
let font_metrics = text::font_metrics_for_style(font_context, &font_style);
let line_height = text::line_height_from_style(style, &font_metrics);

View file

@ -800,6 +800,9 @@ impl LayoutTask {
if self.opts.trace_layout {
layout_debug::begin_trace(layout_root.clone());
}
if self.opts.dump_flow_tree {
layout_root.get_mut().dump();
}
// Propagate damage.
profile(time::LayoutDamagePropagateCategory, Some((&data.url, data.iframe, self.first_reflow.get())),