Move clearing from nsBlockBandData to nsSpaceManager so that 'clear' works even when the floats to be cleared don't overlap the block's border-box. b=148994 Patch by Blake Kaplan <mrbkap@rice.edu>. r+sr=dbaron

This commit is contained in:
dbaron%dbaron.org 2004-06-08 19:18:30 +00:00
Родитель eb8906c0f3
Коммит be338c15ee
10 изменённых файлов: 94 добавлений и 160 удалений

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

@ -1185,6 +1185,45 @@ nsSpaceManager::DestroyFrameInfo(FrameInfo* aFrameInfo)
delete aFrameInfo;
}
static PRBool
ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType)
{
PRUint8 floatType = aFrame->GetStyleDisplay()->mFloats;
PRBool result;
switch (aBreakType) {
case NS_STYLE_CLEAR_LEFT_AND_RIGHT:
result = PR_TRUE;
break;
case NS_STYLE_CLEAR_LEFT:
result = floatType == NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_CLEAR_RIGHT:
result = floatType == NS_STYLE_FLOAT_RIGHT;
break;
default:
result = PR_FALSE;
}
return result;
}
nscoord
nsSpaceManager::ClearFloats(nscoord aY, PRUint8 aBreakType)
{
nscoord bottom = aY + mY;
for (FrameInfo *frame = mFrameInfoMap; frame; frame = frame->mNext) {
if (ShouldClearFrame(frame->mFrame, aBreakType)) {
if (frame->mRect.YMost() > bottom) {
bottom = frame->mRect.YMost();
}
}
}
bottom -= mY;
return bottom;
}
/////////////////////////////////////////////////////////////////////////////
// FrameInfo

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

@ -303,6 +303,12 @@ public:
*/
nscoord GetLowestRegionTop();
/**
* Return the coordinate of the lowest float matching aBreakType in this
* space manager. Returns aY if there are no matching floats.
*/
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType);
#ifdef DEBUG
/**
* Dump the state of the spacemanager out to a file

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

@ -266,80 +266,6 @@ nsBlockBandData::ComputeAvailSpaceRect()
}
/**
* See if the given frame should be cleared
*/
PRBool
nsBlockBandData::ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType)
{
PRBool result = PR_FALSE;
const nsStyleDisplay* display = aFrame->GetStyleDisplay();
if (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType) {
result = PR_TRUE;
}
else if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
if (NS_STYLE_CLEAR_LEFT == aBreakType) {
result = PR_TRUE;
}
}
else if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
if (NS_STYLE_CLEAR_RIGHT == aBreakType) {
result = PR_TRUE;
}
}
return result;
}
// XXX optimization? use mFloats to avoid doing anything
nscoord
nsBlockBandData::ClearFloats(nscoord aY, PRUint8 aBreakType)
{
for (;;) {
nsresult rv = GetBandData(aY);
if (NS_FAILED(rv)) {
break; // something is seriously wrong, bail
}
ComputeAvailSpaceRect();
// Compute aYS as aY in space-manager "root" coordinates.
nscoord aYS = aY + mSpaceManagerY;
// Find the largest frame YMost for the appropriate floats in
// 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) {
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->mState) {
PRInt32 fn, numFrames = trapezoid->mFrames->Count();
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
for (fn = 0; fn < numFrames; fn++) {
nsIFrame* frame = (nsIFrame*) trapezoid->mFrames->ElementAt(fn);
if (ShouldClearFrame(frame, aBreakType)) {
nscoord ym = trapezoid->mBottomY + mSpaceManagerY;
if (ym > yMost) yMost = ym;
}
}
}
else if (ShouldClearFrame(trapezoid->mFrame, aBreakType)) {
nscoord ym = trapezoid->mBottomY + mSpaceManagerY;
if (ym > yMost) yMost = ym;
}
}
}
// If yMost is unchanged (aYS) then there were no appropriate
// floats in the band. Time to stop clearing.
if (yMost == aYS) {
break;
}
aY = aY + (yMost - aYS);
}
return aY;
}
#ifdef DEBUG
void nsBlockBandData::List()
{

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

@ -60,9 +60,6 @@ public:
// space manager translation.
nsresult GetAvailableSpace(nscoord aY, nsRect& aResult);
// Clear any current floats, returning a new Y coordinate
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType);
// Get the raw trapezoid count for this band.
PRInt32 GetTrapezoidCount() const {
return mCount;
@ -120,8 +117,6 @@ protected:
PRInt32 mLeftFloats, mRightFloats;
void ComputeAvailSpaceRect();
PRBool ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType);
};
#endif /* nsBlockBandData_h___ */

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

@ -1169,8 +1169,9 @@ nsBlockReflowState::ClearFloats(nscoord aY, PRUint8 aBreakType)
aY, aBreakType);
mSpaceManager->List(stdout);
#endif
const nsMargin& bp = BorderPadding();
nscoord newY = mBand.ClearFloats(aY - bp.top, aBreakType);
nscoord newY = mSpaceManager->ClearFloats(aY - bp.top, aBreakType);
mY = newY + bp.top;
GetAvailableSpace();

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

