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

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

Issue 2943983002: [LayoutNG] Implement CSS 'text-indent' property (Closed)
Patch Set: Cleanup 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 NGConstraintSpace* space, 60 NGConstraintSpace* space,
61 NGFragmentBuilder* container_builder, 61 NGFragmentBuilder* container_builder,
62 const NGInlineBreakToken* break_token) 62 const NGInlineBreakToken* break_token)
63 : node_(node), 63 : node_(node),
64 constraint_space_(space), 64 constraint_space_(space),
65 container_builder_(container_builder), 65 container_builder_(container_builder),
66 item_index_(0), 66 item_index_(0),
67 offset_(0), 67 offset_(0),
68 break_iterator_(node.Text()), 68 break_iterator_(node.Text()),
69 shaper_(node.Text().Characters16(), node.Text().length()), 69 shaper_(node.Text().Characters16(), node.Text().length()),
70 spacing_(node.Text()) { 70 spacing_(node.Text()),
71 auto_wrap_(false),
72 should_create_line_box_(false),
73 is_after_forced_break_(false) {
71 if (break_token) { 74 if (break_token) {
72 item_index_ = break_token->ItemIndex(); 75 item_index_ = break_token->ItemIndex();
73 offset_ = break_token->TextOffset(); 76 offset_ = break_token->TextOffset();
74 node.AssertOffset(item_index_, offset_); 77 node.AssertOffset(item_index_, offset_);
75 } 78 }
76 } 79 }
77 80
81 // @return if this is the "first formatted line".
82 // https://www.w3.org/TR/CSS22/selector.html#first-formatted-line
83 bool NGLineBreaker::IsFirstFormattedLine() const {
84 if (item_index_ || offset_)
85 return false;
86 // The first line of an anonymous block box is only affected if it is the
87 // first child of its parent element.
88 // https://drafts.csswg.org/css-text-3/#text-indent-property
89 LayoutBlockFlow* block = node_.GetLayoutBlockFlow();
90 if (block->IsAnonymousBlock() && block->PreviousSibling()) {
91 // TODO(kojii): In NG, leading OOF creates a block box.
92 // text-indent-first-line-002.html fails for this reason.
93 // crbug.com/734554
94 return false;
95 }
96 return true;
97 }
98
78 bool NGLineBreaker::NextLine(NGLineInfo* line_info, 99 bool NGLineBreaker::NextLine(NGLineInfo* line_info,
79 const NGLogicalOffset& content_offset) { 100 const NGLogicalOffset& content_offset) {
80 content_offset_ = content_offset; 101 content_offset_ = content_offset;
81 BreakLine(line_info); 102 BreakLine(line_info);
82 103
83 // TODO(kojii): When editing, or caret is enabled, trailing spaces at wrap 104 // TODO(kojii): When editing, or caret is enabled, trailing spaces at wrap
84 // point should not be removed. For other cases, we can a) remove, b) leave 105 // point should not be removed. For other cases, we can a) remove, b) leave
85 // characters without glyphs, or c) leave both characters and glyphs without 106 // characters without glyphs, or c) leave both characters and glyphs without
86 // measuring. Need to decide which one works the best. 107 // measuring. Need to decide which one works the best.
87 SkipCollapsibleWhitespaces(); 108 SkipCollapsibleWhitespaces();
88 109
89 if (line_info->Results().IsEmpty()) 110 if (line_info->Results().IsEmpty())
90 return false; 111 return false;
91 112
92 // TODO(kojii): There are cases where we need to PlaceItems() without creating 113 // TODO(kojii): There are cases where we need to PlaceItems() without creating
93 // line boxes. These cases need to be reviewed. 114 // line boxes. These cases need to be reviewed.
94 if (should_create_line_box_) 115 if (should_create_line_box_)
95 ComputeLineLocation(line_info); 116 ComputeLineLocation(line_info);
96 117
97 return true; 118 return true;
98 } 119 }
99 120
100 void NGLineBreaker::BreakLine(NGLineInfo* line_info) { 121 void NGLineBreaker::BreakLine(NGLineInfo* line_info) {
101 NGInlineItemResults* item_results = &line_info->Results(); 122 NGInlineItemResults* item_results = &line_info->Results();
102 item_results->clear(); 123 item_results->clear();
103 const Vector<NGInlineItem>& items = node_.Items(); 124 const Vector<NGInlineItem>& items = node_.Items();
104 line_info->SetLineStyle(node_, !item_index_ && !offset_); 125 line_info->SetLineStyle(node_, *constraint_space_, IsFirstFormattedLine(),
126 is_after_forced_break_);
105 SetCurrentStyle(line_info->LineStyle()); 127 SetCurrentStyle(line_info->LineStyle());
106 position_ = LayoutUnit(0); 128 is_after_forced_break_ = false;
107 should_create_line_box_ = false; 129 should_create_line_box_ = false;
108 LineBreakState state = LineBreakState::kNotBreakable; 130 LineBreakState state = LineBreakState::kNotBreakable;
109 131
132 // Use 'text-indent' as the initial position. This lets tab positions to align
133 // regardless of 'text-indent'.
134 position_ = line_info->TextIndent();
135
110 // We are only able to calculate our available_width if our container has 136 // We are only able to calculate our available_width if our container has
111 // been positioned in the BFC coordinate space yet. 137 // been positioned in the BFC coordinate space yet.
112 if (container_builder_->BfcOffset()) 138 if (container_builder_->BfcOffset())
113 UpdateAvailableWidth(); 139 UpdateAvailableWidth();
114 else 140 else
115 opportunity_.reset(); 141 opportunity_.reset();
116 142
117 while (item_index_ < items.size()) { 143 while (item_index_ < items.size()) {
118 // CloseTag prohibits to break before. 144 // CloseTag prohibits to break before.
119 const NGInlineItem& item = items[item_index_]; 145 const NGInlineItem& item = items[item_index_];
(...skipping 15 matching lines...) Expand all
135 item_results->push_back( 161 item_results->push_back(
136 NGInlineItemResult(item_index_, offset_, item.EndOffset())); 162 NGInlineItemResult(item_index_, offset_, item.EndOffset()));
137 NGInlineItemResult* item_result = &item_results->back(); 163 NGInlineItemResult* item_result = &item_results->back();
138 if (item.Type() == NGInlineItem::kText) { 164 if (item.Type() == NGInlineItem::kText) {
139 state = HandleText(item, item_result); 165 state = HandleText(item, item_result);
140 } else if (item.Type() == NGInlineItem::kAtomicInline) { 166 } else if (item.Type() == NGInlineItem::kAtomicInline) {
141 state = HandleAtomicInline(item, item_result); 167 state = HandleAtomicInline(item, item_result);
142 } else if (item.Type() == NGInlineItem::kControl) { 168 } else if (item.Type() == NGInlineItem::kControl) {
143 state = HandleControlItem(item, item_result); 169 state = HandleControlItem(item, item_result);
144 if (state == LineBreakState::kForcedBreak) { 170 if (state == LineBreakState::kForcedBreak) {
171 is_after_forced_break_ = true;
145 line_info->SetIsLastLine(true); 172 line_info->SetIsLastLine(true);
146 return; 173 return;
147 } 174 }
148 } else if (item.Type() == NGInlineItem::kOpenTag) { 175 } else if (item.Type() == NGInlineItem::kOpenTag) {
149 HandleOpenTag(item, item_result); 176 HandleOpenTag(item, item_result);
150 state = LineBreakState::kNotBreakable; 177 state = LineBreakState::kNotBreakable;
151 } else if (item.Type() == NGInlineItem::kFloating) { 178 } else if (item.Type() == NGInlineItem::kFloating) {
152 HandleFloat(item, item_results); 179 HandleFloat(item, item_results);
153 } else { 180 } else {
154 MoveToNextOf(item); 181 MoveToNextOf(item);
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 } 652 }
626 653
627 RefPtr<NGInlineBreakToken> NGLineBreaker::CreateBreakToken() const { 654 RefPtr<NGInlineBreakToken> NGLineBreaker::CreateBreakToken() const {
628 const Vector<NGInlineItem>& items = node_.Items(); 655 const Vector<NGInlineItem>& items = node_.Items();
629 if (item_index_ >= items.size()) 656 if (item_index_ >= items.size())
630 return nullptr; 657 return nullptr;
631 return NGInlineBreakToken::Create(node_, item_index_, offset_); 658 return NGInlineBreakToken::Create(node_, item_index_, offset_);
632 } 659 }
633 660
634 } // namespace blink 661 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698