Skip to content

Commit

Permalink
r=troy; fixed bugs 2636 and 17636 - line layout issues for some more …
Browse files Browse the repository at this point in the history
…edge cases (nobr's with floaters in them) and handling of nbsp
  • Loading branch information
kipp%netscape.com committed Nov 2, 1999
1 parent 4f2e6f6 commit c93281e
Show file tree
Hide file tree
Showing 12 changed files with 164 additions and 14 deletions.
7 changes: 6 additions & 1 deletion layout/generic/nsBlockFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3822,7 +3822,12 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState,
if (gNoisyReflow) {
nsFrame::IndentBy(stdout, gNoiseIndent);
printf("split line: from line=%p pushCount=%d aFrame=", aLine, pushCount);
nsFrame::ListTag(stdout, aFrame);
if (aFrame) {
nsFrame::ListTag(stdout, aFrame);
}
else {
printf("(null)");
}
printf("\n");
if (gReallyNoisyReflow) {
aLine->List(aState.mPresContext, stdout, gNoiseIndent+1);
Expand Down
7 changes: 6 additions & 1 deletion layout/generic/nsBlockReflowState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3822,7 +3822,12 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState,
if (gNoisyReflow) {
nsFrame::IndentBy(stdout, gNoiseIndent);
printf("split line: from line=%p pushCount=%d aFrame=", aLine, pushCount);
nsFrame::ListTag(stdout, aFrame);
if (aFrame) {
nsFrame::ListTag(stdout, aFrame);
}
else {
printf("(null)");
}
printf("\n");
if (gReallyNoisyReflow) {
aLine->List(aState.mPresContext, stdout, gNoiseIndent+1);
Expand Down
7 changes: 6 additions & 1 deletion layout/generic/nsBlockReflowState.h
Original file line number Diff line number Diff line change
Expand Up @@ -3822,7 +3822,12 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState,
if (gNoisyReflow) {
nsFrame::IndentBy(stdout, gNoiseIndent);
printf("split line: from line=%p pushCount=%d aFrame=", aLine, pushCount);
nsFrame::ListTag(stdout, aFrame);
if (aFrame) {
nsFrame::ListTag(stdout, aFrame);
}
else {
printf("(null)");
}
printf("\n");
if (gReallyNoisyReflow) {
aLine->List(aState.mPresContext, stdout, gNoiseIndent+1);
Expand Down
51 changes: 47 additions & 4 deletions layout/generic/nsLineLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ nsLineLayout::nsLineLayout(nsIPresContext& aPresContext,
mColumn = 0;
mEndsInWhiteSpace = PR_TRUE;
mUnderstandsWhiteSpace = PR_FALSE;
mTextStartsWithNBSP = PR_FALSE;
mFirstLetterStyleOK = PR_FALSE;
mIsTopOfPage = PR_FALSE;
mUpdatedBand = PR_FALSE;
Expand Down Expand Up @@ -270,6 +271,7 @@ nsLineLayout::BeginLineReflow(nscoord aX, nscoord aY,
mColumn = 0;
mEndsInWhiteSpace = PR_TRUE;
mUnderstandsWhiteSpace = PR_FALSE;
mTextStartsWithNBSP = PR_FALSE;
mFirstLetterStyleOK = PR_FALSE;
mIsTopOfPage = aIsTopOfPage;
mUpdatedBand = PR_FALSE;
Expand Down Expand Up @@ -411,6 +413,7 @@ nsLineLayout::UpdateBand(nscoord aX, nscoord aY,
mLastFloaterWasLetterFrame = nsLayoutAtoms::letterFrame == frameType.get();

// Now update all of the open spans...
mRootSpan->mContainsFloater = PR_TRUE; // make sure mRootSpan gets updated too
psd = mCurrentSpan;
while (psd != mRootSpan) {
NS_ASSERTION(nsnull != psd, "null ptr");
Expand All @@ -424,6 +427,7 @@ nsLineLayout::UpdateBand(nscoord aX, nscoord aY,
else {
psd->mRightEdge += deltaWidth;
}
psd->mContainsFloater = PR_TRUE;
#ifdef NOISY_REFLOW
printf(" span %p: oldRightEdge=%d newRightEdge=%d\n",
psd, psd->mRightEdge - deltaWidth, psd->mRightEdge);
Expand Down Expand Up @@ -479,6 +483,8 @@ nsLineLayout::NewPerSpanData(PerSpanData** aResult)
psd->mFrame = nsnull;
psd->mFirstFrame = nsnull;
psd->mLastFrame = nsnull;
psd->mContainsFloater = PR_FALSE;
psd->mZeroEffectiveSpanBox = PR_FALSE;

#ifdef DEBUG
mSpansAllocated++;
Expand Down Expand Up @@ -514,7 +520,6 @@ nsLineLayout::BeginSpan(nsIFrame* aFrame,
psd->mLeftEdge = aLeftEdge;
psd->mX = aLeftEdge;
psd->mRightEdge = aRightEdge;
psd->mZeroEffectiveSpanBox = PR_FALSE;

const nsStyleText* styleText;
aSpanReflowState->frame->GetStyleData(eStyleStruct_Text,
Expand Down Expand Up @@ -879,6 +884,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
reflowState.mLineLayout = this;
reflowState.isTopOfPage = mIsTopOfPage;
mUnderstandsWhiteSpace = PR_FALSE;
mTextStartsWithNBSP = PR_FALSE;

// Stash copies of some of the computed state away for later
// (vertical alignment, for example)
Expand Down Expand Up @@ -1095,8 +1101,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,

// See if we can place the frame. If we can't fit it, then we
// return now.
if (CanPlaceFrame(pfd, reflowState, notSafeToBreak, metrics,
aReflowStatus)) {
if (CanPlaceFrame(pfd, reflowState, notSafeToBreak, metrics, aReflowStatus)) {
// Place the frame, updating aBounds with the final size and
// location. Then apply the bottom+right margins (as
// appropriate) to the frame.
Expand All @@ -1116,6 +1121,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
else {
PushFrame(aFrame);
}
mTextStartsWithNBSP = PR_FALSE; // reset for next time

#ifdef REALLY_NOISY_REFLOW
nsFrame::IndentBy(stdout, mSpanDepth);
Expand Down Expand Up @@ -1234,7 +1240,7 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd,

PerSpanData* psd = mCurrentSpan;
if (psd->mNoWrap) {
// When wrapping is off, everything fits
// When wrapping is off, everything fits.
return PR_TRUE;
}

Expand Down Expand Up @@ -1345,6 +1351,43 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd,
}
}

// Special check for span frames
if (pfd->mSpan && pfd->mSpan->mContainsFloater) {
// If the span either directly or indirectly contains a floater then
// it fits. Why? It's kind of complicated, but here goes:
//
// 1. CanPlaceFrame is used for all frame placements on a line,
// and in a span. This includes recursively placement of frames
// inside of spans, and the span itself. Because the logic always
// checks for room before proceeding (the code above here), the
// only things on a line will be those things that "fit".
//
// 2. Before a floater is placed on a line, the line has to be empty
// (otherwise its a "below current line" flaoter and will be placed
// after the line).
//
// Therefore, if the span directly or indirectly has a floater
// then it means that at the time of the placement of the floater
// the line was empty. Because of #1, only the frames that fit can
// be added after that point, therefore we can assume that the
// current span being placed has fit.
//
// So how do we get here and have a span that should already fit
// and yet doesn't: Simple: span's that have the no-wrap attribute
// set on them and contain a floater and are placed where they
// don't naturally fit.
return PR_TRUE;
}

// Yet another special check. If the text happens to have started
// with a non-breaking space, then we make it sticky on its left
// edge...Which means that whatever piece of text we just formatted
// will be the piece that fits (the text frame logic knows to stop
// when it runs out of room).
if (pfd->mIsNonEmptyTextFrame && mTextStartsWithNBSP) {
return PR_TRUE;
}

#ifdef NOISY_CAN_PLACE_FRAME
printf(" ==> didn't fit\n");
#endif
Expand Down
6 changes: 6 additions & 0 deletions layout/generic/nsLineLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ class nsLineLayout {
mUnderstandsWhiteSpace = aSetting;
}

void SetTextStartsWithNBSP(PRBool aYes) {
mTextStartsWithNBSP = aYes;
}

void RecordWordFrame(nsIFrame* aWordFrame) {
mWordFrames.AppendElement(aWordFrame);
}
Expand Down Expand Up @@ -222,6 +226,7 @@ class nsLineLayout {
PRInt32 mColumn;
PRBool mEndsInWhiteSpace;
PRBool mUnderstandsWhiteSpace;
PRBool mTextStartsWithNBSP;
PRBool mFirstLetterStyleOK;
PRBool mIsTopOfPage;
PRBool mUpdatedBand;
Expand Down Expand Up @@ -317,6 +322,7 @@ class nsLineLayout {
PRUint8 mDirection;
PRBool mChangedFrameDirection;
PRBool mZeroEffectiveSpanBox;
PRBool mContainsFloater;

nscoord mLeftEdge;
nscoord mX;
Expand Down
11 changes: 11 additions & 0 deletions layout/generic/nsTextFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2818,6 +2818,8 @@ nsTextFrame::Reflow(nsIPresContext& aPresContext,
}
}

PRBool firstThing = PR_TRUE;
PRBool textStartsWithNBSP = PR_FALSE;
for (;;) {
// Get next word/whitespace from the text
PRBool isWhitespace;
Expand Down Expand Up @@ -2886,8 +2888,16 @@ nsTextFrame::Reflow(nsIPresContext& aPresContext,
}
lastWordWidth = width;
}

// See if the first thing in the section of text is a
// non-breaking space (html nbsp entity). If it is then make
// note of that fact for the line layout logic.
if (wrapping && firstThing && (bp[0] == ' ')) {
textStartsWithNBSP = PR_TRUE;
}
skipWhitespace = PR_FALSE;
}
firstThing = PR_FALSE;

// See if there is room for the text
if (measureText) {
Expand Down Expand Up @@ -3050,6 +3060,7 @@ nsTextFrame::Reflow(nsIPresContext& aPresContext,
// text object collapsed into nothingness which means it shouldn't
// effect the current setting of the ends-in-whitespace flag.
lineLayout.SetUnderstandsWhiteSpace(PR_TRUE);
lineLayout.SetTextStartsWithNBSP(textStartsWithNBSP);
if (0 != x) {
lineLayout.SetEndsInWhiteSpace(endsInWhitespace);
}
Expand Down
7 changes: 6 additions & 1 deletion layout/html/base/src/nsBlockFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3822,7 +3822,12 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState,
if (gNoisyReflow) {
nsFrame::IndentBy(stdout, gNoiseIndent);
printf("split line: from line=%p pushCount=%d aFrame=", aLine, pushCount);
nsFrame::ListTag(stdout, aFrame);
if (aFrame) {
nsFrame::ListTag(stdout, aFrame);
}
else {
printf("(null)");
}
printf("\n");
if (gReallyNoisyReflow) {
aLine->List(aState.mPresContext, stdout, gNoiseIndent+1);
Expand Down
7 changes: 6 additions & 1 deletion layout/html/base/src/nsBlockReflowState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3822,7 +3822,12 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState,
if (gNoisyReflow) {
nsFrame::IndentBy(stdout, gNoiseIndent);
printf("split line: from line=%p pushCount=%d aFrame=", aLine, pushCount);
nsFrame::ListTag(stdout, aFrame);
if (aFrame) {
nsFrame::ListTag(stdout, aFrame);
}
else {
printf("(null)");
}
printf("\n");
if (gReallyNoisyReflow) {
aLine->List(aState.mPresContext, stdout, gNoiseIndent+1);
Expand Down
7 changes: 6 additions & 1 deletion layout/html/base/src/nsBlockReflowState.h
Original file line number Diff line number Diff line change
Expand Up @@ -3822,7 +3822,12 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState,
if (gNoisyReflow) {
nsFrame::IndentBy(stdout, gNoiseIndent);
printf("split line: from line=%p pushCount=%d aFrame=", aLine, pushCount);
nsFrame::ListTag(stdout, aFrame);
if (aFrame) {
nsFrame::ListTag(stdout, aFrame);
}
else {
printf("(null)");
}
printf("\n");
if (gReallyNoisyReflow) {
aLine->List(aState.mPresContext, stdout, gNoiseIndent+1);
Expand Down
Loading

0 comments on commit c93281e

Please sign in to comment.