aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/block.rs3
-rw-r--r--components/layout/construct.rs9
-rw-r--r--components/layout/flow.rs7
-rw-r--r--components/layout/lib.rs1
-rw-r--r--components/layout/multicol.rs107
-rw-r--r--components/style/properties.mako.rs6
6 files changed, 130 insertions, 3 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index 10bb2a055aa..39a0fe715f7 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -1394,7 +1394,8 @@ impl BlockFlow {
FormattingContextType::Other
}
_ if style.get_box().overflow_x != overflow_x::T::visible ||
- style.get_box().overflow_y != overflow_y::T(overflow_x::T::visible) => {
+ style.get_box().overflow_y != overflow_y::T(overflow_x::T::visible) ||
+ style.is_multicol() => {
FormattingContextType::Block
}
_ => FormattingContextType::None,
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index f945e8bb526..12f9900b088 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -33,6 +33,7 @@ use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo};
use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
use inline::InlineFlow;
use list_item::{ListItemFlow, ListStyleTypeContent};
+use multicol::MulticolFlow;
use opaque_node::OpaqueNodeMethods;
use parallel;
use table::TableFlow;
@@ -655,8 +656,12 @@ impl<'a> FlowConstructor<'a> {
/// to happen.
fn build_flow_for_nonfloated_block(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
- let flow = box BlockFlow::from_node_and_fragment(node, self.build_fragment_for_block(node))
- as Box<Flow>;
+ let fragment = self.build_fragment_for_block(node);
+ let flow = if node.style().is_multicol() {
+ box MulticolFlow::from_node_and_fragment(node, fragment) as Box<Flow>
+ } else {
+ box BlockFlow::from_node_and_fragment(node, fragment) as Box<Flow>
+ };
self.build_flow_for_block(FlowRef::new(flow), node)
}
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index 6ebf8530c90..647916f33bc 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -44,6 +44,7 @@ use table_colgroup::TableColGroupFlow;
use table_row::TableRowFlow;
use table_rowgroup::TableRowGroupFlow;
use table_wrapper::TableWrapperFlow;
+use multicol::MulticolFlow;
use wrapper::ThreadSafeLayoutNode;
use geom::{Point2D, Rect, Size2D};
@@ -158,6 +159,11 @@ pub trait Flow: fmt::Debug + Sync {
panic!("called as_table_cell() on a non-tablecell flow")
}
+ /// If this is a multicol flow, returns the underlying object. Fails otherwise.
+ fn as_multicol<'a>(&'a mut self) -> &'a mut MulticolFlow {
+ panic!("called as_multicol() on a non-multicol flow")
+ }
+
/// If this is a table cell flow, returns the underlying object, borrowed immutably. Fails
/// otherwise.
fn as_immutable_table_cell<'a>(&'a self) -> &'a TableCellFlow {
@@ -451,6 +457,7 @@ pub enum FlowClass {
TableRow,
TableCaption,
TableCell,
+ Multicol,
}
/// A top-down traversal.
diff --git a/components/layout/lib.rs b/components/layout/lib.rs
index 7fbbb2d3576..844689f0534 100644
--- a/components/layout/lib.rs
+++ b/components/layout/lib.rs
@@ -78,6 +78,7 @@ pub mod incremental;
pub mod inline;
pub mod list_item;
pub mod model;
+pub mod multicol;
pub mod opaque_node;
pub mod parallel;
pub mod sequential;
diff --git a/components/layout/multicol.rs b/components/layout/multicol.rs
new file mode 100644
index 00000000000..b23ccf65c1c
--- /dev/null
+++ b/components/layout/multicol.rs
@@ -0,0 +1,107 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//! CSS Multi-column layout http://dev.w3.org/csswg/css-multicol/
+
+#![deny(unsafe_blocks)]
+
+use block::BlockFlow;
+use context::LayoutContext;
+use flow::{FlowClass, Flow};
+use fragment::{Fragment, FragmentBorderBoxIterator};
+use wrapper::ThreadSafeLayoutNode;
+
+use geom::{Point2D, Rect};
+use util::geometry::Au;
+use util::logical_geometry::LogicalRect;
+use std::fmt;
+use style::properties::ComputedValues;
+use std::sync::Arc;
+
+pub struct MulticolFlow {
+ pub block_flow: BlockFlow,
+}
+
+impl MulticolFlow {
+ pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment)
+ -> MulticolFlow {
+ MulticolFlow {
+ block_flow: BlockFlow::from_node_and_fragment(node, fragment)
+ }
+ }
+}
+
+impl Flow for MulticolFlow {
+ fn class(&self) -> FlowClass {
+ FlowClass::Multicol
+ }
+
+ fn as_multicol<'a>(&'a mut self) -> &'a mut MulticolFlow {
+ self
+ }
+
+ fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
+ &mut self.block_flow
+ }
+
+ fn bubble_inline_sizes(&mut self) {
+ // FIXME(SimonSapin) http://dev.w3.org/csswg/css-sizing/#multicol-intrinsic
+ self.block_flow.bubble_inline_sizes();
+ }
+
+ fn assign_inline_sizes(&mut self, ctx: &LayoutContext) {
+ debug!("assign_inline_sizes({}): assigning inline_size for flow", "multicol");
+ self.block_flow.assign_inline_sizes(ctx);
+ }
+
+ fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) {
+ debug!("assign_block_size: assigning block_size for multicol");
+ self.block_flow.assign_block_size(ctx);
+ }
+
+ fn compute_absolute_position(&mut self) {
+ self.block_flow.compute_absolute_position()
+ }
+
+ fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) {
+ self.block_flow.update_late_computed_inline_position_if_necessary(inline_position)
+ }
+
+ fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) {
+ self.block_flow.update_late_computed_block_position_if_necessary(block_position)
+ }
+
+ fn build_display_list(&mut self, layout_context: &LayoutContext) {
+ debug!("build_display_list_multicol: same process as block flow");
+ self.block_flow.build_display_list(layout_context)
+ }
+
+ fn repair_style(&mut self, new_style: &Arc<ComputedValues>) {
+ self.block_flow.repair_style(new_style)
+ }
+
+ fn compute_overflow(&self) -> Rect<Au> {
+ self.block_flow.compute_overflow()
+ }
+
+ fn generated_containing_block_rect(&self) -> LogicalRect<Au> {
+ self.block_flow.generated_containing_block_rect()
+ }
+
+ fn iterate_through_fragment_border_boxes(&self,
+ iterator: &mut FragmentBorderBoxIterator,
+ stacking_context_position: &Point2D<Au>) {
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
+ }
+
+ fn mutate_fragments(&mut self, mutator: &mut FnMut(&mut Fragment)) {
+ self.block_flow.mutate_fragments(mutator)
+ }
+}
+
+impl fmt::Debug for MulticolFlow {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "MulticolFlow: {:?}", self.block_flow)
+ }
+}
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index c67b3c5c887..38f5821ceb1 100644
--- a/components/style/properties.mako.rs
+++ b/components/style/properties.mako.rs
@@ -5195,6 +5195,12 @@ impl ComputedValues {
}
#[inline]
+ pub fn is_multicol(&self) -> bool {
+ let style = self.get_column();
+ style.column_count.is_some() || style.column_width.is_some()
+ }
+
+ #[inline]
pub fn get_font_arc(&self) -> Arc<style_structs::Font> {
self.font.clone()
}