mirror of
https://github.com/servo/servo.git
synced 2025-07-22 06:43:40 +01:00
Add Multicolumn support block fragmentation.
This commit is contained in:
parent
359b984348
commit
5498b54347
10 changed files with 373 additions and 51 deletions
|
@ -31,7 +31,7 @@ use incremental::{BUBBLE_ISIZES, RECONSTRUCT_FLOW, RestyleDamage};
|
|||
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, InlineFragmentNodeFlags};
|
||||
use inline::{InlineFragmentNodeInfo, LAST_FRAGMENT_OF_ELEMENT};
|
||||
use list_item::{ListItemFlow, ListStyleTypeContent};
|
||||
use multicol::MulticolFlow;
|
||||
use multicol::{MulticolFlow, MulticolColumnFlow};
|
||||
use parallel;
|
||||
use script::dom::bindings::inheritance::{CharacterDataTypeId, ElementTypeId};
|
||||
use script::dom::bindings::inheritance::{HTMLElementTypeId, NodeTypeId};
|
||||
|
@ -754,12 +754,12 @@ impl<'a, 'ln, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'ln>>
|
|||
/// to happen.
|
||||
fn build_flow_for_block(&mut self, node: &ConcreteThreadSafeLayoutNode, float_kind: Option<FloatKind>)
|
||||
-> ConstructionResult {
|
||||
let fragment = self.build_fragment_for_block(node);
|
||||
let flow: FlowRef = if node.style().is_multicol() {
|
||||
Arc::new(MulticolFlow::from_fragment(fragment, float_kind))
|
||||
} else {
|
||||
Arc::new(BlockFlow::from_fragment(fragment, float_kind))
|
||||
};
|
||||
if node.style().is_multicol() {
|
||||
return self.build_flow_for_multicol(node, float_kind)
|
||||
}
|
||||
|
||||
let flow: FlowRef = Arc::new(
|
||||
BlockFlow::from_fragment(self.build_fragment_for_block(node), float_kind));
|
||||
self.build_flow_for_block_like(flow, node)
|
||||
}
|
||||
|
||||
|
@ -1078,6 +1078,53 @@ impl<'a, 'ln, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'ln>>
|
|||
flow.add_new_child(anonymous_flow);
|
||||
}
|
||||
|
||||
/// Builds a flow for a node with `column-count` or `column-width` non-`auto`.
|
||||
/// This yields a `MulticolFlow` with a single `MulticolColumnFlow` underneath it.
|
||||
fn build_flow_for_multicol(&mut self, node: &ConcreteThreadSafeLayoutNode,
|
||||
float_kind: Option<FloatKind>)
|
||||
-> ConstructionResult {
|
||||
let fragment = Fragment::new(node, SpecificFragmentInfo::Multicol);
|
||||
let mut flow: FlowRef = Arc::new(MulticolFlow::from_fragment(fragment, float_kind));
|
||||
|
||||
let column_fragment = Fragment::new(node, SpecificFragmentInfo::MulticolColumn);
|
||||
let column_flow = Arc::new(MulticolColumnFlow::from_fragment(column_fragment));
|
||||
|
||||
// First populate the column flow with its children.
|
||||
let construction_result = self.build_flow_for_block_like(column_flow, node);
|
||||
|
||||
let mut abs_descendants = AbsoluteDescendants::new();
|
||||
let mut fixed_descendants = AbsoluteDescendants::new();
|
||||
|
||||
if let ConstructionResult::Flow(column_flow, column_abs_descendants) = construction_result {
|
||||
flow.add_new_child(column_flow);
|
||||
abs_descendants.push_descendants(column_abs_descendants);
|
||||
}
|
||||
|
||||
// The flow is done.
|
||||
flow.finish();
|
||||
let contains_positioned_fragments = flow.contains_positioned_fragments();
|
||||
if contains_positioned_fragments {
|
||||
// This is the containing block for all the absolute descendants.
|
||||
flow.set_absolute_descendants(abs_descendants);
|
||||
|
||||
abs_descendants = AbsoluteDescendants::new();
|
||||
|
||||
let is_fixed_positioned = flow.as_block().is_fixed();
|
||||
let is_absolutely_positioned =
|
||||
flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
|
||||
if is_fixed_positioned {
|
||||
// Send itself along with the other fixed descendants.
|
||||
fixed_descendants.push(flow.clone());
|
||||
} else if is_absolutely_positioned {
|
||||
// This is now the only absolute flow in the subtree which hasn't yet
|
||||
// reached its containing block.
|
||||
abs_descendants.push(flow.clone());
|
||||
}
|
||||
}
|
||||
|
||||
ConstructionResult::Flow(flow, abs_descendants)
|
||||
}
|
||||
|
||||
/// Builds a flow for a node with `display: table`. This yields a `TableWrapperFlow` with
|
||||
/// possibly other `TableCaptionFlow`s or `TableFlow`s underneath it.
|
||||
fn build_flow_for_table_wrapper(&mut self, node: &ConcreteThreadSafeLayoutNode, float_value: float::T)
|
||||
|
@ -1115,15 +1162,15 @@ impl<'a, 'ln, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode<'ln>>
|
|||
// The flow is done.
|
||||
wrapper_flow.finish();
|
||||
let contains_positioned_fragments = wrapper_flow.contains_positioned_fragments();
|
||||
let is_fixed_positioned = wrapper_flow.as_block().is_fixed();
|
||||
let is_absolutely_positioned =
|
||||
flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
|
||||
if contains_positioned_fragments {
|
||||
// This is the containing block for all the absolute descendants.
|
||||
wrapper_flow.set_absolute_descendants(abs_descendants);
|
||||
|
||||
abs_descendants = AbsoluteDescendants::new();
|
||||
|
||||
let is_fixed_positioned = wrapper_flow.as_block().is_fixed();
|
||||
let is_absolutely_positioned =
|
||||
flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
|
||||
if is_fixed_positioned {
|
||||
// Send itself along with the other fixed descendants.
|
||||
fixed_descendants.push(wrapper_flow.clone());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue