Bug 1549728 - Flush line-breaker whenever the word-break property changes. r=emilio

The patch in bug 1507744 was not sufficient by itself, as the line-breaker could still accumulate a single "current word" across a text-run boundary, and then a single word-break value would be applied to it. We need to flush the line-breaker when word-break changes, so that each part of the word will have break opportunities set according to the appropriate value.

Differential Revision: https://phabricator.services.mozilla.com/D30260

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jonathan Kew 2019-05-08 15:09:44 +00:00
parent 1a7b1e1ca1
commit fabb0dc4d5
4 changed files with 35 additions and 21 deletions

View File

@ -177,7 +177,22 @@ class nsLineBreaker {
* Set word-break mode for linebreaker. This is set by word-break property.
* @param aMode is LineBreaker::kWordBreak_* value.
*/
void SetWordBreak(uint8_t aMode) { mWordBreak = aMode; }
void SetWordBreak(uint8_t aMode) {
// If current word is non-empty and mode is changing, flush the breaker.
if (aMode != mWordBreak && !mCurrentWord.IsEmpty()) {
nsresult rv = FlushCurrentWord();
if (NS_FAILED(rv)) {
NS_WARNING("FlushCurrentWord failed, line-breaks may be wrong");
}
// If previous mode was break-all, we should allow a break here.
// XXX (jfkthame) css-text spec seems unclear on this, raised question in
// https://github.com/w3c/csswg-drafts/issues/3897
if (mWordBreak == mozilla::intl::LineBreaker::kWordBreak_BreakAll) {
mBreakHere = true;
}
}
mWordBreak = aMode;
}
private:
// This is a list of text sources that make up the "current word" (i.e.,

View File

@ -2572,22 +2572,6 @@ void BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun,
const void* aTextPtr) {
using mozilla::intl::LineBreaker;
auto wordBreak =
mMappedFlows[0].mStartFrame->StyleText()->EffectiveWordBreak();
switch (wordBreak) {
case StyleWordBreak::BreakAll:
mLineBreaker.SetWordBreak(LineBreaker::kWordBreak_BreakAll);
break;
case StyleWordBreak::KeepAll:
mLineBreaker.SetWordBreak(LineBreaker::kWordBreak_KeepAll);
break;
case StyleWordBreak::Normal:
default:
MOZ_ASSERT(wordBreak == StyleWordBreak::Normal);
mLineBreaker.SetWordBreak(LineBreaker::kWordBreak_Normal);
break;
}
// textruns have uniform language
const nsStyleFont* styleFont = mMappedFlows[0].mStartFrame->StyleFont();
// We should only use a language for hyphenation if it was specified
@ -2601,6 +2585,25 @@ void BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun,
for (uint32_t i = 0; i < mMappedFlows.Length(); ++i) {
MappedFlow* mappedFlow = &mMappedFlows[i];
// The CSS word-break value may change within a word, so we reset it for
// each MappedFlow. The line-breaker will flush its text if the property
// actually changes.
auto wordBreak =
mappedFlow->mStartFrame->StyleText()->EffectiveWordBreak();
switch (wordBreak) {
case StyleWordBreak::BreakAll:
mLineBreaker.SetWordBreak(LineBreaker::kWordBreak_BreakAll);
break;
case StyleWordBreak::KeepAll:
mLineBreaker.SetWordBreak(LineBreaker::kWordBreak_KeepAll);
break;
case StyleWordBreak::Normal:
default:
MOZ_ASSERT(wordBreak == StyleWordBreak::Normal);
mLineBreaker.SetWordBreak(LineBreaker::kWordBreak_Normal);
break;
}
uint32_t offset = iter.GetSkippedOffset();
gfxSkipCharsIterator iterNext = iter;
iterNext.AdvanceOriginal(mappedFlow->GetContentEnd() -

View File

@ -1,2 +0,0 @@
[word-break-break-all-inline-004.html]
expected: FAIL

View File

@ -1,2 +0,0 @@
[word-break-break-all-inline-005.html]
expected: FAIL