зеркало из https://github.com/mozilla/gecko-dev.git
bug 29595 (and others)
fixes layout of pages where a single line is impacted by 2 or more floaters r=troy
This commit is contained in:
Родитель
0a15601c9b
Коммит
1c6eca645a
|
@ -117,6 +117,7 @@ LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
|
|||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
|
||||
|
||||
// Alphabetical list of event handler names
|
||||
|
|
|
@ -72,6 +72,16 @@ typedef enum SelectionRegion{SELECTION_ANCHOR_REGION = 0,
|
|||
SELECTION_FOCUS_REGION,
|
||||
NUM_SELECTION_REGIONS} SelectionRegion;
|
||||
|
||||
// debug VerifyReflow flags
|
||||
#define VERIFY_REFLOW_ON 0x01
|
||||
#define VERIFY_REFLOW_NOISY 0x02
|
||||
#define VERIFY_REFLOW_ALL 0x04
|
||||
#define VERIFY_REFLOW_DUMP_COMMANDS 0x08
|
||||
#define VERIFY_REFLOW_NOISY_RC 0x10
|
||||
#define VERIFY_REFLOW_REALLY_NOISY_RC 0x20
|
||||
#define VERIFY_REFLOW_INCLUDE_SPACE_MANAGER 0x40
|
||||
#define VERIFY_REFLOW_DURING_RESIZE_REFLOW 0x80
|
||||
|
||||
|
||||
/**
|
||||
* Presentation shell interface. Presentation shells are the
|
||||
|
@ -416,6 +426,10 @@ public:
|
|||
*/
|
||||
static NS_LAYOUT void SetVerifyReflowEnable(PRBool aEnabled);
|
||||
|
||||
/**
|
||||
* Get the flags associated with the VerifyReflow debug tool
|
||||
*/
|
||||
static NS_LAYOUT PRInt32 GetVerifyReflowFlags();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -117,6 +117,7 @@ LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
|
|||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
|
||||
|
||||
// Alphabetical list of event handler names
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 3
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsISpaceManager.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include "nsIDOMSelection.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMNode.h"
|
||||
|
@ -573,15 +575,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrameManager* aFrameManager)
|
|||
* means that you cannot perform logging before then.
|
||||
*/
|
||||
static PRLogModuleInfo* gLogModule;
|
||||
|
||||
static PRUint32 gVerifyReflowFlags;
|
||||
|
||||
#define VERIFY_REFLOW_ON 0x01
|
||||
#define VERIFY_REFLOW_NOISY 0x02
|
||||
#define VERIFY_REFLOW_ALL 0x04
|
||||
#define VERIFY_REFLOW_DUMP_COMMANDS 0x08
|
||||
#define VERIFY_REFLOW_NOISY_RC 0x10
|
||||
#define VERIFY_REFLOW_REALLY_NOISY_RC 0x20
|
||||
#endif
|
||||
|
||||
static PRBool gVerifyReflowEnabled;
|
||||
|
@ -627,6 +621,12 @@ nsIPresShell::SetVerifyReflowEnable(PRBool aEnabled)
|
|||
gVerifyReflowEnabled = aEnabled;
|
||||
}
|
||||
|
||||
NS_LAYOUT PRInt32
|
||||
nsIPresShell::GetVerifyReflowFlags()
|
||||
{
|
||||
return gVerifyReflowFlags;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
NS_LAYOUT nsresult
|
||||
|
@ -1406,6 +1406,13 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
|||
#endif
|
||||
}
|
||||
ExitReflowLock(PR_TRUE);
|
||||
// if the proper flag is set, VerifyReflow now
|
||||
if (GetVerifyReflowEnable() && (VERIFY_REFLOW_DURING_RESIZE_REFLOW & gVerifyReflowFlags))
|
||||
{
|
||||
mInVerifyReflow = PR_TRUE;
|
||||
PRBool ok = VerifyIncrementalReflow();
|
||||
mInVerifyReflow = PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK; //XXX this needs to be real. MMP
|
||||
}
|
||||
|
@ -3231,6 +3238,8 @@ static PRBool
|
|||
CompareTrees(nsIPresContext* aFirstPresContext, nsIFrame* aFirstFrame,
|
||||
nsIPresContext* aSecondPresContext, nsIFrame* aSecondFrame)
|
||||
{
|
||||
if (!aFirstPresContext || !aFirstFrame || !aSecondPresContext || !aSecondFrame)
|
||||
return PR_TRUE;
|
||||
PRBool ok = PR_TRUE;
|
||||
nsIAtom* listName = nsnull;
|
||||
PRInt32 listIndex = 0;
|
||||
|
@ -3305,6 +3314,115 @@ CompareTrees(nsIPresContext* aFirstPresContext, nsIFrame* aFirstFrame,
|
|||
break;
|
||||
}
|
||||
|
||||
// verify that neither frame has a space manager,
|
||||
// or they both do and the space managers are equivalent
|
||||
nsCOMPtr<nsIFrameManager>fm1;
|
||||
nsCOMPtr<nsIPresShell> ps1;
|
||||
nsISpaceManager *sm1; // note, no ref counting here
|
||||
aFirstPresContext->GetShell(getter_AddRefs(ps1));
|
||||
NS_ASSERTION(ps1, "no pres shell for primary tree!");
|
||||
ps1->GetFrameManager(getter_AddRefs(fm1));
|
||||
NS_ASSERTION(fm1, "no frame manager for primary tree!");
|
||||
fm1->GetFrameProperty((nsIFrame*)k1, nsLayoutAtoms::spaceManagerProperty,
|
||||
0, (void **)&sm1);
|
||||
// look at the test frame
|
||||
nsCOMPtr<nsIFrameManager>fm2;
|
||||
nsCOMPtr<nsIPresShell> ps2;
|
||||
nsISpaceManager *sm2; // note, no ref counting here
|
||||
aSecondPresContext->GetShell(getter_AddRefs(ps2));
|
||||
NS_ASSERTION(ps2, "no pres shell for test tree!");
|
||||
ps2->GetFrameManager(getter_AddRefs(fm2));
|
||||
NS_ASSERTION(fm2, "no frame manager for test tree!");
|
||||
fm2->GetFrameProperty((nsIFrame*)k2, nsLayoutAtoms::spaceManagerProperty,
|
||||
0, (void **)&sm2);
|
||||
// now compare the space managers
|
||||
if (((nsnull == sm1) && (nsnull != sm2)) ||
|
||||
((nsnull != sm1) && (nsnull == sm2))) { // one is null, and the other is not
|
||||
ok = PR_FALSE;
|
||||
LogVerifyMessage(k1, k2, "space managers are not matched\n");
|
||||
}
|
||||
else if (sm1 && sm2) { // both are not null, compare them
|
||||
// first, compare yMost
|
||||
nscoord yMost1, yMost2;
|
||||
nsresult smresult = sm1->YMost(yMost1);
|
||||
if (NS_ERROR_ABORT != smresult)
|
||||
{
|
||||
NS_ASSERTION(NS_SUCCEEDED(smresult), "bad result");
|
||||
smresult = sm2->YMost(yMost2);
|
||||
NS_ASSERTION(NS_SUCCEEDED(smresult), "bad result");
|
||||
if (yMost1 != yMost2) {
|
||||
LogVerifyMessage(k1, k2, "yMost of space managers differs\n");
|
||||
}
|
||||
// now compare bands by sampling
|
||||
PRInt32 yIncrement = yMost1/100;
|
||||
if (0==yIncrement) {
|
||||
yIncrement = 1; // guarantee we make progress in the loop below
|
||||
}
|
||||
nscoord yOffset = 0;
|
||||
for ( ; ok && yOffset < yMost1; yOffset += yIncrement)
|
||||
{
|
||||
nscoord small=5, large=100;
|
||||
nsBandData band1, band2;
|
||||
nsBandTrapezoid trap1[20], trap2[20];
|
||||
band1.mSize = band2.mSize = 20;
|
||||
band1.mTrapezoids = trap1;
|
||||
band2.mTrapezoids = trap2;
|
||||
sm1->GetBandData(yOffset, nsSize(small,small), band1);
|
||||
sm2->GetBandData(yOffset, nsSize(small,small), band2);
|
||||
if (band1.mCount != band2.mCount)
|
||||
{ // count mismatch, stop comparing
|
||||
LogVerifyMessage(k1, k2, "band.mCount of space managers differs\n");
|
||||
printf("count1= %d, count2=%d, yOffset = %d, size=%d\n",
|
||||
band1.mCount, band2.mCount, yOffset, small);
|
||||
ok = PR_FALSE;
|
||||
|
||||
}
|
||||
else // band counts match, compare individual traps
|
||||
{
|
||||
PRInt32 trapIndex=0;
|
||||
for ( ;trapIndex<band1.mCount; trapIndex++)
|
||||
{
|
||||
PRBool match = (trap1[trapIndex].EqualGeometry(trap2[trapIndex])) &&
|
||||
trap1[trapIndex].mState == trap2[trapIndex].mState;
|
||||
if (!match)
|
||||
{
|
||||
LogVerifyMessage(k1, k2, "band.mTrapezoids of space managers differs\n");
|
||||
printf ("index %d\n", trapIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
// test the larger maxSize
|
||||
sm1->GetBandData(yOffset, nsSize(large,large), band1);
|
||||
sm2->GetBandData(yOffset, nsSize(large,large), band2);
|
||||
if (band1.mCount != band2.mCount)
|
||||
{ // count mismatch, stop comparing
|
||||
LogVerifyMessage(k1, k2, "band.mCount of space managers differs\n");
|
||||
printf("count1= %d, count2=%d, yOffset = %d, size=%d\n",
|
||||
band1.mCount, band2.mCount, yOffset, small);
|
||||
ok = PR_FALSE;
|
||||
|
||||
}
|
||||
else // band counts match, compare individual traps
|
||||
{
|
||||
PRInt32 trapIndex=0;
|
||||
for ( ; trapIndex<band1.mCount; trapIndex++)
|
||||
{
|
||||
PRBool match = (trap1[trapIndex].EqualGeometry(trap2[trapIndex])) &&
|
||||
trap1[trapIndex].mState == trap2[trapIndex].mState;
|
||||
if (!match)
|
||||
{
|
||||
LogVerifyMessage(k1, k2, "band.mTrapezoids of space managers differs\n");
|
||||
printf ("index %d\n", trapIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Compare the sub-trees too
|
||||
if (!CompareTrees(aFirstPresContext, k1, aSecondPresContext, k2)) {
|
||||
ok = PR_FALSE;
|
||||
|
|
|
@ -72,6 +72,16 @@ typedef enum SelectionRegion{SELECTION_ANCHOR_REGION = 0,
|
|||
SELECTION_FOCUS_REGION,
|
||||
NUM_SELECTION_REGIONS} SelectionRegion;
|
||||
|
||||
// debug VerifyReflow flags
|
||||
#define VERIFY_REFLOW_ON 0x01
|
||||
#define VERIFY_REFLOW_NOISY 0x02
|
||||
#define VERIFY_REFLOW_ALL 0x04
|
||||
#define VERIFY_REFLOW_DUMP_COMMANDS 0x08
|
||||
#define VERIFY_REFLOW_NOISY_RC 0x10
|
||||
#define VERIFY_REFLOW_REALLY_NOISY_RC 0x20
|
||||
#define VERIFY_REFLOW_INCLUDE_SPACE_MANAGER 0x40
|
||||
#define VERIFY_REFLOW_DURING_RESIZE_REFLOW 0x80
|
||||
|
||||
|
||||
/**
|
||||
* Presentation shell interface. Presentation shells are the
|
||||
|
@ -416,6 +426,10 @@ public:
|
|||
*/
|
||||
static NS_LAYOUT void SetVerifyReflowEnable(PRBool aEnabled);
|
||||
|
||||
/**
|
||||
* Get the flags associated with the VerifyReflow debug tool
|
||||
*/
|
||||
static NS_LAYOUT PRInt32 GetVerifyReflowFlags();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -65,6 +65,17 @@ struct nsBandTrapezoid {
|
|||
|
||||
// Set the trapezoid from a rectangle
|
||||
void operator=(const nsRect& aRect);
|
||||
|
||||
/** does a binary compare of this object with aTrap */
|
||||
PRBool Equals(const nsBandTrapezoid aTrap) const;
|
||||
|
||||
/** does a semantic compare only of geometric data in this object and aTrap */
|
||||
PRBool EqualGeometry(const nsBandTrapezoid aTrap) const;
|
||||
|
||||
nsBandTrapezoid() {
|
||||
mTopY = mBottomY = mTopLeftX = mBottomLeftX = mTopRightX = mBottomRightX = 0;
|
||||
mFrame = nsnull;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -214,4 +225,30 @@ inline void nsBandTrapezoid::operator=(const nsRect& aRect)
|
|||
mBottomY = aRect.YMost();
|
||||
}
|
||||
|
||||
inline PRBool nsBandTrapezoid::Equals(const nsBandTrapezoid aTrap) const
|
||||
{
|
||||
return (
|
||||
mTopLeftX == aTrap.mTopLeftX &&
|
||||
mBottomLeftX == aTrap.mBottomLeftX &&
|
||||
mTopRightX == aTrap.mTopRightX &&
|
||||
mBottomRightX == aTrap.mBottomRightX &&
|
||||
mTopY == aTrap.mTopY &&
|
||||
mBottomY == aTrap.mBottomY &&
|
||||
mState == aTrap.mState &&
|
||||
mFrame == aTrap.mFrame
|
||||
);
|
||||
}
|
||||
|
||||
inline PRBool nsBandTrapezoid::EqualGeometry(const nsBandTrapezoid aTrap) const
|
||||
{
|
||||
return (
|
||||
mTopLeftX == aTrap.mTopLeftX &&
|
||||
mBottomLeftX == aTrap.mBottomLeftX &&
|
||||
mTopRightX == aTrap.mTopRightX &&
|
||||
mBottomRightX == aTrap.mBottomRightX &&
|
||||
mTopY == aTrap.mTopY &&
|
||||
mBottomY == aTrap.mBottomY
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* nsISpaceManager_h___ */
|
||||
|
|
|
@ -117,6 +117,7 @@ LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
|
|||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
|
||||
|
||||
// Alphabetical list of event handler names
|
||||
|
|
|
@ -133,6 +133,9 @@ nsBlockBandData::GetBandData(nscoord aY)
|
|||
void
|
||||
nsBlockBandData::ComputeAvailSpaceRect()
|
||||
{
|
||||
#ifdef REALLY_NOISY_COMPUTEAVAILSPACERECT
|
||||
printf("nsBlockBandData::ComputeAvailSpaceRect %p \n", this);
|
||||
#endif
|
||||
if (0 == mCount) {
|
||||
mAvailSpace.x = 0;
|
||||
mAvailSpace.y = 0;
|
||||
|
@ -157,6 +160,9 @@ nsBlockBandData::ComputeAvailSpaceRect()
|
|||
for (i = 0; i < mCount; i++) {
|
||||
trapezoid = &mTrapezoids[i];
|
||||
if (trapezoid->mState != nsBandTrapezoid::Available) {
|
||||
#ifdef REALLY_NOISY_COMPUTEAVAILSPACERECT
|
||||
printf("band %p checking !Avail trap %p with frame %p\n", this, trapezoid, trapezoid->mFrame);
|
||||
#endif
|
||||
const nsStyleDisplay* display;
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->mState) {
|
||||
PRInt32 j, numFrames = trapezoid->mFrames->Count();
|
||||
|
@ -195,6 +201,9 @@ nsBlockBandData::ComputeAvailSpaceRect()
|
|||
// We have a floater using up all the available space
|
||||
leftFloaters = 1;
|
||||
}
|
||||
#ifdef REALLY_NOISY_COMPUTEAVAILSPACERECT
|
||||
printf("band %p has floaters %d, %d\n", this, leftFloaters, rightFloaters);
|
||||
#endif
|
||||
mLeftFloaters = leftFloaters;
|
||||
mRightFloaters = rightFloaters;
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ InitDebugFlags()
|
|||
}
|
||||
|
||||
#undef NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef NOISY_FIRST_LETTER
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FLOATER_CLEARING
|
||||
|
@ -410,6 +410,10 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsImpactedByFloater() {
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockReflowState::IsImpactedByFloater %p returned %d\n",
|
||||
this, mBand.GetFloaterCount());
|
||||
#endif
|
||||
return mBand.GetFloaterCount();
|
||||
}
|
||||
|
||||
|
@ -741,16 +745,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
(const nsStyleStruct*&) spacing);
|
||||
switch (spacing->mFloatEdge) {
|
||||
default:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floaters
|
||||
// The child block will flow around the floater. Therefore
|
||||
// give it all of the available space.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.width = mUnconstrainedWidth
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: mContentArea.width;
|
||||
break;
|
||||
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
case NS_STYLE_FLOAT_EDGE_PADDING:
|
||||
{
|
||||
// The child block's border should be placed adjacent to,
|
||||
|
@ -819,6 +822,9 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
aResult.x = mAvailSpaceRect.x + borderPadding.left;
|
||||
aResult.width = mAvailSpaceRect.width;
|
||||
}
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -1069,7 +1075,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
|||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyReflow || gNoisySpaceManager) {
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
// And then put the translation back again
|
||||
mSpaceManager->Translate(bp.left, bp.top);
|
||||
}
|
||||
|
@ -1394,8 +1404,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (gNoisyReflow) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
ListTag(stdout);
|
||||
printf(": begin reflow availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
printf(": begin reflow type %d availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.reason, aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
}
|
||||
if (gNoisy) {
|
||||
|
@ -1437,6 +1447,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Set the space manager in the existing reflow state
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
reflowState.mSpaceManager = spaceManager.get();
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p\n", reflowState.mSpaceManager);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
|
||||
|
@ -1621,23 +1634,45 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
PRInt32 verifyReflowFlags = nsIPresShell::GetVerifyReflowFlags();
|
||||
if (VERIFY_REFLOW_INCLUDE_SPACE_MANAGER & verifyReflowFlags)
|
||||
{
|
||||
// this is a leak of the space manager, but it's only in debug if verify reflow is enabled, so not a big deal
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
nsISpaceManager *spaceManager = reflowState.mSpaceManager;
|
||||
NS_ADDREF(spaceManager);
|
||||
rv = frameManager->SetFrameProperty(this, nsLayoutAtoms::spaceManagerProperty,
|
||||
reflowState.mSpaceManager, nsnull /* should be nsSpaceManagerDestroyer*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we set the space manager, then restore the old space manager now that we're
|
||||
// going out of scope
|
||||
if (NS_BLOCK_SPACE_MGR & mState) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", oldSpaceManager);
|
||||
#endif
|
||||
reflowState.mSpaceManager = oldSpaceManager;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
if (mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager after reflow\n");
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
if (reflowState.mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", reflowState.mSpaceManager);
|
||||
reflowState.mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If this is an incremental reflow and we changed size, then make sure our
|
||||
|
@ -2364,6 +2399,12 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
}
|
||||
else {
|
||||
// We can avoid reflowing *some* inline lines in some cases.
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("PrepareResizeReflow thinks line %p is %simpacted by floaters\n",
|
||||
line, line->IsImpactedByFloater() ? "" : "not ");
|
||||
#endif
|
||||
|
||||
|
||||
if (notWrapping) {
|
||||
// When no-wrap is set then the only line-breaking that
|
||||
// occurs for inline lines is triggered by BR elements or by
|
||||
|
@ -2525,7 +2566,11 @@ nsBlockFrame::PropogateReflowDamage(nsBlockReflowState& aState,
|
|||
//then we don't need to mark the line dirty.
|
||||
aState.GetAvailableSpace(next->mBounds.y + aDeltaY);
|
||||
PRBool wasImpactedByFloater = next->IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::PropogateReflowDamage %p was = %d, is=%d\n",
|
||||
this, wasImpactedByFloater, isImpactedByFloater);
|
||||
#endif
|
||||
if (wasImpactedByFloater != isImpactedByFloater) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
|
@ -2659,10 +2704,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||
{
|
||||
printf("line %p is not complete\n", line);
|
||||
}
|
||||
if (!keepGoing) {
|
||||
if (0 == line->GetChildCount()) {
|
||||
DeleteLine(aState, line);
|
||||
|
@ -2826,7 +2867,7 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
|||
|
||||
/**
|
||||
* Reflow a line. The line will either contain a single block frame
|
||||
* or contain 1 or more inline frames. aLineReflowStatus indicates
|
||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||
* whether or not the caller should continue to reflow more lines.
|
||||
*/
|
||||
nsresult
|
||||
|
@ -3512,7 +3553,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Compute the available space for the block
|
||||
aState.GetAvailableSpace();
|
||||
aLine->SetLineIsImpactedByFloater(aState.IsImpactedByFloater());
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("setting line %p isImpacted to %s\n", aLine, aState.IsImpactedByFloater()?"true":"false");
|
||||
#endif
|
||||
PRBool isImpacted = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(isImpacted);
|
||||
nsSplittableType splitType = NS_FRAME_NOT_SPLITTABLE;
|
||||
frame->IsSplittable(splitType);
|
||||
nsRect availSpace;
|
||||
|
@ -3855,8 +3900,12 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
// into. Apply a previous block frame's bottom margin first.
|
||||
aState.mY += aState.mPrevBottomMargin;
|
||||
aState.GetAvailableSpace();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(impactedByFloaters);
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
||||
this, impactedByFloaters);
|
||||
#endif
|
||||
|
||||
const nsMargin& borderPadding = aState.BorderPadding();
|
||||
nscoord x = aState.mAvailSpaceRect.x + borderPadding.left;
|
||||
|
@ -4697,10 +4746,10 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// we are told to reflow again before a next-in-flow is created
|
||||
// and reflows.
|
||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (nsnull == lastLine) {
|
||||
mLines = overflowLines;
|
||||
if (nsnull == lastLine) { // if we had no lines before the drain operation
|
||||
mLines = overflowLines; // set our mLines to the overflow
|
||||
}
|
||||
else {
|
||||
else { // otherwise, append the overflow to the mLines list
|
||||
lastLine->mNext = overflowLines;
|
||||
nsIFrame* lastFrame = lastLine->LastChild();
|
||||
lastFrame->SetNextSibling(overflowLines->mFirstChild);
|
||||
|
|
|
@ -140,8 +140,15 @@ public:
|
|||
virtual void DeleteChildsNextInFlow(nsIPresContext* aPresContext,
|
||||
nsIFrame* aNextInFlow);
|
||||
|
||||
/** return the topmost block child based on y-index.
|
||||
* almost always the first or second line, if there is one.
|
||||
* accounts for lines that hold only compressed white space, etc.
|
||||
*/
|
||||
nsIFrame* GetTopBlockChild();
|
||||
|
||||
/** Place the floaters in the spacemanager for all lines in this block.
|
||||
* recursively adds floaters in child blocks of this frame.
|
||||
*/
|
||||
nsresult UpdateSpaceManager(nsIPresContext* aPresContext,
|
||||
nsISpaceManager* aSpaceManager);
|
||||
|
||||
|
@ -160,9 +167,16 @@ protected:
|
|||
return 0 != (mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
|
||||
}
|
||||
|
||||
/** move the frames contained by aLine by aDY
|
||||
* if aLine is a block, it's child floaters are added to the state manager
|
||||
*/
|
||||
void SlideLine(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine, nscoord aDY);
|
||||
|
||||
/** grab overflow lines from this block's prevInFlow, and make them
|
||||
* part of this block's mLines list.
|
||||
* @return PR_TRUE if any lines were drained.
|
||||
*/
|
||||
PRBool DrainOverflowLines(nsIPresContext* aPresContext);
|
||||
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
@ -171,26 +185,51 @@ protected:
|
|||
nsBlockReflowState& aState,
|
||||
nsHTMLReflowMetrics& aMetrics);
|
||||
|
||||
/** add the frames in aFrameList to this block after aPrevSibling
|
||||
* this block thinks in terms of lines, but the frame construction code
|
||||
* knows nothing about lines at all. So we need to find the line that
|
||||
* contains aPrevSibling and add aFrameList after aPrevSibling on that line.
|
||||
* new lines are created as necessary to handle block data in aFrameList.
|
||||
*/
|
||||
nsresult AddFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
/** move the frame list rooted at aFrame into this as a child
|
||||
* assumes prev/next sibling pointers will be or have been set elsewhere
|
||||
* changes aFrame's parent to be this, and reparents aFrame's view and stylecontext.
|
||||
*/
|
||||
void FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
/** does all the real work for removing aDeletedFrame from this
|
||||
* finds the line containing aFrame.
|
||||
* handled continued frames
|
||||
* marks lines dirty as needed
|
||||
*/
|
||||
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame);
|
||||
|
||||
|
||||
/** set up the conditions necessary for an initial reflow */
|
||||
nsresult PrepareInitialReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** set up the conditions necessary for an styleChanged reflow */
|
||||
nsresult PrepareStyleChangedReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** set up the conditions necessary for an incremental reflow.
|
||||
* the primary task is to mark the minimumly sufficient lines dirty.
|
||||
*/
|
||||
nsresult PrepareChildIncrementalReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** set up the conditions necessary for an resize reflow
|
||||
* the primary task is to mark the minimumly sufficient lines dirty.
|
||||
*/
|
||||
nsresult PrepareResizeReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** reflow all lines that have been marked dirty */
|
||||
nsresult ReflowDirtyLines(nsBlockReflowState& aState);
|
||||
|
||||
/** set aState to what it would be if we had done a full reflow to this point. */
|
||||
void RecoverStateFrom(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nscoord aDeltaY,
|
||||
|
@ -198,8 +237,15 @@ protected:
|
|||
|
||||
//----------------------------------------
|
||||
// Methods for line reflow
|
||||
// XXX nuke em
|
||||
|
||||
/**
|
||||
* Reflow a line.
|
||||
* @param aState the current reflow state
|
||||
* @param aLine the line to reflow. can contain a single block frame
|
||||
* or contain 1 or more inline frames.
|
||||
* @param aKeepReflowGoing [OUT] indicates whether the caller should continue to reflow more lines
|
||||
* @param aDamageDirtyArea if PR_TRUE, do extra work to mark the changed areas as damaged for painting
|
||||
* this indicates that frames may have changed size, for example
|
||||
*/
|
||||
nsresult ReflowLine(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
PRBool* aKeepReflowGoing,
|
||||
|
|
|
@ -146,7 +146,7 @@ InitDebugFlags()
|
|||
}
|
||||
|
||||
#undef NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef NOISY_FIRST_LETTER
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FLOATER_CLEARING
|
||||
|
@ -410,6 +410,10 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsImpactedByFloater() {
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockReflowState::IsImpactedByFloater %p returned %d\n",
|
||||
this, mBand.GetFloaterCount());
|
||||
#endif
|
||||
return mBand.GetFloaterCount();
|
||||
}
|
||||
|
||||
|
@ -741,16 +745,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
(const nsStyleStruct*&) spacing);
|
||||
switch (spacing->mFloatEdge) {
|
||||
default:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floaters
|
||||
// The child block will flow around the floater. Therefore
|
||||
// give it all of the available space.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.width = mUnconstrainedWidth
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: mContentArea.width;
|
||||
break;
|
||||
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
case NS_STYLE_FLOAT_EDGE_PADDING:
|
||||
{
|
||||
// The child block's border should be placed adjacent to,
|
||||
|
@ -819,6 +822,9 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
aResult.x = mAvailSpaceRect.x + borderPadding.left;
|
||||
aResult.width = mAvailSpaceRect.width;
|
||||
}
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -1069,7 +1075,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
|||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyReflow || gNoisySpaceManager) {
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
// And then put the translation back again
|
||||
mSpaceManager->Translate(bp.left, bp.top);
|
||||
}
|
||||
|
@ -1394,8 +1404,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (gNoisyReflow) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
ListTag(stdout);
|
||||
printf(": begin reflow availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
printf(": begin reflow type %d availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.reason, aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
}
|
||||
if (gNoisy) {
|
||||
|
@ -1437,6 +1447,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Set the space manager in the existing reflow state
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
reflowState.mSpaceManager = spaceManager.get();
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p\n", reflowState.mSpaceManager);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
|
||||
|
@ -1621,23 +1634,45 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
PRInt32 verifyReflowFlags = nsIPresShell::GetVerifyReflowFlags();
|
||||
if (VERIFY_REFLOW_INCLUDE_SPACE_MANAGER & verifyReflowFlags)
|
||||
{
|
||||
// this is a leak of the space manager, but it's only in debug if verify reflow is enabled, so not a big deal
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
nsISpaceManager *spaceManager = reflowState.mSpaceManager;
|
||||
NS_ADDREF(spaceManager);
|
||||
rv = frameManager->SetFrameProperty(this, nsLayoutAtoms::spaceManagerProperty,
|
||||
reflowState.mSpaceManager, nsnull /* should be nsSpaceManagerDestroyer*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we set the space manager, then restore the old space manager now that we're
|
||||
// going out of scope
|
||||
if (NS_BLOCK_SPACE_MGR & mState) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", oldSpaceManager);
|
||||
#endif
|
||||
reflowState.mSpaceManager = oldSpaceManager;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
if (mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager after reflow\n");
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
if (reflowState.mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", reflowState.mSpaceManager);
|
||||
reflowState.mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If this is an incremental reflow and we changed size, then make sure our
|
||||
|
@ -2364,6 +2399,12 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
}
|
||||
else {
|
||||
// We can avoid reflowing *some* inline lines in some cases.
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("PrepareResizeReflow thinks line %p is %simpacted by floaters\n",
|
||||
line, line->IsImpactedByFloater() ? "" : "not ");
|
||||
#endif
|
||||
|
||||
|
||||
if (notWrapping) {
|
||||
// When no-wrap is set then the only line-breaking that
|
||||
// occurs for inline lines is triggered by BR elements or by
|
||||
|
@ -2525,7 +2566,11 @@ nsBlockFrame::PropogateReflowDamage(nsBlockReflowState& aState,
|
|||
//then we don't need to mark the line dirty.
|
||||
aState.GetAvailableSpace(next->mBounds.y + aDeltaY);
|
||||
PRBool wasImpactedByFloater = next->IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::PropogateReflowDamage %p was = %d, is=%d\n",
|
||||
this, wasImpactedByFloater, isImpactedByFloater);
|
||||
#endif
|
||||
if (wasImpactedByFloater != isImpactedByFloater) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
|
@ -2659,10 +2704,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||
{
|
||||
printf("line %p is not complete\n", line);
|
||||
}
|
||||
if (!keepGoing) {
|
||||
if (0 == line->GetChildCount()) {
|
||||
DeleteLine(aState, line);
|
||||
|
@ -2826,7 +2867,7 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
|||
|
||||
/**
|
||||
* Reflow a line. The line will either contain a single block frame
|
||||
* or contain 1 or more inline frames. aLineReflowStatus indicates
|
||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||
* whether or not the caller should continue to reflow more lines.
|
||||
*/
|
||||
nsresult
|
||||
|
@ -3512,7 +3553,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Compute the available space for the block
|
||||
aState.GetAvailableSpace();
|
||||
aLine->SetLineIsImpactedByFloater(aState.IsImpactedByFloater());
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("setting line %p isImpacted to %s\n", aLine, aState.IsImpactedByFloater()?"true":"false");
|
||||
#endif
|
||||
PRBool isImpacted = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(isImpacted);
|
||||
nsSplittableType splitType = NS_FRAME_NOT_SPLITTABLE;
|
||||
frame->IsSplittable(splitType);
|
||||
nsRect availSpace;
|
||||
|
@ -3855,8 +3900,12 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
// into. Apply a previous block frame's bottom margin first.
|
||||
aState.mY += aState.mPrevBottomMargin;
|
||||
aState.GetAvailableSpace();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(impactedByFloaters);
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
||||
this, impactedByFloaters);
|
||||
#endif
|
||||
|
||||
const nsMargin& borderPadding = aState.BorderPadding();
|
||||
nscoord x = aState.mAvailSpaceRect.x + borderPadding.left;
|
||||
|
@ -4697,10 +4746,10 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// we are told to reflow again before a next-in-flow is created
|
||||
// and reflows.
|
||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (nsnull == lastLine) {
|
||||
mLines = overflowLines;
|
||||
if (nsnull == lastLine) { // if we had no lines before the drain operation
|
||||
mLines = overflowLines; // set our mLines to the overflow
|
||||
}
|
||||
else {
|
||||
else { // otherwise, append the overflow to the mLines list
|
||||
lastLine->mNext = overflowLines;
|
||||
nsIFrame* lastFrame = lastLine->LastChild();
|
||||
lastFrame->SetNextSibling(overflowLines->mFirstChild);
|
||||
|
|
|
@ -146,7 +146,7 @@ InitDebugFlags()
|
|||
}
|
||||
|
||||
#undef NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef NOISY_FIRST_LETTER
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FLOATER_CLEARING
|
||||
|
@ -410,6 +410,10 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsImpactedByFloater() {
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockReflowState::IsImpactedByFloater %p returned %d\n",
|
||||
this, mBand.GetFloaterCount());
|
||||
#endif
|
||||
return mBand.GetFloaterCount();
|
||||
}
|
||||
|
||||
|
@ -741,16 +745,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
(const nsStyleStruct*&) spacing);
|
||||
switch (spacing->mFloatEdge) {
|
||||
default:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floaters
|
||||
// The child block will flow around the floater. Therefore
|
||||
// give it all of the available space.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.width = mUnconstrainedWidth
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: mContentArea.width;
|
||||
break;
|
||||
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
case NS_STYLE_FLOAT_EDGE_PADDING:
|
||||
{
|
||||
// The child block's border should be placed adjacent to,
|
||||
|
@ -819,6 +822,9 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
aResult.x = mAvailSpaceRect.x + borderPadding.left;
|
||||
aResult.width = mAvailSpaceRect.width;
|
||||
}
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -1069,7 +1075,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
|||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyReflow || gNoisySpaceManager) {
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
// And then put the translation back again
|
||||
mSpaceManager->Translate(bp.left, bp.top);
|
||||
}
|
||||
|
@ -1394,8 +1404,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (gNoisyReflow) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
ListTag(stdout);
|
||||
printf(": begin reflow availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
printf(": begin reflow type %d availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.reason, aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
}
|
||||
if (gNoisy) {
|
||||
|
@ -1437,6 +1447,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Set the space manager in the existing reflow state
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
reflowState.mSpaceManager = spaceManager.get();
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p\n", reflowState.mSpaceManager);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
|
||||
|
@ -1621,23 +1634,45 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
PRInt32 verifyReflowFlags = nsIPresShell::GetVerifyReflowFlags();
|
||||
if (VERIFY_REFLOW_INCLUDE_SPACE_MANAGER & verifyReflowFlags)
|
||||
{
|
||||
// this is a leak of the space manager, but it's only in debug if verify reflow is enabled, so not a big deal
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
nsISpaceManager *spaceManager = reflowState.mSpaceManager;
|
||||
NS_ADDREF(spaceManager);
|
||||
rv = frameManager->SetFrameProperty(this, nsLayoutAtoms::spaceManagerProperty,
|
||||
reflowState.mSpaceManager, nsnull /* should be nsSpaceManagerDestroyer*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we set the space manager, then restore the old space manager now that we're
|
||||
// going out of scope
|
||||
if (NS_BLOCK_SPACE_MGR & mState) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", oldSpaceManager);
|
||||
#endif
|
||||
reflowState.mSpaceManager = oldSpaceManager;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
if (mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager after reflow\n");
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
if (reflowState.mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", reflowState.mSpaceManager);
|
||||
reflowState.mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If this is an incremental reflow and we changed size, then make sure our
|
||||
|
@ -2364,6 +2399,12 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
}
|
||||
else {
|
||||
// We can avoid reflowing *some* inline lines in some cases.
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("PrepareResizeReflow thinks line %p is %simpacted by floaters\n",
|
||||
line, line->IsImpactedByFloater() ? "" : "not ");
|
||||
#endif
|
||||
|
||||
|
||||
if (notWrapping) {
|
||||
// When no-wrap is set then the only line-breaking that
|
||||
// occurs for inline lines is triggered by BR elements or by
|
||||
|
@ -2525,7 +2566,11 @@ nsBlockFrame::PropogateReflowDamage(nsBlockReflowState& aState,
|
|||
//then we don't need to mark the line dirty.
|
||||
aState.GetAvailableSpace(next->mBounds.y + aDeltaY);
|
||||
PRBool wasImpactedByFloater = next->IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::PropogateReflowDamage %p was = %d, is=%d\n",
|
||||
this, wasImpactedByFloater, isImpactedByFloater);
|
||||
#endif
|
||||
if (wasImpactedByFloater != isImpactedByFloater) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
|
@ -2659,10 +2704,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||
{
|
||||
printf("line %p is not complete\n", line);
|
||||
}
|
||||
if (!keepGoing) {
|
||||
if (0 == line->GetChildCount()) {
|
||||
DeleteLine(aState, line);
|
||||
|
@ -2826,7 +2867,7 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
|||
|
||||
/**
|
||||
* Reflow a line. The line will either contain a single block frame
|
||||
* or contain 1 or more inline frames. aLineReflowStatus indicates
|
||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||
* whether or not the caller should continue to reflow more lines.
|
||||
*/
|
||||
nsresult
|
||||
|
@ -3512,7 +3553,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Compute the available space for the block
|
||||
aState.GetAvailableSpace();
|
||||
aLine->SetLineIsImpactedByFloater(aState.IsImpactedByFloater());
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("setting line %p isImpacted to %s\n", aLine, aState.IsImpactedByFloater()?"true":"false");
|
||||
#endif
|
||||
PRBool isImpacted = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(isImpacted);
|
||||
nsSplittableType splitType = NS_FRAME_NOT_SPLITTABLE;
|
||||
frame->IsSplittable(splitType);
|
||||
nsRect availSpace;
|
||||
|
@ -3855,8 +3900,12 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
// into. Apply a previous block frame's bottom margin first.
|
||||
aState.mY += aState.mPrevBottomMargin;
|
||||
aState.GetAvailableSpace();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(impactedByFloaters);
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
||||
this, impactedByFloaters);
|
||||
#endif
|
||||
|
||||
const nsMargin& borderPadding = aState.BorderPadding();
|
||||
nscoord x = aState.mAvailSpaceRect.x + borderPadding.left;
|
||||
|
@ -4697,10 +4746,10 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// we are told to reflow again before a next-in-flow is created
|
||||
// and reflows.
|
||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (nsnull == lastLine) {
|
||||
mLines = overflowLines;
|
||||
if (nsnull == lastLine) { // if we had no lines before the drain operation
|
||||
mLines = overflowLines; // set our mLines to the overflow
|
||||
}
|
||||
else {
|
||||
else { // otherwise, append the overflow to the mLines list
|
||||
lastLine->mNext = overflowLines;
|
||||
nsIFrame* lastFrame = lastLine->LastChild();
|
||||
lastFrame->SetNextSibling(overflowLines->mFirstChild);
|
||||
|
|
|
@ -32,10 +32,16 @@
|
|||
#include "nsAbsoluteContainingBlock.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
#undef NOISY_FINAL_SIZE
|
||||
#ifdef DEBUG
|
||||
#undef NOISY_PUSHING
|
||||
#endif
|
||||
|
||||
nsIID nsInlineFrame::kInlineFrameCID = NS_INLINE_FRAME_CID;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Basic nsInlineFrame methods
|
||||
|
@ -426,6 +432,9 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext,
|
|||
PRBool reflowingFirstLetter = lineLayout->GetFirstLetterStyleOK();
|
||||
PRBool isComplete;
|
||||
frame = PullOneFrame(aPresContext, irs, &isComplete);
|
||||
#ifdef NOISY_PUSHING
|
||||
printf("%p pulled up %p\n", this, frame);
|
||||
#endif
|
||||
if (nsnull == frame) {
|
||||
if (!isComplete) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
|
@ -668,6 +677,10 @@ nsInlineFrame::PushFrames(nsIPresContext* aPresContext,
|
|||
NS_PRECONDITION(prevNextSibling == aFromChild, "bad prev sibling");
|
||||
#endif
|
||||
|
||||
#ifdef NOISY_PUSHING
|
||||
printf("%p pushing aFromChild %p, disconnecting from prev sib %p\n",
|
||||
this, aFromChild, aPrevSibling);
|
||||
#endif
|
||||
// Disconnect aFromChild from its previous sibling
|
||||
aPrevSibling->SetNextSibling(nsnull);
|
||||
|
||||
|
|
|
@ -153,8 +153,8 @@ nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
|||
{
|
||||
PR_snprintf(aBuf, aBufSize, "%s,%s,%s,%s[0x%x]",
|
||||
IsBlock() ? "block" : "inline",
|
||||
IsDirty() ? "dirty" : "",
|
||||
IsImpactedByFloater() ? "impacted" : "",
|
||||
IsDirty() ? "dirty" : "clean",
|
||||
IsImpactedByFloater() ? "IMPACTED" : "NOT Impacted",
|
||||
IsTrimmed() ? "trimmed" : "",
|
||||
mAllFlags);
|
||||
return aBuf;
|
||||
|
@ -353,16 +353,15 @@ nsLineBox::FreeFloaters(nsFloaterCacheFreeList& aFreeList)
|
|||
|
||||
void
|
||||
nsLineBox::RemoveFloatersFromSpaceManager(nsISpaceManager* aSpaceManager)
|
||||
{
|
||||
{
|
||||
if (IsInline()) {
|
||||
if (mInlineData) {
|
||||
nsFloaterCache* floaterCache = mInlineData->mFloaters.Head();
|
||||
|
||||
while (floaterCache) {
|
||||
nsIFrame* floater = floaterCache->mPlaceholder->GetOutOfFlowFrame();
|
||||
|
||||
aSpaceManager->RemoveRegion(floater);
|
||||
floaterCache = floaterCache->Next();
|
||||
floaterCache = floaterCache->Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +369,7 @@ nsLineBox::RemoveFloatersFromSpaceManager(nsISpaceManager* aSpaceManager)
|
|||
|
||||
void
|
||||
nsLineBox::AppendFloaters(nsFloaterCacheFreeList& aFreeList)
|
||||
{
|
||||
{
|
||||
NS_ABORT_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||
if (IsInline()) {
|
||||
if (aFreeList.NotEmpty()) {
|
||||
|
@ -404,7 +403,7 @@ nsLineBox::RemoveFloater(nsIFrame* aFrame)
|
|||
|
||||
void
|
||||
nsLineBox::SetCombinedArea(const nsRect& aCombinedArea)
|
||||
{
|
||||
{
|
||||
NS_ASSERTION(aCombinedArea.width >= 0, "illegal width for combined area");
|
||||
NS_ASSERTION(aCombinedArea.height >= 0, "illegal height for combined area");
|
||||
if (aCombinedArea != mBounds) {
|
||||
|
@ -428,13 +427,22 @@ nsLineBox::SetCombinedArea(const nsRect& aCombinedArea)
|
|||
}
|
||||
MaybeFreeData();
|
||||
}
|
||||
#ifdef VERY_NOISY_REFLOW
|
||||
printf("nsLB::SetCombinedArea(1) %p (%d, %d, %d, %d)\n",
|
||||
this, aCombinedArea.x, aCombinedArea.y, aCombinedArea.width, aCombinedArea.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsLineBox::GetCombinedArea(nsRect* aResult)
|
||||
{
|
||||
NS_ASSERTION(aResult, "null arg");
|
||||
if (aResult) {
|
||||
*aResult = mData ? mData->mCombinedArea : mBounds;
|
||||
#ifdef VERY_NOISY_REFLOW
|
||||
printf("nsLB::SetCombinedArea(1) %p (%d, %d, %d, %d)\n",
|
||||
this, aResult->x, aResult->y, aResult->width, aResult->height);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ public:
|
|||
|
||||
// mImpactedByFloater bit
|
||||
void SetLineIsImpactedByFloater(PRBool aValue) {
|
||||
NS_ASSERTION((PR_FALSE==aValue || PR_TRUE==aValue), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mImpactedByFloater = aValue;
|
||||
}
|
||||
PRBool IsImpactedByFloater() const {
|
||||
|
@ -197,6 +198,7 @@ public:
|
|||
|
||||
// mTrimmed bit
|
||||
void SetTrimmed(PRBool aOn) {
|
||||
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mTrimmed = aOn;
|
||||
}
|
||||
PRBool IsTrimmed() const {
|
||||
|
@ -205,6 +207,7 @@ public:
|
|||
|
||||
// mHasPercentageChild bit
|
||||
void SetHasPercentageChild(PRBool aOn) {
|
||||
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mHasPercentageChild = aOn;
|
||||
}
|
||||
PRBool HasPercentageChild() const {
|
||||
|
@ -213,6 +216,7 @@ public:
|
|||
|
||||
// mLineWrapped bit
|
||||
void SetLineWrapped(PRBool aOn) {
|
||||
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mLineWrapped = aOn;
|
||||
}
|
||||
PRBool IsLineWrapped() const {
|
||||
|
|
|
@ -235,6 +235,10 @@ nsLineLayout::BeginLineReflow(nscoord aX, nscoord aY,
|
|||
PRBool aImpactedByFloaters,
|
||||
PRBool aIsTopOfPage)
|
||||
{
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsLL::BeginLineReflow %d, %d, %d, %d, impacted=%s\n",
|
||||
aX, aY, aWidth, aHeight, aImpactedByFloaters?"true":"false");
|
||||
#endif
|
||||
NS_ASSERTION(nsnull == mRootSpan, "bad linelayout user");
|
||||
#ifdef DEBUG
|
||||
if ((aWidth != NS_UNCONSTRAINEDSIZE) && CRAZY_WIDTH(aWidth)) {
|
||||
|
@ -350,6 +354,10 @@ nsLineLayout::UpdateBand(nscoord aX, nscoord aY,
|
|||
PRBool aPlacedLeftFloater,
|
||||
nsIFrame* aFloaterFrame)
|
||||
{
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsLL::UpdateBand %d, %d, %d, %d, frame=%p placedLeft=%s\n will set mImpacted to PR_TRUE",
|
||||
aX, aY, aWidth, aHeight, aFloaterFrame, aPlacedLeftFloater?"true":"false");
|
||||
#endif
|
||||
PerSpanData* psd = mRootSpan;
|
||||
NS_PRECONDITION(psd->mX == psd->mLeftEdge, "update-band called late");
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -133,6 +133,9 @@ nsBlockBandData::GetBandData(nscoord aY)
|
|||
void
|
||||
nsBlockBandData::ComputeAvailSpaceRect()
|
||||
{
|
||||
#ifdef REALLY_NOISY_COMPUTEAVAILSPACERECT
|
||||
printf("nsBlockBandData::ComputeAvailSpaceRect %p \n", this);
|
||||
#endif
|
||||
if (0 == mCount) {
|
||||
mAvailSpace.x = 0;
|
||||
mAvailSpace.y = 0;
|
||||
|
@ -157,6 +160,9 @@ nsBlockBandData::ComputeAvailSpaceRect()
|
|||
for (i = 0; i < mCount; i++) {
|
||||
trapezoid = &mTrapezoids[i];
|
||||
if (trapezoid->mState != nsBandTrapezoid::Available) {
|
||||
#ifdef REALLY_NOISY_COMPUTEAVAILSPACERECT
|
||||
printf("band %p checking !Avail trap %p with frame %p\n", this, trapezoid, trapezoid->mFrame);
|
||||
#endif
|
||||
const nsStyleDisplay* display;
|
||||
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->mState) {
|
||||
PRInt32 j, numFrames = trapezoid->mFrames->Count();
|
||||
|
@ -195,6 +201,9 @@ nsBlockBandData::ComputeAvailSpaceRect()
|
|||
// We have a floater using up all the available space
|
||||
leftFloaters = 1;
|
||||
}
|
||||
#ifdef REALLY_NOISY_COMPUTEAVAILSPACERECT
|
||||
printf("band %p has floaters %d, %d\n", this, leftFloaters, rightFloaters);
|
||||
#endif
|
||||
mLeftFloaters = leftFloaters;
|
||||
mRightFloaters = rightFloaters;
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ InitDebugFlags()
|
|||
}
|
||||
|
||||
#undef NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef NOISY_FIRST_LETTER
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FLOATER_CLEARING
|
||||
|
@ -410,6 +410,10 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsImpactedByFloater() {
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockReflowState::IsImpactedByFloater %p returned %d\n",
|
||||
this, mBand.GetFloaterCount());
|
||||
#endif
|
||||
return mBand.GetFloaterCount();
|
||||
}
|
||||
|
||||
|
@ -741,16 +745,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
(const nsStyleStruct*&) spacing);
|
||||
switch (spacing->mFloatEdge) {
|
||||
default:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floaters
|
||||
// The child block will flow around the floater. Therefore
|
||||
// give it all of the available space.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.width = mUnconstrainedWidth
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: mContentArea.width;
|
||||
break;
|
||||
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
case NS_STYLE_FLOAT_EDGE_PADDING:
|
||||
{
|
||||
// The child block's border should be placed adjacent to,
|
||||
|
@ -819,6 +822,9 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
aResult.x = mAvailSpaceRect.x + borderPadding.left;
|
||||
aResult.width = mAvailSpaceRect.width;
|
||||
}
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -1069,7 +1075,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
|||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyReflow || gNoisySpaceManager) {
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
// And then put the translation back again
|
||||
mSpaceManager->Translate(bp.left, bp.top);
|
||||
}
|
||||
|
@ -1394,8 +1404,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (gNoisyReflow) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
ListTag(stdout);
|
||||
printf(": begin reflow availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
printf(": begin reflow type %d availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.reason, aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
}
|
||||
if (gNoisy) {
|
||||
|
@ -1437,6 +1447,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Set the space manager in the existing reflow state
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
reflowState.mSpaceManager = spaceManager.get();
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p\n", reflowState.mSpaceManager);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
|
||||
|
@ -1621,23 +1634,45 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
PRInt32 verifyReflowFlags = nsIPresShell::GetVerifyReflowFlags();
|
||||
if (VERIFY_REFLOW_INCLUDE_SPACE_MANAGER & verifyReflowFlags)
|
||||
{
|
||||
// this is a leak of the space manager, but it's only in debug if verify reflow is enabled, so not a big deal
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
nsISpaceManager *spaceManager = reflowState.mSpaceManager;
|
||||
NS_ADDREF(spaceManager);
|
||||
rv = frameManager->SetFrameProperty(this, nsLayoutAtoms::spaceManagerProperty,
|
||||
reflowState.mSpaceManager, nsnull /* should be nsSpaceManagerDestroyer*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we set the space manager, then restore the old space manager now that we're
|
||||
// going out of scope
|
||||
if (NS_BLOCK_SPACE_MGR & mState) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", oldSpaceManager);
|
||||
#endif
|
||||
reflowState.mSpaceManager = oldSpaceManager;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
if (mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager after reflow\n");
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
if (reflowState.mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", reflowState.mSpaceManager);
|
||||
reflowState.mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If this is an incremental reflow and we changed size, then make sure our
|
||||
|
@ -2364,6 +2399,12 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
}
|
||||
else {
|
||||
// We can avoid reflowing *some* inline lines in some cases.
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("PrepareResizeReflow thinks line %p is %simpacted by floaters\n",
|
||||
line, line->IsImpactedByFloater() ? "" : "not ");
|
||||
#endif
|
||||
|
||||
|
||||
if (notWrapping) {
|
||||
// When no-wrap is set then the only line-breaking that
|
||||
// occurs for inline lines is triggered by BR elements or by
|
||||
|
@ -2525,7 +2566,11 @@ nsBlockFrame::PropogateReflowDamage(nsBlockReflowState& aState,
|
|||
//then we don't need to mark the line dirty.
|
||||
aState.GetAvailableSpace(next->mBounds.y + aDeltaY);
|
||||
PRBool wasImpactedByFloater = next->IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::PropogateReflowDamage %p was = %d, is=%d\n",
|
||||
this, wasImpactedByFloater, isImpactedByFloater);
|
||||
#endif
|
||||
if (wasImpactedByFloater != isImpactedByFloater) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
|
@ -2659,10 +2704,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||
{
|
||||
printf("line %p is not complete\n", line);
|
||||
}
|
||||
if (!keepGoing) {
|
||||
if (0 == line->GetChildCount()) {
|
||||
DeleteLine(aState, line);
|
||||
|
@ -2826,7 +2867,7 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
|||
|
||||
/**
|
||||
* Reflow a line. The line will either contain a single block frame
|
||||
* or contain 1 or more inline frames. aLineReflowStatus indicates
|
||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||
* whether or not the caller should continue to reflow more lines.
|
||||
*/
|
||||
nsresult
|
||||
|
@ -3512,7 +3553,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Compute the available space for the block
|
||||
aState.GetAvailableSpace();
|
||||
aLine->SetLineIsImpactedByFloater(aState.IsImpactedByFloater());
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("setting line %p isImpacted to %s\n", aLine, aState.IsImpactedByFloater()?"true":"false");
|
||||
#endif
|
||||
PRBool isImpacted = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(isImpacted);
|
||||
nsSplittableType splitType = NS_FRAME_NOT_SPLITTABLE;
|
||||
frame->IsSplittable(splitType);
|
||||
nsRect availSpace;
|
||||
|
@ -3855,8 +3900,12 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
// into. Apply a previous block frame's bottom margin first.
|
||||
aState.mY += aState.mPrevBottomMargin;
|
||||
aState.GetAvailableSpace();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(impactedByFloaters);
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
||||
this, impactedByFloaters);
|
||||
#endif
|
||||
|
||||
const nsMargin& borderPadding = aState.BorderPadding();
|
||||
nscoord x = aState.mAvailSpaceRect.x + borderPadding.left;
|
||||
|
@ -4697,10 +4746,10 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// we are told to reflow again before a next-in-flow is created
|
||||
// and reflows.
|
||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (nsnull == lastLine) {
|
||||
mLines = overflowLines;
|
||||
if (nsnull == lastLine) { // if we had no lines before the drain operation
|
||||
mLines = overflowLines; // set our mLines to the overflow
|
||||
}
|
||||
else {
|
||||
else { // otherwise, append the overflow to the mLines list
|
||||
lastLine->mNext = overflowLines;
|
||||
nsIFrame* lastFrame = lastLine->LastChild();
|
||||
lastFrame->SetNextSibling(overflowLines->mFirstChild);
|
||||
|
|
|
@ -140,8 +140,15 @@ public:
|
|||
virtual void DeleteChildsNextInFlow(nsIPresContext* aPresContext,
|
||||
nsIFrame* aNextInFlow);
|
||||
|
||||
/** return the topmost block child based on y-index.
|
||||
* almost always the first or second line, if there is one.
|
||||
* accounts for lines that hold only compressed white space, etc.
|
||||
*/
|
||||
nsIFrame* GetTopBlockChild();
|
||||
|
||||
/** Place the floaters in the spacemanager for all lines in this block.
|
||||
* recursively adds floaters in child blocks of this frame.
|
||||
*/
|
||||
nsresult UpdateSpaceManager(nsIPresContext* aPresContext,
|
||||
nsISpaceManager* aSpaceManager);
|
||||
|
||||
|
@ -160,9 +167,16 @@ protected:
|
|||
return 0 != (mState & NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
|
||||
}
|
||||
|
||||
/** move the frames contained by aLine by aDY
|
||||
* if aLine is a block, it's child floaters are added to the state manager
|
||||
*/
|
||||
void SlideLine(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine, nscoord aDY);
|
||||
|
||||
/** grab overflow lines from this block's prevInFlow, and make them
|
||||
* part of this block's mLines list.
|
||||
* @return PR_TRUE if any lines were drained.
|
||||
*/
|
||||
PRBool DrainOverflowLines(nsIPresContext* aPresContext);
|
||||
|
||||
virtual PRIntn GetSkipSides() const;
|
||||
|
@ -171,26 +185,51 @@ protected:
|
|||
nsBlockReflowState& aState,
|
||||
nsHTMLReflowMetrics& aMetrics);
|
||||
|
||||
/** add the frames in aFrameList to this block after aPrevSibling
|
||||
* this block thinks in terms of lines, but the frame construction code
|
||||
* knows nothing about lines at all. So we need to find the line that
|
||||
* contains aPrevSibling and add aFrameList after aPrevSibling on that line.
|
||||
* new lines are created as necessary to handle block data in aFrameList.
|
||||
*/
|
||||
nsresult AddFrames(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aPrevSibling);
|
||||
|
||||
/** move the frame list rooted at aFrame into this as a child
|
||||
* assumes prev/next sibling pointers will be or have been set elsewhere
|
||||
* changes aFrame's parent to be this, and reparents aFrame's view and stylecontext.
|
||||
*/
|
||||
void FixParentAndView(nsIPresContext* aPresContext, nsIFrame* aFrame);
|
||||
|
||||
/** does all the real work for removing aDeletedFrame from this
|
||||
* finds the line containing aFrame.
|
||||
* handled continued frames
|
||||
* marks lines dirty as needed
|
||||
*/
|
||||
nsresult DoRemoveFrame(nsIPresContext* aPresContext,
|
||||
nsIFrame* aDeletedFrame);
|
||||
|
||||
|
||||
/** set up the conditions necessary for an initial reflow */
|
||||
nsresult PrepareInitialReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** set up the conditions necessary for an styleChanged reflow */
|
||||
nsresult PrepareStyleChangedReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** set up the conditions necessary for an incremental reflow.
|
||||
* the primary task is to mark the minimumly sufficient lines dirty.
|
||||
*/
|
||||
nsresult PrepareChildIncrementalReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** set up the conditions necessary for an resize reflow
|
||||
* the primary task is to mark the minimumly sufficient lines dirty.
|
||||
*/
|
||||
nsresult PrepareResizeReflow(nsBlockReflowState& aState);
|
||||
|
||||
/** reflow all lines that have been marked dirty */
|
||||
nsresult ReflowDirtyLines(nsBlockReflowState& aState);
|
||||
|
||||
/** set aState to what it would be if we had done a full reflow to this point. */
|
||||
void RecoverStateFrom(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nscoord aDeltaY,
|
||||
|
@ -198,8 +237,15 @@ protected:
|
|||
|
||||
//----------------------------------------
|
||||
// Methods for line reflow
|
||||
// XXX nuke em
|
||||
|
||||
/**
|
||||
* Reflow a line.
|
||||
* @param aState the current reflow state
|
||||
* @param aLine the line to reflow. can contain a single block frame
|
||||
* or contain 1 or more inline frames.
|
||||
* @param aKeepReflowGoing [OUT] indicates whether the caller should continue to reflow more lines
|
||||
* @param aDamageDirtyArea if PR_TRUE, do extra work to mark the changed areas as damaged for painting
|
||||
* this indicates that frames may have changed size, for example
|
||||
*/
|
||||
nsresult ReflowLine(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
PRBool* aKeepReflowGoing,
|
||||
|
|
|
@ -146,7 +146,7 @@ InitDebugFlags()
|
|||
}
|
||||
|
||||
#undef NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef NOISY_FIRST_LETTER
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FLOATER_CLEARING
|
||||
|
@ -410,6 +410,10 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsImpactedByFloater() {
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockReflowState::IsImpactedByFloater %p returned %d\n",
|
||||
this, mBand.GetFloaterCount());
|
||||
#endif
|
||||
return mBand.GetFloaterCount();
|
||||
}
|
||||
|
||||
|
@ -741,16 +745,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
(const nsStyleStruct*&) spacing);
|
||||
switch (spacing->mFloatEdge) {
|
||||
default:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floaters
|
||||
// The child block will flow around the floater. Therefore
|
||||
// give it all of the available space.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.width = mUnconstrainedWidth
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: mContentArea.width;
|
||||
break;
|
||||
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
case NS_STYLE_FLOAT_EDGE_PADDING:
|
||||
{
|
||||
// The child block's border should be placed adjacent to,
|
||||
|
@ -819,6 +822,9 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
aResult.x = mAvailSpaceRect.x + borderPadding.left;
|
||||
aResult.width = mAvailSpaceRect.width;
|
||||
}
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -1069,7 +1075,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
|||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyReflow || gNoisySpaceManager) {
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
// And then put the translation back again
|
||||
mSpaceManager->Translate(bp.left, bp.top);
|
||||
}
|
||||
|
@ -1394,8 +1404,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (gNoisyReflow) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
ListTag(stdout);
|
||||
printf(": begin reflow availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
printf(": begin reflow type %d availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.reason, aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
}
|
||||
if (gNoisy) {
|
||||
|
@ -1437,6 +1447,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Set the space manager in the existing reflow state
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
reflowState.mSpaceManager = spaceManager.get();
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p\n", reflowState.mSpaceManager);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
|
||||
|
@ -1621,23 +1634,45 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
PRInt32 verifyReflowFlags = nsIPresShell::GetVerifyReflowFlags();
|
||||
if (VERIFY_REFLOW_INCLUDE_SPACE_MANAGER & verifyReflowFlags)
|
||||
{
|
||||
// this is a leak of the space manager, but it's only in debug if verify reflow is enabled, so not a big deal
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
nsISpaceManager *spaceManager = reflowState.mSpaceManager;
|
||||
NS_ADDREF(spaceManager);
|
||||
rv = frameManager->SetFrameProperty(this, nsLayoutAtoms::spaceManagerProperty,
|
||||
reflowState.mSpaceManager, nsnull /* should be nsSpaceManagerDestroyer*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we set the space manager, then restore the old space manager now that we're
|
||||
// going out of scope
|
||||
if (NS_BLOCK_SPACE_MGR & mState) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", oldSpaceManager);
|
||||
#endif
|
||||
reflowState.mSpaceManager = oldSpaceManager;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
if (mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager after reflow\n");
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
if (reflowState.mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", reflowState.mSpaceManager);
|
||||
reflowState.mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If this is an incremental reflow and we changed size, then make sure our
|
||||
|
@ -2364,6 +2399,12 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
}
|
||||
else {
|
||||
// We can avoid reflowing *some* inline lines in some cases.
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("PrepareResizeReflow thinks line %p is %simpacted by floaters\n",
|
||||
line, line->IsImpactedByFloater() ? "" : "not ");
|
||||
#endif
|
||||
|
||||
|
||||
if (notWrapping) {
|
||||
// When no-wrap is set then the only line-breaking that
|
||||
// occurs for inline lines is triggered by BR elements or by
|
||||
|
@ -2525,7 +2566,11 @@ nsBlockFrame::PropogateReflowDamage(nsBlockReflowState& aState,
|
|||
//then we don't need to mark the line dirty.
|
||||
aState.GetAvailableSpace(next->mBounds.y + aDeltaY);
|
||||
PRBool wasImpactedByFloater = next->IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::PropogateReflowDamage %p was = %d, is=%d\n",
|
||||
this, wasImpactedByFloater, isImpactedByFloater);
|
||||
#endif
|
||||
if (wasImpactedByFloater != isImpactedByFloater) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
|
@ -2659,10 +2704,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||
{
|
||||
printf("line %p is not complete\n", line);
|
||||
}
|
||||
if (!keepGoing) {
|
||||
if (0 == line->GetChildCount()) {
|
||||
DeleteLine(aState, line);
|
||||
|
@ -2826,7 +2867,7 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
|||
|
||||
/**
|
||||
* Reflow a line. The line will either contain a single block frame
|
||||
* or contain 1 or more inline frames. aLineReflowStatus indicates
|
||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||
* whether or not the caller should continue to reflow more lines.
|
||||
*/
|
||||
nsresult
|
||||
|
@ -3512,7 +3553,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Compute the available space for the block
|
||||
aState.GetAvailableSpace();
|
||||
aLine->SetLineIsImpactedByFloater(aState.IsImpactedByFloater());
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("setting line %p isImpacted to %s\n", aLine, aState.IsImpactedByFloater()?"true":"false");
|
||||
#endif
|
||||
PRBool isImpacted = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(isImpacted);
|
||||
nsSplittableType splitType = NS_FRAME_NOT_SPLITTABLE;
|
||||
frame->IsSplittable(splitType);
|
||||
nsRect availSpace;
|
||||
|
@ -3855,8 +3900,12 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
// into. Apply a previous block frame's bottom margin first.
|
||||
aState.mY += aState.mPrevBottomMargin;
|
||||
aState.GetAvailableSpace();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(impactedByFloaters);
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
||||
this, impactedByFloaters);
|
||||
#endif
|
||||
|
||||
const nsMargin& borderPadding = aState.BorderPadding();
|
||||
nscoord x = aState.mAvailSpaceRect.x + borderPadding.left;
|
||||
|
@ -4697,10 +4746,10 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// we are told to reflow again before a next-in-flow is created
|
||||
// and reflows.
|
||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (nsnull == lastLine) {
|
||||
mLines = overflowLines;
|
||||
if (nsnull == lastLine) { // if we had no lines before the drain operation
|
||||
mLines = overflowLines; // set our mLines to the overflow
|
||||
}
|
||||
else {
|
||||
else { // otherwise, append the overflow to the mLines list
|
||||
lastLine->mNext = overflowLines;
|
||||
nsIFrame* lastFrame = lastLine->LastChild();
|
||||
lastFrame->SetNextSibling(overflowLines->mFirstChild);
|
||||
|
|
|
@ -146,7 +146,7 @@ InitDebugFlags()
|
|||
}
|
||||
|
||||
#undef NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef REALLY_NOISY_FIRST_LINE
|
||||
#undef NOISY_FIRST_LETTER
|
||||
#undef NOISY_MAX_ELEMENT_SIZE
|
||||
#undef NOISY_FLOATER_CLEARING
|
||||
|
@ -410,6 +410,10 @@ public:
|
|||
}
|
||||
|
||||
PRBool IsImpactedByFloater() {
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockReflowState::IsImpactedByFloater %p returned %d\n",
|
||||
this, mBand.GetFloaterCount());
|
||||
#endif
|
||||
return mBand.GetFloaterCount();
|
||||
}
|
||||
|
||||
|
@ -741,16 +745,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
(const nsStyleStruct*&) spacing);
|
||||
switch (spacing->mFloatEdge) {
|
||||
default:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT:
|
||||
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floaters
|
||||
// The child block will flow around the floater. Therefore
|
||||
// give it all of the available space.
|
||||
aResult.x = borderPadding.left;
|
||||
aResult.width = mUnconstrainedWidth
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: mContentArea.width;
|
||||
break;
|
||||
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_BORDER:
|
||||
case NS_STYLE_FLOAT_EDGE_PADDING:
|
||||
{
|
||||
// The child block's border should be placed adjacent to,
|
||||
|
@ -819,6 +822,9 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
aResult.x = mAvailSpaceRect.x + borderPadding.left;
|
||||
aResult.width = mAvailSpaceRect.width;
|
||||
}
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -1069,7 +1075,11 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
|||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (gNoisyReflow || gNoisySpaceManager) {
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
// And then put the translation back again
|
||||
mSpaceManager->Translate(bp.left, bp.top);
|
||||
}
|
||||
|
@ -1394,8 +1404,8 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (gNoisyReflow) {
|
||||
IndentBy(stdout, gNoiseIndent);
|
||||
ListTag(stdout);
|
||||
printf(": begin reflow availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
printf(": begin reflow type %d availSize=%d,%d computedSize=%d,%d\n",
|
||||
aReflowState.reason, aReflowState.availableWidth, aReflowState.availableHeight,
|
||||
aReflowState.mComputedWidth, aReflowState.mComputedHeight);
|
||||
}
|
||||
if (gNoisy) {
|
||||
|
@ -1437,6 +1447,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Set the space manager in the existing reflow state
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
reflowState.mSpaceManager = spaceManager.get();
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p\n", reflowState.mSpaceManager);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsBlockReflowState state(aReflowState, aPresContext, this, aMetrics,
|
||||
|
@ -1621,23 +1634,45 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// see if verifyReflow is enabled, and if so store off the space manager pointer
|
||||
#ifdef DEBUG
|
||||
PRInt32 verifyReflowFlags = nsIPresShell::GetVerifyReflowFlags();
|
||||
if (VERIFY_REFLOW_INCLUDE_SPACE_MANAGER & verifyReflowFlags)
|
||||
{
|
||||
// this is a leak of the space manager, but it's only in debug if verify reflow is enabled, so not a big deal
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
if (shell) {
|
||||
nsCOMPtr<nsIFrameManager> frameManager;
|
||||
shell->GetFrameManager(getter_AddRefs(frameManager));
|
||||
if (frameManager) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
nsISpaceManager *spaceManager = reflowState.mSpaceManager;
|
||||
NS_ADDREF(spaceManager);
|
||||
rv = frameManager->SetFrameProperty(this, nsLayoutAtoms::spaceManagerProperty,
|
||||
reflowState.mSpaceManager, nsnull /* should be nsSpaceManagerDestroyer*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we set the space manager, then restore the old space manager now that we're
|
||||
// going out of scope
|
||||
if (NS_BLOCK_SPACE_MGR & mState) {
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", oldSpaceManager);
|
||||
#endif
|
||||
reflowState.mSpaceManager = oldSpaceManager;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (eReflowReason_Incremental == aReflowState.reason) {
|
||||
if (mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager after reflow\n");
|
||||
mSpaceManager->List(stdout);
|
||||
}
|
||||
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
|
||||
if (reflowState.mSpaceManager) {
|
||||
ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", reflowState.mSpaceManager);
|
||||
reflowState.mSpaceManager->List(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// If this is an incremental reflow and we changed size, then make sure our
|
||||
|
@ -2364,6 +2399,12 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
|
|||
}
|
||||
else {
|
||||
// We can avoid reflowing *some* inline lines in some cases.
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("PrepareResizeReflow thinks line %p is %simpacted by floaters\n",
|
||||
line, line->IsImpactedByFloater() ? "" : "not ");
|
||||
#endif
|
||||
|
||||
|
||||
if (notWrapping) {
|
||||
// When no-wrap is set then the only line-breaking that
|
||||
// occurs for inline lines is triggered by BR elements or by
|
||||
|
@ -2525,7 +2566,11 @@ nsBlockFrame::PropogateReflowDamage(nsBlockReflowState& aState,
|
|||
//then we don't need to mark the line dirty.
|
||||
aState.GetAvailableSpace(next->mBounds.y + aDeltaY);
|
||||
PRBool wasImpactedByFloater = next->IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater();
|
||||
PRBool isImpactedByFloater = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::PropogateReflowDamage %p was = %d, is=%d\n",
|
||||
this, wasImpactedByFloater, isImpactedByFloater);
|
||||
#endif
|
||||
if (wasImpactedByFloater != isImpactedByFloater) {
|
||||
next->MarkDirty();
|
||||
}
|
||||
|
@ -2659,10 +2704,6 @@ nsBlockFrame::ReflowDirtyLines(nsBlockReflowState& aState)
|
|||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!(NS_FRAME_IS_COMPLETE(aState.mReflowStatus)))
|
||||
{
|
||||
printf("line %p is not complete\n", line);
|
||||
}
|
||||
if (!keepGoing) {
|
||||
if (0 == line->GetChildCount()) {
|
||||
DeleteLine(aState, line);
|
||||
|
@ -2826,7 +2867,7 @@ nsBlockFrame::DeleteLine(nsBlockReflowState& aState,
|
|||
|
||||
/**
|
||||
* Reflow a line. The line will either contain a single block frame
|
||||
* or contain 1 or more inline frames. aLineReflowStatus indicates
|
||||
* or contain 1 or more inline frames. aKeepReflowGoing indicates
|
||||
* whether or not the caller should continue to reflow more lines.
|
||||
*/
|
||||
nsresult
|
||||
|
@ -3512,7 +3553,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
|
||||
// Compute the available space for the block
|
||||
aState.GetAvailableSpace();
|
||||
aLine->SetLineIsImpactedByFloater(aState.IsImpactedByFloater());
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("setting line %p isImpacted to %s\n", aLine, aState.IsImpactedByFloater()?"true":"false");
|
||||
#endif
|
||||
PRBool isImpacted = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(isImpacted);
|
||||
nsSplittableType splitType = NS_FRAME_NOT_SPLITTABLE;
|
||||
frame->IsSplittable(splitType);
|
||||
nsRect availSpace;
|
||||
|
@ -3855,8 +3900,12 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
// into. Apply a previous block frame's bottom margin first.
|
||||
aState.mY += aState.mPrevBottomMargin;
|
||||
aState.GetAvailableSpace();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater();
|
||||
PRBool impactedByFloaters = aState.IsImpactedByFloater() ? PR_TRUE : PR_FALSE;
|
||||
aLine->SetLineIsImpactedByFloater(impactedByFloaters);
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
||||
this, impactedByFloaters);
|
||||
#endif
|
||||
|
||||
const nsMargin& borderPadding = aState.BorderPadding();
|
||||
nscoord x = aState.mAvailSpaceRect.x + borderPadding.left;
|
||||
|
@ -4697,10 +4746,10 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// we are told to reflow again before a next-in-flow is created
|
||||
// and reflows.
|
||||
nsLineBox* lastLine = nsLineBox::LastLine(mLines);
|
||||
if (nsnull == lastLine) {
|
||||
mLines = overflowLines;
|
||||
if (nsnull == lastLine) { // if we had no lines before the drain operation
|
||||
mLines = overflowLines; // set our mLines to the overflow
|
||||
}
|
||||
else {
|
||||
else { // otherwise, append the overflow to the mLines list
|
||||
lastLine->mNext = overflowLines;
|
||||
nsIFrame* lastFrame = lastLine->LastChild();
|
||||
lastFrame->SetNextSibling(overflowLines->mFirstChild);
|
||||
|
|
|
@ -32,10 +32,16 @@
|
|||
#include "nsAbsoluteContainingBlock.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
|
||||
#undef NOISY_FINAL_SIZE
|
||||
#ifdef DEBUG
|
||||
#undef NOISY_PUSHING
|
||||
#endif
|
||||
|
||||
nsIID nsInlineFrame::kInlineFrameCID = NS_INLINE_FRAME_CID;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Basic nsInlineFrame methods
|
||||
|
@ -426,6 +432,9 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext,
|
|||
PRBool reflowingFirstLetter = lineLayout->GetFirstLetterStyleOK();
|
||||
PRBool isComplete;
|
||||
frame = PullOneFrame(aPresContext, irs, &isComplete);
|
||||
#ifdef NOISY_PUSHING
|
||||
printf("%p pulled up %p\n", this, frame);
|
||||
#endif
|
||||
if (nsnull == frame) {
|
||||
if (!isComplete) {
|
||||
aStatus = NS_FRAME_NOT_COMPLETE;
|
||||
|
@ -668,6 +677,10 @@ nsInlineFrame::PushFrames(nsIPresContext* aPresContext,
|
|||
NS_PRECONDITION(prevNextSibling == aFromChild, "bad prev sibling");
|
||||
#endif
|
||||
|
||||
#ifdef NOISY_PUSHING
|
||||
printf("%p pushing aFromChild %p, disconnecting from prev sib %p\n",
|
||||
this, aFromChild, aPrevSibling);
|
||||
#endif
|
||||
// Disconnect aFromChild from its previous sibling
|
||||
aPrevSibling->SetNextSibling(nsnull);
|
||||
|
||||
|
|
|
@ -153,8 +153,8 @@ nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const
|
|||
{
|
||||
PR_snprintf(aBuf, aBufSize, "%s,%s,%s,%s[0x%x]",
|
||||
IsBlock() ? "block" : "inline",
|
||||
IsDirty() ? "dirty" : "",
|
||||
IsImpactedByFloater() ? "impacted" : "",
|
||||
IsDirty() ? "dirty" : "clean",
|
||||
IsImpactedByFloater() ? "IMPACTED" : "NOT Impacted",
|
||||
IsTrimmed() ? "trimmed" : "",
|
||||
mAllFlags);
|
||||
return aBuf;
|
||||
|
@ -353,16 +353,15 @@ nsLineBox::FreeFloaters(nsFloaterCacheFreeList& aFreeList)
|
|||
|
||||
void
|
||||
nsLineBox::RemoveFloatersFromSpaceManager(nsISpaceManager* aSpaceManager)
|
||||
{
|
||||
{
|
||||
if (IsInline()) {
|
||||
if (mInlineData) {
|
||||
nsFloaterCache* floaterCache = mInlineData->mFloaters.Head();
|
||||
|
||||
while (floaterCache) {
|
||||
nsIFrame* floater = floaterCache->mPlaceholder->GetOutOfFlowFrame();
|
||||
|
||||
aSpaceManager->RemoveRegion(floater);
|
||||
floaterCache = floaterCache->Next();
|
||||
floaterCache = floaterCache->Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -370,7 +369,7 @@ nsLineBox::RemoveFloatersFromSpaceManager(nsISpaceManager* aSpaceManager)
|
|||
|
||||
void
|
||||
nsLineBox::AppendFloaters(nsFloaterCacheFreeList& aFreeList)
|
||||
{
|
||||
{
|
||||
NS_ABORT_IF_FALSE(IsInline(), "block line can't have floaters");
|
||||
if (IsInline()) {
|
||||
if (aFreeList.NotEmpty()) {
|
||||
|
@ -404,7 +403,7 @@ nsLineBox::RemoveFloater(nsIFrame* aFrame)
|
|||
|
||||
void
|
||||
nsLineBox::SetCombinedArea(const nsRect& aCombinedArea)
|
||||
{
|
||||
{
|
||||
NS_ASSERTION(aCombinedArea.width >= 0, "illegal width for combined area");
|
||||
NS_ASSERTION(aCombinedArea.height >= 0, "illegal height for combined area");
|
||||
if (aCombinedArea != mBounds) {
|
||||
|
@ -428,13 +427,22 @@ nsLineBox::SetCombinedArea(const nsRect& aCombinedArea)
|
|||
}
|
||||
MaybeFreeData();
|
||||
}
|
||||
#ifdef VERY_NOISY_REFLOW
|
||||
printf("nsLB::SetCombinedArea(1) %p (%d, %d, %d, %d)\n",
|
||||
this, aCombinedArea.x, aCombinedArea.y, aCombinedArea.width, aCombinedArea.height);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsLineBox::GetCombinedArea(nsRect* aResult)
|
||||
{
|
||||
NS_ASSERTION(aResult, "null arg");
|
||||
if (aResult) {
|
||||
*aResult = mData ? mData->mCombinedArea : mBounds;
|
||||
#ifdef VERY_NOISY_REFLOW
|
||||
printf("nsLB::SetCombinedArea(1) %p (%d, %d, %d, %d)\n",
|
||||
this, aResult->x, aResult->y, aResult->width, aResult->height);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ public:
|
|||
|
||||
// mImpactedByFloater bit
|
||||
void SetLineIsImpactedByFloater(PRBool aValue) {
|
||||
NS_ASSERTION((PR_FALSE==aValue || PR_TRUE==aValue), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mImpactedByFloater = aValue;
|
||||
}
|
||||
PRBool IsImpactedByFloater() const {
|
||||
|
@ -197,6 +198,7 @@ public:
|
|||
|
||||
// mTrimmed bit
|
||||
void SetTrimmed(PRBool aOn) {
|
||||
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mTrimmed = aOn;
|
||||
}
|
||||
PRBool IsTrimmed() const {
|
||||
|
@ -205,6 +207,7 @@ public:
|
|||
|
||||
// mHasPercentageChild bit
|
||||
void SetHasPercentageChild(PRBool aOn) {
|
||||
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mHasPercentageChild = aOn;
|
||||
}
|
||||
PRBool HasPercentageChild() const {
|
||||
|
@ -213,6 +216,7 @@ public:
|
|||
|
||||
// mLineWrapped bit
|
||||
void SetLineWrapped(PRBool aOn) {
|
||||
NS_ASSERTION((PR_FALSE==aOn || PR_TRUE==aOn), "somebody is playing fast and loose with bools and bits!");
|
||||
mFlags.mLineWrapped = aOn;
|
||||
}
|
||||
PRBool IsLineWrapped() const {
|
||||
|
|
|
@ -235,6 +235,10 @@ nsLineLayout::BeginLineReflow(nscoord aX, nscoord aY,
|
|||
PRBool aImpactedByFloaters,
|
||||
PRBool aIsTopOfPage)
|
||||
{
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsLL::BeginLineReflow %d, %d, %d, %d, impacted=%s\n",
|
||||
aX, aY, aWidth, aHeight, aImpactedByFloaters?"true":"false");
|
||||
#endif
|
||||
NS_ASSERTION(nsnull == mRootSpan, "bad linelayout user");
|
||||
#ifdef DEBUG
|
||||
if ((aWidth != NS_UNCONSTRAINEDSIZE) && CRAZY_WIDTH(aWidth)) {
|
||||
|
@ -350,6 +354,10 @@ nsLineLayout::UpdateBand(nscoord aX, nscoord aY,
|
|||
PRBool aPlacedLeftFloater,
|
||||
nsIFrame* aFloaterFrame)
|
||||
{
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsLL::UpdateBand %d, %d, %d, %d, frame=%p placedLeft=%s\n will set mImpacted to PR_TRUE",
|
||||
aX, aY, aWidth, aHeight, aFloaterFrame, aPlacedLeftFloater?"true":"false");
|
||||
#endif
|
||||
PerSpanData* psd = mRootSpan;
|
||||
NS_PRECONDITION(psd->mX == psd->mLeftEdge, "update-band called late");
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 3
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsISpaceManager.h"
|
||||
#include "nsIPresContext.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include "nsIDOMSelection.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMNode.h"
|
||||
|
@ -573,15 +575,7 @@ VerifyStyleTree(nsIPresContext* aPresContext, nsIFrameManager* aFrameManager)
|
|||
* means that you cannot perform logging before then.
|
||||
*/
|
||||
static PRLogModuleInfo* gLogModule;
|
||||
|
||||
static PRUint32 gVerifyReflowFlags;
|
||||
|
||||
#define VERIFY_REFLOW_ON 0x01
|
||||
#define VERIFY_REFLOW_NOISY 0x02
|
||||
#define VERIFY_REFLOW_ALL 0x04
|
||||
#define VERIFY_REFLOW_DUMP_COMMANDS 0x08
|
||||
#define VERIFY_REFLOW_NOISY_RC 0x10
|
||||
#define VERIFY_REFLOW_REALLY_NOISY_RC 0x20
|
||||
#endif
|
||||
|
||||
static PRBool gVerifyReflowEnabled;
|
||||
|
@ -627,6 +621,12 @@ nsIPresShell::SetVerifyReflowEnable(PRBool aEnabled)
|
|||
gVerifyReflowEnabled = aEnabled;
|
||||
}
|
||||
|
||||
NS_LAYOUT PRInt32
|
||||
nsIPresShell::GetVerifyReflowFlags()
|
||||
{
|
||||
return gVerifyReflowFlags;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
NS_LAYOUT nsresult
|
||||
|
@ -1406,6 +1406,13 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
|||
#endif
|
||||
}
|
||||
ExitReflowLock(PR_TRUE);
|
||||
// if the proper flag is set, VerifyReflow now
|
||||
if (GetVerifyReflowEnable() && (VERIFY_REFLOW_DURING_RESIZE_REFLOW & gVerifyReflowFlags))
|
||||
{
|
||||
mInVerifyReflow = PR_TRUE;
|
||||
PRBool ok = VerifyIncrementalReflow();
|
||||
mInVerifyReflow = PR_FALSE;
|
||||
}
|
||||
|
||||
return NS_OK; //XXX this needs to be real. MMP
|
||||
}
|
||||
|
@ -3231,6 +3238,8 @@ static PRBool
|
|||
CompareTrees(nsIPresContext* aFirstPresContext, nsIFrame* aFirstFrame,
|
||||
nsIPresContext* aSecondPresContext, nsIFrame* aSecondFrame)
|
||||
{
|
||||
if (!aFirstPresContext || !aFirstFrame || !aSecondPresContext || !aSecondFrame)
|
||||
return PR_TRUE;
|
||||
PRBool ok = PR_TRUE;
|
||||
nsIAtom* listName = nsnull;
|
||||
PRInt32 listIndex = 0;
|
||||
|
@ -3305,6 +3314,115 @@ CompareTrees(nsIPresContext* aFirstPresContext, nsIFrame* aFirstFrame,
|
|||
break;
|
||||
}
|
||||
|
||||
// verify that neither frame has a space manager,
|
||||
// or they both do and the space managers are equivalent
|
||||
nsCOMPtr<nsIFrameManager>fm1;
|
||||
nsCOMPtr<nsIPresShell> ps1;
|
||||
nsISpaceManager *sm1; // note, no ref counting here
|
||||
aFirstPresContext->GetShell(getter_AddRefs(ps1));
|
||||
NS_ASSERTION(ps1, "no pres shell for primary tree!");
|
||||
ps1->GetFrameManager(getter_AddRefs(fm1));
|
||||
NS_ASSERTION(fm1, "no frame manager for primary tree!");
|
||||
fm1->GetFrameProperty((nsIFrame*)k1, nsLayoutAtoms::spaceManagerProperty,
|
||||
0, (void **)&sm1);
|
||||
// look at the test frame
|
||||
nsCOMPtr<nsIFrameManager>fm2;
|
||||
nsCOMPtr<nsIPresShell> ps2;
|
||||
nsISpaceManager *sm2; // note, no ref counting here
|
||||
aSecondPresContext->GetShell(getter_AddRefs(ps2));
|
||||
NS_ASSERTION(ps2, "no pres shell for test tree!");
|
||||
ps2->GetFrameManager(getter_AddRefs(fm2));
|
||||
NS_ASSERTION(fm2, "no frame manager for test tree!");
|
||||
fm2->GetFrameProperty((nsIFrame*)k2, nsLayoutAtoms::spaceManagerProperty,
|
||||
0, (void **)&sm2);
|
||||
// now compare the space managers
|
||||
if (((nsnull == sm1) && (nsnull != sm2)) ||
|
||||
((nsnull != sm1) && (nsnull == sm2))) { // one is null, and the other is not
|
||||
ok = PR_FALSE;
|
||||
LogVerifyMessage(k1, k2, "space managers are not matched\n");
|
||||
}
|
||||
else if (sm1 && sm2) { // both are not null, compare them
|
||||
// first, compare yMost
|
||||
nscoord yMost1, yMost2;
|
||||
nsresult smresult = sm1->YMost(yMost1);
|
||||
if (NS_ERROR_ABORT != smresult)
|
||||
{
|
||||
NS_ASSERTION(NS_SUCCEEDED(smresult), "bad result");
|
||||
smresult = sm2->YMost(yMost2);
|
||||
NS_ASSERTION(NS_SUCCEEDED(smresult), "bad result");
|
||||
if (yMost1 != yMost2) {
|
||||
LogVerifyMessage(k1, k2, "yMost of space managers differs\n");
|
||||
}
|
||||
// now compare bands by sampling
|
||||
PRInt32 yIncrement = yMost1/100;
|
||||
if (0==yIncrement) {
|
||||
yIncrement = 1; // guarantee we make progress in the loop below
|
||||
}
|
||||
nscoord yOffset = 0;
|
||||
for ( ; ok && yOffset < yMost1; yOffset += yIncrement)
|
||||
{
|
||||
nscoord small=5, large=100;
|
||||
nsBandData band1, band2;
|
||||
nsBandTrapezoid trap1[20], trap2[20];
|
||||
band1.mSize = band2.mSize = 20;
|
||||
band1.mTrapezoids = trap1;
|
||||
band2.mTrapezoids = trap2;
|
||||
sm1->GetBandData(yOffset, nsSize(small,small), band1);
|
||||
sm2->GetBandData(yOffset, nsSize(small,small), band2);
|
||||
if (band1.mCount != band2.mCount)
|
||||
{ // count mismatch, stop comparing
|
||||
LogVerifyMessage(k1, k2, "band.mCount of space managers differs\n");
|
||||
printf("count1= %d, count2=%d, yOffset = %d, size=%d\n",
|
||||
band1.mCount, band2.mCount, yOffset, small);
|
||||
ok = PR_FALSE;
|
||||
|
||||
}
|
||||
else // band counts match, compare individual traps
|
||||
{
|
||||
PRInt32 trapIndex=0;
|
||||
for ( ;trapIndex<band1.mCount; trapIndex++)
|
||||
{
|
||||
PRBool match = (trap1[trapIndex].EqualGeometry(trap2[trapIndex])) &&
|
||||
trap1[trapIndex].mState == trap2[trapIndex].mState;
|
||||
if (!match)
|
||||
{
|
||||
LogVerifyMessage(k1, k2, "band.mTrapezoids of space managers differs\n");
|
||||
printf ("index %d\n", trapIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
// test the larger maxSize
|
||||
sm1->GetBandData(yOffset, nsSize(large,large), band1);
|
||||
sm2->GetBandData(yOffset, nsSize(large,large), band2);
|
||||
if (band1.mCount != band2.mCount)
|
||||
{ // count mismatch, stop comparing
|
||||
LogVerifyMessage(k1, k2, "band.mCount of space managers differs\n");
|
||||
printf("count1= %d, count2=%d, yOffset = %d, size=%d\n",
|
||||
band1.mCount, band2.mCount, yOffset, small);
|
||||
ok = PR_FALSE;
|
||||
|
||||
}
|
||||
else // band counts match, compare individual traps
|
||||
{
|
||||
PRInt32 trapIndex=0;
|
||||
for ( ; trapIndex<band1.mCount; trapIndex++)
|
||||
{
|
||||
PRBool match = (trap1[trapIndex].EqualGeometry(trap2[trapIndex])) &&
|
||||
trap1[trapIndex].mState == trap2[trapIndex].mState;
|
||||
if (!match)
|
||||
{
|
||||
LogVerifyMessage(k1, k2, "band.mTrapezoids of space managers differs\n");
|
||||
printf ("index %d\n", trapIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Compare the sub-trees too
|
||||
if (!CompareTrees(aFirstPresContext, k1, aSecondPresContext, k2)) {
|
||||
ok = PR_FALSE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче