diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index b5454c1c901..0ffc0038465 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -5217,7 +5217,7 @@ nsBlockFrame::DeleteNextInFlowChild(nsPresContext* aPresContext, nsresult nsBlockFrame::ReflowFloat(nsBlockReflowState& aState, nsPlaceholderFrame* aPlaceholder, - nsFloatCache* aFloatCache, + nsMargin& aFloatMargin, nsReflowStatus& aReflowStatus) { // Reflow the float. @@ -5295,9 +5295,11 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState, } } + nsMargin offsets; // Don't bother returning this to the caller; it's stored + // on a frame property anyawy rv = brc.ReflowBlock(availSpace, PR_TRUE, margin, 0, isAdjacentWithTop, - aFloatCache->mOffsets, floatRS, + offsets, floatRS, aReflowStatus); } while (NS_SUCCEEDED(rv) && clearanceFrame); @@ -5336,17 +5338,16 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState, // Capture the margin information for the caller const nsMargin& m = brc.GetMargin(); - aFloatCache->mMargins.top = brc.GetTopMargin(); - aFloatCache->mMargins.right = m.right; + aFloatMargin.top = brc.GetTopMargin(); + aFloatMargin.right = m.right; // Only last in flows get a bottom margin if (NS_FRAME_IS_COMPLETE(aReflowStatus)) { brc.GetCarriedOutBottomMargin().Include(m.bottom); } - aFloatCache->mMargins.bottom = brc.GetCarriedOutBottomMargin().get(); - aFloatCache->mMargins.left = m.left; + aFloatMargin.bottom = brc.GetCarriedOutBottomMargin().get(); + aFloatMargin.left = m.left; const nsHTMLReflowMetrics& metrics = brc.GetMetrics(); - aFloatCache->mCombinedArea = metrics.mOverflowArea; // Set the rect, make sure the view is properly sized and positioned, // and tell the frame we're done reflowing it diff --git a/mozilla/layout/generic/nsBlockFrame.h b/mozilla/layout/generic/nsBlockFrame.h index fcae33d3489..05846959a88 100644 --- a/mozilla/layout/generic/nsBlockFrame.h +++ b/mozilla/layout/generic/nsBlockFrame.h @@ -480,7 +480,7 @@ protected: // but only if the available height is constrained. nsresult ReflowFloat(nsBlockReflowState& aState, nsPlaceholderFrame* aPlaceholder, - nsFloatCache* aFloatCache, + nsMargin& aFloatMargin, nsReflowStatus& aReflowStatus); //---------------------------------------- diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index b7a2bc5af0d..e2c66e1b2c2 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -377,7 +377,6 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine, nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame(); if (aDeltaY != 0) { fc->mRegion.y += aDeltaY; - fc->mCombinedArea.y += aDeltaY; nsPoint p = floatFrame->GetPosition(); floatFrame->SetPosition(nsPoint(p.x, p.y + aDeltaY)); } @@ -520,13 +519,12 @@ nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout, // Allocate a nsFloatCache for the float nsFloatCache* fc = mFloatCacheFreeList.Alloc(); fc->mPlaceholder = aPlaceholder; - fc->mIsCurrentLineFloat = aLineLayout.CanPlaceFloatNow(); PRBool placed; // Now place the float immediately if possible. Otherwise stash it // away in mPendingFloats and place it later. - if (fc->mIsCurrentLineFloat) { + if (aLineLayout.CanPlaceFloatNow()) { // 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 @@ -716,14 +714,15 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, const nsStyleDisplay* floatDisplay = floatFrame->GetStyleDisplay(); // The float's old region, so we can propagate damage. - nsRect oldRegion = floatFrame->GetRect(); - oldRegion.Inflate(aFloatCache->mMargins); + nsRect oldRegion = aFloatCache->mRegion; // 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(mSpaceManager->GetLowestRegionTop() + 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); @@ -735,7 +734,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, "Float frame has wrong parent"); // Reflow the float - mBlock->ReflowFloat(*this, placeholder, aFloatCache, aReflowStatus); + nsMargin floatMargin; + mBlock->ReflowFloat(*this, placeholder, floatMargin, aReflowStatus); #ifdef DEBUG if (nsBlockFrame::gNoisyReflow) { @@ -748,11 +748,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, } #endif - nsSize floatSize = floatFrame->GetSize(); - // Adjust the float size by its margin. That's the area that will - // impact the space manager. - floatSize.width += aFloatCache->mMargins.left + aFloatCache->mMargins.right; - floatSize.height += aFloatCache->mMargins.top + aFloatCache->mMargins.bottom; + nsSize floatSize = floatFrame->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 @@ -820,17 +817,13 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, // 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, placeholder, aFloatCache, aReflowStatus); + mBlock->ReflowFloat(*this, placeholder, floatMargin, aReflowStatus); // Get the floats bounding box and margin information - floatSize = floatFrame->GetSize(); - // Adjust the float size by its margin. That's the area that will - // impact the space manager. - floatSize.width += aFloatCache->mMargins.left + aFloatCache->mMargins.right; - floatSize.height += aFloatCache->mMargins.top + aFloatCache->mMargins.bottom; + floatSize = floatFrame->GetSize() + + nsSize(floatMargin.LeftRight(), floatMargin.TopBottom()); } } // If the float is continued, it will get the same absolute x value as its prev-in-flow - nsRect prevRect(0,0,0,0); // We don't worry about the geometry of the prev in flow, let the continuation // place and size itself as required. @@ -897,9 +890,19 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, mSpaceManager->AddRectRegion(floatFrame, region); NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "bad float placement"); + // Save away the floats region in the spacemanager, after making + // it relative to the containing block's frame instead of relative + // to the spacemanager translation (which is inset by the + // border+padding). + // XXX Maybe RecoverFloats should calc/add in the borderPadding itself? + // It's kind of confusing to have the spacemanager translation be different + // depending on what stage of reflow we're in. + aFloatCache->mRegion = region + + nsPoint(borderPadding.left, borderPadding.top); + // If the float's dimensions have changed, note the damage in the // space manager. - if (region != oldRegion) { + if (aFloatCache->mRegion != 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 @@ -909,14 +912,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, mSpaceManager->IncludeInDamage(top, bottom); } - // Save away the floats region in the spacemanager, after making - // it relative to the containing block's frame instead of relative - // to the spacemanager translation (which is inset by the - // border+padding). - aFloatCache->mRegion.x = region.x + borderPadding.left; - aFloatCache->mRegion.y = region.y + borderPadding.top; - aFloatCache->mRegion.width = region.width; - aFloatCache->mRegion.height = region.height; #ifdef NOISY_SPACEMANAGER nscoord tx, ty; mSpaceManager->GetTranslation(tx, ty); @@ -927,37 +922,33 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, aFloatCache->mRegion.width, aFloatCache->mRegion.height); #endif - // Set the origin of the float frame, in frame coordinates. These - // coordinates are not relative to the spacemanager - // translation, therefore we have to factor in our border/padding. - nscoord x = borderPadding.left + aFloatCache->mMargins.left + floatX; - nscoord y = borderPadding.top + aFloatCache->mMargins.top + floatY; + // 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 - // XXXldb Should this be done after handling the combined area - // below? if (NS_STYLE_POSITION_RELATIVE == floatDisplay->mPosition) { - x += aFloatCache->mOffsets.left; - y += aFloatCache->mOffsets.top; + nsPoint *offsets = NS_STATIC_CAST(nsPoint*, + floatFrame->GetProperty(nsGkAtoms::computedOffsetProperty)); + if (offsets) { + origin += *offsets; + } } // 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(nsPoint(x, y)); + floatFrame->SetPosition(origin); nsContainerFrame::PositionFrameView(floatFrame); nsContainerFrame::PositionChildViews(floatFrame); // Update the float combined area state - nsRect combinedArea = aFloatCache->mCombinedArea; - combinedArea.x += x; - combinedArea.y += y; - // When we are placing a right float in an unconstrained situation or - // when shrink wrapping, we don't apply it to the float combined area - // immediately, since there's no need to since we're guaranteed another - // reflow, and since there's no need to change the code that was - // necessary back when the float was positioned relative to - // NS_UNCONSTRAINEDSIZE. + nsRect combinedArea = floatFrame->GetOverflowRect() + origin; + + // XXX Floats should really just get invalidated here if necessary mFloatCombinedArea.UnionRect(combinedArea, mFloatCombinedArea); // Now restore mY @@ -984,9 +975,7 @@ nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aList, PRB { nsFloatCache* fc = aList.Head(); while (fc) { - NS_ASSERTION(!fc->mIsCurrentLineFloat, - "A cl float crept into the bcl float list."); - if (!fc->mIsCurrentLineFloat) { + { #ifdef DEBUG if (nsBlockFrame::gNoisyReflow) { nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent); diff --git a/mozilla/layout/generic/nsLineBox.cpp b/mozilla/layout/generic/nsLineBox.cpp index 63b6f443848..5df4d3475db 100644 --- a/mozilla/layout/generic/nsLineBox.cpp +++ b/mozilla/layout/generic/nsLineBox.cpp @@ -153,12 +153,9 @@ ListFloats(FILE* out, PRInt32 aIndent, const nsFloatCacheList& aFloats) fputs(NS_LossyConvertUTF16toASCII(frameName).get(), out); } } - fprintf(out, " %s region={%d,%d,%d,%d} combinedArea={%d,%d,%d,%d}", - fc->mIsCurrentLineFloat ? "cl" : "bcl", + fprintf(out, " %s region={%d,%d,%d,%d}", fc->mRegion.x, fc->mRegion.y, - fc->mRegion.width, fc->mRegion.height, - fc->mCombinedArea.x, fc->mCombinedArea.y, - fc->mCombinedArea.width, fc->mCombinedArea.height); + fc->mRegion.width, fc->mRegion.height); fprintf(out, "\n"); } @@ -992,10 +989,6 @@ nsFloatCacheFreeList::Append(nsFloatCache* aFloat) nsFloatCache::nsFloatCache() : mPlaceholder(nsnull), - mIsCurrentLineFloat(PR_TRUE), - mMargins(0, 0, 0, 0), - mOffsets(0, 0, 0, 0), - mCombinedArea(0, 0, 0, 0), mNext(nsnull) { MOZ_COUNT_CTOR(nsFloatCache); diff --git a/mozilla/layout/generic/nsLineBox.h b/mozilla/layout/generic/nsLineBox.h index 1d14ce0984a..ab1bd6266c8 100644 --- a/mozilla/layout/generic/nsLineBox.h +++ b/mozilla/layout/generic/nsLineBox.h @@ -67,25 +67,12 @@ public: nsPlaceholderFrame* mPlaceholder; // nsPlaceholderFrame - // This will be true if the float was placed on the current line - // instead of below the current line. - PRBool mIsCurrentLineFloat; - - nsMargin mMargins; // computed margins - - nsMargin mOffsets; // computed offsets (relative pos) - // Region in the spacemanager impacted by this float; the // coordinates are relative to the containing block frame. The // region includes the margins around the float, but doesn't // include the relative offsets. nsRect mRegion; - // Combined area for the float. This will not include the margins - // for the float. Like mRegion, the coordinates are relative to - // the containing block frame. - nsRect mCombinedArea; - protected: nsFloatCache* mNext;