r=troy

The problem was the space mgr was computing mCount to be > 2* mSize, which this code couldn't handle correctly. So now if the space mgr computes mCount to be more than twice the size of the current count, we immediately bump up the size to that count.� If more are needed later, the next call will give us twice this number anyway.
This commit is contained in:
buster%netscape.com 1999-12-23 20:49:07 +00:00
Родитель f7bfb1a5f7
Коммит 64906b0b20
4 изменённых файлов: 114 добавлений и 32 удалений

Просмотреть файл

@ -74,20 +74,8 @@ nsresult
nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
{
// Get the raw band data for the given Y coordinate
nsresult rv = mSpaceManager->GetBandData(aY, mSpace, *this);
while (NS_FAILED(rv)) {
// We need more space for our bands
if (mTrapezoids != mData) {
delete [] mTrapezoids;
}
PRInt32 newSize = mSize * 2;
mTrapezoids = new nsBandTrapezoid[newSize];
if (!mTrapezoids) {
return NS_ERROR_OUT_OF_MEMORY;
}
mSize = newSize;
rv = mSpaceManager->GetBandData(aY, mSpace, *this);
}
nsresult rv = GetBandData(aY);
if (NS_FAILED(rv)) { return rv; }
// Compute the bounding rect of the available space, i.e. space
// between any left and right floaters.
@ -96,6 +84,46 @@ nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
return NS_OK;
}
// the code below should never loop more than a very few times.
// this is a safety valve to see if we've gone off the deep end
#define ERROR_TOO_MANY_ITERATIONS 1000
/* nsBlockBandData methods should never call mSpaceManager->GetBandData directly.
* They should always call nsBlockBandData::GetBandData() instead.
*/
nsresult
nsBlockBandData::GetBandData(nscoord aY)
{
PRInt32 iterations =0;
nsresult rv = mSpaceManager->GetBandData(aY, mSpace, *this);
while (NS_FAILED(rv)) {
iterations++;
if (iterations>ERROR_TOO_MANY_ITERATIONS)
{
NS_ASSERTION(PR_FALSE, "too many iterations in nsBlockBandData::GetBandData");
return NS_ERROR_FAILURE;
}
// We need more space for our bands
if (mTrapezoids != mData) {
delete [] mTrapezoids;
}
PRInt32 newSize = mSize * 2;
if (newSize<mCount) {
newSize = mCount;
}
mTrapezoids = new nsBandTrapezoid[newSize];
if (!mTrapezoids) {
return NS_ERROR_OUT_OF_MEMORY;
}
mSize = newSize;
rv = mSpaceManager->GetBandData(aY, mSpace, *this);
}
NS_POSTCONDITION(mCount<=mSize, "bad state, count > size");
return NS_OK;
}
/**
* Computes the bounding rect of the available space, i.e. space
* between any left and right floaters. Uses the current trapezoid
@ -125,6 +153,7 @@ nsBlockBandData::ComputeAvailSpaceRect()
// Examine each trapezoid in the band, counting up the number of
// left and right floaters. Use the right-most floater to
// determine where the right edge of the available space is.
NS_PRECONDITION(mCount<=mSize, "bad state, count > size");
for (i = 0; i < mCount; i++) {
trapezoid = &mTrapezoids[i];
if (trapezoid->mState != nsBandTrapezoid::Available) {
@ -245,8 +274,10 @@ nscoord
nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
{
for (;;) {
// Update band information based on target Y before clearing.
mSpaceManager->GetBandData(aY, mSpace, *this);
nsresult rv = GetBandData(aY);
if (NS_FAILED(rv)) {
break; // something is seriously wrong, bail
}
ComputeAvailSpaceRect();
// Compute aYS as aY in space-manager "root" coordinates.
@ -256,6 +287,7 @@ nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
// this band.
nscoord yMost = aYS;
PRInt32 i;
NS_PRECONDITION(mCount<=mSize, "bad state, count > size");
for (i = 0; i < mCount; i++) {
nsBandTrapezoid* trapezoid = &mTrapezoids[i];
if (nsBandTrapezoid::Available != trapezoid->mState) {

Просмотреть файл

@ -90,6 +90,15 @@ public:
nsSize* aResult);
protected:
/** utility method to calculate the band data at aY.
* nsBlockBandData methods should never call
* mSpaceManager->GetBandData directly.
* They should always call this method instead so data members
* mTrapezoid, mCount, and mSize all get managed properly.
*/
nsresult GetBandData(nscoord aY);
// The spacemanager we are getting space from
nsISpaceManager* mSpaceManager;
nscoord mSpaceManagerX, mSpaceManagerY;

