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

Unified Diff: third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp

Issue 2879093002: [LayoutNG] Fix ShapingLineBreaker when the end of range is needed (Closed)
Patch Set: Rebase 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
index dafe8f19e9a07cc0bdc11a84600fe359ea0e06c8..d306d49a9173dce81b968d9d818ae9ce47e75bd4 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapingLineBreaker.cpp
@@ -122,6 +122,15 @@ PassRefPtr<ShapeResult> ShapingLineBreaker::ShapeLine(
DCHECK_GE(FlipRtl(end_position - start_position, direction), LayoutUnit(0));
unsigned candidate_break =
result_->OffsetForPosition(end_position, false) + range_start;
+
+ if (candidate_break >= range_end) {
eae 2017/06/12 16:51:37 When would this happen?
kojii 2017/06/12 16:54:34 "==" happens when end_position >= result->Width().
+ // The |result_| does not have glyphs to fill the available space,
+ // and thus unable to compute. Return the result up to range_end.
+ DCHECK_EQ(candidate_break, range_end);
+ *break_offset = range_end;
+ return ShapeToEnd(start, start_position, range_end);
+ }
+
// candidate_break should be >= start, but rounding errors can chime in when
// comparing floats. See ShapeLineZeroAvailableWidth on Linux/Mac.
candidate_break = std::max(candidate_break, start);
@@ -130,6 +139,9 @@ PassRefPtr<ShapeResult> ShapingLineBreaker::ShapeLine(
if (break_opportunity <= start) {
break_opportunity = break_iterator_->NextBreakOpportunity(
std::max(candidate_break, start + 1));
+ // |range_end| may not be a break opportunity, but this function cannot
+ // measure beyond it.
+ break_opportunity = std::min(break_opportunity, range_end);
}
DCHECK_GT(break_opportunity, start);
@@ -167,9 +179,9 @@ PassRefPtr<ShapeResult> ShapingLineBreaker::ShapeLine(
LayoutUnit safe_position = SnapStart(
result_->PositionForOffset(previous_safe - range_start), direction);
while (break_opportunity > previous_safe && previous_safe >= start) {
+ DCHECK_LE(break_opportunity, range_end);
line_end_result =
- shaper_->Shape(font_, direction, previous_safe,
- std::min(break_opportunity, range_end));
+ shaper_->Shape(font_, direction, previous_safe, break_opportunity);
if (line_end_result->SnappedWidth() <=
FlipRtl(end_position - safe_position, direction))
break;
@@ -193,6 +205,9 @@ PassRefPtr<ShapeResult> ShapingLineBreaker::ShapeLine(
// No suitable break opportunity, not exceeding the available space,
// found. Choose the next valid one even though it will overflow.
break_opportunity = break_iterator_->NextBreakOpportunity(candidate_break);
+ // |range_end| may not be a break opportunity, but this function cannot
+ // measure beyond it.
+ break_opportunity = std::min(break_opportunity, range_end);
}
// Create shape results for the line by copying from the re-shaped result (if
@@ -214,4 +229,31 @@ PassRefPtr<ShapeResult> ShapingLineBreaker::ShapeLine(
return line_result.Release();
}
+// Shape from the specified offset to the end of the ShapeResult.
+// If |start| is safe-to-break, this copies the subset of the result.
+PassRefPtr<ShapeResult> ShapingLineBreaker::ShapeToEnd(
+ unsigned start,
+ LayoutUnit start_position,
+ unsigned range_end) {
+ unsigned first_safe =
+ NextSafeToBreakBefore(shaper_->GetText(), shaper_->TextLength(), start);
+ DCHECK_GE(first_safe, start);
+
+ RefPtr<ShapeResult> line_result;
+ TextDirection direction = result_->Direction();
+ if (first_safe == start) {
+ // If |start| is safe-to-break, reshape is not needed.
+ line_result = ShapeResult::Create(font_, 0, direction);
+ result_->CopyRange(start, range_end, line_result.Get());
+ } else if (first_safe < range_end) {
+ // Otherwise reshape to the first safe, then copy the rest.
+ line_result = shaper_->Shape(font_, direction, start, first_safe);
+ result_->CopyRange(first_safe, range_end, line_result.Get());
+ } else {
+ // If no safe-to-break in the ragne, reshape the whole range.
+ line_result = shaper_->Shape(font_, direction, start, range_end);
+ }
+ return line_result.Release();
+}
+
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698