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

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

Issue 2757603007: Move NG floats utility methods to the separate file (Closed)
Patch Set: Created 3 years, 9 months 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_block_layout_algorithm.h" 5 #include "core/layout/ng/ng_block_layout_algorithm.h"
6 6
7 #include "core/layout/ng/ng_absolute_utils.h" 7 #include "core/layout/ng/ng_absolute_utils.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_child_iterator.h" 9 #include "core/layout/ng/ng_block_child_iterator.h"
10 #include "core/layout/ng/ng_box_fragment.h" 10 #include "core/layout/ng/ng_box_fragment.h"
11 #include "core/layout/ng/ng_constraint_space.h" 11 #include "core/layout/ng/ng_constraint_space.h"
12 #include "core/layout/ng/ng_constraint_space_builder.h" 12 #include "core/layout/ng/ng_constraint_space_builder.h"
13 #include "core/layout/ng/ng_floats_utils.h"
13 #include "core/layout/ng/ng_fragment.h" 14 #include "core/layout/ng/ng_fragment.h"
14 #include "core/layout/ng/ng_fragment_builder.h" 15 #include "core/layout/ng/ng_fragment_builder.h"
15 #include "core/layout/ng/ng_inline_node.h" 16 #include "core/layout/ng/ng_inline_node.h"
16 #include "core/layout/ng/ng_layout_opportunity_iterator.h" 17 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
17 #include "core/layout/ng/ng_length_utils.h" 18 #include "core/layout/ng/ng_length_utils.h"
18 #include "core/layout/ng/ng_line_builder.h" 19 #include "core/layout/ng/ng_line_builder.h"
19 #include "core/layout/ng/ng_out_of_flow_layout_part.h" 20 #include "core/layout/ng/ng_out_of_flow_layout_part.h"
20 #include "core/style/ComputedStyle.h" 21 #include "core/style/ComputedStyle.h"
21 #include "platform/LengthFunctions.h" 22 #include "platform/LengthFunctions.h"
22 #include "wtf/Optional.h" 23 #include "wtf/Optional.h"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 case EClear::kRight: 76 case EClear::kRight:
76 return right_offset; 77 return right_offset;
77 case EClear::kBoth: 78 case EClear::kBoth:
78 return OptionalMax<LayoutUnit>(left_offset, right_offset); 79 return OptionalMax<LayoutUnit>(left_offset, right_offset);
79 default: 80 default:
80 ASSERT_NOT_REACHED(); 81 ASSERT_NOT_REACHED();
81 } 82 }
82 return WTF::nullopt; 83 return WTF::nullopt;
83 } 84 }
84 85
85 // Creates an exclusion from the fragment that will be placed in the provided
86 // layout opportunity.
87 NGExclusion CreateExclusion(const NGFragment& fragment,
88 const NGLayoutOpportunity& opportunity,
89 const LayoutUnit float_offset,
90 const NGBoxStrut& margins,
91 NGExclusion::Type exclusion_type) {
92 NGExclusion exclusion;
93 exclusion.type = exclusion_type;
94 NGLogicalRect& rect = exclusion.rect;
95 rect.offset = opportunity.offset;
96 rect.offset.inline_offset += float_offset;
97
98 rect.size.inline_size = fragment.InlineSize() + margins.InlineSum();
99 rect.size.block_size = fragment.BlockSize() + margins.BlockSum();
100 return exclusion;
101 }
102
103 // Adjusts the provided offset to the top edge alignment rule.
104 // Top edge alignment rule: the outer top of a floating box may not be higher
105 // than the outer top of any block or floated box generated by an element
106 // earlier in the source document.
107 NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space,
108 const NGLogicalOffset& offset) {
109 NGLogicalOffset adjusted_offset = offset;
110 LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset;
111 if (space.Exclusions()->last_left_float)
112 adjusted_block_offset =
113 std::max(adjusted_block_offset,
114 space.Exclusions()->last_left_float->rect.BlockStartOffset());
115 if (space.Exclusions()->last_right_float)
116 adjusted_block_offset =
117 std::max(adjusted_block_offset,
118 space.Exclusions()->last_right_float->rect.BlockStartOffset());
119 return adjusted_offset;
120 }
121
122 // Finds a layout opportunity for the fragment.
123 // It iterates over all layout opportunities in the constraint space and returns
124 // the first layout opportunity that is wider than the fragment or returns the
125 // last one which is always the widest.
126 //
127 // @param space Constraint space that is used to find layout opportunity for
128 // the fragment.
129 // @param fragment Fragment that needs to be placed.
130 // @param origin_point {@code space}'s offset relative to the space that
131 // establishes a new formatting context that we're currently
132 // in and where all our exclusions reside.
133 // @param margins Margins of the fragment.
134 // @return Layout opportunity for the fragment.
135 const NGLayoutOpportunity FindLayoutOpportunityForFragment(
136 const NGConstraintSpace* space,
137 const NGFragment& fragment,
138 const NGLogicalOffset& origin_point,
139 const NGBoxStrut& margins) {
140 NGLogicalOffset adjusted_origin_point =
141 AdjustToTopEdgeAlignmentRule(*space, origin_point);
142
143 NGLayoutOpportunityIterator opportunity_iter(space, adjusted_origin_point);
144 NGLayoutOpportunity opportunity;
145 NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next();
146
147 while (!opportunity_candidate.IsEmpty()) {
148 opportunity = opportunity_candidate;
149 // Checking opportunity's block size is not necessary as a float cannot be
150 // positioned on top of another float inside of the same constraint space.
151 auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum();
152 if (opportunity.size.inline_size >= fragment_inline_size)
153 break;
154
155 opportunity_candidate = opportunity_iter.Next();
156 }
157 return opportunity;
158 }
159
160 // Calculates the logical offset for opportunity.
161 NGLogicalOffset CalculateLogicalOffsetForOpportunity(
162 const NGLayoutOpportunity& opportunity,
163 const LayoutUnit float_offset,
164 const NGLogicalOffset& from_offset,
165 NGFloatingObject* floating_object) {
166 DCHECK(floating_object);
167 auto margins = floating_object->margins;
168 // Adjust to child's margin.
169 LayoutUnit inline_offset = margins.inline_start;
170 LayoutUnit block_offset = margins.block_start;
171
172 // Offset from the opportunity's block/inline start.
173 inline_offset += opportunity.offset.inline_offset;
174 block_offset += opportunity.offset.block_offset;
175
176 // Adjust to float: right offset if needed.
177 inline_offset += float_offset;
178
179 block_offset -= from_offset.block_offset;
180 inline_offset -= from_offset.inline_offset;
181
182 return NGLogicalOffset(inline_offset, block_offset);
183 }
184
185 // Calculates the relative position from {@code from_offset} of the
186 // floating object that is requested to be positioned from {@code origin_point}.
187 NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point,
188 const NGLogicalOffset& from_offset,
189 NGFloatingObject* floating_object,
190 NGConstraintSpace* new_parent_space) {
191 DCHECK(floating_object);
192 const auto* float_space = floating_object->space.get();
193 DCHECK(floating_object->fragment) << "Fragment cannot be null here";
194
195 // TODO(ikilpatrick): The writing mode switching here looks wrong.
196 NGBoxFragment float_fragment(
197 float_space->WritingMode(),
198 toNGPhysicalBoxFragment(floating_object->fragment.get()));
199
200 // Find a layout opportunity that will fit our float.
201 const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
202 float_space, float_fragment, origin_point, floating_object->margins);
203 DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be";
204
205 // Calculate the float offset if needed.
206 LayoutUnit float_offset;
207 if (floating_object->exclusion_type == NGExclusion::kFloatRight) {
208 LayoutUnit float_margin_box_inline_size =
209 float_fragment.InlineSize() + floating_object->margins.InlineSum();
210 float_offset = opportunity.size.inline_size - float_margin_box_inline_size;
211 }
212
213 // Add the float as an exclusion.
214 const NGExclusion exclusion = CreateExclusion(
215 float_fragment, opportunity, float_offset, floating_object->margins,
216 floating_object->exclusion_type);
217 new_parent_space->AddExclusion(exclusion);
218
219 return CalculateLogicalOffsetForOpportunity(opportunity, float_offset,
220 from_offset, floating_object);
221 }
222
223 // Updates the Floating Object's left offset from the provided parent_space
224 // and {@code floating_object}'s space and margins.
225 void UpdateFloatingObjectLeftOffset(const NGConstraintSpace& new_parent_space,
226 const NGLogicalOffset& float_logical_offset,
227 NGFloatingObject* floating_object) {
228 DCHECK(floating_object);
229 // TODO(glebl): We should use physical offset here.
230 floating_object->left_offset =
231 floating_object->original_parent_space->BfcOffset().inline_offset -
232 new_parent_space.BfcOffset().inline_offset +
233 float_logical_offset.inline_offset;
234 }
235
236 // Positions pending floats stored on the fragment builder starting from 86 // Positions pending floats stored on the fragment builder starting from
237 // {@code origin_point_block_offset}. 87 // {@code origin_point_block_offset}.
238 void PositionPendingFloats(const LayoutUnit origin_point_block_offset, 88 void PositionPendingFloats(const LayoutUnit origin_point_block_offset,
239 NGConstraintSpace* new_parent_space, 89 NGConstraintSpace* new_parent_space,
240 NGFragmentBuilder* builder) { 90 NGFragmentBuilder* builder) {
241 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here"; 91 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here";
242 LayoutUnit bfc_block_offset = builder->BfcOffset().value().block_offset; 92 LayoutUnit bfc_block_offset = builder->BfcOffset().value().block_offset;
243 93
244 for (auto& floating_object : builder->UnpositionedFloats()) { 94 for (auto& floating_object : builder->UnpositionedFloats()) {
245 const auto* float_space = floating_object->space.get(); 95 const auto* float_space = floating_object->space.get();
246 const NGConstraintSpace* original_parent_space = 96 const NGConstraintSpace* original_parent_space =
247 floating_object->original_parent_space.get(); 97 floating_object->original_parent_space.get();
248 98
249 NGLogicalOffset origin_point = {float_space->BfcOffset().inline_offset, 99 NGLogicalOffset origin_point = {float_space->BfcOffset().inline_offset,
250 origin_point_block_offset}; 100 origin_point_block_offset};
251 NGLogicalOffset from_offset = { 101 NGLogicalOffset from_offset = {
252 original_parent_space->BfcOffset().inline_offset, bfc_block_offset}; 102 original_parent_space->BfcOffset().inline_offset, bfc_block_offset};
253 103
254 NGLogicalOffset float_fragment_offset = PositionFloat( 104 NGLogicalOffset float_fragment_offset = PositionFloat(
255 origin_point, from_offset, floating_object.get(), new_parent_space); 105 origin_point, from_offset, floating_object.get(), new_parent_space);
256 builder->AddFloatingObject(floating_object, float_fragment_offset); 106 builder->AddFloatingObject(floating_object, float_fragment_offset);
257 UpdateFloatingObjectLeftOffset(*new_parent_space, float_fragment_offset,
258 floating_object.get());
259 } 107 }
260 builder->MutableUnpositionedFloats().clear(); 108 builder->MutableUnpositionedFloats().clear();
261 } 109 }
262 110
263 // Whether an in-flow block-level child creates a new formatting context. 111 // Whether an in-flow block-level child creates a new formatting context.
264 // 112 //
265 // This will *NOT* check the following cases: 113 // This will *NOT* check the following cases:
266 // - The child is out-of-flow, e.g. floating or abs-pos. 114 // - The child is out-of-flow, e.g. floating or abs-pos.
267 // - The child is a inline-level, e.g. "display: inline-block". 115 // - The child is a inline-level, e.g. "display: inline-block".
268 // - The child establishes a new formatting context, but should be a child of 116 // - The child establishes a new formatting context, but should be a child of
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 DCHECK(builder_.BfcOffset()); 594 DCHECK(builder_.BfcOffset());
747 space_available -= curr_bfc_offset_.block_offset; 595 space_available -= curr_bfc_offset_.block_offset;
748 } 596 }
749 } 597 }
750 space_builder_.SetFragmentainerSpaceAvailable(space_available); 598 space_builder_.SetFragmentainerSpaceAvailable(space_available);
751 599
752 return space_builder_.ToConstraintSpace( 600 return space_builder_.ToConstraintSpace(
753 FromPlatformWritingMode(child_style.getWritingMode())); 601 FromPlatformWritingMode(child_style.getWritingMode()));
754 } 602 }
755 } // namespace blink 603 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698