Bug 775624 Part 12 - Add bit-fields for inline break status, and convert NS_INLINE_LINE_BREAK_BEFORE. r?dholbert
NS_INLINE_LINE_BREAK_BEFORE() was replaced by the help of the following script.
function rename() {
find layout\
-type f\
\( -name "*.cpp" -or\
-name "*.h" \)\
-exec sed -i -r "s/$1/$2/g" "{}" \;
}
rename " = NS_INLINE_LINE_BREAK_BEFORE\(\);" ".SetInlineLineBreakBeforeAndReset();"
MozReview-Commit-ID: mz6L8zay7q
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -3401,17 +3401,17 @@ nsBlockFrame::ReflowBlockFrame(BlockRefl
// Doing this means that we also don't need to worry about the
// |availSpace.BSize(wm) += bStartMargin| below interacting with
// pushed floats (which force nscoord_MAX clearance) to cause a
// constrained block size to turn into an unconstrained one.
aState.mBCoord = startingBCoord;
aState.mPrevBEndMargin = incomingMargin;
*aKeepReflowGoing = false;
if (ShouldAvoidBreakInside(aState.mReflowInput)) {
- aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aState.mReflowStatus.SetInlineLineBreakBeforeAndReset();
} else {
PushLines(aState, aLine.prev());
aState.mReflowStatus.SetIncomplete();
}
return;
}
// Now put the block-dir coordinate back to the start of the
@@ -3578,17 +3578,17 @@ nsBlockFrame::ReflowBlockFrame(BlockRefl
#if defined(REFLOW_STATUS_COVERAGE)
RecordReflowStatus(true, frameReflowStatus);
#endif
if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) {
// None of the child block fits.
*aKeepReflowGoing = false;
if (ShouldAvoidBreakInside(aState.mReflowInput)) {
- aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aState.mReflowStatus.SetInlineLineBreakBeforeAndReset();
} else {
PushLines(aState, aLine.prev());
aState.mReflowStatus.SetIncomplete();
}
}
else {
// Note: line-break-after a block is a nop
@@ -3752,17 +3752,17 @@ nsBlockFrame::ReflowBlockFrame(BlockRefl
aState.mPrevBEndMargin.get());
#endif
} else {
if ((aLine == mLines.front() && !GetPrevInFlow()) ||
ShouldAvoidBreakInside(aState.mReflowInput)) {
// If it's our very first line *or* we're not at the top of the page
// and we have page-break-inside:avoid, then we need to be pushed to
// our parent's next-in-flow.
- aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aState.mReflowStatus.SetInlineLineBreakBeforeAndReset();
} else {
// Push the line that didn't fit and any lines that follow it
// to our next-in-flow.
PushLines(aState, aLine.prev());
aState.mReflowStatus.SetIncomplete();
}
}
}
@@ -4639,28 +4639,28 @@ nsBlockFrame::PlaceLine(BlockReflowInput
nscoord dy = aState.mFlags.mShouldApplyBStartMargin
? -aState.mPrevBEndMargin.get() : 0;
newBCoord = aState.mBCoord + dy;
}
if (!aState.mReflowStatus.IsFullyComplete() &&
ShouldAvoidBreakInside(aState.mReflowInput)) {
aLine->AppendFloats(aState.mCurrentLineFloats);
- aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aState.mReflowStatus.SetInlineLineBreakBeforeAndReset();
return true;
}
// See if the line fit (our first line always does).
if (mLines.front() != aLine &&
newBCoord > aState.mBEndEdge &&
aState.mBEndEdge != NS_UNCONSTRAINEDSIZE) {
NS_ASSERTION(aState.mCurrentLine == aLine, "oops");
if (ShouldAvoidBreakInside(aState.mReflowInput)) {
// All our content doesn't fit, start on the next page.
- aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aState.mReflowStatus.SetInlineLineBreakBeforeAndReset();
} else {
// Push aLine and all of its children and anything else that
// follows to our next-in-flow.
PushTruncatedLine(aState, aLine, aKeepReflowGoing);
}
return true;
}
@@ -6272,17 +6272,17 @@ nsBlockFrame::ReflowFloat(BlockReflowInp
brc.ReflowBlock(aAdjustedAvailableSpace, true, margin,
0, isAdjacentWithTop,
nullptr, floatRS,
aReflowStatus, aState);
} while (clearanceFrame);
if (!aReflowStatus.IsFullyComplete() &&
ShouldAvoidBreakInside(floatRS)) {
- aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aReflowStatus.SetInlineLineBreakBeforeAndReset();
} else if (aReflowStatus.IsIncomplete() &&
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.BSize(wm))) {
// An incomplete reflow status means we should split the float
// if the height is constrained (bug 145305).
aReflowStatus = NS_FRAME_COMPLETE;
}
if (aReflowStatus.NextInFlowNeedsReflow()) {
@@ -7418,17 +7418,17 @@ nsBlockFrame::ComputeFinalBSize(const Re
aStatus->SetOverflowIncomplete();
}
if (aStatus->IsComplete()) {
if (computedBSizeLeftOver > 0 &&
NS_UNCONSTRAINEDSIZE != aReflowInput.AvailableBSize() &&
aFinalSize.BSize(wm) > aReflowInput.AvailableBSize()) {
if (ShouldAvoidBreakInside(aReflowInput)) {
- *aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus->SetInlineLineBreakBeforeAndReset();
return;
}
// We don't fit and we consumed some of the computed height,
// so we should consume all the available height and then
// break. If our bottom border/padding straddles the break
// point, then this will increase our height and push the
// border/padding to the next page/column.
aFinalSize.BSize(wm) = std::max(aReflowInput.AvailableBSize(),
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -5383,17 +5383,17 @@ nsGridContainerFrame::ReflowInFragmentai
if (itemStartRow == endRow) {
break;
}
auto disp = info->mFrame->StyleDisplay();
if (disp->mBreakBefore) {
// Propagate break-before on the first row to the container unless we're
// already at top-of-page.
if ((itemStartRow == 0 && !isTopOfPage) || avoidBreakInside) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
return aState.mFragBStart;
}
if ((itemStartRow > startRow ||
(itemStartRow == startRow && !isTopOfPage)) &&
itemStartRow < endRow) {
endRow = itemStartRow;
isForcedBreak = true;
// reset any BREAK_AFTER we found on an earlier item
@@ -5422,17 +5422,17 @@ nsGridContainerFrame::ReflowInFragmentai
// Except for the first row if there's a break opportunity before it.
if (startRow == endRow && startRow != numRows &&
(startRow != 0 || !aFragmentainer.mCanBreakAtStart)) {
++endRow;
}
// Honor break-inside:avoid if we can't fit all rows.
if (avoidBreakInside && endRow < numRows) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
return aState.mFragBStart;
}
// Calculate the block-size including this fragment.
nscoord bEndRow =
aState.mRows.GridLineEdge(endRow, GridLineSide::eBeforeGridGap);
nscoord bSize;
if (aFragmentainer.mIsAutoBSize) {
@@ -5458,17 +5458,17 @@ nsGridContainerFrame::ReflowInFragmentai
aState.mReflowInput->ComputedMinBSize(),
aState.mReflowInput->ComputedMaxBSize());
}
// Check for overflow and set aStatus INCOMPLETE if so.
bool overflow = bSize + bpBEnd > childAvailableSize;
if (overflow) {
if (avoidBreakInside) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
return aState.mFragBStart;
}
bool breakAfterLastRow = endRow == numRows && aFragmentainer.mCanBreakAtEnd;
if (breakAfterLastRow) {
MOZ_ASSERT(bEndRow < bSize, "bogus aFragmentainer.mCanBreakAtEnd");
nscoord availableSize = childAvailableSize;
if (isBDBClone) {
availableSize -= bpBEnd;
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -192,31 +192,39 @@ enum nsSpread {
// Carried out margin flags
#define NS_CARRIED_TOP_MARGIN_IS_AUTO 0x1
#define NS_CARRIED_BOTTOM_MARGIN_IS_AUTO 0x2
//----------------------------------------------------------------------
// Reflow status returned by the Reflow() methods.
class nsReflowStatus final {
+ using StyleClear = mozilla::StyleClear;
+
public:
nsReflowStatus()
: mStatus(0)
+ , mBreakType(StyleClear::None)
, mIncomplete(false)
, mOverflowIncomplete(false)
, mNextInFlowNeedsReflow(false)
, mTruncated(false)
+ , mInlineBreak(false)
+ , mInlineBreakAfter(false)
{}
// Reset all the bit-fields.
void Reset() {
+ mBreakType = StyleClear::None;
mIncomplete = false;
mOverflowIncomplete = false;
mNextInFlowNeedsReflow = false;
mTruncated = false;
+ mInlineBreak = false;
+ mInlineBreakAfter = false;
}
nsReflowStatus(uint32_t aStatus)
: mStatus(aStatus)
{}
uint32_t& operator=(uint32_t aRhs) {
mStatus = aRhs;
@@ -304,38 +312,53 @@ public:
mOverflowIncomplete |= aStatus.mOverflowIncomplete;
mNextInFlowNeedsReflow |= aStatus.mNextInFlowNeedsReflow;
mTruncated |= aStatus.mTruncated;
if (mIncomplete) {
mOverflowIncomplete = false;
}
}
+ // mInlineBreak bit flag means a break is requested.
+
+ // Suppose a break is requested. When mInlineBreakAfter is set, the break
+ // should occur after the frame just reflowed; when mInlineBreakAfter is
+ // clear, the break should occur before the frame just reflowed.
+
+ // Set the inline line-break-before status, and reset other bit flags. The
+ // break type is StyleClear::Line. Note that other frame completion status
+ // isn't expected to matter after calling this method.
+ void SetInlineLineBreakBeforeAndReset() {
+ Reset();
+ mBreakType = StyleClear::Line;
+ mInlineBreak = true;
+ mInlineBreakAfter = false;
+ }
+
private:
uint32_t mStatus;
+ StyleClear mBreakType;
+
// Frame completion status bit flags.
bool mIncomplete : 1;
bool mOverflowIncomplete : 1;
bool mNextInFlowNeedsReflow : 1;
bool mTruncated : 1;
+
+ // Inline break status bit flags.
+ bool mInlineBreak : 1;
+ bool mInlineBreakAfter : 1;
};
#define NS_FRAME_COMPLETE 0 // Note: not a bit!
#define NS_FRAME_NOT_COMPLETE 0x1
#define NS_FRAME_OVERFLOW_INCOMPLETE 0x4
-// This bit is set, when a break is requested. This bit is orthogonal
-// to the nsIFrame::nsReflowStatus completion bits.
#define NS_INLINE_BREAK 0x0100
-
-// When a break is requested, this bit when set indicates that the
-// break should occur after the frame just reflowed; when the bit is
-// clear the break should occur before the frame just reflowed.
-#define NS_INLINE_BREAK_BEFORE 0x0000
#define NS_INLINE_BREAK_AFTER 0x0200
// The type of break requested can be found in these bits.
#define NS_INLINE_BREAK_TYPE_MASK 0xF000
// Set when a break was induced by completion of a first-letter
#define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000
@@ -351,24 +374,16 @@ private:
#define NS_INLINE_IS_BREAK_BEFORE(_status) \
(NS_INLINE_BREAK == ((_status) & (NS_INLINE_BREAK|NS_INLINE_BREAK_AFTER)))
#define NS_INLINE_GET_BREAK_TYPE(_status) \
(static_cast<StyleClear>(((_status) >> 12) & 0xF))
#define NS_INLINE_MAKE_BREAK_TYPE(_type) (static_cast<int>(_type) << 12)
-// Construct a line-break-before status. Note that there is no
-// completion status for a line-break before because we *know* that
-// the frame will be reflowed later and hence its current completion
-// status doesn't matter.
-#define NS_INLINE_LINE_BREAK_BEFORE() \
- (NS_INLINE_BREAK | NS_INLINE_BREAK_BEFORE | \
- NS_INLINE_MAKE_BREAK_TYPE(StyleClear::Line))
-
// Take a completion status and add to it the desire to have a
// line-break after. For this macro we do need the completion status
// because the user of the status will need to know whether to
// continue the frame or not.
#define NS_INLINE_LINE_BREAK_AFTER(_completionStatus) \
((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \
NS_INLINE_MAKE_BREAK_TYPE(StyleClear::Line))
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -1413,17 +1413,17 @@ nsLineLayout::CanPlaceFrame(PerFrameData
// We will want to try backup.
mNeedBackup = true;
return true;
}
#ifdef NOISY_CAN_PLACE_FRAME
printf(" ==> didn't fit\n");
#endif
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
return false;
}
/**
* Place the frame. Update running counters.
*/
void
nsLineLayout::PlaceFrame(PerFrameData* pfd, ReflowOutput& aMetrics)
--- a/layout/generic/nsRubyBaseContainerFrame.cpp
+++ b/layout/generic/nsRubyBaseContainerFrame.cpp
@@ -509,27 +509,27 @@ nsRubyBaseContainerFrame::ReflowColumns(
}
}
if (!e.AtEnd() && NS_INLINE_IS_BREAK_AFTER(reflowStatus)) {
// The current column has been successfully placed.
// Skip to the next column and mark break before.
e.Next();
e.GetColumn(column);
- reflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ reflowStatus.SetInlineLineBreakBeforeAndReset();
}
if (!e.AtEnd() || (GetNextInFlow() && !isComplete)) {
aStatus.SetIncomplete();
}
if (NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) {
if (!columnIndex || !aReflowInput.mAllowLineBreak) {
// If no column has been placed yet, or we have any span,
// the whole container should be in the next line.
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
return 0;
}
aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus);
MOZ_ASSERT(aStatus.IsComplete() || aReflowInput.mAllowLineBreak);
// If we are on an intra-level whitespace column, null values in
// column.mBaseFrame and column.mTextFrames don't represent the
// end of the frame-sibling-chain at that level -- instead, they
@@ -593,17 +593,17 @@ nsRubyBaseContainerFrame::ReflowOneColum
gfxBreakPriority lastBreakPriority =
baseReflowInput.mLineLayout->LastOptionalBreakPriority();
if (breakPriority >= lastBreakPriority) {
// Either we have been overflow, or we are forced
// to break here, do break before.
if (istart > baseReflowInput.AvailableISize() ||
baseReflowInput.mLineLayout->NotifyOptionalBreakPosition(
aColumn.mBaseFrame, 0, true, breakPriority)) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
return 0;
}
}
}
}
}
const uint32_t rtcCount = aReflowInput.mTextContainers.Length();
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -9545,17 +9545,17 @@ nsTextFrame::ReflowText(nsLineLayout& aL
}
// Compute reflow status
aStatus = contentLength == maxContentLength
? NS_FRAME_COMPLETE : NS_FRAME_NOT_COMPLETE;
if (charsFit == 0 && length > 0 && !usedHyphenation) {
// Couldn't place any text
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
} else if (contentLength > 0 && mContentOffset + contentLength - 1 == newLineOffset) {
// Ends in \n
aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus);
aLineLayout.SetLineEndsInBR(true);
} else if (breakAfter) {
aStatus = NS_INLINE_LINE_BREAK_AFTER(aStatus);
}
if (completedFirstLetter) {
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -3160,28 +3160,28 @@ nsTableFrame::ReflowChildren(TableReflow
childX = rowGroups.IndexOf(kidFrame);
if (childX == RowGroupArray::NoIndex) {
// XXXbz can this happen?
childX = rowGroups.Length();
}
}
if (isPaginated && !aStatus.IsFullyComplete() &&
ShouldAvoidBreakInside(aReflowInput.reflowInput)) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
break;
}
// see if the rowgroup did not fit on this page might be pushed on
// the next page
if (isPaginated &&
(NS_INLINE_IS_BREAK_BEFORE(aStatus) ||
(aStatus.IsComplete() &&
(NS_UNCONSTRAINEDSIZE != kidReflowInput.AvailableHeight()) &&
kidReflowInput.AvailableHeight() < desiredSize.Height()))) {
if (ShouldAvoidBreakInside(aReflowInput.reflowInput)) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
break;
}
// if we are on top of the page place with dataloss
if (kidReflowInput.mFlags.mIsTopOfPage) {
if (childX+1 < rowGroups.Length()) {
nsIFrame* nextRowGroupFrame = rowGroups[childX + 1];
if (nextRowGroupFrame) {
PlaceChild(aReflowInput, kidFrame,
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -1115,17 +1115,17 @@ nsTableRowFrame::Reflow(nsPresContext*
// See if we have a cell with specified/pct bsize
InitHasCellWithStyleBSize(tableFrame);
ReflowChildren(aPresContext, aDesiredSize, aReflowInput, *tableFrame, aStatus);
if (aPresContext->IsPaginated() && !aStatus.IsFullyComplete() &&
ShouldAvoidBreakInside(aReflowInput)) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
}
// Just set our isize to what was available.
// The table will calculate the isize and not use our value.
aDesiredSize.ISize(wm) = aReflowInput.AvailableISize();
// If our parent is in initial reflow, it'll handle invalidating our
// entire overflow rect.
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1171,17 +1171,17 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
ReflowChild(rowFrame, aPresContext, rowMetrics, rowReflowInput,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
rowFrame->SetSize(nsSize(rowMetrics.Width(), rowMetrics.Height()));
rowFrame->DidReflow(aPresContext, nullptr, nsDidReflowStatus::FINISHED);
rowFrame->DidResize();
if (!aRowForcedPageBreak && !aStatus.IsFullyComplete() &&
ShouldAvoidBreakInside(aReflowInput)) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
break;
}
nsTableFrame::InvalidateTableFrame(rowFrame, oldRowRect,
oldRowVisualOverflow,
false);
if (aStatus.IsIncomplete()) {
@@ -1237,17 +1237,17 @@ nsTableRowGroupFrame::SplitRowGroup(nsPr
rowIsOnPage = false;
}
nsTableRowFrame* lastRowThisPage = rowFrame;
nscoord spanningRowBottom = availHeight;
if (!rowIsOnPage) {
NS_ASSERTION(!contRow, "We should not have created a continuation if none of this row fits");
if (!aRowForcedPageBreak && ShouldAvoidBreakInside(aReflowInput)) {
- aStatus = NS_INLINE_LINE_BREAK_BEFORE();
+ aStatus.SetInlineLineBreakBeforeAndReset();
break;
}
if (prevRowFrame) {
spanningRowBottom = prevRowFrame->GetNormalRect().YMost();
lastRowThisPage = prevRowFrame;
isTopOfPage = (lastRowThisPage == firstRowThisPage) && aReflowInput.mFlags.mIsTopOfPage;
aStatus = NS_FRAME_NOT_COMPLETE;
}