OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "core/layout/ng/ng_out_of_flow_layout_part.h" | |
6 | |
7 #include "core/layout/ng/ng_absolute_utils.h" | |
8 #include "core/layout/ng/ng_block_node.h" | |
9 #include "core/layout/ng/ng_constraint_space_builder.h" | |
10 #include "core/layout/ng/ng_fragment_base.h" | |
11 #include "core/layout/ng/ng_length_utils.h" | |
12 #include "core/style/ComputedStyle.h" | |
13 | |
14 namespace blink { | |
15 | |
16 NGOutOfFlowLayoutPart::NGOutOfFlowLayoutPart( | |
17 PassRefPtr<const ComputedStyle> container_style, | |
18 NGLogicalSize container_size) { | |
19 contains_fixed_ = container_style->canContainFixedPositionObjects(); | |
20 contains_absolute_ = container_style->canContainAbsolutePositionObjects(); | |
cbiesinger
2016/12/21 21:38:50
Neat, I didn't know about that function!
But I th
atotic
2016/12/28 19:36:46
done. Good catch.
| |
21 // Initialize ConstraintSpace | |
22 NGLogicalSize space_size = container_size; | |
23 NGBoxStrut borders = ComputeBorders(*container_style); | |
24 space_size.block_size -= borders.block_start + borders.block_end; | |
cbiesinger
2016/12/21 21:38:50
-= borders.BlockSum()
atotic
2016/12/28 19:36:46
done. Also fixed InlineSum()
| |
25 space_size.inline_size -= borders.inline_start + borders.inline_end; | |
26 parent_offset_ = NGLogicalOffset{borders.inline_start, borders.block_start}; | |
27 parent_physical_offset_ = parent_offset_.ConvertToPhysical( | |
28 FromPlatformWritingMode(container_style->getWritingMode()), | |
29 container_style->direction(), | |
30 container_size.ConvertToPhysical( | |
31 FromPlatformWritingMode(container_style->getWritingMode())), | |
32 NGPhysicalSize()); | |
33 NGConstraintSpaceBuilder space_builder( | |
34 FromPlatformWritingMode(container_style->getWritingMode())); | |
35 space_builder.SetAvailableSize(space_size); | |
36 space_builder.SetIsNewFormattingContext(true); | |
37 space_builder.SetTextDirection(container_style->direction()); | |
38 parent_space_ = space_builder.ToConstraintSpace(); | |
39 } | |
40 | |
41 bool NGOutOfFlowLayoutPart::StartLayout( | |
42 NGBlockNode* node, | |
43 const NGStaticPosition& static_position) { | |
44 EPosition position = node->Style()->position(); | |
45 if ((contains_absolute_ && position == AbsolutePosition) || | |
46 (contains_fixed_ && position == FixedPosition)) { | |
47 node_ = node; | |
48 static_position_ = static_position; | |
49 // Adjust static_position origin. static_position coordinate origin is | |
50 // border_box, absolute position coordinate origin is padding box. | |
51 static_position_.offset -= parent_physical_offset_; | |
52 node_fragment_ = nullptr; | |
53 node_position_ = NGAbsolutePhysicalPosition(); | |
54 inline_estimate_.reset(); | |
55 block_estimate_.reset(); | |
56 state_ = kComputeInlineEstimate; | |
57 return true; | |
58 } | |
59 return false; | |
60 } | |
61 | |
62 bool NGOutOfFlowLayoutPart::Layout(NGFragmentBase** fragment, | |
63 NGLogicalOffset* offset) { | |
64 DCHECK(node_); | |
65 switch (state_) { | |
66 case kComputeInlineEstimate: | |
67 if (ComputeInlineSizeEstimate()) | |
68 state_ = kPartialPosition; | |
69 break; | |
70 case kPartialPosition: | |
71 node_position_ = ComputePartialAbsoluteWithChildInlineSize( | |
72 *parent_space_, *node_->Style(), static_position_, inline_estimate_); | |
73 state_ = kComputeBlockEstimate; | |
74 break; | |
75 case kComputeBlockEstimate: | |
76 if (ComputeBlockSizeEstimate()) | |
77 state_ = kFullPosition; | |
78 break; | |
79 case kFullPosition: | |
80 ComputeFullAbsoluteWithChildBlockSize(*parent_space_, *node_->Style(), | |
81 static_position_, block_estimate_, | |
82 &node_position_); | |
83 state_ = kGenerateFragment; | |
84 break; | |
85 case kGenerateFragment: | |
86 block_estimate_ = | |
87 node_position_.size.ConvertToLogical(parent_space_->WritingMode()) | |
88 .block_size; | |
89 if (!ComputeNodeFragment()) | |
90 return false; | |
91 state_ = kDone; | |
92 break; | |
93 case kDone: | |
94 *fragment = node_fragment_; | |
95 // Compute offset | |
96 NGBoxStrut inset = node_position_.inset.ConvertToLogical( | |
97 parent_space_->WritingMode(), parent_space_->Direction()); | |
98 offset->inline_offset = inset.inline_start + parent_offset_.inline_offset; | |
99 offset->block_offset = inset.block_start + parent_offset_.block_offset; | |
100 return true; | |
101 } | |
102 return false; | |
103 } | |
104 | |
105 bool NGOutOfFlowLayoutPart::ComputeInlineSizeEstimate() { | |
106 if (AbsoluteNeedsChildInlineSize(*node_->Style())) { | |
107 MinAndMaxContentSizes size; | |
108 if (node_->ComputeMinAndMaxContentSizes(&size)) { | |
109 inline_estimate_ = | |
110 size.ShrinkToFit(parent_space_->AvailableSize().inline_size); | |
111 return true; | |
112 } | |
113 return false; | |
114 } | |
115 return true; | |
116 } | |
117 | |
118 bool NGOutOfFlowLayoutPart::ComputeBlockSizeEstimate() { | |
119 if (AbsoluteNeedsChildBlockSize(*node_->Style())) { | |
120 if (ComputeNodeFragment()) { | |
121 block_estimate_ = node_fragment_->BlockSize(); | |
122 return true; | |
123 } | |
124 return false; | |
125 } | |
126 return true; | |
127 } | |
128 | |
129 bool NGOutOfFlowLayoutPart::ComputeNodeFragment() { | |
130 if (node_fragment_) | |
131 return true; | |
132 if (!node_space_) { | |
133 NGConstraintSpaceBuilder builder(parent_space_->WritingMode()); | |
134 LayoutUnit inline_width = | |
135 node_position_.size.ConvertToLogical(parent_space_->WritingMode()) | |
136 .inline_size; | |
137 // Node fragment is computed in one of these two scenarios: | |
138 // 1. To estimate block size | |
139 // In this case, available block_size is parent's size. | |
140 // 2. To compute final block fragment, when block size is knows | |
cbiesinger
2016/12/21 21:38:50
knows -> known
atotic
2016/12/28 19:36:46
done
| |
141 | |
142 NGLogicalSize available_size = | |
143 NGLogicalSize(inline_width, parent_space_->AvailableSize().block_size); | |
144 if (block_estimate_) | |
cbiesinger
2016/12/21 21:38:50
When do we enter this if? We don't call this again
atotic
2016/12/28 19:36:46
done. Another good catch, code was a leftover from
| |
145 available_size.block_size = *block_estimate_; | |
146 builder.SetAvailableSize(available_size); | |
147 builder.SetPercentageResolutionSize(available_size); | |
148 if (block_estimate_) | |
149 builder.SetIsFixedSizeBlock(true); | |
150 builder.SetIsFixedSizeInline(true); | |
151 builder.SetIsNewFormattingContext(true); | |
152 node_space_ = builder.ToConstraintSpace(); | |
153 } | |
154 NGFragmentBase* fragment; | |
155 if (node_->Layout(node_space_, &fragment)) { | |
156 node_fragment_ = fragment; | |
157 return true; | |
158 } | |
159 return false; | |
160 } | |
161 | |
162 DEFINE_TRACE(NGOutOfFlowLayoutPart) { | |
163 visitor->trace(node_); | |
164 visitor->trace(parent_space_); | |
165 visitor->trace(node_fragment_); | |
166 visitor->trace(node_space_); | |
167 } | |
168 } | |
OLD | NEW |