layout: Rewrite intrinsic inline-size and automatic table layout to

match L. David Baron's work-in-progress specification.

    http://dbaron.org/css/intrinsic/

Column spans are not yet supported.

This effectively adds support for percentage widths, and it also fixes
many bugs, improving the layout of Google and Wikipedia.
This commit is contained in:
Patrick Walton 2014-10-14 14:17:57 -07:00
parent c9ce56a85d
commit c7e619dfe7
20 changed files with 1081 additions and 618 deletions

View file

@ -12,16 +12,15 @@ use flow;
use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
use fragment::{ScannedTextFragment, ScannedTextFragmentInfo, SplitInfo};
use layout_debug;
use model::IntrinsicISizes;
use model::IntrinsicISizesContribution;
use text;
use wrapper::ThreadSafeLayoutNode;
use collections::{Deque, RingBuf};
use geom::Rect;
use geom::{Rect, Size2D};
use gfx::display_list::{ContentLevel, DisplayList};
use gfx::font::FontMetrics;
use gfx::font_context::FontContext;
use geom::Size2D;
use gfx::text::glyph::CharIndex;
use servo_util::geometry::Au;
use servo_util::logical_geometry::{LogicalRect, LogicalSize};
@ -922,24 +921,12 @@ impl Flow for InlineFlow {
flow::mut_base(kid).floats = Floats::new(writing_mode);
}
let mut intrinsic_inline_sizes = IntrinsicISizes::new();
let mut computation = IntrinsicISizesContribution::new();
for fragment in self.fragments.fragments.iter_mut() {
debug!("Flow: measuring {}", *fragment);
let fragment_intrinsic_inline_sizes =
fragment.intrinsic_inline_sizes();
intrinsic_inline_sizes.minimum_inline_size = max(
intrinsic_inline_sizes.minimum_inline_size,
fragment_intrinsic_inline_sizes.minimum_inline_size);
intrinsic_inline_sizes.preferred_inline_size =
intrinsic_inline_sizes.preferred_inline_size +
fragment_intrinsic_inline_sizes.preferred_inline_size;
intrinsic_inline_sizes.surround_inline_size =
intrinsic_inline_sizes.surround_inline_size +
fragment_intrinsic_inline_sizes.surround_inline_size;
computation.union_inline(&fragment.compute_intrinsic_inline_sizes().finish())
}
self.base.intrinsic_inline_sizes = intrinsic_inline_sizes;
self.base.intrinsic_inline_sizes = computation.finish()
}
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments.
@ -960,6 +947,9 @@ impl Flow for InlineFlow {
let inline_size = self.base.position.size.inline;
let this = &mut *self;
for fragment in this.fragments.fragments.iter_mut() {
fragment.compute_border_and_padding(inline_size);
fragment.compute_block_direction_margins(inline_size);
fragment.compute_inline_direction_margins(inline_size);
fragment.assign_replaced_inline_size_if_necessary(inline_size);
}
}
@ -1130,6 +1120,7 @@ impl Flow for InlineFlow {
let block_flow = info.flow_ref.get_mut().as_block();
// FIXME(#2795): Get the real container size
let container_size = Size2D::zero();
block_flow.base.abs_position =
self.base.abs_position +
fragment.border_box.start.to_physical(self.base.writing_mode,