Add MulticolFlow and use it for multicol elements.

It currently "inherits" from BlockFlow and does not override anything.
This commit is contained in:
Simon Sapin 2015-03-07 17:15:31 +01:00
parent f30cd4f377
commit cc4749373a
6 changed files with 130 additions and 3 deletions

View file

@ -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,

View file

@ -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)
}

View file

@ -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.

View file

@ -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;

View file

@ -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)
}
}

View file

@ -5194,6 +5194,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()