Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_layout_opportunity_iterator.cc

Issue 2457013004: Use NGLogicalRect instead of NGExclusion for exclusions. (Closed)
Patch Set: renamed IsWithing to IsContained Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_layout_opportunity_iterator.h" 5 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
6 6
7 #include "core/layout/ng/ng_physical_constraint_space.h" 7 #include "core/layout/ng/ng_physical_constraint_space.h"
8 #include "core/layout/ng/ng_units.h" 8 #include "core/layout/ng/ng_units.h"
9 #include "wtf/NonCopyingSort.h" 9 #include "wtf/NonCopyingSort.h"
10 10
(...skipping 25 matching lines...) Expand all
36 opportunity.size.inline_size -= origin_point.inline_offset; 36 opportunity.size.inline_size -= origin_point.inline_offset;
37 opportunity.size.block_size -= origin_point.block_offset; 37 opportunity.size.block_size -= origin_point.block_offset;
38 return opportunity; 38 return opportunity;
39 } 39 }
40 40
41 // Whether 2 edges overlap with each other. 41 // Whether 2 edges overlap with each other.
42 bool IsOverlapping(const NGEdge& edge1, const NGEdge& edge2) { 42 bool IsOverlapping(const NGEdge& edge1, const NGEdge& edge2) {
43 return std::max(edge1.start, edge2.start) <= std::min(edge1.end, edge2.end); 43 return std::max(edge1.start, edge2.start) <= std::min(edge1.end, edge2.end);
44 } 44 }
45 45
46 // Whether the exclusion is out of bounds of the LayoutNG constraint space.
47 bool IsExclusionWithinSpace(const NGLayoutOpportunity& opportunity,
48 const NGExclusion& exclusion) {
49 LayoutUnit left = opportunity.offset.inline_offset;
50 LayoutUnit top = opportunity.offset.block_offset;
51 LayoutUnit right = left + opportunity.size.inline_size;
52 LayoutUnit bottom = top + opportunity.size.block_size;
53
54 return !(exclusion.Right() <= left || exclusion.Bottom() <= top ||
55 exclusion.Left() >= right || exclusion.Top() >= bottom);
56 }
57
58 // Creates the *BOTTOM* positioned Layout Opportunity tree node by splitting 46 // Creates the *BOTTOM* positioned Layout Opportunity tree node by splitting
59 // the parent node with the exclusion. 47 // the parent node with the exclusion.
60 // 48 //
61 // @param parent_node Node that needs to be split. 49 // @param parent_node Node that needs to be split.
62 // @param exclusion Exclusion existed in the parent node constraint space. 50 // @param exclusion Exclusion existed in the parent node constraint space.
63 // @return New node or nullptr if the new block size == 0. 51 // @return New node or nullptr if the new block size == 0.
64 NGLayoutOpportunityTreeNode* CreateBottomNGLayoutOpportunityTreeNode( 52 NGLayoutOpportunityTreeNode* CreateBottomNGLayoutOpportunityTreeNode(
65 const NGLayoutOpportunityTreeNode* parent_node, 53 const NGLayoutOpportunityTreeNode* parent_node,
66 const NGExclusion& exclusion) { 54 const NGLogicalRect& exclusion) {
67 const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity; 55 const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity;
68 LayoutUnit left = parent_opportunity.offset.inline_offset; 56 LayoutUnit bottom_opportunity_block_size =
69 LayoutUnit top = exclusion.Bottom(); 57 parent_opportunity.BlockEndOffset() - exclusion.BlockEndOffset();
70 LayoutUnit right = left + parent_opportunity.size.inline_size; 58 if (bottom_opportunity_block_size > 0) {
71 LayoutUnit bottom = parent_opportunity.offset.block_offset + 59 NGLayoutOpportunity opportunity;
72 parent_opportunity.size.block_size; 60 opportunity.offset.inline_offset = parent_opportunity.InlineStartOffset();
73 61 opportunity.offset.block_offset = exclusion.BlockEndOffset();
74 NGEdge exclusion_edge = {exclusion.Left(), exclusion.Right()}; 62 opportunity.size.inline_size = parent_opportunity.InlineSize();
75 LayoutUnit block_size = bottom - top; 63 opportunity.size.block_size = bottom_opportunity_block_size;
76 if (block_size > 0) { 64 NGEdge exclusion_edge = {/* start */ exclusion.InlineStartOffset(),
77 NGLayoutOpportunity opportunity(left, top, right - left, block_size); 65 /* end */ exclusion.InlineEndOffset()};
78 return new NGLayoutOpportunityTreeNode(opportunity, exclusion_edge); 66 return new NGLayoutOpportunityTreeNode(opportunity, exclusion_edge);
79 } 67 }
80 return nullptr; 68 return nullptr;
81 } 69 }
82 70
83 // Creates the *LEFT* positioned Layout Opportunity tree node by splitting 71 // Creates the *LEFT* positioned Layout Opportunity tree node by splitting
84 // the parent node with the exclusion. 72 // the parent node with the exclusion.
85 // 73 //
86 // @param parent_node Node that needs to be split. 74 // @param parent_node Node that needs to be split.
87 // @param exclusion Exclusion existed in the parent node constraint space. 75 // @param exclusion Exclusion existed in the parent node constraint space.
88 // @return New node or nullptr if the new inline size == 0 or the parent's 76 // @return New node or nullptr if the new inline size == 0 or the parent's
89 // exclusion edge doesn't limit the new node's constraint space. 77 // exclusion edge doesn't limit the new node's constraint space.
90 NGLayoutOpportunityTreeNode* CreateLeftNGLayoutOpportunityTreeNode( 78 NGLayoutOpportunityTreeNode* CreateLeftNGLayoutOpportunityTreeNode(
91 const NGLayoutOpportunityTreeNode* parent_node, 79 const NGLayoutOpportunityTreeNode* parent_node,
92 const NGExclusion& exclusion) { 80 const NGLogicalRect& exclusion) {
93 const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity; 81 const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity;
94 LayoutUnit left = parent_opportunity.offset.inline_offset;
95 LayoutUnit top = parent_opportunity.offset.block_offset;
96 LayoutUnit right = exclusion.Left();
97 LayoutUnit bottom = top + parent_opportunity.size.block_size;
98 82
99 NGEdge node_edge = {left, right}; 83 LayoutUnit left_opportunity_inline_size =
100 LayoutUnit inline_size = right - left; 84 exclusion.InlineStartOffset() - parent_opportunity.InlineStartOffset();
101 if (inline_size > 0 && 85 NGEdge node_edge = {/* start */ parent_opportunity.InlineStartOffset(),
86 /* end */ exclusion.InlineStartOffset()};
87
88 if (left_opportunity_inline_size > 0 &&
102 IsOverlapping(parent_node->exclusion_edge, node_edge)) { 89 IsOverlapping(parent_node->exclusion_edge, node_edge)) {
103 NGLayoutOpportunity opportunity(left, top, inline_size, bottom - top); 90 NGLayoutOpportunity opportunity;
91 opportunity.offset.inline_offset = parent_opportunity.InlineStartOffset();
92 opportunity.offset.block_offset = parent_opportunity.BlockStartOffset();
93 opportunity.size.inline_size = left_opportunity_inline_size;
94 opportunity.size.block_size = parent_opportunity.BlockSize();
104 return new NGLayoutOpportunityTreeNode(opportunity); 95 return new NGLayoutOpportunityTreeNode(opportunity);
105 } 96 }
106 return nullptr; 97 return nullptr;
107 } 98 }
108 99
109 // Creates the *RIGHT* positioned Layout Opportunity tree node by splitting 100 // Creates the *RIGHT* positioned Layout Opportunity tree node by splitting
110 // the parent node with the exclusion. 101 // the parent node with the exclusion.
111 // 102 //
112 // @param parent_node Node that needs to be split. 103 // @param parent_node Node that needs to be split.
113 // @param exclusion Exclusion existed in the parent node constraint space. 104 // @param exclusion Exclusion existed in the parent node constraint space.
114 // @return New node or nullptr if the new inline size == 0 or the parent's 105 // @return New node or nullptr if the new inline size == 0 or the parent's
115 // exclusion edge doesn't limit the new node's constraint space. 106 // exclusion edge doesn't limit the new node's constraint space.
116 NGLayoutOpportunityTreeNode* CreateRightNGLayoutOpportunityTreeNode( 107 NGLayoutOpportunityTreeNode* CreateRightNGLayoutOpportunityTreeNode(
117 const NGLayoutOpportunityTreeNode* parent_node, 108 const NGLayoutOpportunityTreeNode* parent_node,
118 const NGExclusion& exclusion) { 109 const NGLogicalRect& exclusion) {
119 const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity; 110 const NGLayoutOpportunity& parent_opportunity = parent_node->opportunity;
120 LayoutUnit left = exclusion.Right();
121 LayoutUnit top = parent_opportunity.offset.block_offset;
122 LayoutUnit right = parent_opportunity.offset.inline_offset +
123 parent_opportunity.size.inline_size;
124 LayoutUnit bottom = top + parent_opportunity.size.block_size;
125 111
126 NGEdge node_edge = {left, right}; 112 NGEdge node_edge = {/* start */ exclusion.InlineEndOffset(),
127 LayoutUnit inline_size = right - left; 113 /* end */ parent_opportunity.InlineEndOffset()};
128 if (inline_size > 0 && 114 LayoutUnit right_opportunity_inline_size =
115 parent_opportunity.InlineEndOffset() - exclusion.InlineEndOffset();
116 if (right_opportunity_inline_size > 0 &&
129 IsOverlapping(parent_node->exclusion_edge, node_edge)) { 117 IsOverlapping(parent_node->exclusion_edge, node_edge)) {
130 NGLayoutOpportunity opportunity(left, top, inline_size, bottom - top); 118 NGLayoutOpportunity opportunity;
119 opportunity.offset.inline_offset = exclusion.InlineEndOffset();
120 opportunity.offset.block_offset = parent_opportunity.BlockStartOffset();
121 opportunity.size.inline_size = right_opportunity_inline_size;
122 opportunity.size.block_size = parent_opportunity.BlockSize();
131 return new NGLayoutOpportunityTreeNode(opportunity); 123 return new NGLayoutOpportunityTreeNode(opportunity);
132 } 124 }
133 return nullptr; 125 return nullptr;
134 } 126 }
135 127
136 // Gets/Creates the "TOP" positioned constraint space by splitting 128 // Gets/Creates the "TOP" positioned constraint space by splitting
137 // the parent node with the exclusion. 129 // the parent node with the exclusion.
138 // 130 //
139 // @param parent_node Node that needs to be split. 131 // @param parent_opportunity Parent opportunity that is being split.
140 // @param exclusion Exclusion existed in the parent node constraint space. 132 // @param exclusion Exclusion existed in the parent node constraint space.
141 // @return New node or nullptr if the new block size == 0. 133 // @return New node or nullptr if the new block size == 0.
142 NGLayoutOpportunity GetTopSpace(const NGLayoutOpportunity& rect, 134 NGLayoutOpportunity GetTopSpace(const NGLayoutOpportunity& parent_opportunity,
143 const NGExclusion& exclusion) { 135 const NGLogicalRect& exclusion) {
144 LayoutUnit left = rect.offset.inline_offset; 136 LayoutUnit top_opportunity_block_size =
145 LayoutUnit top = rect.offset.block_offset; 137 exclusion.BlockStartOffset() - parent_opportunity.BlockStartOffset();
146 LayoutUnit right = left + rect.size.inline_size; 138 if (top_opportunity_block_size > 0) {
147 LayoutUnit bottom = exclusion.Top(); 139 NGLayoutOpportunity opportunity;
148 140 opportunity.offset.inline_offset = parent_opportunity.InlineStartOffset();
149 LayoutUnit block_size = bottom - top; 141 opportunity.offset.block_offset = parent_opportunity.BlockStartOffset();
150 if (block_size > 0) 142 opportunity.size.inline_size = parent_opportunity.InlineSize();
151 return NGLayoutOpportunity(left, top, right - left, block_size); 143 opportunity.size.block_size = top_opportunity_block_size;
152 144 return opportunity;
145 }
153 return NGLayoutOpportunity(); 146 return NGLayoutOpportunity();
154 } 147 }
155 148
156 // Inserts the exclusion into the Layout Opportunity tree. 149 // Inserts the exclusion into the Layout Opportunity tree.
157 void InsertExclusion(NGLayoutOpportunityTreeNode* node, 150 void InsertExclusion(NGLayoutOpportunityTreeNode* node,
158 const NGExclusion* exclusion, 151 const NGLogicalRect* exclusion,
159 NGLayoutOpportunities& opportunities) { 152 NGLayoutOpportunities& opportunities) {
160 // Base case: there is no node. 153 // Base case: there is no node.
161 if (!node) 154 if (!node)
162 return; 155 return;
163 156
164 // Base case: exclusion is not in the node's constraint space. 157 // Base case: exclusion is not in the node's constraint space.
165 if (!IsExclusionWithinSpace(node->opportunity, *exclusion)) 158 if (!exclusion->IsContained(node->opportunity))
166 return; 159 return;
167 160
168 if (node->exclusion) { 161 if (node->exclusion) {
169 InsertExclusion(node->left, exclusion, opportunities); 162 InsertExclusion(node->left, exclusion, opportunities);
170 InsertExclusion(node->bottom, exclusion, opportunities); 163 InsertExclusion(node->bottom, exclusion, opportunities);
171 InsertExclusion(node->right, exclusion, opportunities); 164 InsertExclusion(node->right, exclusion, opportunities);
172 return; 165 return;
173 } 166 }
174 167
175 // Split the current node. 168 // Split the current node.
176 node->left = CreateLeftNGLayoutOpportunityTreeNode(node, *exclusion); 169 node->left = CreateLeftNGLayoutOpportunityTreeNode(node, *exclusion);
177 node->right = CreateRightNGLayoutOpportunityTreeNode(node, *exclusion); 170 node->right = CreateRightNGLayoutOpportunityTreeNode(node, *exclusion);
178 node->bottom = CreateBottomNGLayoutOpportunityTreeNode(node, *exclusion); 171 node->bottom = CreateBottomNGLayoutOpportunityTreeNode(node, *exclusion);
179 172
180 NGLayoutOpportunity top_layout_opp = 173 NGLayoutOpportunity top_layout_opp =
181 GetTopSpace(node->opportunity, *exclusion); 174 GetTopSpace(node->opportunity, *exclusion);
182 if (!top_layout_opp.IsEmpty()) 175 if (!top_layout_opp.IsEmpty())
183 opportunities.append(top_layout_opp); 176 opportunities.append(top_layout_opp);
184 177
185 node->exclusion = exclusion; 178 node->exclusion = exclusion;
186 } 179 }
187 180
188 // Compares exclusions by their top position. 181 // Compares exclusions by their top position.
189 bool CompareNGExclusionsByTopAsc(const Member<const NGExclusion>& lhs, 182 bool CompareNGExclusionsByTopAsc(
190 const Member<const NGExclusion>& rhs) { 183 const std::unique_ptr<const NGLogicalRect>& lhs,
191 return rhs->Top() > lhs->Top(); 184 const std::unique_ptr<const NGLogicalRect>& rhs) {
185 return rhs->offset.block_offset > lhs->offset.block_offset;
192 } 186 }
193 187
194 // Compares Layout Opportunities by Start Point. 188 // Compares Layout Opportunities by Start Point.
195 // Start point is a TopLeft position from where inline content can potentially 189 // Start point is a TopLeft position from where inline content can potentially
196 // start positioning itself. 190 // start positioning itself.
197 bool CompareNGLayoutOpportunitesByStartPoint(const NGLayoutOpportunity& lhs, 191 bool CompareNGLayoutOpportunitesByStartPoint(const NGLayoutOpportunity& lhs,
198 const NGLayoutOpportunity& rhs) { 192 const NGLayoutOpportunity& rhs) {
199 // sort by TOP. 193 // sort by TOP.
200 if (rhs.offset.block_offset > lhs.offset.block_offset) { 194 if (rhs.offset.block_offset > lhs.offset.block_offset) {
201 return true; 195 return true;
(...skipping 15 matching lines...) Expand all
217 } 211 }
218 212
219 } // namespace 213 } // namespace
220 214
221 NGLayoutOpportunityIterator::NGLayoutOpportunityIterator( 215 NGLayoutOpportunityIterator::NGLayoutOpportunityIterator(
222 NGConstraintSpace* space, 216 NGConstraintSpace* space,
223 const NGLogicalOffset origin_point, 217 const NGLogicalOffset origin_point,
224 const NGLogicalOffset leader_point) 218 const NGLogicalOffset leader_point)
225 : constraint_space_(space), leader_point_(leader_point) { 219 : constraint_space_(space), leader_point_(leader_point) {
226 // TODO(chrome-layout-team): Combine exclusions that shadow each other. 220 // TODO(chrome-layout-team): Combine exclusions that shadow each other.
227 auto exclusions = constraint_space_->PhysicalSpace()->Exclusions(); 221 auto& exclusions = constraint_space_->PhysicalSpace()->Exclusions();
228 DCHECK(std::is_sorted(exclusions.begin(), exclusions.end(), 222 DCHECK(std::is_sorted(exclusions.begin(), exclusions.end(),
229 &CompareNGExclusionsByTopAsc)) 223 &CompareNGExclusionsByTopAsc))
230 << "Exclusions are expected to be sorted by TOP"; 224 << "Exclusions are expected to be sorted by TOP";
231 225
232 NGLayoutOpportunity initial_opportunity = 226 NGLayoutOpportunity initial_opportunity =
233 CreateLayoutOpportunityFromConstraintSpace(*space, origin_point); 227 CreateLayoutOpportunityFromConstraintSpace(*space, origin_point);
234 opportunity_tree_root_ = new NGLayoutOpportunityTreeNode(initial_opportunity); 228 opportunity_tree_root_ = new NGLayoutOpportunityTreeNode(initial_opportunity);
235 229
236 for (const auto exclusion : exclusions) { 230 for (const auto& exclusion : exclusions) {
237 InsertExclusion(MutableOpportunityTreeRoot(), exclusion, opportunities_); 231 InsertExclusion(MutableOpportunityTreeRoot(), exclusion.get(),
232 opportunities_);
238 } 233 }
239 CollectAllOpportunities(OpportunityTreeRoot(), opportunities_); 234 CollectAllOpportunities(OpportunityTreeRoot(), opportunities_);
240 std::sort(opportunities_.begin(), opportunities_.end(), 235 std::sort(opportunities_.begin(), opportunities_.end(),
241 &CompareNGLayoutOpportunitesByStartPoint); 236 &CompareNGLayoutOpportunitesByStartPoint);
242 237
243 opportunity_iter_ = opportunities_.begin(); 238 opportunity_iter_ = opportunities_.begin();
244 } 239 }
245 240
246 const NGLayoutOpportunity NGLayoutOpportunityIterator::Next() { 241 const NGLayoutOpportunity NGLayoutOpportunityIterator::Next() {
247 if (opportunity_iter_ == opportunities_.end()) 242 if (opportunity_iter_ == opportunities_.end())
248 return NGLayoutOpportunity(); 243 return NGLayoutOpportunity();
249 auto* opportunity = opportunity_iter_; 244 auto* opportunity = opportunity_iter_;
250 opportunity_iter_++; 245 opportunity_iter_++;
251 return NGLayoutOpportunity(*opportunity); 246 return NGLayoutOpportunity(*opportunity);
252 } 247 }
253 248
254 } // namespace blink 249 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698