From 84b62782fb7d9704b75036ff7da4f5836fe4b309 Mon Sep 17 00:00:00 2001 From: "kipp%netscape.com" Date: Fri, 11 Dec 1998 15:50:12 +0000 Subject: [PATCH] Changed breaking behavior so that empty frames don't trigger a break even if the horizontal space is already over committed --- layout/html/base/src/nsInlineReflow.cpp | 116 ++++++++---------------- layout/html/base/src/nsInlineReflow.h | 16 ---- 2 files changed, 40 insertions(+), 92 deletions(-) diff --git a/layout/html/base/src/nsInlineReflow.cpp b/layout/html/base/src/nsInlineReflow.cpp index 1fdc32f3c388..91453a0c1d88 100644 --- a/layout/html/base/src/nsInlineReflow.cpp +++ b/layout/html/base/src/nsInlineReflow.cpp @@ -201,32 +201,6 @@ nsInlineReflow::GetSpacing() return mSpacing; } -// XXX use frameType instead after constructing a reflow state -PRBool -nsInlineReflow::TreatFrameAsBlockFrame() -{ - const nsStyleDisplay* display = GetDisplay(); - const nsStylePosition* position = GetPosition(); - - if (NS_STYLE_POSITION_ABSOLUTE == position->mPosition) { - return PR_FALSE; - } - if (NS_STYLE_FLOAT_NONE != display->mFloats) { - return PR_FALSE; - } - switch (display->mDisplay) { - case NS_STYLE_DISPLAY_BLOCK: - case NS_STYLE_DISPLAY_LIST_ITEM: - case NS_STYLE_DISPLAY_COMPACT: - case NS_STYLE_DISPLAY_RUN_IN: - case NS_STYLE_DISPLAY_TABLE: - return PR_TRUE; - default: - break; - } - return PR_FALSE; -} - nsresult nsInlineReflow::SetFrame(nsIFrame* aFrame) { @@ -274,7 +248,9 @@ nsInlineReflow::ReflowFrame(nsIFrame* aFrame, nsReflowStatus& aReflowStatus) // Next figure out how much available space there is for the frame. // Calculate raw margin values. - CalculateMargins(); + PerFrameData* pfd = mFrameData; + nsHTMLReflowState::ComputeMarginFor(pfd->mFrame, &mOuterReflowState, + pfd->mMargin); // Apply top+left margins (as appropriate) to the frame computing // the new starting x,y coordinates for the frame. @@ -302,51 +278,6 @@ nsInlineReflow::ReflowFrame(nsIFrame* aFrame, nsReflowStatus& aReflowStatus) return rv; } -void -nsInlineReflow::CalculateMargins() -{ - // Get the margins from the style system - PerFrameData* pfd = mFrameData; - nsHTMLReflowState::ComputeMarginFor(pfd->mFrame, &mOuterReflowState, - pfd->mMargin); -} - -PRUintn -nsInlineReflow::CalculateBlockMarginsFor(nsIPresContext& aPresContext, - nsIFrame* aFrame, - const nsHTMLReflowState* aParentRS, - const nsStyleSpacing* aSpacing, - nsMargin& aMargin) -{ - PRUint32 rv = 0; - - nsHTMLReflowState::ComputeMarginFor(aFrame, aParentRS, aMargin); - - // Get font height if we will be doing an auto margin. We use the - // default font height for the auto margin value. - nsStyleUnit topUnit = aSpacing->mMargin.GetTopUnit(); - nsStyleUnit bottomUnit = aSpacing->mMargin.GetBottomUnit(); - nscoord fontHeight = 0; - if ((eStyleUnit_Auto == topUnit) || (eStyleUnit_Auto == bottomUnit)) { - // XXX Use the font for the frame, not the default font??? - const nsFont& defaultFont = aPresContext.GetDefaultFont(); - nsIFontMetrics* fm = aPresContext.GetMetricsFor(defaultFont); - fm->GetHeight(fontHeight); - NS_RELEASE(fm); - } - - // For auto margins use the font height computed above - if (eStyleUnit_Auto == topUnit) { - aMargin.top = fontHeight; - rv |= NS_CARRIED_TOP_MARGIN_IS_AUTO; - } - if (eStyleUnit_Auto == bottomUnit) { - aMargin.bottom = fontHeight; - rv |= NS_CARRIED_BOTTOM_MARGIN_IS_AUTO; - } - return rv; -} - // XXX doesn't apply top margin void @@ -431,6 +362,7 @@ nsInlineReflow::ComputeAvailableSize() return PR_TRUE; } +#if XXX // Give up now if there is no chance. Note that we allow a reflow if // the available space is zero because that way things that end up // zero sized won't trigger a new line to be created. We also allow @@ -440,6 +372,7 @@ nsInlineReflow::ComputeAvailableSize() ((mFrameAvailSize.width < 0) || (mFrameAvailSize.height < 0))) { return PR_FALSE; } +#endif return PR_TRUE; } @@ -477,6 +410,11 @@ nsInlineReflow::ReflowFrame(nsHTMLReflowMetrics& aMetrics, reflowState.reason = reason; mLineLayout.SetUnderstandsWhiteSpace(PR_FALSE); + // Capture this state *before* we reflow the frame in case it clears + // the state out. We need to know how to treat the current frame + // when breaking. + mInWord = mLineLayout.InWord(); + // Let frame know that are reflowing it nscoord x = pfd->mBounds.x; nscoord y = pfd->mBounds.y; @@ -594,6 +532,32 @@ nsInlineReflow::CanPlaceFrame(nsHTMLReflowMetrics& aMetrics, } } + // Set outside to PR_TRUE if the result of the reflow leads to the + // frame sticking outside of our available area. + PRBool outside = pfd->mBounds.XMost() + mRightMargin > mRightEdge; + + // There are several special conditions that exist which allow us to + // ignore outside. If they are true then we can place frame and + // return PR_TRUE. + if (!mCanBreakBeforeFrame || mInWord || mOuterReflowState.mNoWrap) { + return PR_TRUE; + } + + if (0 == pfd->mMargin.left + pfd->mBounds.width + pfd->mMargin.right) { + // Empty frames always fit right where they are + return PR_TRUE; + } + + if (0 == mFrameNum) { + return PR_TRUE; + } + + if (outside) { + aStatus = NS_INLINE_LINE_BREAK_BEFORE(); + return PR_FALSE; + } + return PR_TRUE; +#if XXX // If this is the first frame going into this inline reflow or it's // the first placed frame in the line or wrapping is disabled then // the frame fits regardless of who much room there is. This @@ -604,8 +568,7 @@ nsInlineReflow::CanPlaceFrame(nsHTMLReflowMetrics& aMetrics, if ((0 == mFrameNum) || (0 == mLineLayout.GetPlacedFrames()) || mOuterReflowState.mNoWrap || - mInWord || - (0 == pfd->mMargin.left + pfd->mBounds.width + pfd->mMargin.right)) { + mInWord) { return PR_TRUE; } @@ -617,6 +580,7 @@ nsInlineReflow::CanPlaceFrame(nsHTMLReflowMetrics& aMetrics, } return PR_TRUE; +#endif } /** @@ -917,7 +881,7 @@ nsInlineReflow::VerticalAlignFrames(nsRect& aLineBox, } void -nsInlineReflow::HorizontalAlignFrames(nsRect& aLineBox, PRBool aIsLastLine) +nsInlineReflow::HorizontalAlignFrames(nsRect& aLineBox, PRBool aAllowJustify) { // Before we start, trim any trailing whitespace off of the last // frame in the line. @@ -959,7 +923,7 @@ nsInlineReflow::HorizontalAlignFrames(nsRect& aLineBox, PRBool aIsLastLine) // If this is not the last line then go ahead and justify the // frames in the line. If it is the last line then if the // direction is right-to-left then we right-align the frames. - if (!aIsLastLine) { + if (aAllowJustify) { JustifyFrames(maxWidth, aLineBox); return; } diff --git a/layout/html/base/src/nsInlineReflow.h b/layout/html/base/src/nsInlineReflow.h index 75e6af8ccd2d..670c8e0bb9db 100644 --- a/layout/html/base/src/nsInlineReflow.h +++ b/layout/html/base/src/nsInlineReflow.h @@ -85,18 +85,6 @@ public: return mRightEdge - mX; } - static PRUintn CalculateBlockMarginsFor(nsIPresContext& aPresContext, - nsIFrame* aFrame, - const nsHTMLReflowState* aParentRS, - const nsStyleSpacing* aSpacing, - nsMargin& aMargin); - -// Return value from CalculateBlockMarginsFor -#define NS_TOP_MARGIN_IS_AUTO 0x1 -#define NS_BOTTOM_MARGIN_IS_AUTO 0x2 - - static nscoord MaxMargin(nscoord a, nscoord b); - /** * Calculate the line-height value for a given frame. */ @@ -107,16 +95,12 @@ public: protected: nsresult SetFrame(nsIFrame* aFrame); - PRBool TreatFrameAsBlockFrame(); - const nsStyleDisplay* GetDisplay(); const nsStylePosition* GetPosition(); const nsStyleSpacing* GetSpacing(); - void CalculateMargins(); - void ApplyTopLeftMargins(); PRBool ComputeAvailableSize();