Bug 1241631. Make nsTextFrame::GetTrimmedOffsets take a flags word parameter. r=mats
MozReview-Commit-ID: CD601keACDq
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -2779,21 +2779,20 @@ GetEndOfTrimmedText(const nsTextFragment
aIterator->AdvanceSkipped(-1);
if (!IsTrimmableSpace(aFrag, aIterator->GetOriginalOffset(), aStyleText))
return aIterator->GetSkippedOffset() + 1;
}
return aStart;
}
nsTextFrame::TrimmedOffsets
-nsTextFrame::GetTrimmedOffsets(const nsTextFragment* aFrag,
- bool aTrimAfter, bool aPostReflow)
+nsTextFrame::GetTrimmedOffsets(const nsTextFragment* aFrag, uint32_t aFlags)
{
NS_ASSERTION(mTextRun, "Need textrun here");
- if (aPostReflow) {
+ if (aFlags & TRIM_POST_REFLOW) {
// This should not be used during reflow. We need our TEXT_REFLOW_FLAGS
// to be set correctly. If our parent wasn't reflowed due to the frame
// tree being too deep then the return value doesn't matter.
NS_ASSERTION(!(GetStateBits() & NS_FRAME_FIRST_REFLOW) ||
(GetParent()->GetStateBits() &
NS_FRAME_TOO_DEEP_IN_FRAME_TREE),
"Can only call this on frames that have been reflowed");
NS_ASSERTION(!(GetStateBits() & NS_FRAME_IN_REFLOW),
@@ -2802,25 +2801,27 @@ nsTextFrame::GetTrimmedOffsets(const nsT
TrimmedOffsets offsets = { GetContentOffset(), GetContentLength() };
const nsStyleText* textStyle = StyleText();
// Note that pre-line newlines should still allow us to trim spaces
// for display
if (textStyle->WhiteSpaceIsSignificant())
return offsets;
- if (!aPostReflow || (GetStateBits() & TEXT_START_OF_LINE)) {
+ if ((aFlags & TRIM_BEFORE) &&
+ (!(aFlags & TRIM_POST_REFLOW) || (GetStateBits() & TEXT_START_OF_LINE))) {
int32_t whitespaceCount =
GetTrimmableWhitespaceCount(aFrag,
offsets.mStart, offsets.mLength, 1);
offsets.mStart += whitespaceCount;
offsets.mLength -= whitespaceCount;
}
- if (aTrimAfter && (!aPostReflow || (GetStateBits() & TEXT_END_OF_LINE))) {
+ if ((aFlags & TRIM_AFTER) &&
+ (!(aFlags & TRIM_POST_REFLOW) || (GetStateBits() & TEXT_END_OF_LINE))) {
// This treats a trailing 'pre-line' newline as trimmable. That's fine,
// it's actually what we want since we want whitespace before it to
// be trimmed.
int32_t whitespaceCount =
GetTrimmableWhitespaceCount(aFrag,
offsets.GetEnd() - 1, offsets.mLength, -1);
offsets.mLength -= whitespaceCount;
}
@@ -3475,27 +3476,30 @@ PropertyProvider::GetHyphenationBreaks(u
}
}
}
void
PropertyProvider::InitializeForDisplay(bool aTrimAfter)
{
nsTextFrame::TrimmedOffsets trimmed =
- mFrame->GetTrimmedOffsets(mFrag, aTrimAfter);
+ mFrame->GetTrimmedOffsets(mFrag, nsTextFrame::TRIM_BEFORE |
+ (aTrimAfter ? nsTextFrame::TRIM_AFTER : 0) |
+ nsTextFrame::TRIM_POST_REFLOW);
mStart.SetOriginalOffset(trimmed.mStart);
mLength = trimmed.mLength;
SetupJustificationSpacing(true);
}
void
PropertyProvider::InitializeForMeasure()
{
nsTextFrame::TrimmedOffsets trimmed =
- mFrame->GetTrimmedOffsets(mFrag, true, false);
+ mFrame->GetTrimmedOffsets(mFrag, nsTextFrame::TRIM_BEFORE |
+ nsTextFrame::TRIM_AFTER);
mStart.SetOriginalOffset(trimmed.mStart);
mLength = trimmed.mLength;
SetupJustificationSpacing(false);
}
static uint32_t GetSkippedDistance(const gfxSkipCharsIterator& aStart,
const gfxSkipCharsIterator& aEnd)
@@ -3511,17 +3515,19 @@ PropertyProvider::SetupJustificationSpac
if (!(mFrame->GetStateBits() & TEXT_JUSTIFICATION_ENABLED))
return;
gfxSkipCharsIterator start(mStart), end(mStart);
// We can't just use our mLength here; when InitializeForDisplay is
// called with false for aTrimAfter, we still shouldn't be assigning
// justification space to any trailing whitespace.
nsTextFrame::TrimmedOffsets trimmed =
- mFrame->GetTrimmedOffsets(mFrag, true, aPostReflow);
+ mFrame->GetTrimmedOffsets(mFrag, nsTextFrame::TRIM_BEFORE |
+ nsTextFrame::TRIM_AFTER |
+ (aPostReflow ? nsTextFrame::TRIM_POST_REFLOW : 0));
end.AdvanceOriginal(trimmed.mLength);
gfxSkipCharsIterator realEnd(end);
ComputeJustification(start.GetOriginalOffset(),
end.GetOriginalOffset() - start.GetOriginalOffset());
auto assign = mFrame->GetJustificationAssignment();
mTotalJustificationGaps =
JustificationUtils::CountGaps(mJustificationInfo, assign);
@@ -7262,17 +7268,18 @@ nsIFrame::FrameSearchResult
nsTextFrame::PeekOffsetNoAmount(bool aForward, int32_t* aOffset)
{
NS_ASSERTION(aOffset && *aOffset <= GetContentLength(), "aOffset out of range");
gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
if (!mTextRun)
return CONTINUE_EMPTY;
- TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), true);
+ TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(),
+ TRIM_BEFORE | TRIM_AFTER | TRIM_POST_REFLOW);
// Check whether there are nonskipped characters in the trimmmed range
return (iter.ConvertOriginalToSkipped(trimmed.GetEnd()) >
iter.ConvertOriginalToSkipped(trimmed.mStart)) ? FOUND : CONTINUE;
}
/**
* This class iterates through the clusters before or after the given
* aPosition (which is a content offset). You can test each cluster
@@ -7364,17 +7371,18 @@ nsTextFrame::PeekOffsetCharacter(bool aF
IsSelectable(&selectable, &selectStyle);
if (selectStyle == NS_STYLE_USER_SELECT_ALL)
return CONTINUE_UNSELECTABLE;
gfxSkipCharsIterator iter = EnsureTextRun(nsTextFrame::eInflated);
if (!mTextRun)
return CONTINUE_EMPTY;
- TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(), false);
+ TrimmedOffsets trimmed = GetTrimmedOffsets(mContent->GetText(),
+ TRIM_BEFORE | TRIM_POST_REFLOW);
// A negative offset means "end of frame".
int32_t startOffset = GetContentOffset() + (*aOffset < 0 ? contentLength : *aOffset);
if (!aForward) {
// If at the beginning of the line, look at the previous continuation
for (int32_t i = std::min(trimmed.GetEnd(), startOffset) - 1;
i >= trimmed.mStart; --i) {
@@ -7499,17 +7507,18 @@ ClusterIterator::ClusterIterator(nsTextF
mIterator = aTextFrame->EnsureTextRun(nsTextFrame::eInflated);
if (!aTextFrame->GetTextRun(nsTextFrame::eInflated)) {
mDirection = 0; // signal failure
return;
}
mIterator.SetOriginalOffset(aPosition);
mFrag = aTextFrame->GetContent()->GetText();
- mTrimmed = aTextFrame->GetTrimmedOffsets(mFrag, true);
+ mTrimmed = aTextFrame->GetTrimmedOffsets(mFrag, nsTextFrame::TRIM_BEFORE |
+ nsTextFrame::TRIM_AFTER | nsTextFrame::TRIM_POST_REFLOW);
int32_t textOffset = aTextFrame->GetContentOffset();
int32_t textLen = aTextFrame->GetContentLength();
if (!mWordBreaks.AppendElements(textLen + 1)) {
mDirection = 0; // signal failure
return;
}
memset(mWordBreaks.Elements(), false, (textLen + 1)*sizeof(bool));
@@ -9071,17 +9080,18 @@ nsTextFrame::TrimTrailingWhiteSpace(Draw
gfxSkipCharsIterator start =
EnsureTextRun(nsTextFrame::eInflated, aDrawTarget);
NS_ENSURE_TRUE(mTextRun, result);
uint32_t trimmedStart = start.GetSkippedOffset();
const nsTextFragment* frag = mContent->GetText();
- TrimmedOffsets trimmed = GetTrimmedOffsets(frag, true);
+ TrimmedOffsets trimmed = GetTrimmedOffsets(frag,
+ TRIM_BEFORE | TRIM_AFTER | TRIM_POST_REFLOW);
gfxSkipCharsIterator trimmedEndIter = start;
const nsStyleText* textStyle = StyleText();
gfxFloat delta = 0;
uint32_t trimmedEnd = trimmedEndIter.ConvertOriginalToSkipped(trimmed.GetEnd());
if (!(GetStateBits() & TEXT_TRIMMED_TRAILING_WHITESPACE) &&
trimmed.GetEnd() < GetContentEnd()) {
gfxSkipCharsIterator end = trimmedEndIter;
@@ -9245,19 +9255,23 @@ nsTextFrame::GetRenderedText(uint32_t aS
gfxSkipCharsIterator iter =
textFrame->EnsureTextRun(nsTextFrame::eInflated);
if (!textFrame->mTextRun) {
break;
}
gfxSkipCharsIterator tmpIter = iter;
// Skip to the start of the text run, past ignored chars at start of line
- TrimmedOffsets trimmedOffsets = textFrame->GetTrimmedOffsets(textFrag,
- textFrame->IsAtEndOfLine() && LineEndsInHardLineBreak(textFrame) &&
- aTrimTrailingWhitespace == TrailingWhitespace::TRIM_TRAILING_WHITESPACE);
+ uint32_t flags = TRIM_BEFORE | TRIM_POST_REFLOW;
+ if (textFrame->IsAtEndOfLine() && LineEndsInHardLineBreak(textFrame) &&
+ aTrimTrailingWhitespace == TrailingWhitespace::TRIM_TRAILING_WHITESPACE) {
+ flags |= TRIM_AFTER;
+ }
+ TrimmedOffsets trimmedOffsets =
+ textFrame->GetTrimmedOffsets(textFrag, flags);
bool trimmedSignificantNewline =
trimmedOffsets.GetEnd() < GetContentEnd() &&
HasSignificantTerminalNewline();
uint32_t skippedToRenderedStringOffset = offsetInRenderedString -
tmpIter.ConvertOriginalToSkipped(trimmedOffsets.mStart);
uint32_t nextOffsetInRenderedString =
tmpIter.ConvertOriginalToSkipped(trimmedOffsets.GetEnd()) +
(trimmedSignificantNewline ? 1 : 0) + skippedToRenderedStringOffset;
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -535,18 +535,23 @@ public:
// Get the DOM content range mapped by this frame after excluding
// whitespace subject to start-of-line and end-of-line trimming.
// The textrun must have been created before calling this.
struct TrimmedOffsets {
int32_t mStart;
int32_t mLength;
int32_t GetEnd() const { return mStart + mLength; }
};
+ enum {
+ TRIM_BEFORE = 0x01,
+ TRIM_AFTER = 0x02,
+ TRIM_POST_REFLOW = 0x04
+ };
TrimmedOffsets GetTrimmedOffsets(const nsTextFragment* aFrag,
- bool aTrimAfter, bool aPostReflow = true);
+ uint32_t aFlags);
// Similar to Reflow(), but for use from nsLineLayout
void ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
DrawTarget* aDrawTarget,
nsHTMLReflowMetrics& aMetrics, nsReflowStatus& aStatus);
bool IsFloatingFirstLetterChild() const;
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -1066,17 +1066,19 @@ TextRenderedRun::GetClipEdges(nscoord& a
// Get the offset/length of the whole nsTextFrame.
frameOffset = mFrame->GetContentOffset();
frameLength = mFrame->GetContentLength();
// Trim the whole-nsTextFrame offset/length to remove any leading/trailing
// white space, as the nsTextFrame when painting does not include them when
// interpreting clip edges.
nsTextFrame::TrimmedOffsets trimmedOffsets =
- mFrame->GetTrimmedOffsets(mFrame->GetContent()->GetText(), true);
+ mFrame->GetTrimmedOffsets(mFrame->GetContent()->GetText(),
+ nsTextFrame::TRIM_BEFORE | nsTextFrame::TRIM_AFTER |
+ nsTextFrame::TRIM_POST_REFLOW);
TrimOffsets(frameOffset, frameLength, trimmedOffsets);
// Convert the trimmed whole-nsTextFrame offset/length into skipped
// characters.
ConvertOriginalToSkipped(it, frameOffset, frameLength);
// Measure the advance width in the text run between the start of
// frame's content and the start of the rendered run's content,
@@ -2054,17 +2056,19 @@ TextRenderedRunIterator::Next()
frame->GetTextRun(nsTextFrame::eInflated),
mFrameIterator.DominantBaseline(),
mFontSizeScaleFactor);
// Trim the offset/length to remove any leading/trailing white space.
uint32_t untrimmedOffset = offset;
uint32_t untrimmedLength = length;
nsTextFrame::TrimmedOffsets trimmedOffsets =
- frame->GetTrimmedOffsets(frame->GetContent()->GetText(), true);
+ frame->GetTrimmedOffsets(frame->GetContent()->GetText(),
+ nsTextFrame::TRIM_BEFORE | nsTextFrame::TRIM_AFTER |
+ nsTextFrame::TRIM_POST_REFLOW);
TrimOffsets(offset, length, trimmedOffsets);
charIndex += offset - untrimmedOffset;
// Get the position and rotation of the character that begins this
// rendered run.
pt = Root()->mPositions[charIndex].mPosition;
rotate = Root()->mPositions[charIndex].mAngle;
@@ -2571,17 +2575,19 @@ CharIterator::IsOriginalCharTrimmed() co
if (mFrameForTrimCheck != TextFrame()) {
// Since we do a lot of trim checking, we cache the trimmed offsets and
// lengths while we are in the same frame.
mFrameForTrimCheck = TextFrame();
uint32_t offset = mFrameForTrimCheck->GetContentOffset();
uint32_t length = mFrameForTrimCheck->GetContentLength();
nsIContent* content = mFrameForTrimCheck->GetContent();
nsTextFrame::TrimmedOffsets trim =
- mFrameForTrimCheck->GetTrimmedOffsets(content->GetText(), true);
+ mFrameForTrimCheck->GetTrimmedOffsets(content->GetText(),
+ nsTextFrame::TRIM_BEFORE | nsTextFrame::TRIM_AFTER |
+ nsTextFrame::TRIM_POST_REFLOW);
TrimOffsets(offset, length, trim);
mTrimmedOffset = offset;
mTrimmedLength = length;
}
// A character is trimmed if it is outside the mTrimmedOffset/mTrimmedLength
// range and it is not a significant newline character.
uint32_t index = mSkipCharsIterator.GetOriginalOffset();
@@ -4704,17 +4710,19 @@ SVGTextFrame::DetermineCharPositions(nsT
// Any characters not in a frame, e.g. when display:none.
for (uint32_t i = 0; i < frit.UndisplayedCharacters(); i++) {
aPositions.AppendElement(position);
}
// Any white space characters trimmed at the start of the line of text.
nsTextFrame::TrimmedOffsets trimmedOffsets =
- frame->GetTrimmedOffsets(frame->GetContent()->GetText(), true);
+ frame->GetTrimmedOffsets(frame->GetContent()->GetText(),
+ nsTextFrame::TRIM_BEFORE | nsTextFrame::TRIM_AFTER |
+ nsTextFrame::TRIM_POST_REFLOW);
while (it.GetOriginalOffset() < trimmedOffsets.mStart) {
aPositions.AppendElement(position);
it.AdvanceOriginal(1);
}
// If a ligature was started in the previous frame, we should record
// the ligature's start position, not any partial position.
while (it.GetOriginalOffset() < frame->GetContentEnd() &&