Skip to content

Commit

Permalink
Auto merge of #27488 - Manishearth:tables-2020, r=pcwalton
Browse files Browse the repository at this point in the history
2020: Implement table map construction

Progress towards #27459

This PR does not do any table  layout whatsoever, nor does it even
construct boxes for table elements.

What this does is construct the CellMap, which makes it easy to find
which cells are occupying each slot of the table. This will be useful
when iterating over the table repeatedly during the layout algorithms.
  • Loading branch information
bors-servo committed Aug 11, 2020
2 parents 1470fd3 + c76f6e9 commit 57a87f3
Show file tree
Hide file tree
Showing 13 changed files with 690 additions and 58 deletions.
3 changes: 3 additions & 0 deletions components/config/prefs.rs
Expand Up @@ -445,6 +445,9 @@ mod gen {
flexbox: {
enabled: bool,
},
table: {
enabled: bool,
},
#[serde(default = "default_layout_threads")]
threads: i64,
viewport: {
Expand Down
4 changes: 1 addition & 3 deletions components/layout_2020/flexbox/construct.rs
Expand Up @@ -163,9 +163,7 @@ where
contents,
box_slot,
} => {
let display_inside = match display {
DisplayGeneratingBox::OutsideInside { inside, .. } => inside,
};
let display_inside = display.display_inside();
let box_ = if info.style.get_box().position.is_absolutely_positioned() {
// https://drafts.csswg.org/css-flexbox/#abspos-items
ArcRefCell::new(FlexLevelBox::OutOfFlowAbsolutelyPositionedBox(
Expand Down
4 changes: 4 additions & 0 deletions components/layout_2020/flow/construct.rs
Expand Up @@ -290,6 +290,10 @@ where
}
},
},
DisplayGeneratingBox::Internal(_internal) => {
// XXXManishearth This can be unreachable once we have table fixups
todo!()
},
}
}

Expand Down
5 changes: 5 additions & 0 deletions components/layout_2020/flow/inline.rs
Expand Up @@ -307,6 +307,11 @@ impl InlineFormattingContext {
},
block: ifc.lines.next_line_block_position,
},
Display::GeneratingBox(DisplayGeneratingBox::Internal(_)) => {
panic!(
"the result of blockification is never a layout-internal value"
);
},
Display::Contents => {
panic!("display:contents does not generate an abspos box")
},
Expand Down
2 changes: 1 addition & 1 deletion components/layout_2020/flow/root.rs
Expand Up @@ -260,7 +260,7 @@ fn construct_for_root_element<'dom>(
unreachable!()
},
// The root element is blockified, ignore DisplayOutside
Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { inside, .. }) => inside,
Display::GeneratingBox(oi) => oi.display_inside(),
};

let contents =
Expand Down
17 changes: 17 additions & 0 deletions components/layout_2020/formatting_contexts.rs
Expand Up @@ -11,6 +11,7 @@ use crate::positioned::PositioningContext;
use crate::replaced::ReplacedContent;
use crate::sizing::{self, ContentSizes};
use crate::style_ext::DisplayInside;
use crate::table::TableContainer;
use crate::ContainingBlock;
use servo_arc::Arc;
use std::convert::TryInto;
Expand Down Expand Up @@ -50,6 +51,7 @@ pub(crate) struct ReplacedFormattingContext {
pub(crate) enum NonReplacedFormattingContextContents {
Flow(BlockFormattingContext),
Flex(FlexContainer),
Table(TableContainer),
// Other layout modes go here
}

Expand Down Expand Up @@ -91,6 +93,14 @@ impl IndependentFormattingContext {
propagated_text_decoration_line,
))
},
DisplayInside::Table => {
NonReplacedFormattingContextContents::Table(TableContainer::construct(
context,
info,
non_replaced,
propagated_text_decoration_line,
))
},
};
Self::NonReplaced(NonReplacedFormattingContext {
tag: Tag::from_node_and_style_info(info),
Expand Down Expand Up @@ -206,6 +216,12 @@ impl NonReplacedFormattingContext {
containing_block,
tree_rank,
),
NonReplacedFormattingContextContents::Table(tc) => tc.layout(
layout_context,
positioning_context,
containing_block,
tree_rank,
),
}
}

Expand All @@ -229,6 +245,7 @@ impl NonReplacedFormattingContextContents {
.contents
.inline_content_sizes(layout_context, writing_mode),
Self::Flex(inner) => inner.inline_content_sizes(),
Self::Table(table) => table.inline_content_sizes(),
}
}
}
1 change: 1 addition & 0 deletions components/layout_2020/lib.rs
Expand Up @@ -29,6 +29,7 @@ pub mod query;
mod replaced;
mod sizing;
mod style_ext;
pub mod table;
pub mod traversal;
pub mod wrapper;

Expand Down
89 changes: 76 additions & 13 deletions components/layout_2020/style_ext.rs
Expand Up @@ -21,36 +21,71 @@ use style::values::specified::box_ as stylo;
use style::Zero;
use webrender_api as wr;

