Commit 52a8eceb authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Fix line initial style for non-first lines

This patch fixes computing the initial style of a line for non-first
lines.

Example:
  <p>text <span style="word-break: break-all">abcdef...
and the line wraps within "abcdef...", the initial style of the 2nd
line is different from the line sytle.

When NGLineBreaker initializes line-breaking-related properties, the
style of the current box was not available. This patch adds the
current style to NGInlineBreakToken.

Bug: 636993
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_layout_tests_layout_ng
Change-Id: I45191cc6491c431b63a6de9e854fb8197d1b945b
Reviewed-on: https://chromium-review.googlesource.com/846585Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Commit-Queue: Koji Ishii <kojii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#527007}
parent 736efbc1
<!DOCTYPE html>
<div>
<br>This line should not wrap
</div>
<!DOCTYPE html>
<div style="width:5ch">
<span style="white-space:pre"><br>This line should not wrap</span>
</div>
...@@ -10,11 +10,13 @@ namespace blink { ...@@ -10,11 +10,13 @@ namespace blink {
NGInlineBreakToken::NGInlineBreakToken( NGInlineBreakToken::NGInlineBreakToken(
NGInlineNode node, NGInlineNode node,
const ComputedStyle* style,
unsigned item_index, unsigned item_index,
unsigned text_offset, unsigned text_offset,
bool is_forced_break, bool is_forced_break,
std::unique_ptr<const NGInlineLayoutStateStack> state_stack) std::unique_ptr<const NGInlineLayoutStateStack> state_stack)
: NGBreakToken(kInlineBreakToken, kUnfinished, node), : NGBreakToken(kInlineBreakToken, kUnfinished, node),
style_(style),
item_index_(item_index), item_index_(item_index),
text_offset_(text_offset), text_offset_(text_offset),
is_forced_break_(is_forced_break), is_forced_break_(is_forced_break),
......
...@@ -20,12 +20,13 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken { ...@@ -20,12 +20,13 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken {
// Takes ownership of the state_stack. // Takes ownership of the state_stack.
static scoped_refptr<NGInlineBreakToken> Create( static scoped_refptr<NGInlineBreakToken> Create(
NGInlineNode node, NGInlineNode node,
const ComputedStyle* style,
unsigned item_index, unsigned item_index,
unsigned text_offset, unsigned text_offset,
bool is_forced_break, bool is_forced_break,
std::unique_ptr<const NGInlineLayoutStateStack> state_stack) { std::unique_ptr<const NGInlineLayoutStateStack> state_stack) {
return base::AdoptRef(new NGInlineBreakToken(node, item_index, text_offset, return base::AdoptRef(new NGInlineBreakToken(node, style, item_index,
is_forced_break, text_offset, is_forced_break,
std::move(state_stack))); std::move(state_stack)));
} }
...@@ -36,6 +37,13 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken { ...@@ -36,6 +37,13 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken {
~NGInlineBreakToken() override; ~NGInlineBreakToken() override;
// The style at the end of this break token. The next line should start with
// this style.
const ComputedStyle* Style() const {
DCHECK(!IsFinished());
return style_.get();
}
unsigned ItemIndex() const { unsigned ItemIndex() const {
DCHECK(!IsFinished()); DCHECK(!IsFinished());
return item_index_; return item_index_;
...@@ -71,6 +79,7 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken { ...@@ -71,6 +79,7 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken {
private: private:
NGInlineBreakToken(NGInlineNode node, NGInlineBreakToken(NGInlineNode node,
const ComputedStyle*,
unsigned item_index, unsigned item_index,
unsigned text_offset, unsigned text_offset,
bool is_forced_break, bool is_forced_break,
...@@ -78,6 +87,7 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken { ...@@ -78,6 +87,7 @@ class CORE_EXPORT NGInlineBreakToken : public NGBreakToken {
explicit NGInlineBreakToken(NGLayoutInputNode node); explicit NGInlineBreakToken(NGLayoutInputNode node);
scoped_refptr<const ComputedStyle> style_;
unsigned item_index_; unsigned item_index_;
unsigned text_offset_; unsigned text_offset_;
unsigned is_forced_break_ : 1; unsigned is_forced_break_ : 1;
......
...@@ -40,6 +40,7 @@ NGLineBreaker::NGLineBreaker( ...@@ -40,6 +40,7 @@ NGLineBreaker::NGLineBreaker(
base_direction_(node_.BaseDirection()), base_direction_(node_.BaseDirection()),
in_line_height_quirks_mode_(node.InLineHeightQuirksMode()) { in_line_height_quirks_mode_(node.InLineHeightQuirksMode()) {
if (break_token) { if (break_token) {
current_style_ = break_token->Style();
item_index_ = break_token->ItemIndex(); item_index_ = break_token->ItemIndex();
offset_ = break_token->TextOffset(); offset_ = break_token->TextOffset();
previous_line_had_forced_break_ = break_token->IsForcedBreak(); previous_line_had_forced_break_ = break_token->IsForcedBreak();
...@@ -100,7 +101,11 @@ void NGLineBreaker::PrepareNextLine(const NGLayoutOpportunity& opportunity, ...@@ -100,7 +101,11 @@ void NGLineBreaker::PrepareNextLine(const NGLayoutOpportunity& opportunity,
line_info->SetStartOffset(offset_); line_info->SetStartOffset(offset_);
line_info->SetLineStyle(node_, constraint_space_, IsFirstFormattedLine(), line_info->SetLineStyle(node_, constraint_space_, IsFirstFormattedLine(),
previous_line_had_forced_break_); previous_line_had_forced_break_);
SetCurrentStyle(line_info->LineStyle()); // Set the initial style of this line from the break token. Example:
// <p>...<span>....</span></p>
// When the line wraps in <span>, the 2nd line needs to start with the style
// of the <span>.
SetCurrentStyle(current_style_ ? *current_style_ : line_info->LineStyle());
ComputeBaseDirection(); ComputeBaseDirection();
line_info->SetBaseDirection(base_direction_); line_info->SetBaseDirection(base_direction_);
...@@ -815,6 +820,8 @@ void NGLineBreaker::TruncateOverflowingText(NGLineInfo* line_info) { ...@@ -815,6 +820,8 @@ void NGLineBreaker::TruncateOverflowingText(NGLineInfo* line_info) {
} }
void NGLineBreaker::SetCurrentStyle(const ComputedStyle& style) { void NGLineBreaker::SetCurrentStyle(const ComputedStyle& style) {
current_style_ = &style;
auto_wrap_ = style.AutoWrap(); auto_wrap_ = style.AutoWrap();
if (auto_wrap_) { if (auto_wrap_) {
...@@ -885,8 +892,8 @@ scoped_refptr<NGInlineBreakToken> NGLineBreaker::CreateBreakToken( ...@@ -885,8 +892,8 @@ scoped_refptr<NGInlineBreakToken> NGLineBreaker::CreateBreakToken(
const Vector<NGInlineItem>& items = node_.Items(); const Vector<NGInlineItem>& items = node_.Items();
if (item_index_ >= items.size()) if (item_index_ >= items.size())
return NGInlineBreakToken::Create(node_); return NGInlineBreakToken::Create(node_);
return NGInlineBreakToken::Create(node_, item_index_, offset_, return NGInlineBreakToken::Create(node_, current_style_.get(), item_index_,
line_.is_after_forced_break, offset_, line_.is_after_forced_break,
std::move(state_stack)); std::move(state_stack));
} }
......
...@@ -150,6 +150,7 @@ class CORE_EXPORT NGLineBreaker { ...@@ -150,6 +150,7 @@ class CORE_EXPORT NGLineBreaker {
Vector<NGPositionedFloat>* positioned_floats_; Vector<NGPositionedFloat>* positioned_floats_;
Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats_; Vector<scoped_refptr<NGUnpositionedFloat>>* unpositioned_floats_;
NGExclusionSpace* exclusion_space_; NGExclusionSpace* exclusion_space_;
scoped_refptr<const ComputedStyle> current_style_;
unsigned item_index_ = 0; unsigned item_index_ = 0;
unsigned offset_ = 0; unsigned offset_ = 0;
......
...@@ -99,7 +99,7 @@ NGFragmentBuilder& NGFragmentBuilder::AddBreakBeforeChild( ...@@ -99,7 +99,7 @@ NGFragmentBuilder& NGFragmentBuilder::AddBreakBeforeChild(
// formatting context, rather than concluding that we're done with the // formatting context, rather than concluding that we're done with the
// whole thing. // whole thing.
inline_break_tokens_.push_back(NGInlineBreakToken::Create( inline_break_tokens_.push_back(NGInlineBreakToken::Create(
ToNGInlineNode(child), 0, 0, false, ToNGInlineNode(child), nullptr, 0, 0, false,
std::make_unique<NGInlineLayoutStateStack>())); std::make_unique<NGInlineLayoutStateStack>()));
} }
return *this; return *this;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment