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

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

Issue 2772503004: [LayoutNG] Add NGInlineBreakToken and back of NGInlineLayoutAlgorithm (Closed)
Patch Set: 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 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_line_builder.h" 5 #include "core/layout/ng/ng_inline_layout_algorithm.h"
6 6
7 #include "core/layout/BidiRun.h" 7 #include "core/layout/BidiRun.h"
8 #include "core/layout/LayoutBlockFlow.h" 8 #include "core/layout/LayoutBlockFlow.h"
9 #include "core/layout/line/LineInfo.h" 9 #include "core/layout/line/LineInfo.h"
10 #include "core/layout/line/RootInlineBox.h" 10 #include "core/layout/line/RootInlineBox.h"
11 #include "core/layout/ng/layout_ng_block_flow.h" 11 #include "core/layout/ng/layout_ng_block_flow.h"
12 #include "core/layout/ng/ng_bidi_paragraph.h" 12 #include "core/layout/ng/ng_bidi_paragraph.h"
13 #include "core/layout/ng/ng_block_layout_algorithm.h" 13 #include "core/layout/ng/ng_block_layout_algorithm.h"
14 #include "core/layout/ng/ng_box_fragment.h" 14 #include "core/layout/ng/ng_box_fragment.h"
15 #include "core/layout/ng/ng_constraint_space.h" 15 #include "core/layout/ng/ng_constraint_space.h"
16 #include "core/layout/ng/ng_constraint_space_builder.h" 16 #include "core/layout/ng/ng_constraint_space_builder.h"
17 #include "core/layout/ng/ng_floating_object.h" 17 #include "core/layout/ng/ng_floating_object.h"
18 #include "core/layout/ng/ng_floats_utils.h" 18 #include "core/layout/ng/ng_floats_utils.h"
19 #include "core/layout/ng/ng_fragment_builder.h" 19 #include "core/layout/ng/ng_fragment_builder.h"
20 #include "core/layout/ng/ng_inline_break_token.h"
20 #include "core/layout/ng/ng_inline_node.h" 21 #include "core/layout/ng/ng_inline_node.h"
21 #include "core/layout/ng/ng_length_utils.h" 22 #include "core/layout/ng/ng_length_utils.h"
22 #include "core/layout/ng/ng_line_box_fragment.h" 23 #include "core/layout/ng/ng_line_box_fragment.h"
23 #include "core/layout/ng/ng_line_box_fragment_builder.h" 24 #include "core/layout/ng/ng_line_box_fragment_builder.h"
25 #include "core/layout/ng/ng_line_breaker.h"
24 #include "core/layout/ng/ng_space_utils.h" 26 #include "core/layout/ng/ng_space_utils.h"
25 #include "core/layout/ng/ng_text_fragment.h" 27 #include "core/layout/ng/ng_text_fragment.h"
26 #include "core/layout/ng/ng_text_fragment_builder.h" 28 #include "core/layout/ng/ng_text_fragment_builder.h"
27 #include "core/style/ComputedStyle.h" 29 #include "core/style/ComputedStyle.h"
28 #include "platform/text/BidiRunList.h" 30 #include "platform/text/BidiRunList.h"
29 31
30 namespace blink { 32 namespace blink {
31 namespace { 33 namespace {
32 34
33 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat( 35 RefPtr<NGConstraintSpace> CreateConstraintSpaceForFloat(
(...skipping 24 matching lines...) Expand all
58 for (auto& floating_object : builder->UnpositionedFloats()) { 60 for (auto& floating_object : builder->UnpositionedFloats()) {
59 NGLogicalOffset offset = PositionFloat(origin_point, space->BfcOffset(), 61 NGLogicalOffset offset = PositionFloat(origin_point, space->BfcOffset(),
60 floating_object.get(), space); 62 floating_object.get(), space);
61 builder->AddFloatingObject(floating_object, offset); 63 builder->AddFloatingObject(floating_object, offset);
62 } 64 }
63 builder->MutableUnpositionedFloats().clear(); 65 builder->MutableUnpositionedFloats().clear();
64 } 66 }
65 67
66 } // namespace 68 } // namespace
67 69
68 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box, 70 NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm(
69 NGConstraintSpace* constraint_space) 71 NGInlineNode* inline_box,
72 NGConstraintSpace* constraint_space,
73 NGInlineBreakToken* break_token)
70 : inline_box_(inline_box), 74 : inline_box_(inline_box),
71 constraint_space_(constraint_space), 75 constraint_space_(constraint_space),
72 container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_), 76 container_builder_(NGPhysicalFragment::kFragmentBox, inline_box_),
73 container_layout_result_(nullptr),
74 is_horizontal_writing_mode_( 77 is_horizontal_writing_mode_(
75 blink::IsHorizontalWritingMode(constraint_space->WritingMode())), 78 blink::IsHorizontalWritingMode(constraint_space->WritingMode())),
76 space_builder_(constraint_space) 79 space_builder_(constraint_space)
77 #if DCHECK_IS_ON() 80 #if DCHECK_IS_ON()
78 , 81 ,
79 is_bidi_reordered_(false) 82 is_bidi_reordered_(false)
80 #endif 83 #endif
81 { 84 {
82 if (!is_horizontal_writing_mode_) 85 if (!is_horizontal_writing_mode_)
83 baseline_type_ = FontBaseline::IdeographicBaseline; 86 baseline_type_ = FontBaseline::IdeographicBaseline;
87 if (break_token)
88 Initialize(break_token->ItemIndex(), break_token->TextOffset());
89 else
90 Initialize(0, 0);
84 } 91 }
85 92
86 bool NGLineBuilder::CanFitOnLine() const { 93 bool NGInlineLayoutAlgorithm::CanFitOnLine() const {
87 LayoutUnit available_size = current_opportunity_.InlineSize(); 94 LayoutUnit available_size = current_opportunity_.InlineSize();
88 if (available_size == NGSizeIndefinite) 95 if (available_size == NGSizeIndefinite)
89 return true; 96 return true;
90 return end_position_ <= available_size; 97 return end_position_ <= available_size;
91 } 98 }
92 99
93 bool NGLineBuilder::HasItems() const { 100 bool NGInlineLayoutAlgorithm::HasItems() const {
94 return start_offset_ != end_offset_; 101 return start_offset_ != end_offset_;
95 } 102 }
96 103
97 bool NGLineBuilder::HasBreakOpportunity() const { 104 bool NGInlineLayoutAlgorithm::HasBreakOpportunity() const {
98 return start_offset_ != last_break_opportunity_offset_; 105 return start_offset_ != last_break_opportunity_offset_;
99 } 106 }
100 107
101 bool NGLineBuilder::HasItemsAfterLastBreakOpportunity() const { 108 bool NGInlineLayoutAlgorithm::HasItemsAfterLastBreakOpportunity() const {
102 return last_break_opportunity_offset_ != end_offset_; 109 return last_break_opportunity_offset_ != end_offset_;
103 } 110 }
104 111
105 void NGLineBuilder::SetStart(unsigned index, unsigned offset) { 112 void NGInlineLayoutAlgorithm::Initialize(unsigned index, unsigned offset) {
106 inline_box_->AssertOffset(index, offset); 113 if (index || offset)
114 inline_box_->AssertOffset(index, offset);
107 115
108 start_index_ = last_index_ = last_break_opportunity_index_ = index; 116 start_index_ = last_index_ = last_break_opportunity_index_ = index;
109 start_offset_ = end_offset_ = last_break_opportunity_offset_ = offset; 117 start_offset_ = end_offset_ = last_break_opportunity_offset_ = offset;
110 end_position_ = last_break_opportunity_position_ = LayoutUnit(); 118 end_position_ = last_break_opportunity_position_ = LayoutUnit();
111 119
112 FindNextLayoutOpportunity(); 120 FindNextLayoutOpportunity();
113 } 121 }
114 122
115 void NGLineBuilder::SetEnd(unsigned new_end_offset) { 123 void NGInlineLayoutAlgorithm::SetEnd(unsigned new_end_offset) {
116 DCHECK_GT(new_end_offset, end_offset_); 124 DCHECK_GT(new_end_offset, end_offset_);
117 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 125 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
118 DCHECK_LE(new_end_offset, items.back().EndOffset()); 126 DCHECK_LE(new_end_offset, items.back().EndOffset());
119 127
120 // SetEnd() while |new_end_offset| is beyond the current last item. 128 // SetEnd() while |new_end_offset| is beyond the current last item.
121 unsigned index = last_index_; 129 unsigned index = last_index_;
122 const NGLayoutInlineItem* item = &items[index]; 130 const NGLayoutInlineItem* item = &items[index];
123 if (new_end_offset > item->EndOffset()) { 131 if (new_end_offset > item->EndOffset()) {
124 if (end_offset_ < item->EndOffset()) { 132 if (end_offset_ < item->EndOffset()) {
125 SetEnd(index, item->EndOffset(), 133 SetEnd(index, item->EndOffset(),
(...skipping 11 matching lines...) Expand all
137 145
138 // Include closing elements. 146 // Include closing elements.
139 while (new_end_offset == item->EndOffset() && index < items.size() - 1) { 147 while (new_end_offset == item->EndOffset() && index < items.size() - 1) {
140 item = &items[++index]; 148 item = &items[++index];
141 if (item->Type() != NGLayoutInlineItem::kCloseTag) 149 if (item->Type() != NGLayoutInlineItem::kCloseTag)
142 break; 150 break;
143 SetEnd(index, new_end_offset, InlineSize(*item)); 151 SetEnd(index, new_end_offset, InlineSize(*item));
144 } 152 }
145 } 153 }
146 154
147 void NGLineBuilder::SetEnd(unsigned index, 155 void NGInlineLayoutAlgorithm::SetEnd(unsigned index,
148 unsigned new_end_offset, 156 unsigned new_end_offset,
149 LayoutUnit inline_size_since_current_end) { 157 LayoutUnit inline_size_since_current_end) {
150 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 158 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
151 DCHECK_LE(new_end_offset, items.back().EndOffset()); 159 DCHECK_LE(new_end_offset, items.back().EndOffset());
152 160
153 // |new_end_offset| should be in the current item or next. 161 // |new_end_offset| should be in the current item or next.
154 // TODO(kojii): Reconsider this restriction if needed. 162 // TODO(kojii): Reconsider this restriction if needed.
155 DCHECK((index == last_index_ && new_end_offset > end_offset_) || 163 DCHECK((index == last_index_ && new_end_offset > end_offset_) ||
156 (index == last_index_ + 1 && new_end_offset >= end_offset_ && 164 (index == last_index_ + 1 && new_end_offset >= end_offset_ &&
157 end_offset_ == items[last_index_].EndOffset())); 165 end_offset_ == items[last_index_].EndOffset()));
158 const NGLayoutInlineItem& item = items[index]; 166 const NGLayoutInlineItem& item = items[index];
159 item.AssertEndOffset(new_end_offset); 167 item.AssertEndOffset(new_end_offset);
160 168
161 if (item.Type() == NGLayoutInlineItem::kFloating) { 169 if (item.Type() == NGLayoutInlineItem::kFloating) {
162 LayoutAndPositionFloat( 170 LayoutAndPositionFloat(
163 LayoutUnit(end_position_) + inline_size_since_current_end, 171 LayoutUnit(end_position_) + inline_size_since_current_end,
164 item.GetLayoutObject()); 172 item.GetLayoutObject());
165 } 173 }
166 174
167 last_index_ = index; 175 last_index_ = index;
168 end_offset_ = new_end_offset; 176 end_offset_ = new_end_offset;
169 end_position_ += inline_size_since_current_end; 177 end_position_ += inline_size_since_current_end;
170 } 178 }
171 179
172 void NGLineBuilder::SetBreakOpportunity() { 180 void NGInlineLayoutAlgorithm::SetBreakOpportunity() {
173 last_break_opportunity_index_ = last_index_; 181 last_break_opportunity_index_ = last_index_;
174 last_break_opportunity_offset_ = end_offset_; 182 last_break_opportunity_offset_ = end_offset_;
175 last_break_opportunity_position_ = end_position_; 183 last_break_opportunity_position_ = end_position_;
176 } 184 }
177 185
178 void NGLineBuilder::SetStartOfHangables(unsigned offset) { 186 void NGInlineLayoutAlgorithm::SetStartOfHangables(unsigned offset) {
179 // TODO(kojii): Implement. 187 // TODO(kojii): Implement.
180 } 188 }
181 189
182 LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item) { 190 LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGLayoutInlineItem& item) {
183 if (item.Type() == NGLayoutInlineItem::kAtomicInline) 191 if (item.Type() == NGLayoutInlineItem::kAtomicInline)
184 return InlineSizeFromLayout(item); 192 return InlineSizeFromLayout(item);
185 return item.InlineSize(); 193 return item.InlineSize();
186 } 194 }
187 195
188 LayoutUnit NGLineBuilder::InlineSize(const NGLayoutInlineItem& item, 196 LayoutUnit NGInlineLayoutAlgorithm::InlineSize(const NGLayoutInlineItem& item,
189 unsigned start_offset, 197 unsigned start_offset,
190 unsigned end_offset) { 198 unsigned end_offset) {
191 if (item.StartOffset() == start_offset && item.EndOffset() == end_offset) 199 if (item.StartOffset() == start_offset && item.EndOffset() == end_offset)
192 return InlineSize(item); 200 return InlineSize(item);
193 return item.InlineSize(start_offset, end_offset); 201 return item.InlineSize(start_offset, end_offset);
194 } 202 }
195 203
196 LayoutUnit NGLineBuilder::InlineSizeFromLayout(const NGLayoutInlineItem& item) { 204 LayoutUnit NGInlineLayoutAlgorithm::InlineSizeFromLayout(
205 const NGLayoutInlineItem& item) {
197 return NGBoxFragment(ConstraintSpace().WritingMode(), 206 return NGBoxFragment(ConstraintSpace().WritingMode(),
198 toNGPhysicalBoxFragment( 207 toNGPhysicalBoxFragment(
199 LayoutItem(item)->PhysicalFragment().get())) 208 LayoutItem(item)->PhysicalFragment().get()))
200 .InlineSize(); 209 .InlineSize();
201 } 210 }
202 211
203 const NGLayoutResult* NGLineBuilder::LayoutItem( 212 const NGLayoutResult* NGInlineLayoutAlgorithm::LayoutItem(
204 const NGLayoutInlineItem& item) { 213 const NGLayoutInlineItem& item) {
205 // Returns the cached NGLayoutResult if available. 214 // Returns the cached NGLayoutResult if available.
206 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 215 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
207 if (layout_results_.isEmpty()) 216 if (layout_results_.isEmpty())
208 layout_results_.resize(items.size()); 217 layout_results_.resize(items.size());
209 unsigned index = std::distance(items.begin(), &item); 218 unsigned index = std::distance(items.begin(), &item);
210 RefPtr<NGLayoutResult>* layout_result = &layout_results_[index]; 219 RefPtr<NGLayoutResult>* layout_result = &layout_results_[index];
211 if (*layout_result) 220 if (*layout_result)
212 return layout_result->get(); 221 return layout_result->get();
213 222
214 DCHECK(item.Type() == NGLayoutInlineItem::kAtomicInline); 223 DCHECK(item.Type() == NGLayoutInlineItem::kAtomicInline);
215 NGBlockNode* node = new NGBlockNode(item.GetLayoutObject()); 224 NGBlockNode* node = new NGBlockNode(item.GetLayoutObject());
216 // TODO(kojii): Keep node in NGLayoutInlineItem. 225 // TODO(kojii): Keep node in NGLayoutInlineItem.
217 const ComputedStyle& style = node->Style(); 226 const ComputedStyle& style = node->Style();
218 NGConstraintSpaceBuilder constraint_space_builder(&ConstraintSpace()); 227 NGConstraintSpaceBuilder constraint_space_builder(&ConstraintSpace());
219 RefPtr<NGConstraintSpace> constraint_space = 228 RefPtr<NGConstraintSpace> constraint_space =
220 constraint_space_builder.SetIsNewFormattingContext(true) 229 constraint_space_builder.SetIsNewFormattingContext(true)
221 .SetIsShrinkToFit(true) 230 .SetIsShrinkToFit(true)
222 .SetTextDirection(style.direction()) 231 .SetTextDirection(style.direction())
223 .ToConstraintSpace(FromPlatformWritingMode(style.getWritingMode())); 232 .ToConstraintSpace(FromPlatformWritingMode(style.getWritingMode()));
224 *layout_result = node->Layout(constraint_space.get()); 233 *layout_result = node->Layout(constraint_space.get());
225 return layout_result->get(); 234 return layout_result->get();
226 } 235 }
227 236
228 void NGLineBuilder::CreateLine() { 237 bool NGInlineLayoutAlgorithm::CreateLine() {
229 if (HasItemsAfterLastBreakOpportunity()) 238 if (HasItemsAfterLastBreakOpportunity())
230 SetBreakOpportunity(); 239 SetBreakOpportunity();
231 CreateLineUpToLastBreakOpportunity(); 240 return CreateLineUpToLastBreakOpportunity();
232 } 241 }
233 242
234 void NGLineBuilder::CreateLineUpToLastBreakOpportunity() { 243 bool NGInlineLayoutAlgorithm::CreateLineUpToLastBreakOpportunity() {
235 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 244 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
236 245
237 // Create a list of LineItemChunk from |start| and |last_break_opportunity|. 246 // Create a list of LineItemChunk from |start| and |last_break_opportunity|.
238 // TODO(kojii): Consider refactoring LineItemChunk once NGLineBuilder's public 247 // TODO(kojii): Consider refactoring LineItemChunk once NGLineBuilder's public
239 // API is more finalized. It does not fit well with the current API. 248 // API is more finalized. It does not fit well with the current API.
240 Vector<LineItemChunk, 32> line_item_chunks; 249 Vector<LineItemChunk, 32> line_item_chunks;
241 unsigned start_offset = start_offset_; 250 unsigned start_offset = start_offset_;
242 for (unsigned i = start_index_; i <= last_break_opportunity_index_; i++) { 251 for (unsigned i = start_index_; i <= last_break_opportunity_index_; i++) {
243 const NGLayoutInlineItem& item = items[i]; 252 const NGLayoutInlineItem& item = items[i];
244 unsigned end_offset = 253 unsigned end_offset =
245 std::min(item.EndOffset(), last_break_opportunity_offset_); 254 std::min(item.EndOffset(), last_break_opportunity_offset_);
246 line_item_chunks.push_back( 255 line_item_chunks.push_back(
247 LineItemChunk{i, start_offset, end_offset, 256 LineItemChunk{i, start_offset, end_offset,
248 InlineSize(item, start_offset, end_offset)}); 257 InlineSize(item, start_offset, end_offset)});
249 start_offset = end_offset; 258 start_offset = end_offset;
250 } 259 }
251 260
252 if (inline_box_->IsBidiEnabled()) 261 if (inline_box_->IsBidiEnabled())
253 BidiReorder(&line_item_chunks); 262 BidiReorder(&line_item_chunks);
254 263
255 PlaceItems(line_item_chunks); 264 if (!PlaceItems(line_item_chunks))
265 return false;
256 266
257 // Prepare for the next line. 267 // Prepare for the next line.
258 // Move |start| to |last_break_opportunity|, keeping items after 268 // Move |start| to |last_break_opportunity|, keeping items after
259 // |last_break_opportunity|. 269 // |last_break_opportunity|.
260 start_index_ = last_break_opportunity_index_; 270 start_index_ = last_break_opportunity_index_;
261 start_offset_ = last_break_opportunity_offset_; 271 start_offset_ = last_break_opportunity_offset_;
262 DCHECK_GE(end_position_, last_break_opportunity_position_); 272 DCHECK_GE(end_position_, last_break_opportunity_position_);
263 end_position_ -= last_break_opportunity_position_; 273 end_position_ -= last_break_opportunity_position_;
264 last_break_opportunity_position_ = LayoutUnit(); 274 last_break_opportunity_position_ = LayoutUnit();
265 #if DCHECK_IS_ON() 275 #if DCHECK_IS_ON()
266 is_bidi_reordered_ = false; 276 is_bidi_reordered_ = false;
267 #endif 277 #endif
268 278
269 NGLogicalOffset origin_point = 279 NGLogicalOffset origin_point =
270 GetOriginPointForFloats(ConstraintSpace(), content_size_); 280 GetOriginPointForFloats(ConstraintSpace(), content_size_);
271 PositionPendingFloats(origin_point, constraint_space_, &container_builder_); 281 PositionPendingFloats(origin_point, constraint_space_, &container_builder_);
272 FindNextLayoutOpportunity(); 282 FindNextLayoutOpportunity();
283 return true;
273 } 284 }
274 285
275 void NGLineBuilder::BidiReorder(Vector<LineItemChunk, 32>* line_item_chunks) { 286 void NGInlineLayoutAlgorithm::BidiReorder(
287 Vector<LineItemChunk, 32>* line_item_chunks) {
276 #if DCHECK_IS_ON() 288 #if DCHECK_IS_ON()
277 DCHECK(!is_bidi_reordered_); 289 DCHECK(!is_bidi_reordered_);
278 is_bidi_reordered_ = true; 290 is_bidi_reordered_ = true;
279 #endif 291 #endif
280 292
281 // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change 293 // TODO(kojii): UAX#9 L1 is not supported yet. Supporting L1 may change
282 // embedding levels of parts of runs, which requires to split items. 294 // embedding levels of parts of runs, which requires to split items.
283 // http://unicode.org/reports/tr9/#L1 295 // http://unicode.org/reports/tr9/#L1
284 // BidiResolver does not support L1 crbug.com/316409. 296 // BidiResolver does not support L1 crbug.com/316409.
285 297
(...skipping 14 matching lines...) Expand all
300 for (unsigned visual_index = 0; visual_index < indices_in_visual_order.size(); 312 for (unsigned visual_index = 0; visual_index < indices_in_visual_order.size();
301 visual_index++) { 313 visual_index++) {
302 unsigned logical_index = indices_in_visual_order[visual_index]; 314 unsigned logical_index = indices_in_visual_order[visual_index];
303 line_item_chunks_in_visual_order[visual_index] = 315 line_item_chunks_in_visual_order[visual_index] =
304 (*line_item_chunks)[logical_index]; 316 (*line_item_chunks)[logical_index];
305 } 317 }
306 line_item_chunks->swap(line_item_chunks_in_visual_order); 318 line_item_chunks->swap(line_item_chunks_in_visual_order);
307 } 319 }
308 320
309 // TODO(glebl): Add the support of clearance for inline floats. 321 // TODO(glebl): Add the support of clearance for inline floats.
310 void NGLineBuilder::LayoutAndPositionFloat(LayoutUnit end_position, 322 void NGInlineLayoutAlgorithm::LayoutAndPositionFloat(
311 LayoutObject* layout_object) { 323 LayoutUnit end_position,
324 LayoutObject* layout_object) {
312 NGBlockNode* node = new NGBlockNode(layout_object); 325 NGBlockNode* node = new NGBlockNode(layout_object);
326
313 RefPtr<NGConstraintSpace> float_space = CreateConstraintSpaceForFloat( 327 RefPtr<NGConstraintSpace> float_space = CreateConstraintSpaceForFloat(
314 node->Style(), ConstraintSpace(), &space_builder_); 328 node->Style(), ConstraintSpace(), &space_builder_);
315 329
316 // TODO(glebl): add the fragmentation support: 330 // TODO(glebl): add the fragmentation support:
317 // same writing mode - get the inline size ComputeInlineSizeForFragment to 331 // same writing mode - get the inline size ComputeInlineSizeForFragment to
318 // determine if it fits on this line, then perform layout with the correct 332 // determine if it fits on this line, then perform layout with the correct
319 // fragmentation line. 333 // fragmentation line.
320 // diff writing mode - get the inline size from performing layout. 334 // diff writing mode - get the inline size from performing layout.
321 RefPtr<NGLayoutResult> layout_result = node->Layout(float_space.get()); 335 RefPtr<NGLayoutResult> layout_result = node->Layout(float_space.get());
322 336
(...skipping 16 matching lines...) Expand all
339 NGLogicalOffset origin_point = 353 NGLogicalOffset origin_point =
340 GetOriginPointForFloats(ConstraintSpace(), content_size_); 354 GetOriginPointForFloats(ConstraintSpace(), content_size_);
341 NGLogicalOffset offset = 355 NGLogicalOffset offset =
342 PositionFloat(origin_point, constraint_space_->BfcOffset(), 356 PositionFloat(origin_point, constraint_space_->BfcOffset(),
343 floating_object.get(), constraint_space_); 357 floating_object.get(), constraint_space_);
344 container_builder_.AddFloatingObject(floating_object, offset); 358 container_builder_.AddFloatingObject(floating_object, offset);
345 FindNextLayoutOpportunity(); 359 FindNextLayoutOpportunity();
346 } 360 }
347 } 361 }
348 362
349 void NGLineBuilder::PlaceItems( 363 bool NGInlineLayoutAlgorithm::PlaceItems(
350 const Vector<LineItemChunk, 32>& line_item_chunks) { 364 const Vector<LineItemChunk, 32>& line_item_chunks) {
351 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 365 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
352 366
353 NGLineBoxFragmentBuilder line_box(inline_box_); 367 NGLineBoxFragmentBuilder line_box(inline_box_);
354 NGTextFragmentBuilder text_builder(inline_box_); 368 NGTextFragmentBuilder text_builder(inline_box_);
355 369
356 // Accumulate a "strut"; a zero-width inline box with the element's font and 370 // Accumulate a "strut"; a zero-width inline box with the element's font and
357 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut 371 // line height properties. https://drafts.csswg.org/css2/visudet.html#strut
358 NGLineHeightMetrics block_metrics(inline_box_->Style(), baseline_type_); 372 NGLineHeightMetrics block_metrics(inline_box_->Style(), baseline_type_);
359 line_box.UniteMetrics(block_metrics); 373 line_box.UniteMetrics(block_metrics);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 430
417 NGLogicalOffset logical_offset( 431 NGLogicalOffset logical_offset(
418 inline_size + current_opportunity_.InlineStartOffset() - 432 inline_size + current_opportunity_.InlineStartOffset() -
419 ConstraintSpace().BfcOffset().inline_offset, 433 ConstraintSpace().BfcOffset().inline_offset,
420 block_start); 434 block_start);
421 line_box.AddChild(std::move(text_fragment), logical_offset); 435 line_box.AddChild(std::move(text_fragment), logical_offset);
422 inline_size += line_item_chunk.inline_size; 436 inline_size += line_item_chunk.inline_size;
423 } 437 }
424 438
425 if (line_box.Children().isEmpty()) { 439 if (line_box.Children().isEmpty()) {
426 // The line was empty. 440 return true; // The line was empty.
427 return; 441 }
442
443 // Check if the line fits into the constraint space in block direction.
444 LayoutUnit block_end = content_size_ + line_box.Metrics().LineHeight();
445 if (!container_builder_.Children().isEmpty() &&
446 ConstraintSpace().AvailableSize().block_size != NGSizeIndefinite &&
447 block_end > ConstraintSpace().AvailableSize().block_size) {
448 return false;
428 } 449 }
429 450
430 // If the estimated baseline position was not the actual position, move all 451 // If the estimated baseline position was not the actual position, move all
431 // fragments in the block direction. 452 // fragments in the block direction.
432 LayoutUnit adjust_baseline(line_box.Metrics().ascent_and_leading - 453 LayoutUnit adjust_baseline(line_box.Metrics().ascent_and_leading -
433 block_metrics.ascent_and_leading); 454 block_metrics.ascent_and_leading);
434 if (adjust_baseline) 455 if (adjust_baseline)
435 line_box.MoveChildrenInBlockDirection(adjust_baseline); 456 line_box.MoveChildrenInBlockDirection(adjust_baseline);
436 457
458 // If there are more content to consume, create an unfinished break token.
459 if (last_break_opportunity_index_ != items.size() - 1 ||
460 last_break_opportunity_offset_ != inline_box_->Text().length()) {
461 line_box.SetBreakToken(
462 NGInlineBreakToken::create(inline_box_, last_break_opportunity_index_,
463 last_break_opportunity_offset_));
464 }
465
437 line_box.SetInlineSize(inline_size); 466 line_box.SetInlineSize(inline_size);
438 NGLogicalOffset offset(LayoutUnit(), content_size_); 467 container_builder_.AddChild(line_box.ToLineBoxFragment(),
439 container_builder_.AddChild(line_box.ToLineBoxFragment(), offset); 468 {LayoutUnit(), content_size_});
469
440 max_inline_size_ = std::max(max_inline_size_, inline_size); 470 max_inline_size_ = std::max(max_inline_size_, inline_size);
441 content_size_ += line_box.Metrics().LineHeight(); 471 content_size_ = block_end;
472 return true;
442 } 473 }
443 474
444 void NGLineBuilder::AccumulateUsedFonts(const NGLayoutInlineItem& item, 475 void NGInlineLayoutAlgorithm::AccumulateUsedFonts(
445 const LineItemChunk& line_item_chunk, 476 const NGLayoutInlineItem& item,
446 NGLineBoxFragmentBuilder* line_box) { 477 const LineItemChunk& line_item_chunk,
478 NGLineBoxFragmentBuilder* line_box) {
447 HashSet<const SimpleFontData*> fallback_fonts; 479 HashSet<const SimpleFontData*> fallback_fonts;
448 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset, 480 item.GetFallbackFonts(&fallback_fonts, line_item_chunk.start_offset,
449 line_item_chunk.end_offset); 481 line_item_chunk.end_offset);
450 for (const auto& fallback_font : fallback_fonts) { 482 for (const auto& fallback_font : fallback_fonts) {
451 NGLineHeightMetrics metrics(fallback_font->getFontMetrics(), 483 NGLineHeightMetrics metrics(fallback_font->getFontMetrics(),
452 baseline_type_); 484 baseline_type_);
453 line_box->UniteMetrics(metrics); 485 line_box->UniteMetrics(metrics);
454 } 486 }
455 } 487 }
456 488
457 LayoutUnit NGLineBuilder::PlaceAtomicInline( 489 LayoutUnit NGInlineLayoutAlgorithm::PlaceAtomicInline(
458 const NGLayoutInlineItem& item, 490 const NGLayoutInlineItem& item,
459 LayoutUnit estimated_baseline, 491 LayoutUnit estimated_baseline,
460 NGLineBoxFragmentBuilder* line_box, 492 NGLineBoxFragmentBuilder* line_box,
461 NGTextFragmentBuilder* text_builder) { 493 NGTextFragmentBuilder* text_builder) {
462 NGBoxFragment fragment( 494 NGBoxFragment fragment(
463 ConstraintSpace().WritingMode(), 495 ConstraintSpace().WritingMode(),
464 toNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().get())); 496 toNGPhysicalBoxFragment(LayoutItem(item)->PhysicalFragment().get()));
465 // TODO(kojii): Margin and border in block progression not implemented yet. 497 // TODO(kojii): Margin and border in block progression not implemented yet.
466 LayoutUnit block_size = fragment.BlockSize(); 498 LayoutUnit block_size = fragment.BlockSize();
467 499
(...skipping 16 matching lines...) Expand all
484 metrics.ascent_and_leading = baseline_offset; 516 metrics.ascent_and_leading = baseline_offset;
485 metrics.descent_and_leading = block_size - baseline_offset; 517 metrics.descent_and_leading = block_size - baseline_offset;
486 line_box->UniteMetrics(metrics); 518 line_box->UniteMetrics(metrics);
487 519
488 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult. 520 // TODO(kojii): Figure out what to do with OOF in NGLayoutResult.
489 // Floats are ok because atomic inlines are BFC? 521 // Floats are ok because atomic inlines are BFC?
490 522
491 return block_start; 523 return block_start;
492 } 524 }
493 525
494 void NGLineBuilder::FindNextLayoutOpportunity() { 526 void NGInlineLayoutAlgorithm::FindNextLayoutOpportunity() {
495 NGLogicalOffset iter_offset = constraint_space_->BfcOffset(); 527 NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
496 iter_offset.block_offset += content_size_; 528 iter_offset.block_offset += content_size_;
497 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset); 529 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset);
498 NGLayoutOpportunity opportunity = iter->Next(); 530 NGLayoutOpportunity opportunity = iter->Next();
499 if (!opportunity.IsEmpty()) 531 if (!opportunity.IsEmpty())
500 current_opportunity_ = opportunity; 532 current_opportunity_ = opportunity;
501 } 533 }
502 534
503 RefPtr<NGLayoutResult> NGLineBuilder::CreateFragments() { 535 RefPtr<NGLayoutResult> NGInlineLayoutAlgorithm::Layout() {
504 DCHECK(!HasItems()) << "Must call CreateLine()"; 536 if (!inline_box_->Text().isEmpty())
537 NGLineBreaker().BreakLines(this, inline_box_->Text(), start_offset_);
505 538
506 // TODO(kojii): Check if the line box width should be content or available. 539 // TODO(kojii): Check if the line box width should be content or available.
507 // TODO(kojii): Need to take constraint_space into account.
508 container_builder_.SetInlineSize(max_inline_size_) 540 container_builder_.SetInlineSize(max_inline_size_)
509 .SetInlineOverflow(max_inline_size_) 541 .SetInlineOverflow(max_inline_size_)
510 .SetBlockSize(content_size_) 542 .SetBlockSize(content_size_)
511 .SetBlockOverflow(content_size_); 543 .SetBlockOverflow(content_size_);
512 544
513 container_layout_result_ = container_builder_.ToBoxFragment(); 545 return container_builder_.ToBoxFragment();
514 return container_layout_result_;
515 } 546 }
516 547
517 void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() { 548 MinMaxContentSize NGInlineLayoutAlgorithm::ComputeMinMaxContentSizeByLayout() {
549 DCHECK(ConstraintSpace().AvailableSize().inline_size == LayoutUnit() &&
550 ConstraintSpace().AvailableSize().block_size == NGSizeIndefinite);
551 if (!inline_box_->Text().isEmpty())
552 NGLineBreaker().BreakLines(this, inline_box_->Text(), start_offset_);
553 MinMaxContentSize sizes;
554 sizes.min_content = MaxInlineSize();
555
556 // max-content is the width without any line wrapping.
557 // TODO(kojii): Implement hard breaks (<br> etc.) to break.
558 for (const auto& item : inline_box_->Items())
559 sizes.max_content += InlineSize(item);
560
561 return sizes;
562 }
563
564 void NGInlineLayoutAlgorithm::CopyFragmentDataToLayoutBlockFlow(
565 NGLayoutResult* layout_result) {
518 LayoutBlockFlow* block = inline_box_->GetLayoutBlockFlow(); 566 LayoutBlockFlow* block = inline_box_->GetLayoutBlockFlow();
519 block->deleteLineBoxTree(); 567 block->deleteLineBoxTree();
520 568
521 Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 569 Vector<NGLayoutInlineItem>& items = inline_box_->Items();
522 Vector<unsigned, 32> text_offsets(items.size()); 570 Vector<unsigned, 32> text_offsets(items.size());
523 inline_box_->GetLayoutTextOffsets(&text_offsets); 571 inline_box_->GetLayoutTextOffsets(&text_offsets);
524 572
525 Vector<const NGPhysicalFragment*, 32> fragments_for_bidi_runs; 573 Vector<const NGPhysicalFragment*, 32> fragments_for_bidi_runs;
526 fragments_for_bidi_runs.reserveInitialCapacity(items.size()); 574 fragments_for_bidi_runs.reserveInitialCapacity(items.size());
527 BidiRunList<BidiRun> bidi_runs; 575 BidiRunList<BidiRun> bidi_runs;
528 LineInfo line_info; 576 LineInfo line_info;
529 NGPhysicalBoxFragment* box_fragment = toNGPhysicalBoxFragment( 577 NGPhysicalBoxFragment* box_fragment =
530 container_layout_result_->PhysicalFragment().get()); 578 toNGPhysicalBoxFragment(layout_result->PhysicalFragment().get());
531 for (const auto& container_child : box_fragment->Children()) { 579 for (const auto& container_child : box_fragment->Children()) {
532 NGPhysicalLineBoxFragment* physical_line_box = 580 NGPhysicalLineBoxFragment* physical_line_box =
533 toNGPhysicalLineBoxFragment(container_child.get()); 581 toNGPhysicalLineBoxFragment(container_child.get());
534 // Create a BidiRunList for this line. 582 // Create a BidiRunList for this line.
535 for (const auto& line_child : physical_line_box->Children()) { 583 for (const auto& line_child : physical_line_box->Children()) {
536 const auto* text_fragment = toNGPhysicalTextFragment(line_child.get()); 584 const auto* text_fragment = toNGPhysicalTextFragment(line_child.get());
537 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()]; 585 const NGLayoutInlineItem& item = items[text_fragment->ItemIndex()];
538 BidiRun* run; 586 BidiRun* run;
539 if (item.Type() == NGLayoutInlineItem::kText) { 587 if (item.Type() == NGLayoutInlineItem::kText) {
540 LayoutObject* layout_object = item.GetLayoutObject(); 588 LayoutObject* layout_object = item.GetLayoutObject();
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 root_line_box->setLineTopBottomPositions( 643 root_line_box->setLineTopBottomPositions(
596 baseline - LayoutUnit(metrics.ascent), 644 baseline - LayoutUnit(metrics.ascent),
597 baseline + LayoutUnit(metrics.descent), line_top_with_leading, 645 baseline + LayoutUnit(metrics.descent), line_top_with_leading,
598 baseline + LayoutUnit(metrics.descent_and_leading)); 646 baseline + LayoutUnit(metrics.descent_and_leading));
599 647
600 bidi_runs.deleteRuns(); 648 bidi_runs.deleteRuns();
601 fragments_for_bidi_runs.clear(); 649 fragments_for_bidi_runs.clear();
602 } 650 }
603 } 651 }
604 } // namespace blink 652 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698