--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -2264,17 +2264,17 @@ nsBlockFrame::MarkLineDirtyForInterrupt(
PRInt32 n = aLine->GetChildCount();
for (nsIFrame* f = aLine->mFirstChild; n > 0;
f = f->GetNextSibling(), --n) {
f->AddStateBits(NS_FRAME_IS_DIRTY);
}
// And mark all the floats whose reflows we might be skipping dirty too.
if (aLine->HasFloats()) {
for (nsFloatCache* fc = aLine->GetFirstFloat(); fc; fc = fc->Next()) {
- fc->mPlaceholder->GetOutOfFlowFrame()->AddStateBits(NS_FRAME_IS_DIRTY);
+ fc->mFloat->AddStateBits(NS_FRAME_IS_DIRTY);
}
}
} else {
// Dirty all the descendant lines of block kids to handle float damage,
// since our nsFloatManager will go away by the next time we're reflowing.
// XXXbz Can we do something more like what PropagateFloatDamage does?
// Would need to sort out the exact business with mBlockDelta for that....
// This marks way too much dirty. If we ever make this better, revisit
@@ -3880,19 +3880,21 @@ GetLastFloat(nsLineBox* aLine)
fc = fc->Next();
}
return fc;
}
static PRBool
CheckPlaceholderInLine(nsIFrame* aBlock, nsLineBox* aLine, nsFloatCache* aFC)
{
- if (!aFC)
+ if (!aFC || aFC->mFloat->GetPrevInFlow())
return PR_TRUE;
- for (nsIFrame* f = aFC->mPlaceholder; f; f = f->GetParent()) {
+ nsIFrame* ph = aBlock->PresContext()->FrameManager()->
+ GetPlaceholderFrameFor(aFC->mFloat->GetFirstInFlow());
+ for (nsIFrame* f = ph; f; f = f->GetParent()) {
if (f->GetParent() == aBlock)
return aLine->Contains(f);
}
NS_ASSERTION(PR_FALSE, "aBlock is not an ancestor of aFrame!");
return PR_TRUE;
}
nsresult
@@ -5468,71 +5470,70 @@ nsBlockFrame::AdjustFloatAvailableSpace(
return nsRect(aState.BorderPadding().left,
aState.BorderPadding().top,
availWidth, availHeight);
}
nscoord
nsBlockFrame::ComputeFloatWidth(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
- nsPlaceholderFrame* aPlaceholder)
+ nsIFrame* aFloat)
{
+ NS_PRECONDITION(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
+ "aFloat must be an out-of-flow frame");
// Reflow the float.
- nsIFrame* floatFrame = aPlaceholder->GetOutOfFlowFrame();
-
nsRect availSpace = AdjustFloatAvailableSpace(aState, aFloatAvailableSpace,
- floatFrame);
-
- nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState,
- floatFrame,
+ aFloat);
+
+ nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState, aFloat,
nsSize(availSpace.width, availSpace.height));
return floatRS.ComputedWidth() + floatRS.mComputedBorderPadding.LeftRight() +
floatRS.mComputedMargin.LeftRight();
}
nsresult
nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
- nsPlaceholderFrame* aPlaceholder,
+ nsIFrame* aFloat,
nsMargin& aFloatMargin,
nsReflowStatus& aReflowStatus)
{
+ NS_PRECONDITION(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
+ "aFloat must be an out-of-flow frame");
// Reflow the float.
- nsIFrame* floatFrame = aPlaceholder->GetOutOfFlowFrame();
aReflowStatus = NS_FRAME_COMPLETE;
#ifdef NOISY_FLOAT
printf("Reflow Float %p in parent %p, availSpace(%d,%d,%d,%d)\n",
- aPlaceholder->GetOutOfFlowFrame(), this,
+ aFloat, this,
aFloatAvailableSpace.x, aFloatAvailableSpace.y,
aFloatAvailableSpace.width, aFloatAvailableSpace.height
);
#endif
nsRect availSpace = AdjustFloatAvailableSpace(aState, aFloatAvailableSpace,
- floatFrame);
-
- nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState,
- floatFrame,
+ aFloat);
+
+ nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState, aFloat,
nsSize(availSpace.width, availSpace.height));
// Setup a block reflow state to reflow the float.
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState);
// Reflow the float
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
nsIFrame* clearanceFrame = nsnull;
nsresult rv;
do {
nsCollapsingMargin margin;
PRBool mayNeedRetry = PR_FALSE;
floatRS.mDiscoveredClearance = nsnull;
// Only first in flow gets a top margin.
- if (!floatFrame->GetPrevInFlow()) {
+ if (!aFloat->GetPrevInFlow()) {
nsBlockReflowContext::ComputeCollapsedTopMargin(floatRS, &margin,
clearanceFrame, &mayNeedRetry);
if (mayNeedRetry && !clearanceFrame) {
floatRS.mDiscoveredClearance = &clearanceFrame;
// We don't need to push the float manager state because the the block has its own
// float manager that will be destroyed and recreated
}
@@ -5549,17 +5550,17 @@ nsBlockFrame::ReflowFloat(nsBlockReflowS
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
(NS_UNCONSTRAINEDSIZE == availSpace.height))
aReflowStatus = NS_FRAME_COMPLETE;
if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) {
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
}
- if (floatFrame->GetType() == nsGkAtoms::letterFrame) {
+ if (aFloat->GetType() == nsGkAtoms::letterFrame) {
// We never split floating first letters; an incomplete state for
// such frames simply means that there is more content to be
// reflowed on the line.
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus))
aReflowStatus = NS_FRAME_COMPLETE;
}
if (NS_FAILED(rv)) {
@@ -5572,30 +5573,30 @@ nsBlockFrame::ReflowFloat(nsBlockReflowS
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
// Set the rect, make sure the view is properly sized and positioned,
// and tell the frame we're done reflowing it
// XXXldb This seems like the wrong place to be doing this -- shouldn't
// we be doing this in nsBlockReflowState::FlowAndPlaceFloat after
// we've positioned the float, and shouldn't we be doing the equivalent
// of |::PlaceFrameView| here?
- floatFrame->SetSize(nsSize(metrics.width, metrics.height));
- if (floatFrame->HasView()) {
- nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, floatFrame,
- floatFrame->GetView(),
+ aFloat->SetSize(nsSize(metrics.width, metrics.height));
+ if (aFloat->HasView()) {
+ nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, aFloat,
+ aFloat->GetView(),
&metrics.mOverflowArea,
NS_FRAME_NO_MOVE_VIEW);
}
// Pass floatRS so the frame hierarchy can be used (redoFloatRS has the same hierarchy)
- floatFrame->DidReflow(aState.mPresContext, &floatRS,
+ aFloat->DidReflow(aState.mPresContext, &floatRS,
NS_FRAME_REFLOW_FINISHED);
#ifdef NOISY_FLOAT
printf("end ReflowFloat %p, sized to %d,%d\n",
- floatFrame, metrics.width, metrics.height);
+ aFloat, metrics.width, metrics.height);
#endif
return NS_OK;
}
//////////////////////////////////////////////////////////////////////
// Painting, event handling
@@ -6430,18 +6431,17 @@ nsBlockFrame::CheckFloats(nsBlockReflowS
// Check that the float list is what we would have built
nsAutoTArray<nsIFrame*, 8> lineFloats;
for (line_iterator line = begin_lines(), line_end = end_lines();
line != line_end; ++line) {
if (line->HasFloats()) {
nsFloatCache* fc = line->GetFirstFloat();
while (fc) {
- nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
- lineFloats.AppendElement(floatFrame);
+ lineFloats.AppendElement(fc->mFloat);
fc = fc->Next();
}
}
if (line->IsDirty()) {
anyLineDirty = PR_TRUE;
}
}
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -538,22 +538,22 @@ protected:
// Compute the available width for a float.
nsRect AdjustFloatAvailableSpace(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
nsIFrame* aFloatFrame);
// Computes the border-box width of the float
nscoord ComputeFloatWidth(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
- nsPlaceholderFrame* aPlaceholder);
+ nsIFrame* aFloat);
// An incomplete aReflowStatus indicates the float should be split
// but only if the available height is constrained.
nsresult ReflowFloat(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
- nsPlaceholderFrame* aPlaceholder,
+ nsIFrame* aFloat,
nsMargin& aFloatMargin,
nsReflowStatus& aReflowStatus);
//----------------------------------------
// Methods for pushing/pulling lines/frames
virtual nsresult CreateContinuationFor(nsBlockReflowState& aState,
nsLineBox* aLine,
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -450,17 +450,17 @@ void
nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
nscoord aDeltaY)
{
if (aLine->HasFloats()) {
// Place the floats into the space-manager again. Also slide
// them, just like the regular frames on the line.
nsFloatCache* fc = aLine->GetFirstFloat();
while (fc) {
- nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
+ nsIFrame* floatFrame = fc->mFloat;
if (aDeltaY != 0) {
nsPoint p = floatFrame->GetPosition();
floatFrame->SetPosition(nsPoint(p.x, p.y + aDeltaY));
nsContainerFrame::PositionFrameView(floatFrame);
nsContainerFrame::PositionChildViews(floatFrame);
}
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisyFloatManager) {
@@ -561,29 +561,31 @@ nsBlockReflowState::RecoverStateFrom(nsL
// placement is deferred until the line has been reflowed.
// XXXldb This behavior doesn't quite fit with CSS1 and CSS2 --
// technically we're supposed let the current line flow around the
// float as well unless it won't fit next to what we already have.
// But nobody else implements it that way...
PRBool
nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout,
- nsPlaceholderFrame* aPlaceholder,
+ nsIFrame* aFloat,
nscoord aAvailableWidth,
nsReflowStatus& aReflowStatus)
{
NS_PRECONDITION(mBlock->end_lines() != mCurrentLine, "null ptr");
+ NS_PRECONDITION(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
+ "aFloat must be an out-of-flow frame");
// Set the geometric parent of the float
- aPlaceholder->GetOutOfFlowFrame()->SetParent(mBlock);
+ aFloat->SetParent(mBlock);
aReflowStatus = NS_FRAME_COMPLETE;
// Allocate a nsFloatCache for the float
nsFloatCache* fc = mFloatCacheFreeList.Alloc();
- fc->mPlaceholder = aPlaceholder;
+ fc->mFloat = aFloat;
// Because we are in the middle of reflowing a placeholder frame
// within a line (and possibly nested in an inline frame or two
// that's a child of our block) we need to restore the space
// manager's translation to the space that the block resides in
// before placing the float.
nscoord ox, oy;
mFloatManager->GetTranslation(ox, oy);
@@ -596,34 +598,34 @@ nsBlockReflowState::AddFloat(nsLineLayou
// Now place the float immediately if possible. Otherwise stash it
// away in mPendingFloats and place it later.
// If one or more floats has already been pushed to the next line,
// don't let this one go on the current line, since that would violate
// float ordering.
nsRect floatAvailableSpace = GetFloatAvailableSpace().mRect;
if (mBelowCurrentLineFloats.IsEmpty() &&
(aLineLayout.LineIsEmpty() ||
- mBlock->ComputeFloatWidth(*this, floatAvailableSpace, aPlaceholder) <=
+ mBlock->ComputeFloatWidth(*this, floatAvailableSpace, aFloat) <=
aAvailableWidth)) {
// And then place it
// force it to fit if we're at the top of the block and we can't
// break before this
PRBool forceFit = IsAdjacentWithTop() && !aLineLayout.LineIsBreakable();
- placed = FlowAndPlaceFloat(fc, aReflowStatus, forceFit);
+ placed = FlowAndPlaceFloat(aFloat, aReflowStatus, forceFit);
NS_ASSERTION(placed || !forceFit,
"If we asked for force-fit, it should have been placed");
if (forceFit || (placed && !NS_FRAME_IS_TRUNCATED(aReflowStatus))) {
// Pass on updated available space to the current inline reflow engine
nsFlowAreaRect floatAvailSpace =
GetFloatAvailableSpace(mY, forceFit);
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x + BorderPadding().left,
mY),
floatAvailSpace.mRect.Size());
- aLineLayout.UpdateBand(availSpace, aPlaceholder->GetOutOfFlowFrame());
-
+ aLineLayout.UpdateBand(availSpace, aFloat);
+
// Record this float in the current-line list
mCurrentLineFloats.Append(fc);
// If we can't break here, hide the fact that it's truncated
// XXX We can probably do this more cleanly
aReflowStatus &= ~NS_FRAME_TRUNCATED;
}
else {
if (IsAdjacentWithTop()) {
@@ -751,75 +753,72 @@ nsBlockReflowState::CanPlaceFloat(const
// Restore Y coordinate
mY = saveY;
}
return result;
}
PRBool
-nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
+nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat,
nsReflowStatus& aReflowStatus,
PRBool aForceFit)
{
aReflowStatus = NS_FRAME_COMPLETE;
// Save away the Y coordinate before placing the float. We will
// restore mY at the end after placing the float. This is
// necessary because any adjustments to mY during the float
// placement are for the float only, not for any non-floating
// content.
nscoord saveY = mY;
- nsPlaceholderFrame* placeholder = aFloatCache->mPlaceholder;
- nsIFrame* floatFrame = placeholder->GetOutOfFlowFrame();
-
// Grab the float's display information
- const nsStyleDisplay* floatDisplay = floatFrame->GetStyleDisplay();
+ const nsStyleDisplay* floatDisplay = aFloat->GetStyleDisplay();
// The float's old region, so we can propagate damage.
- nsRect oldRegion = nsFloatManager::GetRegionFor(floatFrame);
+ nsRect oldRegion = nsFloatManager::GetRegionFor(aFloat);
// Enforce CSS2 9.5.1 rule [2], i.e., make sure that a float isn't
// ``above'' another float that preceded it in the flow.
mY = NS_MAX(mFloatManager->GetLowestFloatTop() + BorderPadding().top, mY);
// See if the float should clear any preceding floats...
// XXX We need to mark this float somehow so that it gets reflowed
// when floats are inserted before it.
if (NS_STYLE_CLEAR_NONE != floatDisplay->mBreakType) {
// XXXldb Does this handle vertical margins correctly?
mY = ClearFloats(mY, floatDisplay->mBreakType);
}
// Get the band of available space
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(mY, aForceFit);
- NS_ASSERTION(floatFrame->GetParent() == mBlock,
+ NS_ASSERTION(aFloat->GetParent() == mBlock,
"Float frame has wrong parent");
// Reflow the float
nsMargin floatMargin; // computed margin
- mBlock->ReflowFloat(*this, floatAvailableSpace.mRect, placeholder,
+ mBlock->ReflowFloat(*this, floatAvailableSpace.mRect, aFloat,
floatMargin, aReflowStatus);
- if (placeholder->GetPrevInFlow())
+ if (aFloat->GetPrevInFlow())
floatMargin.top = 0;
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus))
floatMargin.bottom = 0;
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
- nsRect region = floatFrame->GetRect();
+ nsRect region = aFloat->GetRect();
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("flowed float: ");
- nsFrame::ListTag(stdout, floatFrame);
+ nsFrame::ListTag(stdout, aFloat);
printf(" (%d,%d,%d,%d)\n",
region.x, region.y, region.width, region.height);
}
#endif
- nsSize floatSize = floatFrame->GetSize() +
+ nsSize floatSize = aFloat->GetSize() +
nsSize(floatMargin.LeftRight(), floatMargin.TopBottom());
// Find a place to place the float. The CSS2 spec doesn't want
// floats overlapping each other or sticking out of the containing
// block if possible (CSS2 spec section 9.5.1, see the rule list).
NS_ASSERTION((NS_STYLE_FLOAT_LEFT == floatDisplay->mFloats) ||
(NS_STYLE_FLOAT_RIGHT == floatDisplay->mFloats),
"invalid float type");
@@ -844,20 +843,20 @@ nsBlockReflowState::FlowAndPlaceFloat(ns
} else {
// This quirk matches the one in nsBlockFrame::ReflowFloat
// IE handles float tables in a very special way
// see if the previous float is also a table and has "align"
nsFloatCache* fc = mCurrentLineFloats.Head();
nsIFrame* prevFrame = nsnull;
while (fc) {
- if (fc->mPlaceholder->GetOutOfFlowFrame() == floatFrame) {
+ if (fc->mFloat == aFloat) {
break;
}
- prevFrame = fc->mPlaceholder->GetOutOfFlowFrame();
+ prevFrame = fc->mFloat;
fc = fc->Next();
}
if(prevFrame) {
//get the frame type
if (nsGkAtoms::tableOuterFrame == prevFrame->GetType()) {
//see if it has "align="
// IE makes a difference between align and he float property
@@ -879,20 +878,20 @@ nsBlockReflowState::FlowAndPlaceFloat(ns
// the table does not fit anymore in this line so advance to next band
mY += floatAvailableSpace.mRect.height;
floatAvailableSpace = GetFloatAvailableSpace(mY, aForceFit);
// reflow the float again now since we have more space
// XXXldb We really don't need to Reflow in a loop, we just need
// to ComputeSize in a loop (once ComputeSize depends on
// availableWidth, which should make this work again).
- mBlock->ReflowFloat(*this, floatAvailableSpace.mRect, placeholder,
+ mBlock->ReflowFloat(*this, floatAvailableSpace.mRect, aFloat,
floatMargin, aReflowStatus);
// Get the floats bounding box and margin information
- floatSize = floatFrame->GetSize() +
+ floatSize = aFloat->GetSize() +
nsSize(floatMargin.LeftRight(), floatMargin.TopBottom());
}
}
// If the float is continued, it will get the same absolute x value as its prev-in-flow
// We don't worry about the geometry of the prev in flow, let the continuation
// place and size itself as required.
@@ -929,46 +928,46 @@ nsBlockReflowState::FlowAndPlaceFloat(ns
// Calculate the actual origin of the float frame's border rect
// relative to the parent block; floatX/Y must be converted from space-manager
// coordinates to parent coordinates, and the margin must be added in
// to get the border rect
nsPoint origin(borderPadding.left + floatMargin.left + floatX,
borderPadding.top + floatMargin.top + floatY);
// If float is relatively positioned, factor that in as well
- origin += floatFrame->GetRelativeOffset(floatDisplay);
+ origin += aFloat->GetRelativeOffset(floatDisplay);
// Position the float and make sure and views are properly
// positioned. We need to explicitly position its child views as
// well, since we're moving the float after flowing it.
- floatFrame->SetPosition(origin);
- nsContainerFrame::PositionFrameView(floatFrame);
- nsContainerFrame::PositionChildViews(floatFrame);
+ aFloat->SetPosition(origin);
+ nsContainerFrame::PositionFrameView(aFloat);
+ nsContainerFrame::PositionChildViews(aFloat);
// Update the float combined area state
- nsRect combinedArea = floatFrame->GetOverflowRect() + origin;
+ nsRect combinedArea = aFloat->GetOverflowRect() + origin;
// XXX Floats should really just get invalidated here if necessary
mFloatCombinedArea.UnionRect(combinedArea, mFloatCombinedArea);
// Place the float in the float manager
// calculate region
- nsRect region = nsFloatManager::CalculateRegionFor(floatFrame, floatMargin);
+ nsRect region = nsFloatManager::CalculateRegionFor(aFloat, floatMargin);
// if the float split, then take up all of the vertical height
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
(NS_UNCONSTRAINEDSIZE != mContentArea.height)) {
region.height = PR_MAX(region.height, mContentArea.height - floatY);
}
nsresult rv =
// spacemanager translation is inset by the border+padding.
- mFloatManager->AddFloat(floatFrame,
+ mFloatManager->AddFloat(aFloat,
region - nsPoint(borderPadding.left, borderPadding.top));
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "bad float placement");
// store region
- rv = nsFloatManager::StoreRegionFor(floatFrame, region);
+ rv = nsFloatManager::StoreRegionFor(aFloat, region);
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "float region storage failed");
// If the float's dimensions have changed, note the damage in the
// float manager.
if (region != oldRegion) {
// XXXwaterson conservative: we could probably get away with noting
// less damage; e.g., if only height has changed, then only note the
// area into which the float has grown or from which the float has
@@ -987,20 +986,20 @@ nsBlockReflowState::FlowAndPlaceFloat(ns
region.x, region.y, region.width, region.height);
#endif
// Now restore mY
mY = saveY;
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
- nsRect r = floatFrame->GetRect();
+ nsRect r = aFloat->GetRect();
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("placed float: ");
- nsFrame::ListTag(stdout, floatFrame);
+ nsFrame::ListTag(stdout, aFloat);
printf(" %d,%d,%d,%d\n", r.x, r.y, r.width, r.height);
}
#endif
return PR_TRUE;
}
/**
@@ -1011,23 +1010,23 @@ nsBlockReflowState::PlaceBelowCurrentLin
{
nsFloatCache* fc = aList.Head();
while (fc) {
{
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("placing bcl float: ");
- nsFrame::ListTag(stdout, fc->mPlaceholder->GetOutOfFlowFrame());
+ nsFrame::ListTag(stdout, fc->mFloat);
printf("\n");
}
#endif
// Place the float
nsReflowStatus reflowStatus;
- PRBool placed = FlowAndPlaceFloat(fc, reflowStatus, aForceFit);
+ PRBool placed = FlowAndPlaceFloat(fc->mFloat, reflowStatus, aForceFit);
NS_ASSERTION(placed || !aForceFit,
"If we're in force-fit mode, we should have placed the float");
if (!placed || (NS_FRAME_IS_TRUNCATED(reflowStatus) && !aForceFit)) {
// return before processing all of the floats, since the line will be pushed.
return PR_FALSE;
}
else if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus)) {
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -105,23 +105,23 @@ public:
nsFloatManager::SavedState *aState) const;
/*
* The following functions all return PR_TRUE if they were able to
* place the float, PR_FALSE if the float did not fit in available
* space.
*/
PRBool AddFloat(nsLineLayout& aLineLayout,
- nsPlaceholderFrame* aPlaceholderFrame,
+ nsIFrame* aFloat,
nscoord aAvailableWidth,
nsReflowStatus& aReflowStatus);
PRBool CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats,
const nsFlowAreaRect& aFloatAvailableSpace,
PRBool aForceFit);
- PRBool FlowAndPlaceFloat(nsFloatCache* aFloatCache,
+ PRBool FlowAndPlaceFloat(nsIFrame* aFloat,
nsReflowStatus& aReflowStatus,
PRBool aForceFit);
PRBool PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aFloats, PRBool aForceFit);
// Returns the first coordinate >= aY that clears the
// floats indicated by aBreakType and has enough width between floats
// (or no floats remaining) to accomodate aReplacedBlock.
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType,
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -40,16 +40,17 @@
*
* ***** END LICENSE BLOCK ***** */
/* base class of all rendering objects */
#include "nsCOMPtr.h"
#include "nsFrame.h"
#include "nsFrameList.h"
+#include "nsPlaceholderFrame.h"
#include "nsLineLayout.h"
#include "nsIContent.h"
#include "nsContentUtils.h"
#include "nsIAtom.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsStyleContext.h"
#include "nsIView.h"
@@ -1477,17 +1478,18 @@ nsIFrame::BuildDisplayListForChild(nsDis
PRBool isComposited = disp->mOpacity != 1.0f ||
((aChild->mState & NS_FRAME_MAY_BE_TRANSFORMED_OR_HAVE_RENDERING_OBSERVERS) &&
aChild->GetStyleDisplay()->HasTransform())
#ifdef MOZ_SVG
|| nsSVGIntegrationUtils::UsingEffectsForFrame(aChild)
#endif
;
PRBool isPositioned = disp->IsPositioned();
- if (isComposited || isPositioned || (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
+ if (isComposited || isPositioned || disp->IsFloating() ||
+ (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
// If you change this, also change IsPseudoStackingContextFromStyle()
pseudoStackingContext = PR_TRUE;
}
nsRect overflowClip;
PRBool applyOverflowClip =
ApplyOverflowClipping(aBuilder, aChild, disp, &overflowClip);
// Don't use overflowClip to restrict the dirty rect, since some of the
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -2068,17 +2068,17 @@ public:
/**
* Determines whether this frame is a pseudo stacking context, looking
* only as style --- i.e., assuming that it's in-flow and not a replaced
* element.
*/
PRBool IsPseudoStackingContextFromStyle() {
const nsStyleDisplay* disp = GetStyleDisplay();
- return disp->mOpacity != 1.0f || disp->IsPositioned();
+ return disp->mOpacity != 1.0f || disp->IsPositioned() || disp->IsFloating();
}
virtual PRBool HonorPrintBackgroundSettings() { return PR_TRUE; }
/**
* Determine whether the frame is logically empty, which is roughly
* whether the layout would be the same whether or not the frame is
* present. Placeholder frames should return true. Block frames
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -35,16 +35,17 @@
*
* ***** END LICENSE BLOCK ***** */
/* rendering object for CSS display:inline objects */
#include "nsCOMPtr.h"
#include "nsInlineFrame.h"
#include "nsBlockFrame.h"
+#include "nsPlaceholderFrame.h"
#include "nsGkAtoms.h"
#include "nsHTMLParts.h"
#include "nsStyleContext.h"
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsIRenderingContext.h"
#include "nsIFontMetrics.h"
#include "nsAbsoluteContainingBlock.h"
--- a/layout/generic/nsLineBox.cpp
+++ b/layout/generic/nsLineBox.cpp
@@ -135,31 +135,27 @@ nsLineBox::Cleanup()
#ifdef DEBUG
static void
ListFloats(FILE* out, PRInt32 aIndent, const nsFloatCacheList& aFloats)
{
nsFloatCache* fc = aFloats.Head();
while (fc) {
nsFrame::IndentBy(out, aIndent);
- nsPlaceholderFrame* ph = fc->mPlaceholder;
- if (ph) {
- fprintf(out, "placeholder@%p ", static_cast<void*>(ph));
- nsIFrame* frame = ph->GetOutOfFlowFrame();
- if (frame) {
- nsAutoString frameName;
- frame->GetFrameName(frameName);
- fputs(NS_LossyConvertUTF16toASCII(frameName).get(), out);
- }
-
- if (!frame) {
- fputs("\n###!!! NULL out-of-flow frame", out);
- }
- fprintf(out, "\n");
+ nsIFrame* frame = fc->mFloat;
+ fprintf(out, "floatframe@%p ", static_cast<void*>(frame));
+ if (frame) {
+ nsAutoString frameName;
+ frame->GetFrameName(frameName);
+ fputs(NS_LossyConvertUTF16toASCII(frameName).get(), out);
}
+ else {
+ fputs("\n###!!! NULL out-of-flow frame", out);
+ }
+ fprintf(out, "\n");
fc = fc->Next();
}
}
#endif
#ifdef DEBUG
const char *
BreakTypeToString(PRUint8 aBreakType)
@@ -831,17 +827,17 @@ nsFloatCacheList::Append(nsFloatCacheFre
aList.mTail = nsnull;
}
nsFloatCache*
nsFloatCacheList::Find(nsIFrame* aOutOfFlowFrame)
{
nsFloatCache* fc = mHead;
while (fc) {
- if (fc->mPlaceholder->GetOutOfFlowFrame() == aOutOfFlowFrame) {
+ if (fc->mFloat == aOutOfFlowFrame) {
break;
}
fc = fc->Next();
}
return fc;
}
nsFloatCache*
@@ -945,17 +941,17 @@ nsFloatCacheFreeList::Append(nsFloatCach
NS_ASSERTION(!mHead, "Bogus!");
mHead = mTail = aFloat;
}
}
//----------------------------------------------------------------------
nsFloatCache::nsFloatCache()
- : mPlaceholder(nsnull),
+ : mFloat(nsnull),
mNext(nsnull)
{
MOZ_COUNT_CTOR(nsFloatCache);
}
#ifdef NS_BUILD_REFCNT_LOGGING
nsFloatCache::~nsFloatCache()
{
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -38,18 +38,18 @@
*
* ***** END LICENSE BLOCK ***** */
/* representation of one line within a block frame, a CSS line box */
#ifndef nsLineBox_h___
#define nsLineBox_h___
-#include "nsPlaceholderFrame.h"
#include "nsILineIterator.h"
+#include "nsIFrame.h"
class nsLineBox;
class nsFloatCache;
class nsFloatCacheList;
class nsFloatCacheFreeList;
// State cached after reflowing a float. This state is used during
// incremental reflow when we avoid reflowing a float.
@@ -59,17 +59,17 @@ public:
#ifdef NS_BUILD_REFCNT_LOGGING
~nsFloatCache();
#else
~nsFloatCache() { }
#endif
nsFloatCache* Next() const { return mNext; }
- nsPlaceholderFrame* mPlaceholder; // nsPlaceholderFrame
+ nsIFrame* mFloat; // floating frame
protected:
nsFloatCache* mNext;
friend class nsFloatCacheList;
friend class nsFloatCacheFreeList;
};
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -862,34 +862,33 @@ nsLineLayout::ReflowFrame(nsIFrame* aFra
if (!frameType) {
isEmpty = pfd->mFrame->IsEmpty();
} else {
if (nsGkAtoms::placeholderFrame == frameType) {
isEmpty = PR_TRUE;
pfd->SetFlag(PFD_SKIPWHENTRIMMINGWHITESPACE, PR_TRUE);
nsIFrame* outOfFlowFrame = nsLayoutUtils::GetFloatFromPlaceholder(aFrame);
if (outOfFlowFrame) {
- nsPlaceholderFrame* placeholder = static_cast<nsPlaceholderFrame*>(aFrame);
// Add mTrimmableWidth to the available width since if the line ends
// here, the width of the inline content will be reduced by
// mTrimmableWidth.
nscoord availableWidth = psd->mRightEdge - (psd->mX - mTrimmableWidth);
if (psd->mNoWrap) {
// If we place floats after inline content where there's
// no break opportunity, we don't know how much additional
// width is required for the non-breaking content after the float,
// so we can't know whether the float plus that content will fit
// on the line. So for now, don't place floats after inline
// content where there's no break opportunity. This is incorrect
// but hopefully rare. Fixing it will require significant
// restructuring of line layout.
// We might as well allow zero-width floats to be placed, though.
availableWidth = 0;
}
- placedFloat = AddFloat(placeholder, availableWidth, aReflowStatus);
+ placedFloat = AddFloat(outOfFlowFrame, availableWidth, aReflowStatus);
NS_ASSERTION(!(outOfFlowFrame->GetType() == nsGkAtoms::letterFrame &&
GetFirstLetterStyleOK()),
"FirstLetterStyle set on line with floating first letter");
}
}
else if (nsGkAtoms::textFrame == frameType) {
// Note non-empty text-frames for inline frame compatibility hackery
pfd->SetFlag(PFD_ISTEXTFRAME, PR_TRUE);
--- a/layout/generic/nsLineLayout.h
+++ b/layout/generic/nsLineLayout.h
@@ -204,20 +204,21 @@ public:
void SetLineEndsInBR(PRBool aOn)
{
SetFlag(LL_LINEENDSINBR, aOn);
}
//----------------------------------------
// Inform the line-layout about the presence of a floating frame
// XXX get rid of this: use get-frame-type?
- PRBool AddFloat(nsPlaceholderFrame* aFrame,
- nscoord aAvailableWidth,
- nsReflowStatus& aReflowStatus) {
- return mBlockRS->AddFloat(*this, aFrame, aAvailableWidth, aReflowStatus);
+ PRBool AddFloat(nsIFrame* aFloat,
+ nscoord aAvailableWidth,
+ nsReflowStatus& aReflowStatus)
+ {
+ return mBlockRS->AddFloat(*this, aFloat, aAvailableWidth, aReflowStatus);
}
void SetTrimmableWidth(nscoord aTrimmableWidth) {
mTrimmableWidth = aTrimmableWidth;
}
//----------------------------------------
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -72,16 +72,17 @@
#include "nsIDocument.h"
#include "nsIDeviceContext.h"
#include "nsCSSPseudoElements.h"
#include "nsCompatibility.h"
#include "nsCSSColorUtils.h"
#include "nsLayoutUtils.h"
#include "nsDisplayList.h"
#include "nsFrame.h"
+#include "nsPlaceholderFrame.h"
#include "nsTextFrameUtils.h"
#include "nsTextRunTransformations.h"
#include "nsFrameManager.h"
#include "nsTextFrameTextRunCache.h"
#include "nsExpirationTracker.h"
#include "nsTextFrame.h"
#include "nsICaseConversion.h"
#include "nsIUGenCategory.h"