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

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

Issue 2739683006: Use Opportunity Iterator to position text fragments in NGLineBuilder (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_line_builder.h" 5 #include "core/layout/ng/ng_line_builder.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/ng_bidi_paragraph.h" 11 #include "core/layout/ng/ng_bidi_paragraph.h"
12 #include "core/layout/ng/ng_constraint_space.h" 12 #include "core/layout/ng/ng_constraint_space.h"
13 #include "core/layout/ng/ng_fragment_builder.h" 13 #include "core/layout/ng/ng_fragment_builder.h"
14 #include "core/layout/ng/ng_inline_node.h" 14 #include "core/layout/ng/ng_inline_node.h"
15 #include "core/layout/ng/ng_length_utils.h" 15 #include "core/layout/ng/ng_length_utils.h"
16 #include "core/layout/ng/ng_text_fragment.h" 16 #include "core/layout/ng/ng_text_fragment.h"
17 #include "core/style/ComputedStyle.h" 17 #include "core/style/ComputedStyle.h"
18 #include "platform/text/BidiRunList.h" 18 #include "platform/text/BidiRunList.h"
19 19
20 namespace blink { 20 namespace blink {
21 21
22 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box, 22 NGLineBuilder::NGLineBuilder(NGInlineNode* inline_box,
23 const NGConstraintSpace* constraint_space) 23 NGConstraintSpace* constraint_space)
24 : inline_box_(inline_box), 24 : inline_box_(inline_box),
25 constraint_space_(constraint_space), 25 constraint_space_(constraint_space),
26 baseline_type_(constraint_space->WritingMode() == 26 baseline_type_(constraint_space->WritingMode() ==
27 NGWritingMode::kHorizontalTopBottom 27 NGWritingMode::kHorizontalTopBottom
28 ? FontBaseline::AlphabeticBaseline 28 ? FontBaseline::AlphabeticBaseline
29 : FontBaseline::IdeographicBaseline) 29 : FontBaseline::IdeographicBaseline)
30 #if DCHECK_IS_ON() 30 #if DCHECK_IS_ON()
31 , 31 ,
32 is_bidi_reordered_(false) 32 is_bidi_reordered_(false)
33 #endif 33 #endif
34 { 34 {
35 } 35 }
36 36
37 bool NGLineBuilder::CanFitOnLine() const { 37 bool NGLineBuilder::CanFitOnLine() const {
38 LayoutUnit available_size = constraint_space_->AvailableSize().inline_size; 38 LayoutUnit available_size = current_opportunity_.InlineSize();
39 if (available_size == NGSizeIndefinite) 39 if (available_size == NGSizeIndefinite)
40 return true; 40 return true;
41 return end_position_ <= available_size; 41 return end_position_ <= available_size;
42 } 42 }
43 43
44 bool NGLineBuilder::HasItems() const { 44 bool NGLineBuilder::HasItems() const {
45 return start_offset_ != end_offset_; 45 return start_offset_ != end_offset_;
46 } 46 }
47 47
48 bool NGLineBuilder::HasBreakOpportunity() const { 48 bool NGLineBuilder::HasBreakOpportunity() const {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 line_item_chunks->swap(line_item_chunks_in_visual_order); 182 line_item_chunks->swap(line_item_chunks_in_visual_order);
183 } 183 }
184 184
185 void NGLineBuilder::PlaceItems( 185 void NGLineBuilder::PlaceItems(
186 const Vector<LineItemChunk, 32>& line_item_chunks) { 186 const Vector<LineItemChunk, 32>& line_item_chunks) {
187 const Vector<NGLayoutInlineItem>& items = inline_box_->Items(); 187 const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
188 const unsigned fragment_start_index = fragments_.size(); 188 const unsigned fragment_start_index = fragments_.size();
189 189
190 NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText, 190 NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText,
191 inline_box_); 191 inline_box_);
192 text_builder.SetWritingMode(constraint_space_->WritingMode()); 192 text_builder.SetWritingMode(ConstraintSpace().WritingMode());
193 line_box_data_list_.grow(line_box_data_list_.size() + 1); 193 line_box_data_list_.grow(line_box_data_list_.size() + 1);
194 LineBoxData& line_box_data = line_box_data_list_.back(); 194 LineBoxData& line_box_data = line_box_data_list_.back();
195 195
196 // Use the block style to compute the estimated baseline position because the 196 // Use the block style to compute the estimated baseline position because the
197 // baseline position is not known until we know the maximum ascent and leading 197 // baseline position is not known until we know the maximum ascent and leading
198 // of the line. Items are placed on this baseline, then adjusted later if the 198 // of the line. Items are placed on this baseline, then adjusted later if the
199 // estimation turned out to be different. 199 // estimation turned out to be different.
200 const ComputedStyle* block_style = inline_box_->BlockStyle(); 200 const ComputedStyle* block_style = inline_box_->BlockStyle();
201 InlineItemMetrics estimated_metrics(*block_style, baseline_type_); 201 InlineItemMetrics estimated_metrics(*block_style, baseline_type_);
202 LayoutUnit estimated_baseline = 202 LayoutUnit estimated_baseline =
(...skipping 28 matching lines...) Expand all
231 // properties, not the resolved bidi direction. 231 // properties, not the resolved bidi direction.
232 text_builder.SetDirection(style->direction()) 232 text_builder.SetDirection(style->direction())
233 .SetInlineSize(line_item_chunk.inline_size) 233 .SetInlineSize(line_item_chunk.inline_size)
234 .SetInlineOverflow(line_item_chunk.inline_size) 234 .SetInlineOverflow(line_item_chunk.inline_size)
235 .SetBlockSize(height) 235 .SetBlockSize(height)
236 .SetBlockOverflow(height); 236 .SetBlockOverflow(height);
237 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment( 237 RefPtr<NGPhysicalTextFragment> text_fragment = text_builder.ToTextFragment(
238 line_item_chunk.index, line_item_chunk.start_offset, 238 line_item_chunk.index, line_item_chunk.start_offset,
239 line_item_chunk.end_offset); 239 line_item_chunk.end_offset);
240 fragments_.push_back(std::move(text_fragment)); 240 fragments_.push_back(std::move(text_fragment));
241 offsets_.push_back(NGLogicalOffset(line_box_data.inline_size, top)); 241
242 NGLogicalOffset logical_offset(
243 current_opportunity_.InlineStartOffset() -
244 ConstraintSpace().BfcOffset().inline_offset,
245 top);
kojii 2017/03/09 03:01:54 Don't we need to add |line_box_data.inline_size|,
Gleb Lanbin 2017/03/09 22:26:45 could you explain why you think we need to include
kojii 2017/03/10 03:12:43 Ok if tests pass, I'll need to debug to understand
246 offsets_.push_back(logical_offset);
242 line_box_data.inline_size += line_item_chunk.inline_size; 247 line_box_data.inline_size += line_item_chunk.inline_size;
243 } 248 }
244 DCHECK_EQ(fragments_.size(), offsets_.size()); 249 DCHECK_EQ(fragments_.size(), offsets_.size());
245 250
246 if (fragment_start_index == fragments_.size()) { 251 if (fragment_start_index == fragments_.size()) {
247 // The line was empty. Remove the LineBoxData. 252 // The line was empty. Remove the LineBoxData.
248 line_box_data_list_.shrink(line_box_data_list_.size() - 1); 253 line_box_data_list_.shrink(line_box_data_list_.size() - 1);
249 return; 254 return;
250 } 255 }
251 256
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 DCHECK(!HasItems()) << "Must call CreateLine()"; 328 DCHECK(!HasItems()) << "Must call CreateLine()";
324 DCHECK_EQ(fragments_.size(), offsets_.size()); 329 DCHECK_EQ(fragments_.size(), offsets_.size());
325 330
326 for (unsigned i = 0; i < fragments_.size(); i++) { 331 for (unsigned i = 0; i < fragments_.size(); i++) {
327 // TODO(layout-dev): This should really be a std::move but 332 // TODO(layout-dev): This should really be a std::move but
328 // CopyFragmentDataToLayoutBlockFlow also uses the fragments. 333 // CopyFragmentDataToLayoutBlockFlow also uses the fragments.
329 container_builder->AddChild(fragments_[i].get(), offsets_[i]); 334 container_builder->AddChild(fragments_[i].get(), offsets_[i]);
330 } 335 }
331 336
332 // TODO(kojii): Check if the line box width should be content or available. 337 // TODO(kojii): Check if the line box width should be content or available.
333 // TODO(kojii): Need to take constraint_space into account.
334 container_builder->SetInlineSize(max_inline_size_) 338 container_builder->SetInlineSize(max_inline_size_)
335 .SetInlineOverflow(max_inline_size_) 339 .SetInlineOverflow(max_inline_size_)
336 .SetBlockSize(content_size_) 340 .SetBlockSize(content_size_)
337 .SetBlockOverflow(content_size_); 341 .SetBlockOverflow(content_size_);
338 } 342 }
339 343
340 void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() { 344 void NGLineBuilder::CopyFragmentDataToLayoutBlockFlow() {
341 LayoutBlockFlow* block = inline_box_->GetLayoutBlockFlow(); 345 LayoutBlockFlow* block = inline_box_->GetLayoutBlockFlow();
342 block->deleteLineBoxTree(); 346 block->deleteLineBoxTree();
343 347
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 // RootInlineBox are set to Bidirun::m_box. 384 // RootInlineBox are set to Bidirun::m_box.
381 line_info.setEmpty(false); 385 line_info.setEmpty(false);
382 // TODO(kojii): Implement setFirstLine, LastLine, etc. 386 // TODO(kojii): Implement setFirstLine, LastLine, etc.
383 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info); 387 RootInlineBox* line_box = block->constructLine(bidi_runs, line_info);
384 388
385 // Copy fragments data to InlineBoxes. 389 // Copy fragments data to InlineBoxes.
386 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount()); 390 DCHECK_EQ(fragments_for_bidi_runs.size(), bidi_runs.runCount());
387 BidiRun* run = bidi_runs.firstRun(); 391 BidiRun* run = bidi_runs.firstRun();
388 for (auto* physical_fragment : fragments_for_bidi_runs) { 392 for (auto* physical_fragment : fragments_for_bidi_runs) {
389 DCHECK(run); 393 DCHECK(run);
390 NGTextFragment fragment(constraint_space_->WritingMode(), 394 NGTextFragment fragment(ConstraintSpace().WritingMode(),
391 toNGPhysicalTextFragment(physical_fragment)); 395 toNGPhysicalTextFragment(physical_fragment));
392 InlineBox* inline_box = run->m_box; 396 InlineBox* inline_box = run->m_box;
393 inline_box->setLogicalWidth(fragment.InlineSize()); 397 inline_box->setLogicalWidth(fragment.InlineSize());
394 inline_box->setLogicalLeft(fragment.InlineOffset()); 398 inline_box->setLogicalLeft(fragment.InlineOffset());
395 inline_box->setLogicalTop(fragment.BlockOffset()); 399 inline_box->setLogicalTop(fragment.BlockOffset());
396 run = run->next(); 400 run = run->next();
397 } 401 }
398 DCHECK(!run); 402 DCHECK(!run);
399 403
400 // Copy LineBoxData to RootInlineBox. 404 // Copy LineBoxData to RootInlineBox.
401 line_box->setLogicalWidth(line_box_data.inline_size); 405 line_box->setLogicalWidth(line_box_data.inline_size);
402 LayoutUnit baseline_position = 406 LayoutUnit baseline_position =
403 line_box_data.top_with_leading + 407 line_box_data.top_with_leading +
404 LayoutUnit(line_box_data.max_ascent_and_leading); 408 LayoutUnit(line_box_data.max_ascent_and_leading);
405 line_box->setLineTopBottomPositions( 409 line_box->setLineTopBottomPositions(
406 baseline_position - LayoutUnit(line_box_data.max_ascent), 410 baseline_position - LayoutUnit(line_box_data.max_ascent),
407 baseline_position + LayoutUnit(line_box_data.max_descent), 411 baseline_position + LayoutUnit(line_box_data.max_descent),
408 line_box_data.top_with_leading, 412 line_box_data.top_with_leading,
409 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading)); 413 baseline_position + LayoutUnit(line_box_data.max_descent_and_leading));
410 414
411 bidi_runs.deleteRuns(); 415 bidi_runs.deleteRuns();
412 fragments_for_bidi_runs.clear(); 416 fragments_for_bidi_runs.clear();
413 } 417 }
414 } 418 }
415 419
420 void NGLineBuilder::FindNextLayoutOpportunity() {
421 NGLogicalOffset iter_offset = constraint_space_->BfcOffset();
422 iter_offset.block_offset += content_size_;
423 auto* iter = constraint_space_->LayoutOpportunityIterator(iter_offset);
424 NGLayoutOpportunity opportunity = iter->Next();
425 if (!opportunity.IsEmpty())
426 current_opportunity_ = opportunity;
427 }
428
416 } // namespace blink 429 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698