Fix crash printing fixed-position float elements (bug 200347), r=kin@netscape.com, sr=dbaron@dbaron.org, a=asa
git-svn-id: svn://10.0.0.236/trunk@142762 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -45,6 +45,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsHTMLReflowState.h"
|
||||
#ifdef DEBUG
|
||||
#include "nsIFrameDebug.h"
|
||||
#endif
|
||||
@@ -1377,3 +1378,54 @@ nsSpaceManager::BandRect::Length() const
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsAutoSpaceManager::~nsAutoSpaceManager()
|
||||
{
|
||||
// Restore the old space manager in the reflow state if necessary.
|
||||
if (mNew) {
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", mOld);
|
||||
#endif
|
||||
|
||||
mReflowState.mSpaceManager = mOld;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (mOld) {
|
||||
NS_STATIC_CAST(nsFrame *, mReflowState.frame)->ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", mOld);
|
||||
mOld->List(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mOwns)
|
||||
#endif
|
||||
delete mNew;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoSpaceManager::CreateSpaceManagerFor(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
||||
{
|
||||
// Create a new space manager and install it in the reflow
|
||||
// state. `Remember' the old space manager so we can restore it
|
||||
// later.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
mNew = new nsSpaceManager(shell, aFrame);
|
||||
if (! mNew)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p (replacing %p)\n",
|
||||
mNew, mReflowState.mSpaceManager);
|
||||
#endif
|
||||
|
||||
// Set the space manager in the existing reflow state
|
||||
mOld = mReflowState.mSpaceManager;
|
||||
mReflowState.mSpaceManager = mNew;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ class nsIPresShell;
|
||||
class nsIFrame;
|
||||
class nsVoidArray;
|
||||
struct nsSize;
|
||||
struct nsHTMLReflowState;
|
||||
class nsIPresContext;
|
||||
|
||||
#define NS_SPACE_MANAGER_CACHE_SIZE 4
|
||||
|
||||
@@ -438,5 +440,49 @@ private:
|
||||
void operator=(const nsSpaceManager&); // no implementation
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class to manage maintenance of the space manager during
|
||||
* nsBlockFrame::Reflow. It automatically restores the old space
|
||||
* manager in the reflow state when the object goes out of scope.
|
||||
*/
|
||||
class nsAutoSpaceManager {
|
||||
public:
|
||||
nsAutoSpaceManager(nsHTMLReflowState& aReflowState)
|
||||
: mReflowState(aReflowState),
|
||||
#ifdef DEBUG
|
||||
mOwns(PR_TRUE),
|
||||
#endif
|
||||
mNew(nsnull),
|
||||
mOld(nsnull) {}
|
||||
|
||||
~nsAutoSpaceManager();
|
||||
|
||||
/**
|
||||
* Create a new space manager for the specified frame. This will
|
||||
* `remember' the old space manager, and install the new space
|
||||
* manager in the reflow state.
|
||||
*/
|
||||
nsresult
|
||||
CreateSpaceManagerFor(nsIPresContext *aPresContext,
|
||||
nsIFrame *aFrame);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* `Orphan' any space manager that the nsAutoSpaceManager created;
|
||||
* i.e., make it so that we don't destroy the space manager when we
|
||||
* go out of scope.
|
||||
*/
|
||||
void DebugOrphanSpaceManager() { mOwns = PR_FALSE; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsHTMLReflowState &mReflowState;
|
||||
#ifdef DEBUG
|
||||
PRBool mOwns;
|
||||
#endif
|
||||
nsSpaceManager *mNew;
|
||||
nsSpaceManager *mOld;
|
||||
};
|
||||
|
||||
#endif /* nsSpaceManager_h___ */
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsSpaceManager.h"
|
||||
|
||||
class nsLegendFrame;
|
||||
|
||||
@@ -302,7 +303,17 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext,
|
||||
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
|
||||
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// Should we create a space manager?
|
||||
nsAutoSpaceManager autoSpaceManager(NS_CONST_CAST(nsHTMLReflowState &, aReflowState));
|
||||
|
||||
// XXXldb If we start storing the space manager in the frame rather
|
||||
// than keeping it around only during reflow then we should create it
|
||||
// only when there are actually floats to manage. Otherwise things
|
||||
// like tables will gain significant bloat.
|
||||
if (NS_BLOCK_SPACE_MGR & mState)
|
||||
autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
|
||||
|
||||
if (aDesiredSize.mComputeMEW) {
|
||||
aDesiredSize.mMaxElementWidth = 0;
|
||||
|
||||
@@ -253,100 +253,6 @@ RecordReflowStatus(PRBool aChildIsBlock, nsReflowStatus aFrameReflowStatus)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A helper class to manage maintenance of the space manager during
|
||||
* nsBlockFrame::Reflow. It automatically restores the old space
|
||||
* manager in the reflow state when the object goes out of scope.
|
||||
*/
|
||||
class nsAutoSpaceManager {
|
||||
public:
|
||||
nsAutoSpaceManager(nsHTMLReflowState& aReflowState)
|
||||
: mReflowState(aReflowState),
|
||||
#ifdef DEBUG
|
||||
mOwns(PR_TRUE),
|
||||
#endif
|
||||
mNew(nsnull),
|
||||
mOld(nsnull) {}
|
||||
|
||||
~nsAutoSpaceManager();
|
||||
|
||||
/**
|
||||
* Create a new space manager for the specified frame. This will
|
||||
* `remember' the old space manager, and install the new space
|
||||
* manager in the reflow state.
|
||||
*/
|
||||
nsresult
|
||||
CreateSpaceManagerFor(nsIPresContext *aPresContext,
|
||||
nsIFrame *aFrame);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* `Orphan' any space manager that the nsAutoSpaceManager created;
|
||||
* i.e., make it so that we don't destroy the space manager when we
|
||||
* go out of scope.
|
||||
*/
|
||||
void DebugOrphanSpaceManager() { mOwns = PR_FALSE; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsHTMLReflowState &mReflowState;
|
||||
#ifdef DEBUG
|
||||
PRBool mOwns;
|
||||
#endif
|
||||
nsSpaceManager *mNew;
|
||||
nsSpaceManager *mOld;
|
||||
};
|
||||
|
||||
nsAutoSpaceManager::~nsAutoSpaceManager()
|
||||
{
|
||||
// Restore the old space manager in the reflow state if necessary.
|
||||
if (mNew) {
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", mOld);
|
||||
#endif
|
||||
|
||||
mReflowState.mSpaceManager = mOld;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (mOld) {
|
||||
NS_STATIC_CAST(nsFrame *, mReflowState.frame)->ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", mOld);
|
||||
mOld->List(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mOwns)
|
||||
#endif
|
||||
delete mNew;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoSpaceManager::CreateSpaceManagerFor(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
||||
{
|
||||
// Create a new space manager and install it in the reflow
|
||||
// state. `Remember' the old space manager so we can restore it
|
||||
// later.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
mNew = new nsSpaceManager(shell, aFrame);
|
||||
if (! mNew)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p (replacing %p)\n",
|
||||
mNew, mReflowState.mSpaceManager);
|
||||
#endif
|
||||
|
||||
// Set the space manager in the existing reflow state
|
||||
mOld = mReflowState.mSpaceManager;
|
||||
mReflowState.mSpaceManager = mNew;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void
|
||||
nsBlockFrame::CombineRects(const nsRect& r1, nsRect& r2)
|
||||
{
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsHTMLReflowState.h"
|
||||
#ifdef DEBUG
|
||||
#include "nsIFrameDebug.h"
|
||||
#endif
|
||||
@@ -1377,3 +1378,54 @@ nsSpaceManager::BandRect::Length() const
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsAutoSpaceManager::~nsAutoSpaceManager()
|
||||
{
|
||||
// Restore the old space manager in the reflow state if necessary.
|
||||
if (mNew) {
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", mOld);
|
||||
#endif
|
||||
|
||||
mReflowState.mSpaceManager = mOld;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (mOld) {
|
||||
NS_STATIC_CAST(nsFrame *, mReflowState.frame)->ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", mOld);
|
||||
mOld->List(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mOwns)
|
||||
#endif
|
||||
delete mNew;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoSpaceManager::CreateSpaceManagerFor(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
||||
{
|
||||
// Create a new space manager and install it in the reflow
|
||||
// state. `Remember' the old space manager so we can restore it
|
||||
// later.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
mNew = new nsSpaceManager(shell, aFrame);
|
||||
if (! mNew)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p (replacing %p)\n",
|
||||
mNew, mReflowState.mSpaceManager);
|
||||
#endif
|
||||
|
||||
// Set the space manager in the existing reflow state
|
||||
mOld = mReflowState.mSpaceManager;
|
||||
mReflowState.mSpaceManager = mNew;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ class nsIPresShell;
|
||||
class nsIFrame;
|
||||
class nsVoidArray;
|
||||
struct nsSize;
|
||||
struct nsHTMLReflowState;
|
||||
class nsIPresContext;
|
||||
|
||||
#define NS_SPACE_MANAGER_CACHE_SIZE 4
|
||||
|
||||
@@ -438,5 +440,49 @@ private:
|
||||
void operator=(const nsSpaceManager&); // no implementation
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class to manage maintenance of the space manager during
|
||||
* nsBlockFrame::Reflow. It automatically restores the old space
|
||||
* manager in the reflow state when the object goes out of scope.
|
||||
*/
|
||||
class nsAutoSpaceManager {
|
||||
public:
|
||||
nsAutoSpaceManager(nsHTMLReflowState& aReflowState)
|
||||
: mReflowState(aReflowState),
|
||||
#ifdef DEBUG
|
||||
mOwns(PR_TRUE),
|
||||
#endif
|
||||
mNew(nsnull),
|
||||
mOld(nsnull) {}
|
||||
|
||||
~nsAutoSpaceManager();
|
||||
|
||||
/**
|
||||
* Create a new space manager for the specified frame. This will
|
||||
* `remember' the old space manager, and install the new space
|
||||
* manager in the reflow state.
|
||||
*/
|
||||
nsresult
|
||||
CreateSpaceManagerFor(nsIPresContext *aPresContext,
|
||||
nsIFrame *aFrame);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* `Orphan' any space manager that the nsAutoSpaceManager created;
|
||||
* i.e., make it so that we don't destroy the space manager when we
|
||||
* go out of scope.
|
||||
*/
|
||||
void DebugOrphanSpaceManager() { mOwns = PR_FALSE; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsHTMLReflowState &mReflowState;
|
||||
#ifdef DEBUG
|
||||
PRBool mOwns;
|
||||
#endif
|
||||
nsSpaceManager *mNew;
|
||||
nsSpaceManager *mOld;
|
||||
};
|
||||
|
||||
#endif /* nsSpaceManager_h___ */
|
||||
|
||||
|
||||
@@ -253,100 +253,6 @@ RecordReflowStatus(PRBool aChildIsBlock, nsReflowStatus aFrameReflowStatus)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A helper class to manage maintenance of the space manager during
|
||||
* nsBlockFrame::Reflow. It automatically restores the old space
|
||||
* manager in the reflow state when the object goes out of scope.
|
||||
*/
|
||||
class nsAutoSpaceManager {
|
||||
public:
|
||||
nsAutoSpaceManager(nsHTMLReflowState& aReflowState)
|
||||
: mReflowState(aReflowState),
|
||||
#ifdef DEBUG
|
||||
mOwns(PR_TRUE),
|
||||
#endif
|
||||
mNew(nsnull),
|
||||
mOld(nsnull) {}
|
||||
|
||||
~nsAutoSpaceManager();
|
||||
|
||||
/**
|
||||
* Create a new space manager for the specified frame. This will
|
||||
* `remember' the old space manager, and install the new space
|
||||
* manager in the reflow state.
|
||||
*/
|
||||
nsresult
|
||||
CreateSpaceManagerFor(nsIPresContext *aPresContext,
|
||||
nsIFrame *aFrame);
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* `Orphan' any space manager that the nsAutoSpaceManager created;
|
||||
* i.e., make it so that we don't destroy the space manager when we
|
||||
* go out of scope.
|
||||
*/
|
||||
void DebugOrphanSpaceManager() { mOwns = PR_FALSE; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
nsHTMLReflowState &mReflowState;
|
||||
#ifdef DEBUG
|
||||
PRBool mOwns;
|
||||
#endif
|
||||
nsSpaceManager *mNew;
|
||||
nsSpaceManager *mOld;
|
||||
};
|
||||
|
||||
nsAutoSpaceManager::~nsAutoSpaceManager()
|
||||
{
|
||||
// Restore the old space manager in the reflow state if necessary.
|
||||
if (mNew) {
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("restoring old space manager %p\n", mOld);
|
||||
#endif
|
||||
|
||||
mReflowState.mSpaceManager = mOld;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
if (mOld) {
|
||||
NS_STATIC_CAST(nsFrame *, mReflowState.frame)->ListTag(stdout);
|
||||
printf(": space-manager %p after reflow\n", mOld);
|
||||
mOld->List(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (mOwns)
|
||||
#endif
|
||||
delete mNew;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAutoSpaceManager::CreateSpaceManagerFor(nsIPresContext *aPresContext, nsIFrame *aFrame)
|
||||
{
|
||||
// Create a new space manager and install it in the reflow
|
||||
// state. `Remember' the old space manager so we can restore it
|
||||
// later.
|
||||
nsCOMPtr<nsIPresShell> shell;
|
||||
aPresContext->GetShell(getter_AddRefs(shell));
|
||||
mNew = new nsSpaceManager(shell, aFrame);
|
||||
if (! mNew)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
#ifdef NOISY_SPACEMANAGER
|
||||
printf("constructed new space manager %p (replacing %p)\n",
|
||||
mNew, mReflowState.mSpaceManager);
|
||||
#endif
|
||||
|
||||
// Set the space manager in the existing reflow state
|
||||
mOld = mReflowState.mSpaceManager;
|
||||
mReflowState.mSpaceManager = mNew;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void
|
||||
nsBlockFrame::CombineRects(const nsRect& r1, nsRect& r2)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsSpaceManager.h"
|
||||
|
||||
class nsLegendFrame;
|
||||
|
||||
@@ -302,7 +303,17 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext,
|
||||
DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
|
||||
|
||||
// Initialize OUT parameter
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
// Should we create a space manager?
|
||||
nsAutoSpaceManager autoSpaceManager(NS_CONST_CAST(nsHTMLReflowState &, aReflowState));
|
||||
|
||||
// XXXldb If we start storing the space manager in the frame rather
|
||||
// than keeping it around only during reflow then we should create it
|
||||
// only when there are actually floats to manage. Otherwise things
|
||||
// like tables will gain significant bloat.
|
||||
if (NS_BLOCK_SPACE_MGR & mState)
|
||||
autoSpaceManager.CreateSpaceManagerFor(aPresContext, this);
|
||||
|
||||
if (aDesiredSize.mComputeMEW) {
|
||||
aDesiredSize.mMaxElementWidth = 0;
|
||||
|
||||
Reference in New Issue
Block a user