mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
layout: Implement z-index
.
This commit is contained in:
parent
eff0de0ce1
commit
01c90d8d6a
9 changed files with 81 additions and 18 deletions
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())),
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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"),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue