mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-23 21:17:52 +00:00
Bug 59200. Merge floater reflow and placement into FlowAndPlaceFloater() to deal with the fact that a floater may need to be reflowed as its 'pushed' to a new location. For auto-width floaters, ensure that the floater is not flowed at a width less than its max-element-size. Enforce CSS2 section 9.5.1 rule [2] by maintaining mLastFloaterY in the reflow state. r=rbs, sr=attinasi.
This commit is contained in:
parent
3b89e30362
commit
b55568be36
@ -4122,18 +4122,10 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
|
||||
printf(": line=%p xmost=%d\n", aLine, xmost);
|
||||
}
|
||||
#endif
|
||||
// If we're shrink wrapping our width and the line was wrapped,
|
||||
// then make sure we take up all of the available width
|
||||
if (aState.GetFlag(BRS_SHRINKWRAPWIDTH) && aLine->IsLineWrapped()) {
|
||||
aState.mKidXMost = aState.BorderPadding().left + aState.mContentArea.width;
|
||||
#ifdef NOISY_KIDXMOST
|
||||
printf("%p PostPlaceLine A aState.mKidXMost=%d\n", this, aState.mKidXMost);
|
||||
#endif
|
||||
}
|
||||
else if (xmost > aState.mKidXMost) {
|
||||
if (xmost > aState.mKidXMost) {
|
||||
aState.mKidXMost = xmost;
|
||||
#ifdef NOISY_KIDXMOST
|
||||
printf("%p PostPlaceLine B aState.mKidXMost=%d\n", this, aState.mKidXMost);
|
||||
printf("%p PostPlaceLine aState.mKidXMost=%d\n", this, aState.mKidXMost);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -4778,10 +4770,14 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
|
||||
nsresult
|
||||
nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRect,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult)
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nscoord& aMaxElementWidthResult)
|
||||
{
|
||||
// Reflow the floater.
|
||||
nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame();
|
||||
|
||||
#ifdef NOISY_FLOATER
|
||||
printf("Reflow Floater %p in parent %p, availSpace(%d,%d,%d,%d)\n",
|
||||
aPlaceholder->GetOutOfFlowFrame(), this,
|
||||
@ -4789,40 +4785,81 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
aState.mAvailSpaceRect.width, aState.mAvailSpaceRect.height
|
||||
);
|
||||
#endif
|
||||
// XXX update this just
|
||||
aState.GetAvailableSpace();
|
||||
|
||||
// Reflow the floater. Since floaters are continued we given them an
|
||||
// unbounded height. Floaters with an auto width are sized to zero
|
||||
// according to the css2 spec.
|
||||
// XXX We also need to take into account whether we should clear any
|
||||
// preceeding floaters...
|
||||
// Compute the available width. By default, assume the width of the
|
||||
// available space rect.
|
||||
nscoord availWidth = aState.mAvailSpaceRect.width;
|
||||
|
||||
// If the floater's width is automatic, we can't let the floater's
|
||||
// width shrink below its maxElementSize.
|
||||
const nsStylePosition* position;
|
||||
GetStyleData(eStyleStruct_Position, NS_REINTERPRET_CAST(const nsStyleStruct*&, position));
|
||||
|
||||
PRBool isAutoWidth = (eStyleUnit_Auto == position->mWidth.GetUnit());
|
||||
if (isAutoWidth) {
|
||||
// It's auto-width. Have we computed a max element size yet? (If
|
||||
// not, the floater cache will have NS_UNCONSTRAINEDSIZE as the
|
||||
// initial value.) If we _have_ computed a max element size, and
|
||||
// its larger then the available width, pin the avaiable width to
|
||||
// the maxElementSize.
|
||||
if ((NS_UNCONSTRAINEDSIZE != aMaxElementWidthResult) &&
|
||||
(aMaxElementWidthResult > availWidth)) {
|
||||
availWidth = aMaxElementWidthResult;
|
||||
}
|
||||
}
|
||||
|
||||
// We'll need to compute the max element size if either 1) we're
|
||||
// auto-width and we've not yet cached the value, or 2) the state
|
||||
// wanted us to compute it anyway.
|
||||
PRBool computeMaxElementSize =
|
||||
(isAutoWidth && (NS_UNCONSTRAINEDSIZE == aMaxElementWidthResult)) ||
|
||||
aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE);
|
||||
|
||||
// XXX Why do we have to add in our border/padding?
|
||||
nsRect availSpace(aState.mAvailSpaceRect.x + aState.BorderPadding().left,
|
||||
aState.mAvailSpaceRect.y + aState.BorderPadding().top,
|
||||
aState.mAvailSpaceRect.width, NS_UNCONSTRAINEDSIZE);
|
||||
nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame();
|
||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||
availWidth, NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
// Setup block reflow state to reflow the floater
|
||||
// Setup a block reflow state to reflow the floater.
|
||||
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
|
||||
aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE),
|
||||
computeMaxElementSize,
|
||||
aState.GetFlag(BRS_COMPUTEMAXWIDTH));
|
||||
|
||||
brc.SetNextRCFrame(aState.mNextRCFrame);
|
||||
|
||||
// Reflow the floater
|
||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||
|
||||
nsReflowStatus frameReflowStatus;
|
||||
nsresult rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, 0,
|
||||
isAdjacentWithTop,
|
||||
nsresult rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, 0, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, frameReflowStatus);
|
||||
if (PR_TRUE==brc.BlockShouldInvalidateItself()) {
|
||||
|
||||
if (NS_SUCCEEDED(rv) && isAutoWidth && (NS_UNCONSTRAINEDSIZE == aMaxElementWidthResult)) {
|
||||
// We've just flowed an auto-width floater, but have not yet cached
|
||||
// the maxElementSize. Do so now.
|
||||
nsSize maxElementSize = brc.GetMaxElementSize();
|
||||
aMaxElementWidthResult = maxElementSize.width;
|
||||
|
||||
if (aMaxElementWidthResult > availSpace.width) {
|
||||
// The floater's maxElementSize is larger than the available
|
||||
// width. Reflow it again, this time pinning the width to the
|
||||
// maxElementSize.
|
||||
availSpace.width = aMaxElementWidthResult;
|
||||
rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, 0, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, frameReflowStatus);
|
||||
}
|
||||
}
|
||||
|
||||
if (brc.BlockShouldInvalidateItself()) {
|
||||
Invalidate(aState.mPresContext, mRect);
|
||||
}
|
||||
|
||||
if (floater == aState.mNextRCFrame) {
|
||||
// NULL out mNextRCFrame so if we reflow it again we don't think it's still
|
||||
// an incremental reflow
|
||||
// Null out mNextRCFrame so if we reflow it again, we don't think
|
||||
// it's still an incremental reflow
|
||||
aState.mNextRCFrame = nsnull;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -4837,7 +4874,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
aMarginResult.left = m.left;
|
||||
|
||||
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
|
||||
aCombinedRect = metrics.mOverflowArea;
|
||||
aCombinedRectResult = metrics.mOverflowArea;
|
||||
|
||||
// Set the rect, make sure the view is properly sized and positioned,
|
||||
// and tell the frame we're done reflowing it
|
||||
floater->SizeTo(aState.mPresContext, metrics.width, metrics.height);
|
||||
|
@ -351,9 +351,10 @@ protected:
|
||||
|
||||
nsresult ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRect,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult);
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nscoord& aMaxElementWidthResult);
|
||||
|
||||
//----------------------------------------
|
||||
// Methods for pushing/pulling lines/frames
|
||||
@ -482,9 +483,5 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
// Some #ifdef'd bug fixes
|
||||
#define FIX_BUG_38157
|
||||
#define FIX_BUG_37657
|
||||
|
||||
#endif /* nsBlockFrame_h___ */
|
||||
|
||||
|
@ -314,8 +314,10 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
|
||||
(const nsStyleStruct*&)display);
|
||||
if ((eStyleUnit_Auto == widthUnit) &&
|
||||
((NS_STYLE_FLOAT_LEFT == display->mFloats) ||
|
||||
(NS_STYLE_FLOAT_RIGHT == display->mFloats)))
|
||||
{
|
||||
(NS_STYLE_FLOAT_RIGHT == display->mFloats))) {
|
||||
// Construct the reflow state using the ctor that explicitly
|
||||
// constrains the containing block's width and height to the
|
||||
// available width and height.
|
||||
nsHTMLReflowState autoReflowState(mPresContext, mOuterReflowState, aFrame,
|
||||
availSpace, aSpace.width, aSpace.height);
|
||||
autoReflowState.reason = reason;
|
||||
@ -325,8 +327,10 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
|
||||
aComputedOffsets,
|
||||
aFrameReflowStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Construct the reflow state using the ctor that will use the
|
||||
// containing block's computed width and height (or handle derive
|
||||
// appropriate values for an absolutely positioned frame).
|
||||
nsHTMLReflowState normalReflowState(mPresContext, mOuterReflowState, aFrame,
|
||||
availSpace, reason);
|
||||
rv = DoReflowBlock(normalReflowState, reason, aFrame, aSpace,
|
||||
|
@ -43,6 +43,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
||||
: mBlock(aFrame),
|
||||
mPresContext(aPresContext),
|
||||
mReflowState(aReflowState),
|
||||
mLastFloaterY(0),
|
||||
mNextRCFrame(nsnull),
|
||||
mPrevBottomMargin(0),
|
||||
mLineNumber(0),
|
||||
@ -93,18 +94,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
||||
else if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxWidth) {
|
||||
// Choose a width based on the content (shrink wrap width) up
|
||||
// to the maximum width
|
||||
// Part 2 of a possible fix for 38157
|
||||
#ifdef FIX_BUG_38157
|
||||
const nsMargin& margin = Margin();
|
||||
nscoord availContentWidth = aReflowState.availableWidth;
|
||||
if (NS_UNCONSTRAINEDSIZE != availContentWidth) {
|
||||
availContentWidth -= (borderPadding.left + borderPadding.right) +
|
||||
(margin.left + margin.right);
|
||||
}
|
||||
mContentArea.width = PR_MIN(aReflowState.mComputedMaxWidth, availContentWidth);
|
||||
#else
|
||||
mContentArea.width = aReflowState.mComputedMaxWidth;
|
||||
#endif
|
||||
SetFlag(BRS_SHRINKWRAPWIDTH, PR_TRUE);
|
||||
}
|
||||
else {
|
||||
@ -606,6 +596,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
||||
}
|
||||
#endif
|
||||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
mLastFloaterY = fc->mRegion.y;
|
||||
fc = fc->Next();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@ -702,13 +693,9 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout,
|
||||
nscoord dy = oy - mSpaceManagerY;
|
||||
mSpaceManager->Translate(-dx, -dy);
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, aPlaceholder, fc->mCombinedArea,
|
||||
fc->mMargins, fc->mOffsets);
|
||||
|
||||
// And then place it
|
||||
PRBool isLeftFloater;
|
||||
PlaceFloater(fc, &isLeftFloater);
|
||||
FlowAndPlaceFloater(fc, &isLeftFloater);
|
||||
|
||||
// Pass on updated available space to the current inline reflow engine
|
||||
GetAvailableSpace();
|
||||
@ -907,8 +894,8 @@ nsBlockReflowState::CanPlaceFloater(const nsRect& aFloaterRect,
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater)
|
||||
nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater)
|
||||
{
|
||||
// Save away the Y coordinate before placing the floater. We will
|
||||
// restore mY at the end after placing the floater. This is
|
||||
@ -916,9 +903,14 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
// placement are for the floater only, not for any non-floating
|
||||
// content.
|
||||
nscoord saveY = mY;
|
||||
|
||||
// Grab the compatibility mode
|
||||
nsCompatibility mode;
|
||||
mPresContext->GetCompatibilityMode(&mode);
|
||||
|
||||
nsIFrame* floater = aFloaterCache->mPlaceholder->GetOutOfFlowFrame();
|
||||
|
||||
// Get the type of floater
|
||||
// Grab the floater's display information
|
||||
const nsStyleDisplay* floaterDisplay;
|
||||
const nsStylePosition* floaterPosition;
|
||||
floater->GetStyleData(eStyleStruct_Display,
|
||||
@ -926,59 +918,72 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
floater->GetStyleData(eStyleStruct_Position,
|
||||
(const nsStyleStruct*&)floaterPosition);
|
||||
|
||||
// See if the floater should clear any preceeding floaters...
|
||||
if (NS_STYLE_CLEAR_NONE != floaterDisplay->mBreakType) {
|
||||
ClearFloaters(mY, floaterDisplay->mBreakType);
|
||||
}
|
||||
else {
|
||||
// Get the band of available space
|
||||
GetAvailableSpace();
|
||||
}
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
// This will hold the floater's geometry when we've found a place
|
||||
// for it to live.
|
||||
nsRect region;
|
||||
floater->GetRect(region);
|
||||
|
||||
// Adjust the floater size by its margin. That's the area that will
|
||||
// impact the space manager.
|
||||
region.width += aFloaterCache->mMargins.left + aFloaterCache->mMargins.right;
|
||||
region.height += aFloaterCache->mMargins.top + aFloaterCache->mMargins.bottom;
|
||||
// Advance mY to mLastFloaterY (if it's not past it already) to
|
||||
// enforce 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(mLastFloaterY, mY);
|
||||
|
||||
// Find a place to place the floater. The CSS2 spec doesn't want
|
||||
// floaters 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 == floaterDisplay->mFloats) ||
|
||||
(NS_STYLE_FLOAT_RIGHT == floaterDisplay->mFloats),
|
||||
"invalid float type");
|
||||
|
||||
// While there is not enough room for the floater, clear past other
|
||||
// floaters until there is room (or the band is not impacted by a
|
||||
// floater).
|
||||
//
|
||||
// Note: The CSS2 spec says that floaters should be placed as high
|
||||
// as possible.
|
||||
//
|
||||
#ifdef FIX_BUG_37657
|
||||
// Also note that in backwards compatibility mode, we skip this step
|
||||
// for tables, since in old browsers, floating tables are horizontally
|
||||
// stacked regardless of available space. (See bug 43086 about
|
||||
// tables vs. non-tables.)
|
||||
nsCompatibility mode;
|
||||
mPresContext->GetCompatibilityMode(&mode);
|
||||
if ((eCompatibility_NavQuirks != mode) ||
|
||||
(NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay)) {
|
||||
while (!CanPlaceFloater(region, floaterDisplay->mFloats)) {
|
||||
mY += mAvailSpaceRect.height;
|
||||
while (1) {
|
||||
// See if the floater should clear any preceeding floaters...
|
||||
if (NS_STYLE_CLEAR_NONE != floaterDisplay->mBreakType) {
|
||||
ClearFloaters(mY, floaterDisplay->mBreakType);
|
||||
}
|
||||
else {
|
||||
// Get the band of available space
|
||||
GetAvailableSpace();
|
||||
}
|
||||
}
|
||||
#else
|
||||
while (!CanPlaceFloater(region, floaterDisplay->mFloats)) {
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
}
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets,
|
||||
aFloaterCache->mMaxElementWidth);
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("flowed floater: ");
|
||||
nsFrame::ListTag(stdout, floater);
|
||||
printf(" (%d,%d,%d,%d), max-element-width=%d\n",
|
||||
region.x, region.y, region.width, region.height,
|
||||
aFloaterCache->mMaxElementWidth);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Adjust the floater size by its margin. That's the area that will
|
||||
// impact the space manager.
|
||||
region.width += aFloaterCache->mMargins.left + aFloaterCache->mMargins.right;
|
||||
region.height += aFloaterCache->mMargins.top + aFloaterCache->mMargins.bottom;
|
||||
|
||||
// Find a place to place the floater. The CSS2 spec doesn't want
|
||||
// floaters 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 == floaterDisplay->mFloats) ||
|
||||
(NS_STYLE_FLOAT_RIGHT == floaterDisplay->mFloats),
|
||||
"invalid float type");
|
||||
|
||||
// In backwards compatibility mode, we don't bother to see if a
|
||||
// floated table can ``really'' fit: in old browsers, floating
|
||||
// tables are horizontally stacked regardless of available space.
|
||||
// (See bug 43086 about tables vs. non-tables.)
|
||||
if ((eCompatibility_NavQuirks == mode) &&
|
||||
(NS_STYLE_DISPLAY_TABLE == floaterDisplay->mDisplay))
|
||||
break;
|
||||
|
||||
// Can the floater fit here?
|
||||
if (CanPlaceFloater(region, floaterDisplay->mFloats))
|
||||
break;
|
||||
|
||||
// Nope. Advance to the next band.
|
||||
mY += mAvailSpaceRect.height;
|
||||
}
|
||||
|
||||
// Assign an x and y coordinate to the floater. Note that the x,y
|
||||
// coordinates are computed <b>relative to the translation in the
|
||||
// spacemanager</b> which means that the impacted region will be
|
||||
@ -1082,6 +1087,9 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
nsBlockFrame::CombineRects(combinedArea, mFloaterCombinedArea);
|
||||
}
|
||||
|
||||
// Remember the y-coordinate of the floater we've just placed
|
||||
mLastFloaterY = mY;
|
||||
|
||||
// Now restore mY
|
||||
mY = saveY;
|
||||
|
||||
@ -1091,7 +1099,7 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
floater->GetRect(r);
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("placed floater: ");
|
||||
((nsFrame*)floater)->ListTag(stdout);
|
||||
nsFrame::ListTag(stdout, floater);
|
||||
printf(" %d,%d,%d,%d\n", r.x, r.y, r.width, r.height);
|
||||
}
|
||||
#endif
|
||||
@ -1114,12 +1122,10 @@ nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList)
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
mBlock->ReflowFloater(*this, fc->mPlaceholder, fc->mCombinedArea,
|
||||
fc->mMargins, fc->mOffsets);
|
||||
|
||||
// Place the floater
|
||||
PRBool isLeftFloater;
|
||||
PlaceFloater(fc, &isLeftFloater);
|
||||
FlowAndPlaceFloater(fc, &isLeftFloater);
|
||||
}
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
@ -65,8 +65,8 @@ public:
|
||||
|
||||
PRBool CanPlaceFloater(const nsRect& aFloaterRect, PRUint8 aFloats);
|
||||
|
||||
void PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater);
|
||||
void FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater);
|
||||
|
||||
void PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aFloaters);
|
||||
|
||||
@ -177,6 +177,10 @@ public:
|
||||
// The combined area of all floaters placed so far
|
||||
nsRect mFloaterCombinedArea;
|
||||
|
||||
// The y-coordinate of the last floater placed. We keep this around
|
||||
// to enforce 9.5.1 rule [2]
|
||||
nscoord mLastFloaterY;
|
||||
|
||||
// For unconstained-width reflow, we keep the right floaters
|
||||
// combined area stored seperately.
|
||||
PRBool mHaveRightFloaters;
|
||||
|
@ -355,20 +355,20 @@ NS_IMETHODIMP
|
||||
nsInlineFrame::ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild)
|
||||
{
|
||||
// The inline container frame does not handle the reflow
|
||||
// request. It passes it up to its parent container.
|
||||
// request. It passes it up to its parent container.
|
||||
|
||||
// If you don't already have dirty children,
|
||||
if (!(mState & NS_FRAME_HAS_DIRTY_CHILDREN)) {
|
||||
if (mParent) {
|
||||
// Record that you are dirty and have dirty children
|
||||
// Record that you are dirty and have dirty children
|
||||
mState |= NS_FRAME_IS_DIRTY;
|
||||
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
|
||||
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
|
||||
|
||||
// Pass the reflow request up to the parent
|
||||
mParent->ReflowDirtyChild(aPresShell, (nsIFrame*) this);
|
||||
// Pass the reflow request up to the parent
|
||||
mParent->ReflowDirtyChild(aPresShell, this);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(0, "No parent to pass the reflow request up to.");
|
||||
NS_ERROR("No parent to pass the reflow request up to.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1097,6 +1097,7 @@ nsFloaterCache::nsFloaterCache()
|
||||
mMargins(0, 0, 0, 0),
|
||||
mOffsets(0, 0, 0, 0),
|
||||
mCombinedArea(0, 0, 0, 0),
|
||||
mMaxElementWidth(NS_UNCONSTRAINEDSIZE),
|
||||
mNext(nsnull)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsFloaterCache);
|
||||
|
@ -67,6 +67,9 @@ public:
|
||||
// the containing block frame.
|
||||
nsRect mCombinedArea;
|
||||
|
||||
// The max element size for the floater.
|
||||
nscoord mMaxElementWidth;
|
||||
|
||||
protected:
|
||||
nsFloaterCache* mNext;
|
||||
|
||||
|
@ -4122,18 +4122,10 @@ nsBlockFrame::PostPlaceLine(nsBlockReflowState& aState,
|
||||
printf(": line=%p xmost=%d\n", aLine, xmost);
|
||||
}
|
||||
#endif
|
||||
// If we're shrink wrapping our width and the line was wrapped,
|
||||
// then make sure we take up all of the available width
|
||||
if (aState.GetFlag(BRS_SHRINKWRAPWIDTH) && aLine->IsLineWrapped()) {
|
||||
aState.mKidXMost = aState.BorderPadding().left + aState.mContentArea.width;
|
||||
#ifdef NOISY_KIDXMOST
|
||||
printf("%p PostPlaceLine A aState.mKidXMost=%d\n", this, aState.mKidXMost);
|
||||
#endif
|
||||
}
|
||||
else if (xmost > aState.mKidXMost) {
|
||||
if (xmost > aState.mKidXMost) {
|
||||
aState.mKidXMost = xmost;
|
||||
#ifdef NOISY_KIDXMOST
|
||||
printf("%p PostPlaceLine B aState.mKidXMost=%d\n", this, aState.mKidXMost);
|
||||
printf("%p PostPlaceLine aState.mKidXMost=%d\n", this, aState.mKidXMost);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -4778,10 +4770,14 @@ nsBlockFrame::DeleteChildsNextInFlow(nsIPresContext* aPresContext,
|
||||
nsresult
|
||||
nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRect,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult)
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nscoord& aMaxElementWidthResult)
|
||||
{
|
||||
// Reflow the floater.
|
||||
nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame();
|
||||
|
||||
#ifdef NOISY_FLOATER
|
||||
printf("Reflow Floater %p in parent %p, availSpace(%d,%d,%d,%d)\n",
|
||||
aPlaceholder->GetOutOfFlowFrame(), this,
|
||||
@ -4789,40 +4785,81 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
aState.mAvailSpaceRect.width, aState.mAvailSpaceRect.height
|
||||
);
|
||||
#endif
|
||||
// XXX update this just
|
||||
aState.GetAvailableSpace();
|
||||
|
||||
// Reflow the floater. Since floaters are continued we given them an
|
||||
// unbounded height. Floaters with an auto width are sized to zero
|
||||
// according to the css2 spec.
|
||||
// XXX We also need to take into account whether we should clear any
|
||||
// preceeding floaters...
|
||||
// Compute the available width. By default, assume the width of the
|
||||
// available space rect.
|
||||
nscoord availWidth = aState.mAvailSpaceRect.width;
|
||||
|
||||
// If the floater's width is automatic, we can't let the floater's
|
||||
// width shrink below its maxElementSize.
|
||||
const nsStylePosition* position;
|
||||
GetStyleData(eStyleStruct_Position, NS_REINTERPRET_CAST(const nsStyleStruct*&, position));
|
||||
|
||||
PRBool isAutoWidth = (eStyleUnit_Auto == position->mWidth.GetUnit());
|
||||
if (isAutoWidth) {
|
||||
// It's auto-width. Have we computed a max element size yet? (If
|
||||
// not, the floater cache will have NS_UNCONSTRAINEDSIZE as the
|
||||
// initial value.) If we _have_ computed a max element size, and
|
||||
// its larger then the available width, pin the avaiable width to
|
||||
// the maxElementSize.
|
||||
if ((NS_UNCONSTRAINEDSIZE != aMaxElementWidthResult) &&
|
||||
(aMaxElementWidthResult > availWidth)) {
|
||||
availWidth = aMaxElementWidthResult;
|
||||
}
|
||||
}
|
||||
|
||||
// We'll need to compute the max element size if either 1) we're
|
||||
// auto-width and we've not yet cached the value, or 2) the state
|
||||
// wanted us to compute it anyway.
|
||||
PRBool computeMaxElementSize =
|
||||
(isAutoWidth && (NS_UNCONSTRAINEDSIZE == aMaxElementWidthResult)) ||
|
||||
aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE);
|
||||
|
||||
// XXX Why do we have to add in our border/padding?
|
||||
nsRect availSpace(aState.mAvailSpaceRect.x + aState.BorderPadding().left,
|
||||
aState.mAvailSpaceRect.y + aState.BorderPadding().top,
|
||||
aState.mAvailSpaceRect.width, NS_UNCONSTRAINEDSIZE);
|
||||
nsIFrame* floater = aPlaceholder->GetOutOfFlowFrame();
|
||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||
availWidth, NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
// Setup block reflow state to reflow the floater
|
||||
// Setup a block reflow state to reflow the floater.
|
||||
nsBlockReflowContext brc(aState.mPresContext, aState.mReflowState,
|
||||
aState.GetFlag(BRS_COMPUTEMAXELEMENTSIZE),
|
||||
computeMaxElementSize,
|
||||
aState.GetFlag(BRS_COMPUTEMAXWIDTH));
|
||||
|
||||
brc.SetNextRCFrame(aState.mNextRCFrame);
|
||||
|
||||
// Reflow the floater
|
||||
PRBool isAdjacentWithTop = aState.IsAdjacentWithTop();
|
||||
|
||||
nsReflowStatus frameReflowStatus;
|
||||
nsresult rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, 0,
|
||||
isAdjacentWithTop,
|
||||
nsresult rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, 0, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, frameReflowStatus);
|
||||
if (PR_TRUE==brc.BlockShouldInvalidateItself()) {
|
||||
|
||||
if (NS_SUCCEEDED(rv) && isAutoWidth && (NS_UNCONSTRAINEDSIZE == aMaxElementWidthResult)) {
|
||||
// We've just flowed an auto-width floater, but have not yet cached
|
||||
// the maxElementSize. Do so now.
|
||||
nsSize maxElementSize = brc.GetMaxElementSize();
|
||||
aMaxElementWidthResult = maxElementSize.width;
|
||||
|
||||
if (aMaxElementWidthResult > availSpace.width) {
|
||||
// The floater's maxElementSize is larger than the available
|
||||
// width. Reflow it again, this time pinning the width to the
|
||||
// maxElementSize.
|
||||
availSpace.width = aMaxElementWidthResult;
|
||||
rv = brc.ReflowBlock(floater, availSpace, PR_TRUE, 0, isAdjacentWithTop,
|
||||
aComputedOffsetsResult, frameReflowStatus);
|
||||
}
|
||||
}
|
||||
|
||||
if (brc.BlockShouldInvalidateItself()) {
|
||||
Invalidate(aState.mPresContext, mRect);
|
||||
}
|
||||
|
||||
if (floater == aState.mNextRCFrame) {
|
||||
// NULL out mNextRCFrame so if we reflow it again we don't think it's still
|
||||
// an incremental reflow
|
||||
// Null out mNextRCFrame so if we reflow it again, we don't think
|
||||
// it's still an incremental reflow
|
||||
aState.mNextRCFrame = nsnull;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -4837,7 +4874,8 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
|
||||
aMarginResult.left = m.left;
|
||||
|
||||
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
|
||||
aCombinedRect = metrics.mOverflowArea;
|
||||
aCombinedRectResult = metrics.mOverflowArea;
|
||||
|
||||
// Set the rect, make sure the view is properly sized and positioned,
|
||||
// and tell the frame we're done reflowing it
|
||||
floater->SizeTo(aState.mPresContext, metrics.width, metrics.height);
|
||||
|
@ -351,9 +351,10 @@ protected:
|
||||
|
||||
nsresult ReflowFloater(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsRect& aCombinedRect,
|
||||
nsRect& aCombinedRectResult,
|
||||
nsMargin& aMarginResult,
|
||||
nsMargin& aComputedOffsetsResult);
|
||||
nsMargin& aComputedOffsetsResult,
|
||||
nscoord& aMaxElementWidthResult);
|
||||
|
||||
//----------------------------------------
|
||||
// Methods for pushing/pulling lines/frames
|
||||
@ -482,9 +483,5 @@ protected:
|
||||
#endif
|
||||
};
|
||||
|
||||
// Some #ifdef'd bug fixes
|
||||
#define FIX_BUG_38157
|
||||
#define FIX_BUG_37657
|
||||
|
||||
#endif /* nsBlockFrame_h___ */
|
||||
|
||||
|
@ -314,8 +314,10 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
|
||||
(const nsStyleStruct*&)display);
|
||||
if ((eStyleUnit_Auto == widthUnit) &&
|
||||
((NS_STYLE_FLOAT_LEFT == display->mFloats) ||
|
||||
(NS_STYLE_FLOAT_RIGHT == display->mFloats)))
|
||||
{
|
||||
(NS_STYLE_FLOAT_RIGHT == display->mFloats))) {
|
||||
// Construct the reflow state using the ctor that explicitly
|
||||
// constrains the containing block's width and height to the
|
||||
// available width and height.
|
||||
nsHTMLReflowState autoReflowState(mPresContext, mOuterReflowState, aFrame,
|
||||
availSpace, aSpace.width, aSpace.height);
|
||||
autoReflowState.reason = reason;
|
||||
@ -325,8 +327,10 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
|
||||
aComputedOffsets,
|
||||
aFrameReflowStatus);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Construct the reflow state using the ctor that will use the
|
||||
// containing block's computed width and height (or handle derive
|
||||
// appropriate values for an absolutely positioned frame).
|
||||
nsHTMLReflowState normalReflowState(mPresContext, mOuterReflowState, aFrame,
|
||||
availSpace, reason);
|
||||
rv = DoReflowBlock(normalReflowState, reason, aFrame, aSpace,
|
||||
|
@ -43,6 +43,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
||||
: mBlock(aFrame),
|
||||
mPresContext(aPresContext),
|
||||
mReflowState(aReflowState),
|
||||
mLastFloaterY(0),
|
||||
mNextRCFrame(nsnull),
|
||||
mPrevBottomMargin(0),
|
||||
mLineNumber(0),
|
||||
@ -93,18 +94,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
|
||||
else if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedMaxWidth) {
|
||||
// Choose a width based on the content (shrink wrap width) up
|
||||
// to the maximum width
|
||||
// Part 2 of a possible fix for 38157
|
||||
#ifdef FIX_BUG_38157
|
||||
const nsMargin& margin = Margin();
|
||||
nscoord availContentWidth = aReflowState.availableWidth;
|
||||
if (NS_UNCONSTRAINEDSIZE != availContentWidth) {
|
||||
availContentWidth -= (borderPadding.left + borderPadding.right) +
|
||||
(margin.left + margin.right);
|
||||
}
|
||||
mContentArea.width = PR_MIN(aReflowState.mComputedMaxWidth, availContentWidth);
|
||||
#else
|
||||
mContentArea.width = aReflowState.mComputedMaxWidth;
|
||||
#endif
|
||||
SetFlag(BRS_SHRINKWRAPWIDTH, PR_TRUE);
|
||||
}
|
||||
else {
|
||||
@ -606,6 +596,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine,
|
||||
}
|
||||
#endif
|
||||
mSpaceManager->AddRectRegion(floater, fc->mRegion);
|
||||
mLastFloaterY = fc->mRegion.y;
|
||||
fc = fc->Next();
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@ -702,13 +693,9 @@ nsBlockReflowState::AddFloater(nsLineLayout& aLineLayout,
|
||||
nscoord dy = oy - mSpaceManagerY;
|
||||
mSpaceManager->Translate(-dx, -dy);
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, aPlaceholder, fc->mCombinedArea,
|
||||
fc->mMargins, fc->mOffsets);
|
||||
|
||||
// And then place it
|
||||
PRBool isLeftFloater;
|
||||
PlaceFloater(fc, &isLeftFloater);
|
||||
FlowAndPlaceFloater(fc, &isLeftFloater);
|
||||
|
||||
// Pass on updated available space to the current inline reflow engine
|
||||
GetAvailableSpace();
|
||||
@ -907,8 +894,8 @@ nsBlockReflowState::CanPlaceFloater(const nsRect& aFloaterRect,
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater)
|
||||
nsBlockReflowState::FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater)
|
||||
{
|
||||
// Save away the Y coordinate before placing the floater. We will
|
||||
// restore mY at the end after placing the floater. This is
|
||||
@ -916,9 +903,14 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
// placement are for the floater only, not for any non-floating
|
||||
// content.
|
||||
nscoord saveY = mY;
|
||||
|
||||
// Grab the compatibility mode
|
||||
nsCompatibility mode;
|
||||
mPresContext->GetCompatibilityMode(&mode);
|
||||
|
||||
nsIFrame* floater = aFloaterCache->mPlaceholder->GetOutOfFlowFrame();
|
||||
|
||||
// Get the type of floater
|
||||
// Grab the floater's display information
|
||||
const nsStyleDisplay* floaterDisplay;
|
||||
const nsStylePosition* floaterPosition;
|
||||
floater->GetStyleData(eStyleStruct_Display,
|
||||
@ -926,59 +918,72 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
floater->GetStyleData(eStyleStruct_Position,
|
||||
(const nsStyleStruct*&)floaterPosition);
|
||||
|
||||
// See if the floater should clear any preceeding floaters...
|
||||
if (NS_STYLE_CLEAR_NONE != floaterDisplay->mBreakType) {
|
||||
ClearFloaters(mY, floaterDisplay->mBreakType);
|
||||
}
|
||||
else {
|
||||
// Get the band of available space
|
||||
GetAvailableSpace();
|
||||
}
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
// This will hold the floater's geometry when we've found a place
|
||||
// for it to live.
|
||||
nsRect region;
|
||||
floater->GetRect(region);
|
||||
|
||||
// Adjust the floater size by its margin. That's the area that will
|
||||
// impact the space manager.
|
||||
region.width += aFloaterCache->mMargins.left + aFloaterCache->mMargins.right;
|
||||
region.height += aFloaterCache->mMargins.top + aFloaterCache->mMargins.bottom;
|
||||
// Advance mY to mLastFloaterY (if it's not past it already) to
|
||||
// enforce 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(mLastFloaterY, mY);
|
||||
|
||||
// Find a place to place the floater. The CSS2 spec doesn't want
|
||||
// floaters 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 == floaterDisplay->mFloats) ||
|
||||
(NS_STYLE_FLOAT_RIGHT == floaterDisplay->mFloats),
|
||||
"invalid float type");
|
||||
|
||||
// While there is not enough room for the floater, clear past other
|
||||
// floaters until there is room (or the band is not impacted by a
|
||||
// floater).
|
||||
//
|
||||
// Note: The CSS2 spec says that floaters should be placed as high
|
||||
// as possible.
|
||||
//
|
||||
#ifdef FIX_BUG_37657
|
||||
// Also note that in backwards compatibility mode, we skip this step
|
||||
// for tables, since in old browsers, floating tables are horizontally
|
||||
// stacked regardless of available space. (See bug 43086 about
|
||||
// tables vs. non-tables.)
|
||||
nsCompatibility mode;
|
||||
mPresContext->GetCompatibilityMode(&mode);
|
||||
if ((eCompatibility_NavQuirks != mode) ||
|
||||
(NS_STYLE_DISPLAY_TABLE != floaterDisplay->mDisplay)) {
|
||||
while (!CanPlaceFloater(region, floaterDisplay->mFloats)) {
|
||||
mY += mAvailSpaceRect.height;
|
||||
while (1) {
|
||||
// See if the floater should clear any preceeding floaters...
|
||||
if (NS_STYLE_CLEAR_NONE != floaterDisplay->mBreakType) {
|
||||
ClearFloaters(mY, floaterDisplay->mBreakType);
|
||||
}
|
||||
else {
|
||||
// Get the band of available space
|
||||
GetAvailableSpace();
|
||||
}
|
||||
}
|
||||
#else
|
||||
while (!CanPlaceFloater(region, floaterDisplay->mFloats)) {
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
}
|
||||
|
||||
// Reflow the floater
|
||||
mBlock->ReflowFloater(*this, aFloaterCache->mPlaceholder, aFloaterCache->mCombinedArea,
|
||||
aFloaterCache->mMargins, aFloaterCache->mOffsets,
|
||||
aFloaterCache->mMaxElementWidth);
|
||||
|
||||
// Get the floaters bounding box and margin information
|
||||
floater->GetRect(region);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("flowed floater: ");
|
||||
nsFrame::ListTag(stdout, floater);
|
||||
printf(" (%d,%d,%d,%d), max-element-width=%d\n",
|
||||
region.x, region.y, region.width, region.height,
|
||||
aFloaterCache->mMaxElementWidth);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Adjust the floater size by its margin. That's the area that will
|
||||
// impact the space manager.
|
||||
region.width += aFloaterCache->mMargins.left + aFloaterCache->mMargins.right;
|
||||
region.height += aFloaterCache->mMargins.top + aFloaterCache->mMargins.bottom;
|
||||
|
||||
// Find a place to place the floater. The CSS2 spec doesn't want
|
||||
// floaters 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 == floaterDisplay->mFloats) ||
|
||||
(NS_STYLE_FLOAT_RIGHT == floaterDisplay->mFloats),
|
||||
"invalid float type");
|
||||
|
||||
// In backwards compatibility mode, we don't bother to see if a
|
||||
// floated table can ``really'' fit: in old browsers, floating
|
||||
// tables are horizontally stacked regardless of available space.
|
||||
// (See bug 43086 about tables vs. non-tables.)
|
||||
if ((eCompatibility_NavQuirks == mode) &&
|
||||
(NS_STYLE_DISPLAY_TABLE == floaterDisplay->mDisplay))
|
||||
break;
|
||||
|
||||
// Can the floater fit here?
|
||||
if (CanPlaceFloater(region, floaterDisplay->mFloats))
|
||||
break;
|
||||
|
||||
// Nope. Advance to the next band.
|
||||
mY += mAvailSpaceRect.height;
|
||||
}
|
||||
|
||||
// Assign an x and y coordinate to the floater. Note that the x,y
|
||||
// coordinates are computed <b>relative to the translation in the
|
||||
// spacemanager</b> which means that the impacted region will be
|
||||
@ -1082,6 +1087,9 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
nsBlockFrame::CombineRects(combinedArea, mFloaterCombinedArea);
|
||||
}
|
||||
|
||||
// Remember the y-coordinate of the floater we've just placed
|
||||
mLastFloaterY = mY;
|
||||
|
||||
// Now restore mY
|
||||
mY = saveY;
|
||||
|
||||
@ -1091,7 +1099,7 @@ nsBlockReflowState::PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
floater->GetRect(r);
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("placed floater: ");
|
||||
((nsFrame*)floater)->ListTag(stdout);
|
||||
nsFrame::ListTag(stdout, floater);
|
||||
printf(" %d,%d,%d,%d\n", r.x, r.y, r.width, r.height);
|
||||
}
|
||||
#endif
|
||||
@ -1114,12 +1122,10 @@ nsBlockReflowState::PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aList)
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
mBlock->ReflowFloater(*this, fc->mPlaceholder, fc->mCombinedArea,
|
||||
fc->mMargins, fc->mOffsets);
|
||||
|
||||
// Place the floater
|
||||
PRBool isLeftFloater;
|
||||
PlaceFloater(fc, &isLeftFloater);
|
||||
FlowAndPlaceFloater(fc, &isLeftFloater);
|
||||
}
|
||||
fc = fc->Next();
|
||||
}
|
||||
|
@ -65,8 +65,8 @@ public:
|
||||
|
||||
PRBool CanPlaceFloater(const nsRect& aFloaterRect, PRUint8 aFloats);
|
||||
|
||||
void PlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater);
|
||||
void FlowAndPlaceFloater(nsFloaterCache* aFloaterCache,
|
||||
PRBool* aIsLeftFloater);
|
||||
|
||||
void PlaceBelowCurrentLineFloaters(nsFloaterCacheList& aFloaters);
|
||||
|
||||
@ -177,6 +177,10 @@ public:
|
||||
// The combined area of all floaters placed so far
|
||||
nsRect mFloaterCombinedArea;
|
||||
|
||||
// The y-coordinate of the last floater placed. We keep this around
|
||||
// to enforce 9.5.1 rule [2]
|
||||
nscoord mLastFloaterY;
|
||||
|
||||
// For unconstained-width reflow, we keep the right floaters
|
||||
// combined area stored seperately.
|
||||
PRBool mHaveRightFloaters;
|
||||
|
@ -355,20 +355,20 @@ NS_IMETHODIMP
|
||||
nsInlineFrame::ReflowDirtyChild(nsIPresShell* aPresShell, nsIFrame* aChild)
|
||||
{
|
||||
// The inline container frame does not handle the reflow
|
||||
// request. It passes it up to its parent container.
|
||||
// request. It passes it up to its parent container.
|
||||
|
||||
// If you don't already have dirty children,
|
||||
if (!(mState & NS_FRAME_HAS_DIRTY_CHILDREN)) {
|
||||
if (mParent) {
|
||||
// Record that you are dirty and have dirty children
|
||||
// Record that you are dirty and have dirty children
|
||||
mState |= NS_FRAME_IS_DIRTY;
|
||||
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
|
||||
mState |= NS_FRAME_HAS_DIRTY_CHILDREN;
|
||||
|
||||
// Pass the reflow request up to the parent
|
||||
mParent->ReflowDirtyChild(aPresShell, (nsIFrame*) this);
|
||||
// Pass the reflow request up to the parent
|
||||
mParent->ReflowDirtyChild(aPresShell, this);
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(0, "No parent to pass the reflow request up to.");
|
||||
NS_ERROR("No parent to pass the reflow request up to.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1097,6 +1097,7 @@ nsFloaterCache::nsFloaterCache()
|
||||
mMargins(0, 0, 0, 0),
|
||||
mOffsets(0, 0, 0, 0),
|
||||
mCombinedArea(0, 0, 0, 0),
|
||||
mMaxElementWidth(NS_UNCONSTRAINEDSIZE),
|
||||
mNext(nsnull)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsFloaterCache);
|
||||
|
@ -67,6 +67,9 @@ public:
|
||||
// the containing block frame.
|
||||
nsRect mCombinedArea;
|
||||
|
||||
// The max element size for the floater.
|
||||
nscoord mMaxElementWidth;
|
||||
|
||||
protected:
|
||||
nsFloaterCache* mNext;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user