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

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

Issue 2921463004: [LayoutNG] PODify NGLayoutInputNode and sub-classes. (Closed)
Patch Set: new ng-bot expectations Created 3 years, 6 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/inline/ng_line_breaker.h" 5 #include "core/layout/ng/inline/ng_line_breaker.h"
6 6
7 #include "core/layout/ng/inline/ng_inline_break_token.h" 7 #include "core/layout/ng/inline/ng_inline_break_token.h"
8 #include "core/layout/ng/inline/ng_inline_layout_algorithm.h" 8 #include "core/layout/ng/inline/ng_inline_layout_algorithm.h"
9 #include "core/layout/ng/inline/ng_inline_node.h" 9 #include "core/layout/ng/inline/ng_inline_node.h"
10 #include "core/layout/ng/inline/ng_text_fragment.h" 10 #include "core/layout/ng/inline/ng_text_fragment.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 return std::make_pair(next_break, next_inline_size); 49 return std::make_pair(next_break, next_inline_size);
50 offset = next_break; 50 offset = next_break;
51 inline_size = next_inline_size; 51 inline_size = next_inline_size;
52 has_break_opportunities = true; 52 has_break_opportunities = true;
53 } 53 }
54 } 54 }
55 #endif 55 #endif
56 56
57 } // namespace 57 } // namespace
58 58
59 NGLineBreaker::NGLineBreaker(NGInlineNode* node, 59 NGLineBreaker::NGLineBreaker(NGInlineNode node,
60 const NGConstraintSpace* space, 60 const NGConstraintSpace* space,
61 NGInlineBreakToken* break_token) 61 NGInlineBreakToken* break_token)
62 : node_(node), 62 : node_(node),
63 constraint_space_(space), 63 constraint_space_(space),
64 item_index_(0), 64 item_index_(0),
65 offset_(0), 65 offset_(0),
66 break_iterator_(node->Text()) { 66 break_iterator_(node.Text()) {
67 if (break_token) { 67 if (break_token) {
68 item_index_ = break_token->ItemIndex(); 68 item_index_ = break_token->ItemIndex();
69 offset_ = break_token->TextOffset(); 69 offset_ = break_token->TextOffset();
70 node->AssertOffset(item_index_, offset_); 70 node.AssertOffset(item_index_, offset_);
71 } 71 }
72 } 72 }
73 73
74 void NGLineBreaker::NextLine(NGInlineItemResults* item_results, 74 void NGLineBreaker::NextLine(NGInlineItemResults* item_results,
75 NGInlineLayoutAlgorithm* algorithm) { 75 NGInlineLayoutAlgorithm* algorithm) {
76 BreakLine(item_results, algorithm); 76 BreakLine(item_results, algorithm);
77 77
78 // TODO(kojii): When editing, or caret is enabled, trailing spaces at wrap 78 // TODO(kojii): When editing, or caret is enabled, trailing spaces at wrap
79 // point should not be removed. For other cases, we can a) remove, b) leave 79 // point should not be removed. For other cases, we can a) remove, b) leave
80 // characters without glyphs, or c) leave both characters and glyphs without 80 // characters without glyphs, or c) leave both characters and glyphs without
81 // measuring. Need to decide which one works the best. 81 // measuring. Need to decide which one works the best.
82 SkipCollapsibleWhitespaces(); 82 SkipCollapsibleWhitespaces();
83 } 83 }
84 84
85 void NGLineBreaker::BreakLine(NGInlineItemResults* item_results, 85 void NGLineBreaker::BreakLine(NGInlineItemResults* item_results,
86 NGInlineLayoutAlgorithm* algorithm) { 86 NGInlineLayoutAlgorithm* algorithm) {
87 DCHECK(item_results->IsEmpty()); 87 DCHECK(item_results->IsEmpty());
88 const Vector<NGInlineItem>& items = node_->Items(); 88 const Vector<NGInlineItem>& items = node_.Items();
89 const ComputedStyle& style = node_->Style(); 89 const ComputedStyle& style = node_.Style();
90 UpdateBreakIterator(style); 90 UpdateBreakIterator(style);
91 #if !defined(MOCK_SHAPE_LINE) 91 #if !defined(MOCK_SHAPE_LINE)
92 // TODO(kojii): Instantiate in the constructor. 92 // TODO(kojii): Instantiate in the constructor.
93 HarfBuzzShaper shaper(text.Characters16(), text.length()); 93 HarfBuzzShaper shaper(text.Characters16(), text.length());
94 #endif 94 #endif
95 available_width_ = algorithm->AvailableWidth(); 95 available_width_ = algorithm->AvailableWidth();
96 position_ = LayoutUnit(0); 96 position_ = LayoutUnit(0);
97 LineBreakState state = LineBreakState::kNotBreakable; 97 LineBreakState state = LineBreakState::kNotBreakable;
98 98
99 while (item_index_ < items.size()) { 99 while (item_index_ < items.size()) {
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 item_result->end_offset = item.EndOffset(); 223 item_result->end_offset = item.EndOffset();
224 } 224 }
225 } 225 }
226 226
227 // Measure control items; new lines and tab, that are similar to text, affect 227 // Measure control items; new lines and tab, that are similar to text, affect
228 // layout, but do not need shaping/painting. 228 // layout, but do not need shaping/painting.
229 NGLineBreaker::LineBreakState NGLineBreaker::HandleControlItem( 229 NGLineBreaker::LineBreakState NGLineBreaker::HandleControlItem(
230 const NGInlineItem& item, 230 const NGInlineItem& item,
231 NGInlineItemResult* item_result) { 231 NGInlineItemResult* item_result) {
232 DCHECK_EQ(item.Length(), 1u); 232 DCHECK_EQ(item.Length(), 1u);
233 UChar character = node_->Text()[item.StartOffset()]; 233 UChar character = node_.Text()[item.StartOffset()];
234 if (character == kNewlineCharacter) { 234 if (character == kNewlineCharacter) {
235 MoveToNextOf(item); 235 MoveToNextOf(item);
236 return LineBreakState::kForcedBreak; 236 return LineBreakState::kForcedBreak;
237 } 237 }
238 DCHECK_EQ(character, kTabulationCharacter); 238 DCHECK_EQ(character, kTabulationCharacter);
239 DCHECK(item.Style()); 239 DCHECK(item.Style());
240 const ComputedStyle& style = *item.Style(); 240 const ComputedStyle& style = *item.Style();
241 const Font& font = style.GetFont(); 241 const Font& font = style.GetFont();
242 item_result->inline_size = font.TabWidth(style.GetTabSize(), position_); 242 item_result->inline_size = font.TabWidth(style.GetTabSize(), position_);
243 position_ += item_result->inline_size; 243 position_ += item_result->inline_size;
244 MoveToNextOf(item); 244 MoveToNextOf(item);
245 // TODO(kojii): Implement break around the tab character. 245 // TODO(kojii): Implement break around the tab character.
246 return LineBreakState::kIsBreakable; 246 return LineBreakState::kIsBreakable;
247 } 247 }
248 248
249 NGLineBreaker::LineBreakState NGLineBreaker::HandleAtomicInline( 249 NGLineBreaker::LineBreakState NGLineBreaker::HandleAtomicInline(
250 const NGInlineItem& item, 250 const NGInlineItem& item,
251 NGInlineItemResult* item_result) { 251 NGInlineItemResult* item_result) {
252 DCHECK_EQ(item.Type(), NGInlineItem::kAtomicInline); 252 DCHECK_EQ(item.Type(), NGInlineItem::kAtomicInline);
253 NGBlockNode* node = new NGBlockNode(item.GetLayoutObject()); 253 NGBlockNode node = NGBlockNode(ToLayoutBox(item.GetLayoutObject()));
254 const ComputedStyle& style = node->Style(); 254 const ComputedStyle& style = node.Style();
255 NGConstraintSpaceBuilder constraint_space_builder(constraint_space_); 255 NGConstraintSpaceBuilder constraint_space_builder(constraint_space_);
256 RefPtr<NGConstraintSpace> constraint_space = 256 RefPtr<NGConstraintSpace> constraint_space =
257 constraint_space_builder.SetIsNewFormattingContext(true) 257 constraint_space_builder.SetIsNewFormattingContext(true)
258 .SetIsShrinkToFit(true) 258 .SetIsShrinkToFit(true)
259 .SetTextDirection(style.Direction()) 259 .SetTextDirection(style.Direction())
260 .ToConstraintSpace(FromPlatformWritingMode(style.GetWritingMode())); 260 .ToConstraintSpace(FromPlatformWritingMode(style.GetWritingMode()));
261 item_result->layout_result = node->Layout(constraint_space.Get()); 261 item_result->layout_result = node.Layout(constraint_space.Get());
262 262
263 item_result->inline_size = 263 item_result->inline_size =
264 NGBoxFragment(constraint_space_->WritingMode(), 264 NGBoxFragment(constraint_space_->WritingMode(),
265 ToNGPhysicalBoxFragment( 265 ToNGPhysicalBoxFragment(
266 item_result->layout_result->PhysicalFragment().Get())) 266 item_result->layout_result->PhysicalFragment().Get()))
267 .InlineSize(); 267 .InlineSize();
268 268
269 item_result->margins = 269 item_result->margins =
270 ComputeMargins(*constraint_space_, style, 270 ComputeMargins(*constraint_space_, style,
271 constraint_space_->WritingMode(), style.Direction()); 271 constraint_space_->WritingMode(), style.Direction());
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 324 }
325 DCHECK(item.GetLayoutObject() && item.GetLayoutObject()->Parent()); 325 DCHECK(item.GetLayoutObject() && item.GetLayoutObject()->Parent());
326 UpdateBreakIterator(item.GetLayoutObject()->Parent()->StyleRef()); 326 UpdateBreakIterator(item.GetLayoutObject()->Parent()->StyleRef());
327 MoveToNextOf(item); 327 MoveToNextOf(item);
328 } 328 }
329 329
330 // Handles when the last item overflows. 330 // Handles when the last item overflows.
331 // At this point, item_results does not fit into the current line, and there 331 // At this point, item_results does not fit into the current line, and there
332 // are no break opportunities in item_results.back(). 332 // are no break opportunities in item_results.back().
333 void NGLineBreaker::HandleOverflow(NGInlineItemResults* item_results) { 333 void NGLineBreaker::HandleOverflow(NGInlineItemResults* item_results) {
334 const Vector<NGInlineItem>& items = node_->Items(); 334 const Vector<NGInlineItem>& items = node_.Items();
335 LayoutUnit rewind_width = available_width_ - position_; 335 LayoutUnit rewind_width = available_width_ - position_;
336 DCHECK_LT(rewind_width, 0); 336 DCHECK_LT(rewind_width, 0);
337 337
338 // Search for a break opportunity that can fit. 338 // Search for a break opportunity that can fit.
339 // Also keep track of the first break opportunity in case of overflow. 339 // Also keep track of the first break opportunity in case of overflow.
340 unsigned break_before = 0; 340 unsigned break_before = 0;
341 unsigned break_before_if_before_allow = 0; 341 unsigned break_before_if_before_allow = 0;
342 LayoutUnit rewind_width_if_before_allow; 342 LayoutUnit rewind_width_if_before_allow;
343 bool last_item_prohibits_break_before = true; 343 bool last_item_prohibits_break_before = true;
344 for (unsigned i = item_results->size(); i;) { 344 for (unsigned i = item_results->size(); i;) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 break_iterator_.SetBreakType(LineBreakType::kKeepAll); 418 break_iterator_.SetBreakType(LineBreakType::kKeepAll);
419 } else { 419 } else {
420 break_iterator_.SetBreakType(LineBreakType::kNormal); 420 break_iterator_.SetBreakType(LineBreakType::kNormal);
421 } 421 }
422 422
423 // TODO(kojii): Implement word-wrap/overflow-wrap property 423 // TODO(kojii): Implement word-wrap/overflow-wrap property
424 } 424 }
425 } 425 }
426 426
427 void NGLineBreaker::MoveToNextOf(const NGInlineItem& item) { 427 void NGLineBreaker::MoveToNextOf(const NGInlineItem& item) {
428 DCHECK_EQ(&item, &node_->Items()[item_index_]); 428 DCHECK_EQ(&item, &node_.Items()[item_index_]);
429 offset_ = item.EndOffset(); 429 offset_ = item.EndOffset();
430 item_index_++; 430 item_index_++;
431 } 431 }
432 432
433 void NGLineBreaker::MoveToNextOf(const NGInlineItemResult& item_result) { 433 void NGLineBreaker::MoveToNextOf(const NGInlineItemResult& item_result) {
434 offset_ = item_result.end_offset; 434 offset_ = item_result.end_offset;
435 item_index_ = item_result.item_index; 435 item_index_ = item_result.item_index;
436 const NGInlineItem& item = node_->Items()[item_result.item_index]; 436 const NGInlineItem& item = node_.Items()[item_result.item_index];
437 if (offset_ == item.EndOffset()) 437 if (offset_ == item.EndOffset())
438 item_index_++; 438 item_index_++;
439 } 439 }
440 440
441 void NGLineBreaker::SkipCollapsibleWhitespaces() { 441 void NGLineBreaker::SkipCollapsibleWhitespaces() {
442 const Vector<NGInlineItem>& items = node_->Items(); 442 const Vector<NGInlineItem>& items = node_.Items();
443 if (item_index_ >= items.size()) 443 if (item_index_ >= items.size())
444 return; 444 return;
445 const NGInlineItem& item = items[item_index_]; 445 const NGInlineItem& item = items[item_index_];
446 if (item.Type() != NGInlineItem::kText || !item.Style()->CollapseWhiteSpace()) 446 if (item.Type() != NGInlineItem::kText || !item.Style()->CollapseWhiteSpace())
447 return; 447 return;
448 448
449 DCHECK_LT(offset_, item.EndOffset()); 449 DCHECK_LT(offset_, item.EndOffset());
450 if (node_->Text()[offset_] == kSpaceCharacter) { 450 if (node_.Text()[offset_] == kSpaceCharacter) {
451 // Skip one whitespace. Collapsible spaces are collapsed to single space in 451 // Skip one whitespace. Collapsible spaces are collapsed to single space in
452 // NGInlineItemBuilder, so this removes all collapsible spaces. 452 // NGInlineItemBuilder, so this removes all collapsible spaces.
453 offset_++; 453 offset_++;
454 if (offset_ == item.EndOffset()) 454 if (offset_ == item.EndOffset())
455 item_index_++; 455 item_index_++;
456 } 456 }
457 } 457 }
458 458
459 RefPtr<NGInlineBreakToken> NGLineBreaker::CreateBreakToken() const { 459 RefPtr<NGInlineBreakToken> NGLineBreaker::CreateBreakToken() const {
460 const Vector<NGInlineItem>& items = node_->Items(); 460 const Vector<NGInlineItem>& items = node_.Items();
461 if (item_index_ >= items.size()) 461 if (item_index_ >= items.size())
462 return nullptr; 462 return nullptr;
463 return NGInlineBreakToken::Create(node_, item_index_, offset_); 463 return NGInlineBreakToken::Create(node_, item_index_, offset_);
464 } 464 }
465 465
466 } // namespace blink 466 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698