| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/layout/ng/ng_fragment_builder.h" | 5 #include "core/layout/ng/ng_fragment_builder.h" |
| 6 | 6 |
| 7 #include "core/layout/ng/inline/ng_physical_text_fragment.h" | 7 #include "core/layout/ng/inline/ng_physical_text_fragment.h" |
| 8 #include "core/layout/ng/ng_block_break_token.h" | 8 #include "core/layout/ng/ng_block_break_token.h" |
| 9 #include "core/layout/ng/ng_block_node.h" | 9 #include "core/layout/ng/ng_block_node.h" |
| 10 #include "core/layout/ng/ng_break_token.h" | 10 #include "core/layout/ng/ng_break_token.h" |
| 11 #include "core/layout/ng/ng_fragment.h" | 11 #include "core/layout/ng/ng_fragment.h" |
| 12 #include "core/layout/ng/ng_layout_result.h" | 12 #include "core/layout/ng/ng_layout_result.h" |
| 13 #include "core/layout/ng/ng_physical_box_fragment.h" | 13 #include "core/layout/ng/ng_physical_box_fragment.h" |
| 14 #include "platform/heap/Handle.h" | 14 #include "platform/heap/Handle.h" |
| 15 | 15 |
| 16 namespace blink { | 16 namespace blink { |
| 17 | 17 |
| 18 // TODO(ikilpatrick): Make writing mode and direction be in the constructor. | 18 // TODO(ikilpatrick): Make writing mode and direction be in the constructor. |
| 19 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, | 19 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, |
| 20 NGLayoutInputNode* node) | 20 NGLayoutInputNode node) |
| 21 : type_(type), | 21 : type_(type), |
| 22 writing_mode_(kHorizontalTopBottom), | 22 writing_mode_(kHorizontalTopBottom), |
| 23 direction_(TextDirection::kLtr), | 23 direction_(TextDirection::kLtr), |
| 24 node_(node), | 24 node_(node), |
| 25 layout_object_(node->GetLayoutObject()), | 25 layout_object_(node.GetLayoutObject()), |
| 26 did_break_(false), | 26 did_break_(false), |
| 27 border_edges_(NGBorderEdges::kAll) {} | 27 border_edges_(NGBorderEdges::kAll) {} |
| 28 | 28 |
| 29 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, | 29 NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, |
| 30 LayoutObject* layout_object) | 30 LayoutObject* layout_object) |
| 31 : type_(type), | 31 : type_(type), |
| 32 writing_mode_(kHorizontalTopBottom), | 32 writing_mode_(kHorizontalTopBottom), |
| 33 direction_(TextDirection::kLtr), | 33 direction_(TextDirection::kLtr), |
| 34 node_(nullptr), |
| 34 layout_object_(layout_object), | 35 layout_object_(layout_object), |
| 35 did_break_(false) {} | 36 did_break_(false) {} |
| 36 | 37 |
| 37 NGFragmentBuilder& NGFragmentBuilder::SetWritingMode( | 38 NGFragmentBuilder& NGFragmentBuilder::SetWritingMode( |
| 38 NGWritingMode writing_mode) { | 39 NGWritingMode writing_mode) { |
| 39 writing_mode_ = writing_mode; | 40 writing_mode_ = writing_mode; |
| 40 return *this; | 41 return *this; |
| 41 } | 42 } |
| 42 | 43 |
| 43 NGFragmentBuilder& NGFragmentBuilder::SetDirection(TextDirection direction) { | 44 NGFragmentBuilder& NGFragmentBuilder::SetDirection(TextDirection direction) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 68 | 69 |
| 69 NGFragmentBuilder& NGFragmentBuilder::AddChild( | 70 NGFragmentBuilder& NGFragmentBuilder::AddChild( |
| 70 RefPtr<NGLayoutResult> child, | 71 RefPtr<NGLayoutResult> child, |
| 71 const NGLogicalOffset& child_offset) { | 72 const NGLogicalOffset& child_offset) { |
| 72 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) | 73 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) |
| 73 << "Only box fragments can have children"; | 74 << "Only box fragments can have children"; |
| 74 | 75 |
| 75 // Collect child's out of flow descendants. | 76 // Collect child's out of flow descendants. |
| 76 const Vector<NGStaticPosition>& oof_positions = child->OutOfFlowPositions(); | 77 const Vector<NGStaticPosition>& oof_positions = child->OutOfFlowPositions(); |
| 77 size_t oof_index = 0; | 78 size_t oof_index = 0; |
| 78 for (auto& oof_node : child->OutOfFlowDescendants()) { | 79 for (NGBlockNode oof_node : child->OutOfFlowDescendants()) { |
| 79 NGStaticPosition oof_position = oof_positions[oof_index++]; | 80 NGStaticPosition oof_position = oof_positions[oof_index++]; |
| 80 out_of_flow_descendant_candidates_.insert(oof_node); | 81 out_of_flow_descendant_candidates_.push_back(oof_node); |
| 81 out_of_flow_candidate_placements_.push_back( | 82 out_of_flow_candidate_placements_.push_back( |
| 82 OutOfFlowPlacement{child_offset, oof_position}); | 83 OutOfFlowPlacement{child_offset, oof_position}); |
| 83 } | 84 } |
| 84 | 85 |
| 85 return AddChild(child->PhysicalFragment(), child_offset); | 86 return AddChild(child->PhysicalFragment(), child_offset); |
| 86 } | 87 } |
| 87 | 88 |
| 88 NGFragmentBuilder& NGFragmentBuilder::AddChild( | 89 NGFragmentBuilder& NGFragmentBuilder::AddChild( |
| 89 RefPtr<NGPhysicalFragment> child, | 90 RefPtr<NGPhysicalFragment> child, |
| 90 const NGLogicalOffset& child_offset) { | 91 const NGLogicalOffset& child_offset) { |
| 91 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) | 92 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox) |
| 92 << "Only box fragments can have children"; | 93 << "Only box fragments can have children"; |
| 93 | 94 |
| 94 switch (child->Type()) { | 95 switch (child->Type()) { |
| 95 case NGPhysicalBoxFragment::kFragmentBox: | 96 case NGPhysicalBoxFragment::kFragmentBox: |
| 96 // Update if we have fragmented in this flow. | 97 // Update if we have fragmented in this flow. |
| 97 if (child->BreakToken()) { | 98 if (child->BreakToken()) { |
| 98 did_break_ |= !child->BreakToken()->IsFinished(); | 99 did_break_ |= !child->BreakToken()->IsFinished(); |
| 99 child_break_tokens_.push_back(child->BreakToken()); | 100 child_break_tokens_.push_back(child->BreakToken()); |
| 100 } | 101 } |
| 101 break; | 102 break; |
| 102 case NGPhysicalBoxFragment::kFragmentLineBox: | 103 case NGPhysicalBoxFragment::kFragmentLineBox: |
| 103 // NGInlineNode produces multiple line boxes in an anonymous box. Only | 104 // NGInlineNode produces multiple line boxes in an anonymous box. Only |
| 104 // the last break token is needed to be reported to the parent. | 105 // the last break token is needed to be reported to the parent. |
| 105 DCHECK(child->BreakToken()); | 106 DCHECK(child->BreakToken()); |
| 106 DCHECK_EQ(child->BreakToken()->InputNode(), node_); | 107 DCHECK(child->BreakToken()->InputNode() == node_); |
| 107 last_inline_break_token_ = | 108 last_inline_break_token_ = |
| 108 child->BreakToken()->IsFinished() ? nullptr : child->BreakToken(); | 109 child->BreakToken()->IsFinished() ? nullptr : child->BreakToken(); |
| 109 break; | 110 break; |
| 110 case NGPhysicalBoxFragment::kFragmentText: | 111 case NGPhysicalBoxFragment::kFragmentText: |
| 111 DCHECK(!child->BreakToken()); | 112 DCHECK(!child->BreakToken()); |
| 112 break; | 113 break; |
| 113 default: | 114 default: |
| 114 NOTREACHED(); | 115 NOTREACHED(); |
| 115 break; | 116 break; |
| 116 } | 117 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 129 return *this; | 130 return *this; |
| 130 } | 131 } |
| 131 | 132 |
| 132 NGFragmentBuilder& NGFragmentBuilder::SetBfcOffset( | 133 NGFragmentBuilder& NGFragmentBuilder::SetBfcOffset( |
| 133 const NGLogicalOffset& offset) { | 134 const NGLogicalOffset& offset) { |
| 134 bfc_offset_ = offset; | 135 bfc_offset_ = offset; |
| 135 return *this; | 136 return *this; |
| 136 } | 137 } |
| 137 | 138 |
| 138 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowChildCandidate( | 139 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowChildCandidate( |
| 139 NGBlockNode* child, | 140 NGBlockNode child, |
| 140 NGLogicalOffset child_offset) { | 141 NGLogicalOffset child_offset) { |
| 141 out_of_flow_descendant_candidates_.insert(child); | 142 out_of_flow_descendant_candidates_.push_back(child); |
| 142 NGStaticPosition child_position = | 143 NGStaticPosition child_position = |
| 143 NGStaticPosition::Create(writing_mode_, direction_, NGPhysicalOffset()); | 144 NGStaticPosition::Create(writing_mode_, direction_, NGPhysicalOffset()); |
| 144 out_of_flow_candidate_placements_.push_back( | 145 out_of_flow_candidate_placements_.push_back( |
| 145 OutOfFlowPlacement{child_offset, child_position}); | 146 OutOfFlowPlacement{child_offset, child_position}); |
| 146 child->SaveStaticOffsetForLegacy(child_offset); | 147 child.SaveStaticOffsetForLegacy(child_offset); |
| 147 return *this; | 148 return *this; |
| 148 } | 149 } |
| 149 | 150 |
| 150 NGFragmentBuilder& NGFragmentBuilder::AddUnpositionedFloat( | 151 NGFragmentBuilder& NGFragmentBuilder::AddUnpositionedFloat( |
| 151 RefPtr<NGUnpositionedFloat> unpositioned_float) { | 152 RefPtr<NGUnpositionedFloat> unpositioned_float) { |
| 152 unpositioned_floats_.push_back(std::move(unpositioned_float)); | 153 unpositioned_floats_.push_back(std::move(unpositioned_float)); |
| 153 return *this; | 154 return *this; |
| 154 } | 155 } |
| 155 | 156 |
| 156 void NGFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates( | 157 void NGFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates( |
| 157 WeakBoxList* descendants, | 158 Vector<NGBlockNode>* descendants, |
| 158 Vector<NGStaticPosition>* descendant_positions) { | 159 Vector<NGStaticPosition>* descendant_positions) { |
| 159 DCHECK(descendants->IsEmpty()); | 160 DCHECK(descendants->IsEmpty()); |
| 160 DCHECK(descendant_positions->IsEmpty()); | 161 DCHECK(descendant_positions->IsEmpty()); |
| 161 | 162 |
| 162 DCHECK_GE(size_.inline_size, LayoutUnit()); | 163 DCHECK_GE(size_.inline_size, LayoutUnit()); |
| 163 DCHECK_GE(size_.block_size, LayoutUnit()); | 164 DCHECK_GE(size_.block_size, LayoutUnit()); |
| 164 NGPhysicalSize builder_physical_size{size_.ConvertToPhysical(writing_mode_)}; | 165 NGPhysicalSize builder_physical_size{size_.ConvertToPhysical(writing_mode_)}; |
| 165 | 166 |
| 166 size_t placement_index = 0; | 167 size_t placement_index = 0; |
| 167 for (auto& oof_node : out_of_flow_descendant_candidates_) { | 168 for (NGBlockNode oof_node : out_of_flow_descendant_candidates_) { |
| 168 OutOfFlowPlacement oof_placement = | 169 OutOfFlowPlacement oof_placement = |
| 169 out_of_flow_candidate_placements_[placement_index++]; | 170 out_of_flow_candidate_placements_[placement_index++]; |
| 170 | 171 |
| 171 NGPhysicalOffset child_offset = | 172 NGPhysicalOffset child_offset = |
| 172 oof_placement.child_offset.ConvertToPhysical( | 173 oof_placement.child_offset.ConvertToPhysical( |
| 173 writing_mode_, direction_, builder_physical_size, NGPhysicalSize()); | 174 writing_mode_, direction_, builder_physical_size, NGPhysicalSize()); |
| 174 | 175 |
| 175 NGStaticPosition builder_relative_position; | 176 NGStaticPosition builder_relative_position; |
| 176 builder_relative_position.type = oof_placement.descendant_position.type; | 177 builder_relative_position.type = oof_placement.descendant_position.type; |
| 177 builder_relative_position.offset = | 178 builder_relative_position.offset = |
| 178 child_offset + oof_placement.descendant_position.offset; | 179 child_offset + oof_placement.descendant_position.offset; |
| 179 descendants->insert(oof_node); | 180 descendants->push_back(oof_node); |
| 180 descendant_positions->push_back(builder_relative_position); | 181 descendant_positions->push_back(builder_relative_position); |
| 181 } | 182 } |
| 182 out_of_flow_descendant_candidates_.clear(); | 183 out_of_flow_descendant_candidates_.clear(); |
| 183 out_of_flow_candidate_placements_.clear(); | 184 out_of_flow_candidate_placements_.clear(); |
| 184 } | 185 } |
| 185 | 186 |
| 186 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowDescendant( | 187 NGFragmentBuilder& NGFragmentBuilder::AddOutOfFlowDescendant( |
| 187 NGBlockNode* descendant, | 188 NGBlockNode descendant, |
| 188 const NGStaticPosition& position) { | 189 const NGStaticPosition& position) { |
| 189 out_of_flow_descendants_.insert(descendant); | 190 out_of_flow_descendants_.push_back(descendant); |
| 190 out_of_flow_positions_.push_back(position); | 191 out_of_flow_positions_.push_back(position); |
| 191 return *this; | 192 return *this; |
| 192 } | 193 } |
| 193 | 194 |
| 194 RefPtr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment() { | 195 RefPtr<NGLayoutResult> NGFragmentBuilder::ToBoxFragment() { |
| 195 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox); | 196 DCHECK_EQ(type_, NGPhysicalFragment::kFragmentBox); |
| 196 DCHECK_EQ(offsets_.size(), children_.size()); | 197 DCHECK_EQ(offsets_.size(), children_.size()); |
| 197 | 198 |
| 198 NGPhysicalSize physical_size = size_.ConvertToPhysical(writing_mode_); | 199 NGPhysicalSize physical_size = size_.ConvertToPhysical(writing_mode_); |
| 199 | 200 |
| 200 for (size_t i = 0; i < children_.size(); ++i) { | 201 for (size_t i = 0; i < children_.size(); ++i) { |
| 201 NGPhysicalFragment* child = children_[i].Get(); | 202 NGPhysicalFragment* child = children_[i].Get(); |
| 202 child->SetOffset(offsets_[i].ConvertToPhysical( | 203 child->SetOffset(offsets_[i].ConvertToPhysical( |
| 203 writing_mode_, direction_, physical_size, child->Size())); | 204 writing_mode_, direction_, physical_size, child->Size())); |
| 204 } | 205 } |
| 205 | 206 |
| 206 RefPtr<NGBreakToken> break_token; | 207 RefPtr<NGBreakToken> break_token; |
| 207 if (node_) { | 208 if (node_) { |
| 208 if (last_inline_break_token_) { | 209 if (last_inline_break_token_) { |
| 209 DCHECK(!last_inline_break_token_->IsFinished()); | 210 DCHECK(!last_inline_break_token_->IsFinished()); |
| 210 child_break_tokens_.push_back(std::move(last_inline_break_token_)); | 211 child_break_tokens_.push_back(std::move(last_inline_break_token_)); |
| 211 did_break_ = true; | 212 did_break_ = true; |
| 212 } | 213 } |
| 213 if (did_break_) { | 214 if (did_break_) { |
| 214 break_token = NGBlockBreakToken::Create(node_.Get(), used_block_size_, | 215 break_token = NGBlockBreakToken::Create(node_, used_block_size_, |
| 215 child_break_tokens_); | 216 child_break_tokens_); |
| 216 } else { | 217 } else { |
| 217 break_token = NGBlockBreakToken::Create(node_.Get()); | 218 break_token = NGBlockBreakToken::Create(node_); |
| 218 } | 219 } |
| 219 } | 220 } |
| 220 | 221 |
| 221 for (auto& positioned_float : positioned_floats_) { | 222 for (auto& positioned_float : positioned_floats_) { |
| 222 NGPhysicalFragment* floating_fragment = positioned_float.fragment.Get(); | 223 NGPhysicalFragment* floating_fragment = positioned_float.fragment.Get(); |
| 223 floating_fragment->SetOffset( | 224 floating_fragment->SetOffset( |
| 224 positioned_float.logical_offset.ConvertToPhysical( | 225 positioned_float.logical_offset.ConvertToPhysical( |
| 225 writing_mode_, direction_, physical_size, | 226 writing_mode_, direction_, physical_size, |
| 226 floating_fragment->Size())); | 227 floating_fragment->Size())); |
| 227 } | 228 } |
| 228 | 229 |
| 229 RefPtr<NGPhysicalBoxFragment> fragment = AdoptRef(new NGPhysicalBoxFragment( | 230 RefPtr<NGPhysicalBoxFragment> fragment = AdoptRef(new NGPhysicalBoxFragment( |
| 230 layout_object_, physical_size, overflow_.ConvertToPhysical(writing_mode_), | 231 layout_object_, physical_size, overflow_.ConvertToPhysical(writing_mode_), |
| 231 children_, positioned_floats_, bfc_offset_, end_margin_strut_, | 232 children_, positioned_floats_, bfc_offset_, end_margin_strut_, |
| 232 NGBorderEdges::ToPhysical(border_edges_, writing_mode_), | 233 NGBorderEdges::ToPhysical(border_edges_, writing_mode_), |
| 233 std::move(break_token))); | 234 std::move(break_token))); |
| 234 | 235 |
| 235 return AdoptRef( | 236 return AdoptRef( |
| 236 new NGLayoutResult(std::move(fragment), out_of_flow_descendants_, | 237 new NGLayoutResult(std::move(fragment), out_of_flow_descendants_, |
| 237 out_of_flow_positions_, unpositioned_floats_)); | 238 out_of_flow_positions_, unpositioned_floats_)); |
| 238 } | 239 } |
| 239 | 240 |
| 240 } // namespace blink | 241 } // namespace blink |
| OLD | NEW |