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

Side by Side Diff: third_party/WebKit/Source/core/layout/ng/ng_floats_utils.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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "core/layout/ng/ng_floats_utils.h"
6
7 #include "core/layout/ng/ng_box_fragment.h"
8
9 namespace blink {
10 namespace {
11
12 // 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 // than the outer top of any block or floated box generated by an element
15 // earlier in the source document.
16 NGLogicalOffset AdjustToTopEdgeAlignmentRule(const NGConstraintSpace& space,
17 const NGLogicalOffset& offset) {
18 NGLogicalOffset adjusted_offset = offset;
19 LayoutUnit& adjusted_block_offset = adjusted_offset.block_offset;
20 if (space.Exclusions()->last_left_float)
21 adjusted_block_offset =
22 std::max(adjusted_block_offset,
23 space.Exclusions()->last_left_float->rect.BlockStartOffset());
24 if (space.Exclusions()->last_right_float)
25 adjusted_block_offset =
26 std::max(adjusted_block_offset,
27 space.Exclusions()->last_right_float->rect.BlockStartOffset());
28 return adjusted_offset;
29 }
30
31 // Finds a layout opportunity for the fragment.
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 origin_point {@code space}'s offset relative to the space that
40 // establishes a new formatting context that we're currently
41 // in and where all our exclusions reside.
42 // @param margins Margins of the fragment.
43 // @return Layout opportunity for the fragment.
44 const NGLayoutOpportunity FindLayoutOpportunityForFragment(
45 const NGConstraintSpace* space,
46 const NGFragment& fragment,
47 const NGLogicalOffset& origin_point,
48 const NGBoxStrut& margins) {
49 NGLogicalOffset adjusted_origin_point =
50 AdjustToTopEdgeAlignmentRule(*space, origin_point);
51
52 NGLayoutOpportunityIterator opportunity_iter(space, adjusted_origin_point);
53 NGLayoutOpportunity opportunity;
54 NGLayoutOpportunity opportunity_candidate = opportunity_iter.Next();
55
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 }
68
69 // Calculates the logical offset for opportunity.
70 NGLogicalOffset CalculateLogicalOffsetForOpportunity(
71 const NGLayoutOpportunity& opportunity,
72 const LayoutUnit float_offset,
73 const NGLogicalOffset& from_offset,
74 NGFloatingObject* floating_object) {
75 DCHECK(floating_object);
76 auto margins = floating_object->margins;
77 // Adjust to child's margin.
78 LayoutUnit inline_offset = margins.inline_start;
79 LayoutUnit block_offset = margins.block_start;
80
81 // Offset from the opportunity's block/inline start.
82 inline_offset += opportunity.offset.inline_offset;
83 block_offset += opportunity.offset.block_offset;
84
85 // Adjust to float: right offset if needed.
86 inline_offset += float_offset;
87
88 block_offset -= from_offset.block_offset;
89 inline_offset -= from_offset.inline_offset;
90
91 return NGLogicalOffset(inline_offset, block_offset);
92 }
93
94 // Creates an exclusion from the fragment that will be placed in the provided
95 // layout opportunity.
96 NGExclusion CreateExclusion(const NGFragment& fragment,
97 const NGLayoutOpportunity& opportunity,
98 const LayoutUnit float_offset,
99 const NGBoxStrut& margins,
100 NGExclusion::Type exclusion_type) {
101 NGExclusion exclusion;
102 exclusion.type = exclusion_type;
103 NGLogicalRect& rect = exclusion.rect;
104 rect.offset = opportunity.offset;
105 rect.offset.inline_offset += float_offset;
106
107 rect.size.inline_size = fragment.InlineSize() + margins.InlineSum();
108 rect.size.block_size = fragment.BlockSize() + margins.BlockSum();
109 return exclusion;
110 }
111
112 // Updates the Floating Object's left offset from the provided parent_space
113 // and {@code floating_object}'s space and margins.
114 void UpdateFloatingObjectLeftOffset(const NGConstraintSpace& new_parent_space,
115 const NGLogicalOffset& float_logical_offset,
116 NGFloatingObject* floating_object) {
117 DCHECK(floating_object);
118 // TODO(glebl): We should use physical offset here.
119 floating_object->left_offset =
120 floating_object->original_parent_space->BfcOffset().inline_offset -
121 new_parent_space.BfcOffset().inline_offset +
122 float_logical_offset.inline_offset;
123 }
124 } // namespace
125
126 // Calculates the relative position from {@code from_offset} of the
127 // floating object that is requested to be positioned from {@code origin_point}.
128 NGLogicalOffset PositionFloat(const NGLogicalOffset& origin_point,
129 const NGLogicalOffset& from_offset,
130 NGFloatingObject* floating_object,
131 NGConstraintSpace* new_parent_space) {
132 DCHECK(floating_object);
133 const auto* float_space = floating_object->space.get();
134 DCHECK(floating_object->fragment) << "Fragment cannot be null here";
135
136 // TODO(ikilpatrick): The writing mode switching here looks wrong.
137 NGBoxFragment float_fragment(
138 float_space->WritingMode(),
139 toNGPhysicalBoxFragment(floating_object->fragment.get()));
140
141 // Find a layout opportunity that will fit our float.
142 const NGLayoutOpportunity opportunity = FindLayoutOpportunityForFragment(
143 float_space, float_fragment, origin_point, floating_object->margins);
144 DCHECK(!opportunity.IsEmpty()) << "Opportunity is empty but it shouldn't be";
145
146 // Calculate the float offset if needed.
147 LayoutUnit float_offset;
148 if (floating_object->exclusion_type == NGExclusion::kFloatRight) {
149 LayoutUnit float_margin_box_inline_size =
150 float_fragment.InlineSize() + floating_object->margins.InlineSum();
151 float_offset = opportunity.size.inline_size - float_margin_box_inline_size;
152 }
153
154 // Add the float as an exclusion.
155 const NGExclusion exclusion = CreateExclusion(
156 float_fragment, opportunity, float_offset, floating_object->margins,
157 floating_object->exclusion_type);
158 new_parent_space->AddExclusion(exclusion);
159
160 NGLogicalOffset logical_offset = CalculateLogicalOffsetForOpportunity(
161 opportunity, float_offset, from_offset, floating_object);
162 UpdateFloatingObjectLeftOffset(*new_parent_space, logical_offset,
163 floating_object);
164 return logical_offset;
165 }
166 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698