Commit 582e65aa authored by Koji Ishii's avatar Koji Ishii Committed by Commit Bot

[LayoutNG] Ensure ShapingLineBreaker moves offset forward

After the fix for crbug.com/915567, there are reports of
cases where ShapingLineBreaker does not move forward.

While I could not find a reproducible case for this, there
is a case it may occur from the code review. This patch fixes
the case, along with adding CHECK to ShapingLineBreaker.

This is a speculative fix.

Bug: 928178
Change-Id: I51cf733fdad9abf2feee529bfaf90a7e1bdbb09d
Reviewed-on: https://chromium-review.googlesource.com/c/1453777
Commit-Queue: Emil A Eklund <eae@chromium.org>
Reviewed-by: default avatarEmil A Eklund <eae@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629151}
parent 0829f9e2
...@@ -255,7 +255,8 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine( ...@@ -255,7 +255,8 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine(
return ShapeToEnd(start, first_safe, range_start, range_end); return ShapeToEnd(start, first_safe, range_start, range_end);
} }
} }
DCHECK_GT(break_opportunity.offset, start); // It is critical to move forward, or callers may end up in an infinite loop.
CHECK_GT(break_opportunity.offset, start);
// If the start offset is not at a safe-to-break boundary the content between // If the start offset is not at a safe-to-break boundary the content between
// the start and the next safe-to-break boundary needs to be reshaped and the // the start and the next safe-to-break boundary needs to be reshaped and the
...@@ -281,7 +282,6 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine( ...@@ -281,7 +282,6 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine(
scoped_refptr<const ShapeResult> line_end_result; scoped_refptr<const ShapeResult> line_end_result;
unsigned last_safe = break_opportunity.offset; unsigned last_safe = break_opportunity.offset;
if (break_opportunity.offset > start) {
// If the previous valid break opportunity is not at a safe-to-break // If the previous valid break opportunity is not at a safe-to-break
// boundary reshape between the safe-to-break offset and the valid break // boundary reshape between the safe-to-break offset and the valid break
// offset. If the resulting width exceeds the available space the // offset. If the resulting width exceeds the available space the
...@@ -321,10 +321,19 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine( ...@@ -321,10 +321,19 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine(
// because none can fit. The one after candidate_break is better for // because none can fit. The one after candidate_break is better for
// ligatures, but the one before is better for kernings. // ligatures, but the one before is better for kernings.
break_opportunity = PreviousBreakOpportunity(candidate_break, start); break_opportunity = PreviousBreakOpportunity(candidate_break, start);
if (break_opportunity.offset <= start) {
break_opportunity = NextBreakOpportunity(
std::max(candidate_break, start + 1), start, range_end);
if (break_opportunity.offset >= range_end) {
result_out->break_offset = range_end;
return ShapeToEnd(start, first_safe, range_start, range_end);
}
}
// Loop once more to compute last_safe for the new break opportunity. // Loop once more to compute last_safe for the new break opportunity.
is_overflow = true; is_overflow = true;
} }
} // It is critical to move forward, or callers may end up in an infinite loop.
CHECK_GT(break_opportunity.offset, start);
DCHECK_GE(break_opportunity.offset, last_safe); DCHECK_GE(break_opportunity.offset, last_safe);
DCHECK_EQ(break_opportunity.offset - start, DCHECK_EQ(break_opportunity.offset - start,
(line_start_result ? line_start_result->NumCharacters() : 0) + (line_start_result ? line_start_result->NumCharacters() : 0) +
...@@ -344,7 +353,6 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine( ...@@ -344,7 +353,6 @@ scoped_refptr<const ShapeResultView> ShapingLineBreaker::ShapeLine(
segments[count++] = {line_end_result.get(), last_safe, max_length}; segments[count++] = {line_end_result.get(), last_safe, max_length};
auto line_result = ShapeResultView::Create(&segments[0], count); auto line_result = ShapeResultView::Create(&segments[0], count);
DCHECK_GT(break_opportunity.offset, start);
DCHECK_LE(break_opportunity.offset, range_end); DCHECK_LE(break_opportunity.offset, range_end);
DCHECK_EQ(break_opportunity.offset - start, line_result->NumCharacters()); DCHECK_EQ(break_opportunity.offset - start, line_result->NumCharacters());
......
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