Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add an adjustment to currentLineWidth comparisons when pushing greedy…
… line breaks

This is similar to the workaround used for
flutter/flutter#30347

The Minikin line breaker inserts greedy breaks based on a comparison of
postBreak width and currentLineWidth.  currentLineWidth is provided by
the framework based on previous calls to Layout::measureText.
That calculation may not exactly match the calculation of postBreak.

This change ensures that breaks are only added if the difference
between postBreak and currentLineWidth is significant.

Fixes flutter/flutter#65419
  • Loading branch information
jason-simmons committed Sep 23, 2020
commit 1b203c65109932d23d940329f8f74b6b62b392e6
13 changes: 10 additions & 3 deletions third_party/txt/src/minikin/LineBreaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ const size_t MAX_TEXT_BUF_RETAIN = 32678;
// Maximum amount that spaces can shrink, in justified text.
const float SHRINKABILITY = 1.0 / 3.0;

// libtxt: Add a fudge factor to comparisons between currentLineWidth and
// postBreak width. The currentLineWidth passed by the Flutter framework
// is based on maxIntrinsicWidth/Layout::measureText calculations that may
// not precisely match the postBreak width.
const float LIBTXT_WIDTH_ADJUST = 0.00001;

void LineBreaker::setLocale(const icu::Locale& locale, Hyphenator* hyphenator) {
mWordBreaker.setLocale(locale);
mLocale = locale;
Expand Down Expand Up @@ -240,7 +246,7 @@ void LineBreaker::addWordBreak(size_t offset,
// libtxt: add a fudge factor to this comparison. The currentLineWidth passed
// by the framework is based on maxIntrinsicWidth/Layout::measureText
// calculations that may not precisely match the postBreak width.
if (postBreak - width > currentLineWidth() + 0.00001) {
if (postBreak - width > currentLineWidth() + LIBTXT_WIDTH_ADJUST) {
// Add desperate breaks.
// Note: these breaks are based on the shaping of the (non-broken) original
// text; they are imprecise especially in the presence of kerning,
Expand Down Expand Up @@ -305,7 +311,7 @@ void LineBreaker::addCandidate(Candidate cand) {
// mCandidates, and mPreBreak is its preBreak value. mBestBreak is the index
// of the best line breaking candidate we have found since then, and
// mBestScore is its penalty.
if (cand.postBreak - mPreBreak > currentLineWidth()) {
if (cand.postBreak - mPreBreak > currentLineWidth() + LIBTXT_WIDTH_ADJUST) {
// This break would create an overfull line, pick the best break and break
// there (greedy)
if (mBestBreak == mLastBreak) {
Expand All @@ -316,7 +322,8 @@ void LineBreaker::addCandidate(Candidate cand) {
}

while (mLastBreak != candIndex &&
cand.postBreak - mPreBreak > currentLineWidth()) {
cand.postBreak - mPreBreak >
currentLineWidth() + LIBTXT_WIDTH_ADJUST) {
// We should rarely come here. But if we are here, we have broken the line,
// but the remaining part still doesn't fit. We now need to break at the
// second best place after the last break, but we have not kept that
Expand Down