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

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

Issue 2816933003: Use Layout Opportunity Iterator to position new FC blocks. (Closed)
Patch Set: fix block-formatting-contexts-{005|007} Created 3 years, 8 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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_floats_utils.h" 5 #include "core/layout/ng/ng_floats_utils.h"
6 6
7 #include "core/layout/ng/ng_box_fragment.h" 7 #include "core/layout/ng/ng_box_fragment.h"
8 #include "core/layout/ng/ng_layout_opportunity_iterator.h"
8 9
9 namespace blink { 10 namespace blink {
10 namespace { 11 namespace {
11 12
12 // Adjusts the provided offset to the top edge alignment rule. 13 // Adjusts the provided offset to the top edge alignment rule.
13 // Top edge alignment rule: the outer top of a floating box may not be higher 14 // Top edge alignment rule: the outer top of a floating box may not be higher
14 // than the outer top of any block or floated box generated by an element 15 // than the outer top of any block or floated box generated by an element
15 // earlier in the source document. 16 // earlier in the source document.
16 NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space, 17 NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space,
17 const NGLogicalOffset& offset) { 18 const NGLogicalOffset& offset) {
18 NGLogicalOffset adjusted_offset = offset; 19 NGLogicalOffset adjusted_offset = offset;
19 LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset; 20 LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset;
20 if (space.Exclusions()->last_left_float) 21 if (space.Exclusions()->last_left_float)
21 adjusted_block_offset = 22 adjusted_block_offset =
22 std::max(adjusted_block_offset, 23 std::max(adjusted_block_offset,
23 space.Exclusions()->last_left_float->rect.BlockStartOffset()); 24 space.Exclusions()->last_left_float->rect.BlockStartOffset());
24 if (space.Exclusions()->last_right_float) 25 if (space.Exclusions()->last_right_float)
25 adjusted_block_offset = 26 adjusted_block_offset =
26 std::max(adjusted_block_offset, 27 std::max(adjusted_block_offset,
27 space.Exclusions()->last_right_float->rect.BlockStartOffset()); 28 space.Exclusions()->last_right_float->rect.BlockStartOffset());
28 return adjusted_offset; 29 return adjusted_offset;
29 } 30 }
30 31
31 // Finds a layout opportunity for the fragment. 32 NGLayoutOpportunity FindLayoutOpportunityForFloat(
32 // It iterates over all layout opportunities in the constraint space and returns
33 // the first layout opportunity that is wider than the fragment or returns the
34 // last one which is always the widest.
35 //
36 // @param space Constraint space that is used to find layout opportunity for
37 // the fragment.
38 // @param fragment Fragment that needs to be placed.
39 // @param floating_object Floating object for which we need to find a layout
40 // opportunity.
41 // @return Layout opportunity for the fragment.
42 const NGLayoutOpportunity FindLayoutOpportunityForFragment(
43 const NGConstraintSpace* space, 33 const NGConstraintSpace* space,
44 const NGFragment& fragment, 34 const NGFragment& fragment,
45 const NGFloatingObject* floating_object) { 35 const NGFloatingObject* floating_object) {
46 NGLogicalOffset adjusted_origin_point = 36 NGLogicalOffset adjusted_origin_point =
47 AdjustToTopEdgeAlignmentRule(*space, floating_object->origin_offset); 37 AdjustToTopEdgeAlignmentRule(*space, floating_object->origin_offset);
48 38 return FindLayoutOpportunityForFragment(
49 NGLayoutOpportunityIterator opportunity_iter(space->Exclusions().get(), 39 space->Exclusions().get(), floating_object->available_size,
50 floating_object->available_size, 40 adjusted_origin_point, floating_object->margins, fragment);
51 adjusted_origin_point);
52 NGLayoutOpportunity opportunity;
53 NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next();
54
55 NGBoxStrut margins = floating_object->margins;
56 while (!opportunity_candidate.IsEmpty()) {
57 opportunity = opportunity_candidate;
58 // Checking opportunity's block size is not necessary as a float cannot be
59 // positioned on top of another float inside of the same constraint space.
60 auto fragment_inline_size = fragment.InlineSize() + margins.InlineSum();
61 if (opportunity.size.inline_size >= fragment_inline_size)
62 break;
63
64 opportunity_candidate = opportunity_iter.Next();
65 }
66 return opportunity;
67 } 41 }
68 42
69 // Calculates the logical offset for opportunity. 43 // Calculates the logical offset for opportunity.
70 NGLogicalOffset CalculateLogicalOffsetForOpportunity( 44 NGLogicalOffset CalculateLogicalOffsetForOpportunity(
71 const NGLayoutOpportunity& opportunity, 45 const NGLayoutOpportunity& opportunity,
72 const LayoutUnit float_offset, 46 const LayoutUnit float_offset,
73 const NGFloatingObject* floating_object) { 47 const NGFloatingObject* floating_object) {
74 DCHECK(floating_object); 48 DCHECK(floating_object);
75 auto margins = floating_object->margins; 49 auto margins = floating_object->margins;
76 // Adjust to child's margin. 50 // Adjust to child's margin.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 NGConstraintSpace* new_parent_space) { 95 NGConstraintSpace* new_parent_space) {
122 DCHECK(floating_object); 96 DCHECK(floating_object);
123 DCHECK(floating_object->fragment) << "Fragment cannot be null here"; 97 DCHECK(floating_object->fragment) << "Fragment cannot be null here";
124 98
125 // TODO(ikilpatrick): The writing mode switching here looks wrong. 99 // TODO(ikilpatrick): The writing mode switching here looks wrong.
126 NGBoxFragment float_fragment( 100 NGBoxFragment float_fragment(
127 floating_object->writing_mode, 101 floating_object->writing_mode,
128 ToNGPhysicalBoxFragment(floating_object->fragment.Get())); 102 ToNGPhysicalBoxFragment(floating_object->fragment.Get()));
129 103
130 // Find a layout opportunity that will fit our float. 104 // Find a layout opportunity that will fit our float.
131 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment( 105 NGLayoutOpportunity opportunity = FindLayoutOpportunityForFloat(
132 new_parent_space, float_fragment, floating_object); 106 new_parent_space, float_fragment, floating_object);
133 107
134 // TODO(glebl): This should check for infinite opportunity instead. 108 // TODO(glebl): This should check for infinite opportunity instead.
135 if (opportunity.IsEmpty()) { 109 if (opportunity.IsEmpty()) {
136 // Because of the implementation specific of the layout opportunity iterator 110 // Because of the implementation specific of the layout opportunity iterator
137 // an empty opportunity can mean 2 things: 111 // an empty opportunity can mean 2 things:
138 // - search for layout opportunities is exhausted. 112 // - search for layout opportunities is exhausted.
139 // - opportunity has an infinite size. That's because CS is infinite. 113 // - opportunity has an infinite size. That's because CS is infinite.
140 opportunity = NGLayoutOpportunity( 114 opportunity = NGLayoutOpportunity(
141 NGLogicalOffset(), 115 NGLogicalOffset(),
(...skipping 14 matching lines...) Expand all
156 floating_object->exclusion_type); 130 floating_object->exclusion_type);
157 new_parent_space->AddExclusion(exclusion); 131 new_parent_space->AddExclusion(exclusion);
158 132
159 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity( 133 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity(
160 opportunity, float_offset, floating_object); 134 opportunity, float_offset, floating_object);
161 UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset, 135 UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset,
162 floating_object); 136 floating_object);
163 return logical_offset; 137 return logical_offset;
164 } 138 }
165 139
166 void PositionPendingFloats(const LayoutUnit& origin_block_offset, 140 void PositionFloats(LayoutUnit origin_block_offset,
167 NGConstraintSpace* space, 141 LayoutUnit from_block_offset,
168 NGFragmentBuilder* builder) { 142 const Vector<RefPtr<NGFloatingObject>>& floating_objects,
169 DCHECK(builder) << "Builder cannot be null here"; 143 NGConstraintSpace* space) {
170 DCHECK(builder->BfcOffset()) << "Parent BFC offset should be known here"; 144 for (auto& floating_object : floating_objects) {
171 LayoutUnit bfc_block_offset = builder->BfcOffset().value().block_offset;
172
173 for (auto& floating_object : builder->UnpositionedFloats()) {
174 floating_object->origin_offset.block_offset = origin_block_offset; 145 floating_object->origin_offset.block_offset = origin_block_offset;
175 floating_object->from_offset.block_offset = bfc_block_offset; 146 floating_object->from_offset.block_offset = from_block_offset;
176 147 floating_object->logical_offset =
177 NGLogicalOffset offset = PositionFloat(floating_object.Get(), space); 148 PositionFloat(floating_object.Get(), space);
178 builder->AddFloatingObject(floating_object, offset);
179 } 149 }
180 builder->MutableUnpositionedFloats().clear();
181 } 150 }
182 151
183 } // namespace blink 152 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698