aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/table_cell.rs
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2016-04-19 14:47:55 -0700
committerMichael Howell <michael@notriddle.com>2016-04-20 14:40:02 -0700
commit8953207f83d480853226acdc518707ab621fb75e (patch)
treee864ebd1714047f2eb8ae01e5254964253f2114c /components/layout/table_cell.rs
parentf051028ee8cd93168b1abe3742929d43d19cb002 (diff)
downloadservo-8953207f83d480853226acdc518707ab621fb75e.tar.gz
servo-8953207f83d480853226acdc518707ab621fb75e.zip
Add support for vertical alignment within table cells.
Fixes #10621
Diffstat (limited to 'components/layout/table_cell.rs')
-rw-r--r--components/layout/table_cell.rs41
1 files changed, 39 insertions, 2 deletions
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 2e7b96464d5..37a916a920a 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -12,14 +12,15 @@ use context::LayoutContext;
use cssparser::Color;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode, DisplayListBuildState};
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
-use flow::{Flow, FlowClass, OpaqueFlow};
+use flow::{self, Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
+use incremental::REFLOW;
use layout_debug;
use model::MaybeAuto;
use std::fmt;
use std::sync::Arc;
-use style::computed_values::{border_collapse, border_top_style};
+use style::computed_values::{border_collapse, border_top_style, vertical_align};
use style::logical_geometry::{LogicalMargin, LogicalRect, LogicalSize, WritingMode};
use style::properties::{ComputedValues, ServoComputedValues};
use table::InternalTable;
@@ -74,6 +75,42 @@ impl TableCellFlow {
None,
MarginsMayCollapseFlag::MarginsMayNotCollapse);
debug_assert!(remaining.is_none());
+ if !flow::base(self).restyle_damage.contains(REFLOW) {
+ return;
+ }
+ let first_start = flow::base(self).children.front().map(|kid| {
+ flow::base(kid).position.start.b
+ });
+ if let Some(mut first_start) = first_start {
+ let mut last_end = first_start;
+ for kid in flow::base(self).children.iter() {
+ let kid_base = flow::base(kid);
+ let start = kid_base.position.start.b
+ - kid_base.collapsible_margins.block_start_margin_for_noncollapsible_context();
+ let end = kid_base.position.start.b + kid_base.position.size.block
+ + kid_base.collapsible_margins.block_end_margin_for_noncollapsible_context();
+ if start < first_start {
+ first_start = start;
+ }
+ if end > last_end {
+ last_end = end;
+ }
+ }
+ let kids_size = last_end - first_start;
+ let self_size = flow::base(self).position.size.block -
+ self.block_flow.fragment.border_padding.block_start_end();
+ let kids_self_gap = self_size - kids_size;
+ let offset = match self.block_flow.fragment.style().get_box().vertical_align {
+ vertical_align::T::middle => kids_self_gap / 2,
+ vertical_align::T::bottom => kids_self_gap,
+ _ => Au(0),
+ };
+ if offset != Au(0) {
+ for kid in flow::mut_base(self).children.iter_mut() {
+ flow::mut_base(kid).position.start.b = flow::mut_base(kid).position.start.b + offset;
+ }
+ }
+ }
}
}