@ -1185,6 +1185,45 @@ nsSpaceManager::DestroyFrameInfo(FrameInfo* aFrameInfo)
delete aFrameInfo;
}
static PRBool
ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType)
{
PRUint8 floatType = aFrame->GetStyleDisplay()->mFloats;
PRBool result;
switch (aBreakType) {
case NS_STYLE_CLEAR_LEFT_AND_RIGHT:
result = PR_TRUE;
break;
case NS_STYLE_CLEAR_LEFT:
result = floatType == NS_STYLE_FLOAT_LEFT;
break;
case NS_STYLE_CLEAR_RIGHT:
result = floatType == NS_STYLE_FLOAT_RIGHT;
break;
default:
result = PR_FALSE;
}
return result;
}
nscoord
nsSpaceManager::ClearFloats(nscoord aY, PRUint8 aBreakType)
{
nscoord bottom = aY + mY;
for (FrameInfo *frame = mFrameInfoMap; frame; frame = frame->mNext) {
if (ShouldClearFrame(frame->mFrame, aBreakType)) {
if (frame->mRect.YMost() > bottom) {
bottom = frame->mRect.YMost();
}
}
}
bottom -= mY;
return bottom;
}
/////////////////////////////////////////////////////////////////////////////
// FrameInfo

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

@ -303,6 +303,12 @@ public:
*/
nscoord GetLowestRegionTop();
/**
* Return the coordinate of the lowest float matching aBreakType in this
* space manager. Returns aY if there are no matching floats.
*/
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType);
#ifdef DEBUG
/**
* Dump the state of the spacemanager out to a file

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

@ -266,80 +266,6 @@ nsBlockBandData::ComputeAvailSpaceRect()
}
/**
* See if the given frame should be cleared
*/
PRBool
nsBlockBandData::ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType)
{
PRBool result = PR_FALSE;
const nsStyleDisplay* display = aFrame->GetStyleDisplay();
if (NS_STYLE_CLEAR_LEFT_AND_RIGHT == aBreakType) {
result = PR_TRUE;
}
else if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
if (NS_STYLE_CLEAR_LEFT == aBreakType) {
result = PR_TRUE;
}
}
else if (NS_STYLE_FLOAT_RIGHT == display->mFloats) {
if (NS_STYLE_CLEAR_RIGHT == aBreakType) {
result = PR_TRUE;
}
}
return result;
}
// XXX optimization? use mFloats to avoid doing anything
nscoord
nsBlockBandData::ClearFloats(nscoord aY, PRUint8 aBreakType)
{
for (;;) {
nsresult rv = GetBandData(aY);
if (NS_FAILED(rv)) {
break; // something is seriously wrong, bail
}
ComputeAvailSpaceRect();
// Compute aYS as aY in space-manager "root" coordinates.
nscoord aYS = aY + mSpaceManagerY;
// Find the largest frame YMost for the appropriate floats in
// 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) {
if (nsBandTrapezoid::OccupiedMultiple == trapezoid->mState) {
PRInt32 fn, numFrames = trapezoid->mFrames->Count();
NS_ASSERTION(numFrames > 0, "bad trapezoid frame list");
for (fn = 0; fn < numFrames; fn++) {
nsIFrame* frame = (nsIFrame*) trapezoid->mFrames->ElementAt(fn);
if (ShouldClearFrame(frame, aBreakType)) {
nscoord ym = trapezoid->mBottomY + mSpaceManagerY;
if (ym > yMost) yMost = ym;
}
}
}
else if (ShouldClearFrame(trapezoid->mFrame, aBreakType)) {
nscoord ym = trapezoid->mBottomY + mSpaceManagerY;
if (ym > yMost) yMost = ym;
}
}
}
// If yMost is unchanged (aYS) then there were no appropriate
// floats in the band. Time to stop clearing.
if (yMost == aYS) {
break;
}
aY = aY + (yMost - aYS);
}
return aY;
}
#ifdef DEBUG
void nsBlockBandData::List()
{

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

@ -60,9 +60,6 @@ public:
// space manager translation.
nsresult GetAvailableSpace(nscoord aY, nsRect& aResult);
// Clear any current floats, returning a new Y coordinate
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType);
// Get the raw trapezoid count for this band.
PRInt32 GetTrapezoidCount() const {
return mCount;
@ -120,8 +117,6 @@ protected:
PRInt32 mLeftFloats, mRightFloats;
void ComputeAvailSpaceRect();
PRBool ShouldClearFrame(nsIFrame* aFrame, PRUint8 aBreakType);
};
#endif /* nsBlockBandData_h___ */

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

@ -1169,8 +1169,9 @@ nsBlockReflowState::ClearFloats(nscoord aY, PRUint8 aBreakType)
aY, aBreakType);
mSpaceManager->List(stdout);
#endif
const nsMargin& bp = BorderPadding();
nscoord newY = mBand.ClearFloats(aY - bp.top, aBreakType);
nscoord newY = mSpaceManager->ClearFloats(aY - bp.top, aBreakType);
mY = newY + bp.top;
GetAvailableSpace();