#[derive(Clone, Copy, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum Display {
None,
Contents,
GeneratingBox(DisplayGeneratingBox),
}

#[derive(Clone, Copy, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum DisplayGeneratingBox {
OutsideInside {
outside: DisplayOutside,
inside: DisplayInside,
},
// Layout-internal display types go here:
// https://drafts.csswg.org/css-display-3/#layout-specific-display
Internal(DisplayInternal), // Layout-internal display types go here:
// https://drafts.csswg.org/css-display-3/#layout-specific-display
}

#[derive(Clone, Copy, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum DisplayOutside {
Block,
Inline,
}

#[derive(Clone, Copy, Eq, PartialEq)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum DisplayInside {
// “list-items are limited to the Flow Layout display types”
// https://drafts.csswg.org/css-display/#list-items
Flow { is_list_item: bool },
FlowRoot { is_list_item: bool },
Flex,
Table,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
/// https://drafts.csswg.org/css-display-3/#layout-specific-display
pub(crate) enum DisplayInternal {
TableRowGroup,
TableColumn,
TableColumnGroup,
TableHeaderGroup,
TableFooterGroup,
TableRow,
TableCell,
TableCaption,
}

impl DisplayInternal {
/// https://drafts.csswg.org/css-display-3/#layout-specific-displa
pub(crate) fn display_inside(&self) -> DisplayInside {
// When we add ruby, the display_inside of ruby must be Flow
// XXXManishearth this should be unreachable for everything but
// table cell and caption, once we have box tree fixups
DisplayInside::FlowRoot {
is_list_item: false,
}
}
}

impl DisplayGeneratingBox {
pub(crate) fn display_inside(&self) -> DisplayInside {
match *self {
DisplayGeneratingBox::OutsideInside { inside, .. } => inside,
DisplayGeneratingBox::Internal(i) => i.display_inside(),
}
}
}

/// Percentages resolved but not `auto` margins
Expand Down Expand Up @@ -444,6 +479,31 @@ impl ComputedValuesExt for ComputedValues {

impl From<stylo::Display> for Display {
fn from(packed: stylo::Display) -> Self {
let outside = packed.outside();
let outside = match outside {
stylo::DisplayOutside::Block => DisplayOutside::Block,
stylo::DisplayOutside::Inline => DisplayOutside::Inline,
stylo::DisplayOutside::TableCaption => {
return Display::GeneratingBox(DisplayGeneratingBox::Internal(
DisplayInternal::TableCaption,
));
},
stylo::DisplayOutside::InternalTable => {
let internal = match packed.inside() {
stylo::DisplayInside::TableRowGroup => DisplayInternal::TableRowGroup,
stylo::DisplayInside::TableColumn => DisplayInternal::TableColumn,
stylo::DisplayInside::TableColumnGroup => DisplayInternal::TableColumnGroup,
stylo::DisplayInside::TableHeaderGroup => DisplayInternal::TableHeaderGroup,
stylo::DisplayInside::TableFooterGroup => DisplayInternal::TableFooterGroup,
stylo::DisplayInside::TableRow => DisplayInternal::TableRow,
stylo::DisplayInside::TableCell => DisplayInternal::TableCell,
_ => unreachable!("Non-internal DisplayInside found"),
};
return Display::GeneratingBox(DisplayGeneratingBox::Internal(internal));
},
// This should not be a value of DisplayInside, but oh well
stylo::DisplayOutside::None => return Display::None,
};
let inside = match packed.inside() {
stylo::DisplayInside::Flow => DisplayInside::Flow {
is_list_item: packed.is_list_item(),
Expand All @@ -452,18 +512,21 @@ impl From<stylo::Display> for Display {
is_list_item: packed.is_list_item(),
},
stylo::DisplayInside::Flex => DisplayInside::Flex,
stylo::DisplayInside::Table => DisplayInside::Table,
stylo::DisplayInside::TableRowGroup |
stylo::DisplayInside::TableColumn |
stylo::DisplayInside::TableColumnGroup |
stylo::DisplayInside::TableHeaderGroup |
stylo::DisplayInside::TableFooterGroup |
stylo::DisplayInside::TableRow |
stylo::DisplayInside::TableCell => {
unreachable!("Table display values should be handled by TableInternal")
},

// These should not be values of DisplayInside, but oh well
stylo::DisplayInside::None => return Display::None,
stylo::DisplayInside::Contents => return Display::Contents,
};
let outside = match packed.outside() {
stylo::DisplayOutside::Block => DisplayOutside::Block,
stylo::DisplayOutside::Inline => DisplayOutside::Inline,

// This should not be a value of DisplayInside, but oh well
stylo::DisplayOutside::None => return Display::None,
};
Display::GeneratingBox(DisplayGeneratingBox::OutsideInside { outside, inside })
}
}
Expand Down

0 comments on commit 57a87f3

Please sign in to comment.