diff options
author | bors-servo <metajack+bors@gmail.com> | 2014-10-08 23:33:33 -0600 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2014-10-08 23:33:33 -0600 |
commit | c4ac93b315f058d9a061b20ce64cacbead339f86 (patch) | |
tree | 65835acd80831ba3b41cd62d62da01b577a3030c | |
parent | eff0de0ce12b20ffc4806d14c95777004003f2ae (diff) | |
parent | 01c90d8d6aa6876a4479d44c167b1b9ab0a7e0ba (diff) | |
download | servo-c4ac93b315f058d9a061b20ce64cacbead339f86.tar.gz servo-c4ac93b315f058d9a061b20ce64cacbead339f86.zip |
auto merge of #3599 : pcwalton/servo/z-index, r=glennw
r? @glennw
-rw-r--r-- | components/gfx/display_list/mod.rs | 8 | ||||
-rw-r--r-- | components/layout/block.rs | 9 | ||||
-rw-r--r-- | components/layout/construct.rs | 7 | ||||
-rw-r--r-- | components/layout/fragment.rs | 22 | ||||
-rw-r--r-- | components/layout/inline.rs | 9 | ||||
-rw-r--r-- | components/layout/layout_task.rs | 3 | ||||
-rw-r--r-- | components/style/properties/mod.rs.mako | 35 | ||||
-rw-r--r-- | components/util/opts.rs | 5 | ||||
-rw-r--r-- | ports/cef/core.rs | 1 |
9 files changed, 81 insertions, 18 deletions
diff --git a/components/gfx/display_list/mod.rs b/components/gfx/display_list/mod.rs index 5025542765c..00a79c9d979 100644 --- a/components/gfx/display_list/mod.rs +++ b/components/gfx/display_list/mod.rs @@ -177,9 +177,6 @@ struct StackingContext { /// All other content. pub content: DisplayList, /// Positioned descendant stacking contexts, along with their `z-index` levels. - /// - /// TODO(pcwalton): `z-index` should be the actual CSS property value in order to handle - /// `auto`, not just an integer. pub positioned_descendants: Vec<(i32, DisplayList)>, } @@ -383,7 +380,10 @@ impl DisplayList { // Steps 1 and 2: Borders and background for the root. result.push_all_move(background_and_borders); - // TODO(pcwalton): Sort positioned children according to z-index. + // Sort positioned children according to z-index. + positioned_descendants.sort_by(|&(z_index_a, _), &(z_index_b, _)| { + z_index_a.cmp(&z_index_b) + }); // Step 3: Positioned descendants with negative z-indices. for &(ref mut z_index, ref mut list) in positioned_descendants.iter_mut() { diff --git a/components/layout/block.rs b/components/layout/block.rs index eff98e27377..ae4f8753d3b 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -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 } diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 83185801772..826a59a7ead 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -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); diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs index 244aa34b24f..aa7e586542f 100644 --- a/components/layout/fragment.rs +++ b/components/layout/fragment.rs @@ -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) { diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 700ffa56602..b9901a3f13b 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -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); diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index e974b1287fc..5e2fb1b4426 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -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())), diff --git a/components/style/properties/mod.rs.mako b/components/style/properties/mod.rs.mako index d51d5d91e14..c5ca7159893 100644 --- a/components/style/properties/mod.rs.mako +++ b/components/style/properties/mod.rs.mako @@ -345,6 +345,41 @@ pub mod longhands { </%self:longhand> + <%self:single_component_value name="z-index"> + pub use super::computed_as_specified as to_computed_value; + pub type SpecifiedValue = computed_value::T; + pub mod computed_value { + #[deriving(PartialEq, Clone)] + pub enum T { + Auto, + Number(i32), + } + + impl T { + pub fn number_or_zero(self) -> i32 { + match self { + Auto => 0, + Number(value) => value, + } + } + } + } + #[inline] + pub fn get_initial_value() -> computed_value::T { + Auto + } + fn from_component_value(input: &ComponentValue, _: &Url) -> Result<SpecifiedValue,()> { + match *input { + Ident(ref keyword) if keyword.as_slice().eq_ignore_ascii_case("auto") => Ok(Auto), + ast::Number(ast::NumericValue { + int_value: Some(value), + .. + }) => Ok(Number(value as i32)), + _ => Err(()) + } + } + </%self:single_component_value> + ${new_style_struct("InheritedBox", is_inherited=True)} ${single_keyword("direction", "ltr rtl", experimental=True)} diff --git a/components/util/opts.rs b/components/util/opts.rs index 47a65797615..de8b295d1eb 100644 --- a/components/util/opts.rs +++ b/components/util/opts.rs @@ -94,6 +94,9 @@ pub struct Opts { /// An optional string allowing the user agent to be set for testing. pub user_agent: Option<String>, + + /// Dumps the flow tree after a layout. + pub dump_flow_tree: bool, } fn print_usage(app: &str, opts: &[getopts::OptGroup]) { @@ -131,6 +134,7 @@ pub fn from_cmdline_args(args: &[String]) -> Option<Opts> { getopts::optflagopt("", "devtools", "Start remote devtools server on port", "6000"), getopts::optopt("", "resolution", "Set window resolution.", "800x600"), getopts::optopt("u", "user-agent", "Set custom user agent string", "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)"), + getopts::optflag("", "dump-flow-tree", "Dump the flow (render) tree during each layout."), getopts::optflag("h", "help", "Print this message") ); @@ -248,6 +252,7 @@ pub fn from_cmdline_args(args: &[String]) -> Option<Opts> { devtools_port: devtools_port, initial_window_size: initial_window_size, user_agent: opt_match.opt_str("u"), + dump_flow_tree: opt_match.opt_present("dump-flow-tree"), }) } diff --git a/ports/cef/core.rs b/ports/cef/core.rs index f08bf007fed..d425252f3a2 100644 --- a/ports/cef/core.rs +++ b/ports/cef/core.rs @@ -71,6 +71,7 @@ pub extern "C" fn cef_run_message_loop() { devtools_port: None, initial_window_size: TypedSize2D(800, 600), user_agent: None, + dump_flow_tree: false, }; native::start(0, 0 as *const *const u8, proc() { servo::run(opts); |