diff options
author | Patrick Walton <pcwalton@mimiga.net> | 2014-09-12 21:11:27 -0700 |
---|---|---|
committer | Patrick Walton <pcwalton@mimiga.net> | 2014-09-12 21:11:27 -0700 |
commit | b64f27b2b69996508eed0a76acc7414a791b1a9e (patch) | |
tree | 59486833dc598fe1fd9d65ae08eedee0b7174435 /components/layout/construct.rs | |
parent | 88aa7d55537e8a8fcf76517c5145b6ff206a77e3 (diff) | |
parent | 98624c957645748e7155367f70d51a4648559224 (diff) | |
download | servo-b64f27b2b69996508eed0a76acc7414a791b1a9e.tar.gz servo-b64f27b2b69996508eed0a76acc7414a791b1a9e.zip |
Merge pull request #3286 from glennw/inline_block
Implement basic support for display: inline-block.
Diffstat (limited to 'components/layout/construct.rs')
-rw-r--r-- | components/layout/construct.rs | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index e30838acbc5..d48612375d4 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -27,6 +27,7 @@ use flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils}; use flow::{Descendants, AbsDescendants}; use flow; use flow_ref::FlowRef; +use fragment::{InlineBlockFragment, InlineBlockFragmentInfo}; use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo}; use fragment::{ImageFragment, ImageFragmentInfo, SpecificFragmentInfo, TableFragment}; use fragment::{TableCellFragment, TableColumnFragment, TableColumnFragmentInfo}; @@ -266,19 +267,38 @@ impl<'a, 'b> FlowConstructor<'a, 'b> { } } - let mut inline_flow = box InlineFlow::from_fragments((*node).clone(), fragments); - let (ascent, descent) = inline_flow.compute_minimum_ascent_and_descent(self.layout_context.font_context(), &**node.style()); - inline_flow.minimum_block_size_above_baseline = ascent; - inline_flow.minimum_depth_below_baseline = descent; - let mut inline_flow = inline_flow as Box<Flow>; - TextRunScanner::new().scan_for_runs(self.layout_context.font_context(), inline_flow); - let mut inline_flow = FlowRef::new(inline_flow); - inline_flow.finish(self.layout_context); - - if flow.get().need_anonymous_flow(inline_flow.get()) { - flow_list.push(inline_flow) + // Build a list of all the inline-block fragments before fragments is moved. + let mut inline_block_flows = vec!(); + for f in fragments.fragments.iter() { + match f.specific { + InlineBlockFragment(ref info) => { + inline_block_flows.push(info.flow_ref.clone()); + }, + _ => {} + } + } + + let mut inline_flow_ref = FlowRef::new(box InlineFlow::from_fragments((*node).clone(), fragments)); + + // Add all the inline-block fragments as children of the inline flow. + for inline_block_flow in inline_block_flows.iter() { + inline_flow_ref.add_new_child(inline_block_flow.clone()); + } + + { + let mut inline_flow = inline_flow_ref.get_mut().as_inline(); + let (ascent, descent) = inline_flow.compute_minimum_ascent_and_descent(self.layout_context.font_context(), &**node.style()); + inline_flow.minimum_block_size_above_baseline = ascent; + inline_flow.minimum_depth_below_baseline = descent; + TextRunScanner::new().scan_for_runs(self.layout_context.font_context(), inline_flow); + } + + inline_flow_ref.finish(self.layout_context); + + if flow.get().need_anonymous_flow(inline_flow_ref.get()) { + flow_list.push(inline_flow_ref) } else { - flow.add_new_child(inline_flow) + flow.add_new_child(inline_flow_ref) } } @@ -582,6 +602,27 @@ impl<'a, 'b> FlowConstructor<'a, 'b> { ConstructionItemConstructionResult(construction_item) } + fn build_fragment_for_inline_block(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { + let block_flow_result = self.build_flow_for_block(node); + let block_flow = match block_flow_result { + FlowConstructionResult(block_flow, _) => block_flow, + _ => unreachable!() + }; + + let fragment_info = InlineBlockFragment(InlineBlockFragmentInfo::new(block_flow)); + let mut fragment = Fragment::new_from_specific_info(node, fragment_info); + + let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node); + fragment_accumulator.fragments.push(&mut fragment, node.style().clone()); + + let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult { + splits: Vec::new(), + fragments: fragment_accumulator.finish(), + abs_descendants: Descendants::new(), + }); + ConstructionItemConstructionResult(construction_item) + } + /// Builds one or more fragments for a node with `display: inline`. This yields an /// `InlineFragmentsConstructionResult`. fn build_fragments_for_inline(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult { @@ -840,6 +881,12 @@ impl<'a, 'b> PostorderNodeMutTraversal for FlowConstructor<'a, 'b> { node.set_flow_construction_result(construction_result) } + // Inline-block items contribute inline fragment construction results. + (display::inline_block, float::none, _) => { + let construction_result = self.build_fragment_for_inline_block(node); + node.set_flow_construction_result(construction_result) + } + // Table items contribute table flow construction results. (display::table_caption, _, _) => { let construction_result = self.build_flow_for_table_caption(node); |