aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/table.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout/table.rs')
-rw-r--r--components/layout/table.rs103
1 files changed, 68 insertions, 35 deletions
diff --git a/components/layout/table.rs b/components/layout/table.rs
index 20bc19c91fc..b65fa689919 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -34,8 +34,13 @@ use sync::Arc;
pub struct TableFlow {
pub block_flow: BlockFlow,
- /// Information about the inline-sizes of each column.
- pub column_inline_sizes: Vec<ColumnInlineSize>,
+ /// Information about the intrinsic inline-sizes of each column, computed bottom-up during
+ /// intrinsic inline-size bubbling.
+ pub column_intrinsic_inline_sizes: Vec<ColumnIntrinsicInlineSize>,
+
+ /// Information about the actual inline-sizes of each column, computed top-down during actual
+ /// inline-size bubbling.
+ pub column_computed_inline_sizes: Vec<ColumnComputedInlineSize>,
/// Table-layout property
pub table_layout: TableLayout,
@@ -54,7 +59,8 @@ impl TableFlow {
};
TableFlow {
block_flow: block_flow,
- column_inline_sizes: Vec::new(),
+ column_intrinsic_inline_sizes: Vec::new(),
+ column_computed_inline_sizes: Vec::new(),
table_layout: table_layout
}
}
@@ -71,7 +77,8 @@ impl TableFlow {
};
TableFlow {
block_flow: block_flow,
- column_inline_sizes: Vec::new(),
+ column_intrinsic_inline_sizes: Vec::new(),
+ column_computed_inline_sizes: Vec::new(),
table_layout: table_layout
}
}
@@ -89,7 +96,8 @@ impl TableFlow {
};
TableFlow {
block_flow: block_flow,
- column_inline_sizes: Vec::new(),
+ column_intrinsic_inline_sizes: Vec::new(),
+ column_computed_inline_sizes: Vec::new(),
table_layout: table_layout
}
}
@@ -97,13 +105,13 @@ impl TableFlow {
/// Update the corresponding value of `self_inline_sizes` if a value of `kid_inline_sizes` has
/// a larger value than one of `self_inline_sizes`. Returns the minimum and preferred inline
/// sizes.
- pub fn update_column_inline_sizes(parent_inline_sizes: &mut Vec<ColumnInlineSize>,
- child_inline_sizes: &Vec<ColumnInlineSize>)
+ pub fn update_column_inline_sizes(parent_inline_sizes: &mut Vec<ColumnIntrinsicInlineSize>,
+ child_inline_sizes: &Vec<ColumnIntrinsicInlineSize>)
-> IntrinsicISizes {
let mut total_inline_sizes = IntrinsicISizes::new();
for (parent_sizes, child_sizes) in parent_inline_sizes.iter_mut()
.zip(child_inline_sizes.iter()) {
- *parent_sizes = ColumnInlineSize {
+ *parent_sizes = ColumnIntrinsicInlineSize {
minimum_length: max(parent_sizes.minimum_length, child_sizes.minimum_length),
percentage: parent_sizes.greatest_percentage(child_sizes),
preferred: max(parent_sizes.preferred, child_sizes.preferred),
@@ -147,8 +155,12 @@ impl Flow for TableFlow {
&mut self.block_flow
}
- fn column_inline_sizes<'a>(&'a mut self) -> &'a mut Vec<ColumnInlineSize> {
- &mut self.column_inline_sizes
+ fn column_intrinsic_inline_sizes<'a>(&'a mut self) -> &'a mut Vec<ColumnIntrinsicInlineSize> {
+ &mut self.column_intrinsic_inline_sizes
+ }
+
+ fn column_computed_inline_sizes<'a>(&'a mut self) -> &'a mut Vec<ColumnComputedInlineSize> {
+ &mut self.column_computed_inline_sizes
}
/// The specified column inline-sizes are set from column group and the first row for the fixed
@@ -165,7 +177,7 @@ impl Flow for TableFlow {
debug_assert!(kid.is_proper_table_child());
if kid.is_table_colgroup() {
for specified_inline_size in kid.as_table_colgroup().inline_sizes.iter() {
- self.column_inline_sizes.push(ColumnInlineSize {
+ self.column_intrinsic_inline_sizes.push(ColumnIntrinsicInlineSize {
minimum_length: match *specified_inline_size {
LPA_Auto | LPA_Percentage(_) => Au(0),
LPA_Length(length) => length,
@@ -188,25 +200,26 @@ impl Flow for TableFlow {
// Fixed table layout only looks at the first row.
if !did_first_row {
did_first_row = true;
- for child_column_inline_size in kid.column_inline_sizes().iter() {
- self.column_inline_sizes.push(*child_column_inline_size);
+ for child_column_inline_size in kid.column_intrinsic_inline_sizes()
+ .iter() {
+ self.column_intrinsic_inline_sizes.push(*child_column_inline_size);
}
}
}
AutoLayout => {
- let child_column_inline_sizes = kid.column_inline_sizes();
- let mut child_intrinsic_sizes =
- TableFlow::update_column_inline_sizes(&mut self.column_inline_sizes,
- child_column_inline_sizes);
+ let child_column_inline_sizes = kid.column_intrinsic_inline_sizes();
+ let mut child_intrinsic_sizes = TableFlow::update_column_inline_sizes(
+ &mut self.column_intrinsic_inline_sizes,
+ child_column_inline_sizes);
// Add new columns if processing this row caused us to discover them.
let child_column_count = child_column_inline_sizes.len();
- let parent_column_count = self.column_inline_sizes.len();
+ let parent_column_count = self.column_intrinsic_inline_sizes.len();
debug!("table until the previous row has {} column(s) and this row has {} \
column(s)",
parent_column_count,
child_column_count);
- self.column_inline_sizes.reserve(child_column_count);
+ self.column_intrinsic_inline_sizes.reserve(child_column_count);
for i in range(parent_column_count, child_column_count) {
let inline_size_for_new_column = (*child_column_inline_sizes)[i];
child_intrinsic_sizes.minimum_inline_size =
@@ -215,7 +228,7 @@ impl Flow for TableFlow {
child_intrinsic_sizes.preferred_inline_size =
child_intrinsic_sizes.preferred_inline_size +
inline_size_for_new_column.preferred;
- self.column_inline_sizes.push(inline_size_for_new_column);
+ self.column_intrinsic_inline_sizes.push(inline_size_for_new_column);
}
computation.union_block(&child_intrinsic_sizes)
@@ -239,7 +252,7 @@ impl Flow for TableFlow {
let mut num_unspecified_inline_sizes = 0;
let mut total_column_inline_size = Au(0);
- for column_inline_size in self.column_inline_sizes.iter() {
+ for column_inline_size in self.column_intrinsic_inline_sizes.iter() {
let this_column_inline_size = column_inline_size.minimum_length;
if this_column_inline_size == Au(0) {
num_unspecified_inline_sizes += 1
@@ -263,28 +276,38 @@ impl Flow for TableFlow {
FixedLayout => {
// In fixed table layout, we distribute extra space among the unspecified columns
// if there are any, or among all the columns if all are specified.
+ self.column_computed_inline_sizes.clear();
if total_column_inline_size < content_inline_size &&
num_unspecified_inline_sizes == 0 {
- let ratio = content_inline_size.to_subpx() / total_column_inline_size.to_subpx();
- for column_inline_size in self.column_inline_sizes.iter_mut() {
- column_inline_size.minimum_length = column_inline_size.minimum_length.scale_by(ratio);
- column_inline_size.percentage = 0.0;
+ let ratio = content_inline_size.to_subpx() /
+ total_column_inline_size.to_subpx();
+ for column_inline_size in self.column_intrinsic_inline_sizes.iter() {
+ self.column_computed_inline_sizes.push(ColumnComputedInlineSize {
+ size: column_inline_size.minimum_length.scale_by(ratio),
+ });
}
} else if num_unspecified_inline_sizes != 0 {
let extra_column_inline_size =
(content_inline_size - total_column_inline_size) /
num_unspecified_inline_sizes;
- for column_inline_size in self.column_inline_sizes.iter_mut() {
+ for column_inline_size in self.column_intrinsic_inline_sizes.iter() {
if column_inline_size.minimum_length == Au(0) &&
column_inline_size.percentage == 0.0 {
- column_inline_size.minimum_length = extra_column_inline_size /
- num_unspecified_inline_sizes
+ self.column_computed_inline_sizes.push(ColumnComputedInlineSize {
+ size: extra_column_inline_size / num_unspecified_inline_sizes,
+ });
+ } else {
+ self.column_computed_inline_sizes.push(ColumnComputedInlineSize {
+ size: column_inline_size.minimum_length,
+ });
}
- column_inline_size.percentage = 0.0;
}
}
}
- _ => {}
+ _ => {
+ // The table wrapper already computed the inline-sizes and propagated them down
+ // to us.
+ }
}
// As tables are always wrapped inside a table wrapper, they are never impacted by floats.
@@ -294,7 +317,7 @@ impl Flow for TableFlow {
self.block_flow.propagate_assigned_inline_size_to_children(
inline_start_content_edge,
content_inline_size,
- Some(self.column_inline_sizes.as_slice()));
+ Some(self.column_computed_inline_sizes.as_slice()));
}
fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) {
@@ -365,7 +388,7 @@ impl ISizeAndMarginsComputer for InternalTable {
}
}
-/// Information about the inline sizes of columns within a table.
+/// Information about the intrinsic inline sizes of columns within a table.
///
/// During table inline-size bubbling, we might need to store both a percentage constraint and a
/// specific width constraint. For instance, one cell might say that it wants to be 100 pixels wide
@@ -377,7 +400,7 @@ impl ISizeAndMarginsComputer for InternalTable {
/// potentially store both a specified width *and* a specified percentage, so that the inline-size
/// assignment phase of layout will know which one to pick.
#[deriving(Clone, Encodable, Show)]
-pub struct ColumnInlineSize {
+pub struct ColumnIntrinsicInlineSize {
/// The preferred intrinsic inline size.
pub preferred: Au,
/// The largest specified size of this column as a length.
@@ -388,7 +411,7 @@ pub struct ColumnInlineSize {
pub constrained: bool,
}
-impl ColumnInlineSize {
+impl ColumnIntrinsicInlineSize {
/// Returns the true minimum size of this column, given the containing block's inline size.
/// Beware that this is generally only correct for fixed table layout. (Compare CSS 2.1 §
/// 17.5.2.1 with the algorithm in INTRINSIC § 4.)
@@ -397,7 +420,7 @@ impl ColumnInlineSize {
}
/// Returns the higher of the two percentages specified in `self` and `other`.
- pub fn greatest_percentage(&self, other: &ColumnInlineSize) -> CSSFloat {
+ pub fn greatest_percentage(&self, other: &ColumnIntrinsicInlineSize) -> CSSFloat {
if self.percentage > other.percentage {
self.percentage
} else {
@@ -405,3 +428,13 @@ impl ColumnInlineSize {
}
}
}
+
+/// The actual inline size for each column.
+///
+/// TODO(pcwalton): There will probably be some `border-collapse`-related info in here too
+/// eventually.
+#[deriving(Encodable)]
+pub struct ColumnComputedInlineSize {
+ /// The computed size of this inline column.
+ pub size: Au,
+}