Просмотреть файл

@ -74,20 +74,8 @@ nsresult
nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
{
// Get the raw band data for the given Y coordinate
nsresult rv = mSpaceManager->GetBandData(aY, mSpace, *this);
while (NS_FAILED(rv)) {
// We need more space for our bands
if (mTrapezoids != mData) {
delete [] mTrapezoids;
}
PRInt32 newSize = mSize * 2;
mTrapezoids = new nsBandTrapezoid[newSize];
if (!mTrapezoids) {
return NS_ERROR_OUT_OF_MEMORY;
}
mSize = newSize;
rv = mSpaceManager->GetBandData(aY, mSpace, *this);
}
nsresult rv = GetBandData(aY);
if (NS_FAILED(rv)) { return rv; }
// Compute the bounding rect of the available space, i.e. space
// between any left and right floaters.
@ -96,6 +84,46 @@ nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
return NS_OK;
}
// the code below should never loop more than a very few times.
// this is a safety valve to see if we've gone off the deep end
#define ERROR_TOO_MANY_ITERATIONS 1000
/* nsBlockBandData methods should never call mSpaceManager->GetBandData directly.
* They should always call nsBlockBandData::GetBandData() instead.
*/
nsresult
nsBlockBandData::GetBandData(nscoord aY)
{
PRInt32 iterations =0;
nsresult rv = mSpaceManager->GetBandData(aY, mSpace, *this);
while (NS_FAILED(rv)) {
iterations++;
if (iterations>ERROR_TOO_MANY_ITERATIONS)
{
NS_ASSERTION(PR_FALSE, "too many iterations in nsBlockBandData::GetBandData");
return NS_ERROR_FAILURE;
}
// We need more space for our bands
if (mTrapezoids != mData) {
delete [] mTrapezoids;
}
PRInt32 newSize = mSize * 2;
if (newSize<mCount) {
newSize = mCount;
}
mTrapezoids = new nsBandTrapezoid[newSize];
if (!mTrapezoids) {
return NS_ERROR_OUT_OF_MEMORY;
}
mSize = newSize;
rv = mSpaceManager->GetBandData(aY, mSpace, *this);
}
NS_POSTCONDITION(mCount<=mSize, "bad state, count > size");
return NS_OK;
}
/**
* Computes the bounding rect of the available space, i.e. space
* between any left and right floaters. Uses the current trapezoid
@ -125,6 +153,7 @@ nsBlockBandData::ComputeAvailSpaceRect()
// Examine each trapezoid in the band, counting up the number of
// left and right floaters. Use the right-most floater to
// determine where the right edge of the available space is.
NS_PRECONDITION(mCount<=mSize, "bad state, count > size");
for (i = 0; i < mCount; i++) {
trapezoid = &mTrapezoids[i];
if (trapezoid->mState != nsBandTrapezoid::Available) {
@ -245,8 +274,10 @@ nscoord
nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
{
for (;;) {
// Update band information based on target Y before clearing.
mSpaceManager->GetBandData(aY, mSpace, *this);
nsresult rv = GetBandData(aY);
if (NS_FAILED(rv)) {
break; // something is seriously wrong, bail
}
ComputeAvailSpaceRect();
// Compute aYS as aY in space-manager "root" coordinates.
@ -256,6 +287,7 @@ nsBlockBandData::ClearFloaters(nscoord aY, PRUint8 aBreakType)
// this band.
nscoord yMost = aYS;
PRInt32 i;
NS_PRECONDITION(mCount<=mSize, "bad state, count > size");
for (i = 0; i < mCount; i++) {
nsBandTrapezoid* trapezoid = &mTrapezoids[i];
if (nsBandTrapezoid::Available != trapezoid->mState) {

Просмотреть файл

@ -90,6 +90,15 @@ public:
nsSize* aResult);
protected:
/** utility method to calculate the band data at aY.
* nsBlockBandData methods should never call
* mSpaceManager->GetBandData directly.
* They should always call this method instead so data members
* mTrapezoid, mCount, and mSize all get managed properly.
*/
nsresult GetBandData(nscoord aY);
// The spacemanager we are getting space from
nsISpaceManager* mSpaceManager;
nscoord mSpaceManagerX, mSpaceManagerY;