author | Jason Woofenden <jason@jasonwoof.com> |
Sun, 20 Mar 2016 17:54:00 -0400 | |
changeset 312924 | 4d1901a5332aeb47b3408d6d982f1d9788650812 |
parent 312923 | 50f9f9bec91838935029181f22ae228840b56228 |
child 312925 | 4959bbdb0d99480d556b3738a1bdfb22b371c485 |
push id | 30665 |
push user | cbook@mozilla.com |
push date | Wed, 07 Sep 2016 15:20:43 +0000 |
treeherder | mozilla-central@95acb9299faf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jfkthame |
bugs | 1008019 |
milestone | 51.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/thebes/gfxTextRun.cpp +++ b/gfx/thebes/gfxTextRun.cpp @@ -833,16 +833,17 @@ gfxTextRun::MeasureText(Range aRange, #define MEASUREMENT_BUFFER_SIZE 100 uint32_t gfxTextRun::BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength, bool aLineBreakBefore, gfxFloat aWidth, PropertyProvider *aProvider, SuppressBreak aSuppressBreak, gfxFloat *aTrimWhitespace, + bool aWhitespaceCanHang, Metrics *aMetrics, gfxFont::BoundingBoxType aBoundingBoxType, DrawTarget* aRefDrawTarget, bool *aUsedHyphenation, uint32_t *aLastBreak, bool aCanWordWrap, gfxBreakPriority *aBreakPriority) { @@ -863,17 +864,17 @@ gfxTextRun::BreakAndMeasureText(uint32_t (aProvider->GetHyphensOption() == NS_STYLE_HYPHENS_MANUAL && (mFlags & gfxTextRunFactory::TEXT_ENABLE_HYPHEN_BREAKS) != 0)); if (haveHyphenation) { aProvider->GetHyphenationBreaks(bufferRange, hyphenBuffer); } gfxFloat width = 0; gfxFloat advance = 0; - // The number of space characters that can be trimmed + // The number of space characters that can be trimmed or hang at a soft-wrap uint32_t trimmableChars = 0; // The amount of space removed by ignoring trimmableChars gfxFloat trimmableAdvance = 0; int32_t lastBreak = -1; int32_t lastBreakTrimmableChars = -1; gfxFloat lastBreakTrimmableAdvance = -1; bool aborted = false; uint32_t end = aStart + aMaxLength; @@ -946,17 +947,17 @@ gfxTextRun::BreakAndMeasureText(uint32_t charAdvance += space->mBefore + space->mAfter; } } else { charAdvance = ComputePartialLigatureWidth(Range(i, i + 1), aProvider); } advance += charAdvance; - if (aTrimWhitespace) { + if (aTrimWhitespace || aWhitespaceCanHang) { if (mCharacterGlyphs[i].CharIsSpace()) { ++trimmableChars; trimmableAdvance += charAdvance; } else { trimmableAdvance = 0; trimmableChars = 0; } } @@ -980,23 +981,35 @@ gfxTextRun::BreakAndMeasureText(uint32_t trimmableAdvance = lastBreakTrimmableAdvance; usedHyphenation = lastBreakUsedHyphenation; } else { charsFit = aMaxLength; } if (aMetrics) { auto fitEnd = aStart + charsFit; - *aMetrics = MeasureText(Range(aStart, fitEnd), aBoundingBoxType, - aRefDrawTarget, aProvider); - if (trimmableChars) { - Metrics trimMetrics = + // Initially, measure everything, so that our bounding box includes + // any trimmable or hanging whitespace. + *aMetrics = MeasureText(Range(aStart, fitEnd), + aBoundingBoxType, aRefDrawTarget, + aProvider); + if (aTrimWhitespace || aWhitespaceCanHang) { + // Measure trailing whitespace that is to be trimmed/hung. + Metrics trimOrHangMetrics = MeasureText(Range(fitEnd - trimmableChars, fitEnd), - aBoundingBoxType, aRefDrawTarget, aProvider); - aMetrics->mAdvanceWidth -= trimMetrics.mAdvanceWidth; + aBoundingBoxType, aRefDrawTarget, + aProvider); + if (aTrimWhitespace) { + aMetrics->mAdvanceWidth -= trimOrHangMetrics.mAdvanceWidth; + } else if (aMetrics->mAdvanceWidth > aWidth) { + // Restrict width of hanging whitespace so it doesn't overflow. + aMetrics->mAdvanceWidth = + std::max(aWidth, aMetrics->mAdvanceWidth - + trimOrHangMetrics.mAdvanceWidth); + } } } if (aTrimWhitespace) { *aTrimWhitespace = trimmableAdvance; } if (aUsedHyphenation) { *aUsedHyphenation = usedHyphenation; }
--- a/gfx/thebes/gfxTextRun.h +++ b/gfx/thebes/gfxTextRun.h @@ -390,16 +390,17 @@ public: * Note that negative advance widths are possible especially if negative * spacing is provided. */ uint32_t BreakAndMeasureText(uint32_t aStart, uint32_t aMaxLength, bool aLineBreakBefore, gfxFloat aWidth, PropertyProvider *aProvider, SuppressBreak aSuppressBreak, gfxFloat *aTrimWhitespace, + bool aHangWhitespace, Metrics *aMetrics, gfxFont::BoundingBoxType aBoundingBoxType, DrawTarget* aDrawTargetForTightBoundingBox, bool *aUsedHyphenation, uint32_t *aLastBreak, bool aCanWordWrap, gfxBreakPriority *aBreakPriority);
--- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9088,30 +9088,34 @@ nsTextFrame::ReflowText(nsLineLayout& aL gfxFloat availWidth = aAvailableWidth; if (StyleContext()->IsTextCombined()) { // If text-combine-upright is 'all', we would compress whatever long // text into ~1em width, so there is no limited on the avail width. availWidth = std::numeric_limits<gfxFloat>::infinity(); } bool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant() || (GetStateBits() & TEXT_IS_IN_TOKEN_MATHML); + // allow whitespace to overflow the container + bool whitespaceCanHang = textStyle->WhiteSpaceCanWrapStyle() && + textStyle->WhiteSpaceIsSignificant(); gfxBreakPriority breakPriority = aLineLayout.LastOptionalBreakPriority(); gfxTextRun::SuppressBreak suppressBreak = gfxTextRun::eNoSuppressBreak; bool shouldSuppressLineBreak = ShouldSuppressLineBreak(); if (shouldSuppressLineBreak) { suppressBreak = gfxTextRun::eSuppressAllBreaks; } else if (!aLineLayout.LineIsBreakable()) { suppressBreak = gfxTextRun::eSuppressInitialBreak; } uint32_t transformedCharsFit = mTextRun->BreakAndMeasureText(transformedOffset, transformedLength, (GetStateBits() & TEXT_START_OF_LINE) != 0, availWidth, &provider, suppressBreak, canTrimTrailingWhitespace ? &trimmedWidth : nullptr, + whitespaceCanHang, &textMetrics, boundingBoxType, aDrawTarget, &usedHyphenation, &transformedLastBreak, textStyle->WordCanWrap(this), &breakPriority); if (!length && !textMetrics.mAscent && !textMetrics.mDescent) { // If we're measuring a zero-length piece of text, update // the height manually. nsFontMetrics* fm = provider.GetFontMetrics();