зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
eb8906c0f3
Коммит
be338c15ee
|
@ -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();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче