Bug 475968. Eliminate NS_FRAME_OUTSIDE_CHILDREN flag, store small overflow areas cheaply within the frame. r+sr=roc

This commit is contained in:
Jonathan Kew 2009-04-06 12:31:50 +12:00
parent 1bea884aa2
commit bdab93a7ca
19 changed files with 181 additions and 59 deletions

View File

@ -148,8 +148,8 @@ The table cell requires its children to compute the MES. It is reported back fro
The block has been required to compute the max. element size only once and it reports now:
<p> <code class="log">block 02D7BCF8 d=1410,300</code></p>
<p>The block shows the same address as the previous one.
<p>Frames with children that overflow the parent have the <code>NS_FRAME_OUTSIDE_CHILDREN</code> flag set. For these frames
the overflowarea is displayed as <code class="log">block 025ED8F0 d=8940,1020 o=(0,0) 9180 x 1020</code>. The overflow area is specified as (x,y) origin and width x height.
<p>Frames with children that overflow the parent will return <code>PR_TRUE</code> from <code>HasOverflowRect()</code>. For these frames
the overflow area is displayed as <code class="log">block 025ED8F0 d=8940,1020 o=(0,0) 9180 x 1020</code>. The overflow area is specified as (x,y) origin and width x height.
<p> The reflow finishes at the same level where it started.
<h2>Advanced reflow debugging</h2>

View File

@ -368,7 +368,7 @@ nsBlockFrame::List(FILE* out, PRInt32 aIndent) const
fprintf(out, " [state=%08x]", mState);
}
nsBlockFrame* f = const_cast<nsBlockFrame*>(this);
if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (f->HasOverflowRect()) {
nsRect overflowArea = f->GetOverflowRect();
fprintf(out, " [overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
overflowArea.width, overflowArea.height);
@ -1186,7 +1186,7 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext,
aStatus, NS_FRAME_IS_COMPLETE(aStatus) ? "" : "not ",
aMetrics.width, aMetrics.height,
aMetrics.mCarriedOutBottomMargin.get());
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
if (HasOverflowRect()) {
printf(" combinedArea={%d,%d,%d,%d}",
aMetrics.mOverflowArea.x,
aMetrics.mOverflowArea.y,

View File

@ -326,7 +326,7 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
}
#endif
if (!(NS_FRAME_OUTSIDE_CHILDREN & mFrame->GetStateBits())) {
if (!mFrame->HasOverflowRect()) {
// Provide overflow area for child that doesn't have any
mMetrics.mOverflowArea.x = 0;
mMetrics.mOverflowArea.y = 0;

View File

@ -564,8 +564,8 @@ nsContainerFrame::SyncFrameViewAfterReflow(nsPresContext* aPresContext,
vm->ResizeView(aView, *aCombinedArea, PR_TRUE);
// Even if the size hasn't changed, we need to sync up the
// geometry dependent properties, because (kidState &
// NS_FRAME_OUTSIDE_CHILDREN) might have changed, and we can't
// geometry dependent properties, because overflow areas of
// children might have changed, and we can't
// detect whether it has or not. Likewise, whether the view size
// has changed or not, we may need to change the transparency
// state even if there is no clip.
@ -1608,7 +1608,7 @@ nsContainerFrame::List(FILE* out, PRInt32 aIndent) const
}
fprintf(out, " [content=%p]", static_cast<void*>(mContent));
nsContainerFrame* f = const_cast<nsContainerFrame*>(this);
if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (f->HasOverflowRect()) {
nsRect overflowArea = f->GetOverflowRect();
fprintf(out, " [overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
overflowArea.width, overflowArea.height);

View File

@ -3975,11 +3975,22 @@ nsIFrame::GetOverflowRect() const
// areas will invalidate the appropriate area, so any (mis)uses of
// this method will be fixed up.
if (GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN)
if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) {
// there is an overflow rect, and it's not stored as deltas but as
// a separately-allocated rect
return *const_cast<nsIFrame*>(this)->GetOverflowAreaProperty(PR_FALSE);
// NOTE this won't return accurate info if the overflow rect was updated
// but the mRect hasn't been set yet!
return nsRect(nsPoint(0, 0), GetSize());
}
// Calculate the rect using deltas from the frame's border rect.
// Note that the mOverflow.mDeltas fields are unsigned, but we will often
// need to return negative values for the left and top, so take care
// to cast away the unsigned-ness.
return nsRect(-(PRInt32)mOverflow.mDeltas.mLeft,
-(PRInt32)mOverflow.mDeltas.mTop,
mRect.width + mOverflow.mDeltas.mRight +
mOverflow.mDeltas.mLeft,
mRect.height + mOverflow.mDeltas.mBottom +
mOverflow.mDeltas.mTop);
}
nsRect
@ -4068,7 +4079,7 @@ nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
{
if (aReflowState.mReflowDepth > MAX_FRAME_DEPTH) {
mState |= NS_FRAME_TOO_DEEP_IN_FRAME_TREE;
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
ClearOverflowRect();
aMetrics.width = 0;
aMetrics.height = 0;
aMetrics.ascent = 0;
@ -4148,7 +4159,7 @@ nsFrame::List(FILE* out, PRInt32 aIndent) const
}
fprintf(out, " [content=%p]", static_cast<void*>(mContent));
nsFrame* f = const_cast<nsFrame*>(this);
if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (f->HasOverflowRect()) {
nsRect overflowArea = f->GetOverflowRect();
fprintf(out, " [overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
overflowArea.width, overflowArea.height);
@ -5569,7 +5580,8 @@ nsFrame::GetAccessible(nsIAccessible** aAccessible)
nsRect*
nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary)
{
if (!((GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) || aCreateIfNecessary)) {
if (!((mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) ||
aCreateIfNecessary)) {
return nsnull;
}
@ -5588,10 +5600,44 @@ nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary)
return overflow;
}
NS_NOTREACHED("Frame abuses NS_FRAME_OUTSIDE_CHILDREN flag");
NS_NOTREACHED("Frame abuses GetOverflowAreaProperty()");
return nsnull;
}
/** Set the overflowArea rect, storing it as deltas or a separate rect
* depending on its size in relation to the primary frame rect.
*/
void
nsIFrame::SetOverflowRect(const nsRect& aRect)
{
PRUint32 l = -aRect.x, // left edge: positive delta is leftwards
t = -aRect.y, // top: positive is upwards
r = aRect.XMost() - mRect.width, // right: positive is rightwards
b = aRect.YMost() - mRect.height; // bottom: positive is downwards
if (l <= NS_FRAME_OVERFLOW_DELTA_MAX &&
t <= NS_FRAME_OVERFLOW_DELTA_MAX &&
r <= NS_FRAME_OVERFLOW_DELTA_MAX &&
b <= NS_FRAME_OVERFLOW_DELTA_MAX &&
(l | t | r | b) != 0) {
// It's a "small" overflow area so we store the deltas for each edge
// directly in the frame, rather than allocating a separate rect.
// Note that we do NOT store in this way if *all* the deltas are zero,
// as that would be indistinguishable from the complete absence of
// an overflow rect.
DeleteProperty(nsGkAtoms::overflowAreaProperty);
mOverflow.mDeltas.mLeft = l;
mOverflow.mDeltas.mTop = t;
mOverflow.mDeltas.mRight = r;
mOverflow.mDeltas.mBottom = b;
} else {
// it's a large overflow area that we need to store as a property
mOverflow.mType = NS_FRAME_OVERFLOW_LARGE;
nsRect* overflowArea = GetOverflowAreaProperty(PR_TRUE);
NS_ASSERTION(overflowArea, "should have created rect");
*overflowArea = aRect;
}
}
inline PRBool
IsInlineFrame(nsIFrame *aFrame)
{
@ -5682,18 +5728,14 @@ nsIFrame::FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize)
PRBool overflowChanged;
if (*aOverflowArea != nsRect(nsPoint(0, 0), aNewSize)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
nsRect* overflowArea = GetOverflowAreaProperty(PR_TRUE);
NS_ASSERTION(overflowArea, "should have created rect");
overflowChanged = *overflowArea != *aOverflowArea;
*overflowArea = *aOverflowArea;
overflowChanged = *aOverflowArea != GetOverflowRect();
SetOverflowRect(*aOverflowArea);
}
else {
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
if (HasOverflowRect()) {
// remove the previously stored overflow area
DeleteProperty(nsGkAtoms::overflowAreaProperty);
ClearOverflowRect();
overflowChanged = PR_TRUE;
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
} else {
overflowChanged = PR_FALSE;
}
@ -6624,7 +6666,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
// see if the overflow option is set. If it is then if our child's bounds overflow then
// we will set the child's rect to include the overflow size.
if (GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (HasOverflowRect()) {
// This kinda sucks. We should be able to handle the case
// where there's overflow above or to the left of the
// origin. But for now just chop that stuff off.
@ -6661,7 +6703,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
AddStateBits(NS_FRAME_IS_DIRTY);
WillReflow(aPresContext);
Reflow(aPresContext, aDesiredSize, reflowState, status);
if (GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN)
if (HasOverflowRect())
aDesiredSize.height = aDesiredSize.mOverflowArea.YMost();
}
}
@ -7694,13 +7736,13 @@ void nsFrame::DisplayReflowExit(nsPresContext* aPresContext,
if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
printf(" status=0x%x", aStatus);
}
if (aFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (aFrame->HasOverflowRect()) {
DR_state->PrettyUC(aMetrics.mOverflowArea.x, x);
DR_state->PrettyUC(aMetrics.mOverflowArea.y, y);
DR_state->PrettyUC(aMetrics.mOverflowArea.width, width);
DR_state->PrettyUC(aMetrics.mOverflowArea.height, height);
printf(" o=(%s,%s) %s x %s", x, y, width, height);
if (aFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (aFrame->HasOverflowRect()) {
nsRect storedOverflow = aFrame->GetOverflowRect();
DR_state->PrettyUC(storedOverflow.x, x);
DR_state->PrettyUC(storedOverflow.y, y);

View File

@ -540,7 +540,7 @@ nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState* aState,
// always set mOverflowArea. In fact nsObjectFrame and nsFrameFrame don't
// support the 'outline' property because of this. Rather than fix the world
// right now, just fix up the overflow area if necessary. Note that we don't
// check NS_FRAME_OUTSIDE_CHILDREN because it could be set even though the
// check HasOverflowRect() because it could be set even though the
// overflow area doesn't include the frame bounds.
aMetrics->mOverflowArea.UnionRect(aMetrics->mOverflowArea,
nsRect(0, 0, aMetrics->width, aMetrics->height));
@ -712,12 +712,12 @@ nsHTMLScrollFrame::PlaceScrollArea(const ScrollReflowState& aState)
// Store the new overflow area. Note that this changes where an outline
// of the scrolled frame would be painted, but scrolled frames can't have
// outlines (the outline would go on this scrollframe instead).
// Using FinishAndStoreOverflow is needed so NS_FRAME_OUTSIDE_CHILDREN
// Using FinishAndStoreOverflow is needed so the overflow rect
// gets set correctly. It also messes with the overflow rect in the
// -moz-hidden-unscrollable case, but scrolled frames can't have
// 'overflow' either.
// This needs to happen before SyncFrameViewAfterReflow so
// NS_FRAME_OUTSIDE_CHILDREN is set.
// HasOverflowRect() will return the correct value.
scrolledFrame->FinishAndStoreOverflow(&scrolledArea,
scrolledFrame->GetSize());
@ -2083,9 +2083,7 @@ nsXULScrollFrame::LayoutScrollArea(nsBoxLayoutState& aState, const nsRect& aRect
// remove overflow area when we update the bounds,
// because we've already accounted for it
mInner.mScrolledFrame->SetBounds(aState, childRect);
PresContext()->PropertyTable()->
DeleteProperty(mInner.mScrolledFrame, nsGkAtoms::overflowAreaProperty);
mInner.mScrolledFrame->RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN);
mInner.mScrolledFrame->ClearOverflowRect();
}
aState.SetLayoutFlags(oldflags);

View File

@ -159,7 +159,7 @@ struct nsHTMLReflowMetrics {
nsCollapsingMargin mCarriedOutBottomMargin;
// For frames that have content that overflow their content area
// (NS_FRAME_OUTSIDE_CHILDREN) this rectangle represents the total area
// (HasOverflowRect() is true) this rectangle represents the total area
// of the frame including visible overflow, i.e., don't include overflowing
// content that is hidden.
// The rect is in the local coordinate space of the frame, and should be at

View File

@ -162,9 +162,14 @@ enum {
// continuation, e.g. a bidi continuation.
NS_FRAME_IS_FLUID_CONTINUATION = 0x00000004,
// This bit is set when the frame's overflow rect is
// different from its border rect (i.e. GetOverflowRect() != GetRect())
NS_FRAME_OUTSIDE_CHILDREN = 0x00000008,
/*
* This bit is obsolete, replaced by HasOverflowRect().
* The definition is left here as a placeholder for now, to remind us
* that this bit is now free to allocate for other purposes.
* // This bit is set when the frame's overflow rect is
* // different from its border rect (i.e. GetOverflowRect() != GetRect())
* NS_FRAME_OUTSIDE_CHILDREN = 0x00000008,
*/
// If this bit is set, then a reference to the frame is being held
// elsewhere. The frame may want to send a notification when it is
@ -441,6 +446,24 @@ typedef PRBool nsDidReflowStatus;
#define NS_FRAME_REFLOW_NOT_FINISHED PR_FALSE
#define NS_FRAME_REFLOW_FINISHED PR_TRUE
/**
* The overflow rect may be stored as four 1-byte deltas each strictly
* LESS THAN 0xff, for the four edges of the rectangle, or the four bytes
* may be read as a single 32-bit "overflow-rect type" value including
* at least one 0xff byte as an indicator that the value does NOT
* represent four deltas.
* If all four deltas are zero, this means that no overflow rect has
* actually been set (this is the initial state of newly-created frames).
*/
#define NS_FRAME_OVERFLOW_DELTA_MAX 0xfe // max delta we can store
#define NS_FRAME_OVERFLOW_NONE 0x00000000 // there is no overflow rect;
// code relies on this being
// the all-zero value
#define NS_FRAME_OVERFLOW_LARGE 0x000000ff // overflow is stored as a
// separate rect property
//----------------------------------------------------------------------
/**
@ -710,9 +733,32 @@ public:
nsRect GetRect() const { return mRect; }
nsPoint GetPosition() const { return nsPoint(mRect.x, mRect.y); }
nsSize GetSize() const { return nsSize(mRect.width, mRect.height); }
void SetRect(const nsRect& aRect) { mRect = aRect; }
/**
* When we change the size of the frame's border-box rect, we may need to
* reset the overflow rect if it was previously stored as deltas.
* (If it is currently a "large" overflow and could be re-packed as deltas,
* we don't bother as the cost of the allocation has already been paid.)
*/
void SetRect(const nsRect& aRect) {
if (HasOverflowRect() && mOverflow.mType != NS_FRAME_OVERFLOW_LARGE) {
nsRect r = GetOverflowRect();
mRect = aRect;
SetOverflowRect(r);
} else {
mRect = aRect;
}
}
void SetSize(const nsSize& aSize) {
if (HasOverflowRect() && mOverflow.mType != NS_FRAME_OVERFLOW_LARGE) {
nsRect r = GetOverflowRect();
mRect.SizeTo(aSize);
SetOverflowRect(r);
} else {
mRect.SizeTo(aSize);
}
}
void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); }
void SetSize(const nsSize& aSize) { mRect.SizeTo(aSize); }
/**
* Return frame's computed offset due to relative positioning
@ -1756,8 +1802,8 @@ public:
* frame's outline, and descentant frames' outline, but does not include
* areas clipped out by the CSS "overflow" and "clip" properties.
*
* The NS_FRAME_OUTSIDE_CHILDREN state bit is set when this overflow rect
* is different from nsRect(0, 0, GetRect().width, GetRect().height).
* HasOverflowRect() (below) will return PR_TRUE when this overflow rect
* has been explicitly set, even if it matches mRect.
* XXX Note: because of a space optimization using the formula above,
* during reflow this function does not give accurate data if
* FinishAndStoreOverflow has been called but mRect hasn't yet been
@ -1776,7 +1822,7 @@ public:
* frame's outline, and descentant frames' outline, but does not include
* areas clipped out by the CSS "overflow" and "clip" properties.
*
* The NS_FRAME_OUTSIDE_CHILDREN state bit is set when this overflow rect
* HasOverflowRect() (below) will return PR_TRUE when this overflow rect
* is different from nsRect(0, 0, GetRect().width, GetRect().height).
* XXX Note: because of a space optimization using the formula above,
* during reflow this function does not give accurate data if
@ -1800,7 +1846,7 @@ public:
nsRect GetOverflowRectRelativeToSelf() const;
/**
* Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area
* Store the overflow area in the frame's mOverflow.mDeltas fields or
* as a frame property in the frame manager so that it can be retrieved
* later without reflowing the frame.
*/
@ -1810,6 +1856,22 @@ public:
FinishAndStoreOverflow(&aMetrics->mOverflowArea, nsSize(aMetrics->width, aMetrics->height));
}
/**
* Returns whether the frame has an overflow rect that is different from
* its border-box.
*/
PRBool HasOverflowRect() const {
return mOverflow.mType != NS_FRAME_OVERFLOW_NONE;
}
/**
* Removes any stored overflow rect from the frame.
*/
void ClearOverflowRect() {
DeleteProperty(nsGkAtoms::overflowAreaProperty);
mOverflow.mType = NS_FRAME_OVERFLOW_NONE;
}
/**
* Determine whether borders should not be painted on certain sides of the
* frame.
@ -2255,6 +2317,25 @@ protected:
nsIFrame* mParent;
nsIFrame* mNextSibling; // singly-linked list of frames
nsFrameState mState;
// When there is an overflow area only slightly larger than mRect,
// we store a set of four 1-byte deltas from the edges of mRect
// rather than allocating a whole separate rectangle property.
// Note that these are unsigned values, all measured "outwards"
// from the edges of mRect, so /mLeft/ and /mTop/ are reversed from
// our normal coordinate system.
// If mOverflow.mType == NS_FRAME_OVERFLOW_LARGE, then the
// delta values are not meaningful and the overflow area is stored
// as a separate rect property.
union {
PRUint32 mType;
struct {
PRUint8 mLeft;
PRUint8 mTop;
PRUint8 mRight;
PRUint8 mBottom;
} mDeltas;
} mOverflow;
// Helpers
/**
@ -2357,6 +2438,7 @@ protected:
private:
nsRect* GetOverflowAreaProperty(PRBool aCreateIfNecessary = PR_FALSE);
void SetOverflowRect(const nsRect& aRect);
};
//----------------------------------------------------------------------

View File

@ -384,7 +384,7 @@ nsInlineFrame::Reflow(nsPresContext* aPresContext,
rv = ReflowFrames(aPresContext, aReflowState, irs, aMetrics, aStatus);
// Note: the line layout code will properly compute our
// NS_FRAME_OUTSIDE_CHILDREN state for us.
// overflow-rect state for us.
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
return rv;

View File

@ -2635,8 +2635,8 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
nsContainerFrame::PositionChildViews(frame);
}
// Do this here (rather than along with NS_FRAME_OUTSIDE_CHILDREN
// handling below) so we get leaf frames as well. No need to worry
// Do this here (rather than along with setting the overflow rect
// below) so we get leaf frames as well. No need to worry
// about the root span, since it doesn't have a frame.
if (frame->HasView())
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, frame,
@ -2647,7 +2647,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
}
// If we just computed a spans combined area, we need to update its
// NS_FRAME_OUTSIDE_CHILDREN bit..
// overflow rect...
if (psd->mFrame) {
PerFrameData* spanPFD = psd->mFrame;
nsIFrame* frame = spanPFD->mFrame;

View File

@ -140,7 +140,7 @@ public:
/**
* Handle all the relative positioning in the line, compute the
* combined area (== overflow area) for the line, and handle view
* sizing/positioning and the setting of NS_FRAME_OUTSIDE_CHILDREN.
* sizing/positioning and the setting of the overflow rect.
*/
void RelativePositionFrames(nsRect& aCombinedArea);

View File

@ -111,7 +111,7 @@ nsPageContentFrame::Reflow(nsPresContext* aPresContext,
kidReflowState.mStylePadding->GetPadding(padding);
// First check the combined area
if (NS_FRAME_OUTSIDE_CHILDREN & frame->GetStateBits()) {
if (frame->HasOverflowRect()) {
// The background covers the content area and padding area, so check
// for children sticking outside the child frame's padding edge
if (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) {

View File

@ -6625,7 +6625,7 @@ nsTextFrame::List(FILE* out, PRInt32 aIndent) const
}
}
fprintf(out, " [content=%p]", static_cast<void*>(mContent));
if (GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (HasOverflowRect()) {
nsRect overflowArea = GetOverflowRect();
fprintf(out, " [overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
overflowArea.width, overflowArea.height);

View File

@ -6423,6 +6423,8 @@ nsTableFrame::PaintBCBorders(nsIRenderingContext& aRenderingContext,
rowY += rowSize.height;
}
}
// XXX comment refers to the obsolete NS_FRAME_OUTSIDE_CHILDREN flag
// XXX but I don't understand it, so not changing it for now
// outer table borders overflow the table, so the table might be
// target to other areas as the NS_FRAME_OUTSIDE_CHILDREN is set
// on the table

View File

@ -923,7 +923,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
desiredSize.width = cellDesiredSize.width;
desiredSize.height = cellDesiredSize.height;
if (cellFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN)
if (cellFrame->HasOverflowRect())
desiredSize.mOverflowArea = cellFrame->GetOverflowRect();
else
desiredSize.mOverflowArea.SetRect(0, 0, cellDesiredSize.width,

View File

@ -280,11 +280,9 @@ nsBox::SetBounds(nsBoxLayoutState& aState, const nsRect& aRect, PRBool aRemoveOv
// Nuke the overflow area. The caller is responsible for restoring
// it if necessary.
if (aRemoveOverflowArea && (GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN)) {
if (aRemoveOverflowArea && HasOverflowRect()) {
// remove the previously stored overflow area
PresContext()->PropertyTable()->
DeleteProperty(this, nsGkAtoms::overflowAreaProperty);
RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN);
ClearOverflowRect();
}
if (!(flags & NS_FRAME_NO_MOVE_VIEW))

View File

@ -351,7 +351,7 @@ nsLeafBoxFrame::Reflow(nsPresContext* aPresContext,
aDesiredSize.height = mRect.height;
aDesiredSize.ascent = GetBoxAscent(state);
// NS_FRAME_OUTSIDE_CHILDREN is set in SetBounds() above
// the overflow rect is set in SetBounds() above
aDesiredSize.mOverflowArea = GetOverflowRect();
#ifdef DO_NOISY_REFLOW

View File

@ -329,7 +329,7 @@ nsPopupSetFrame::List(FILE* out, PRInt32 aIndent) const
}
fprintf(out, " [content=%p]", static_cast<void*>(mContent));
nsPopupSetFrame* f = const_cast<nsPopupSetFrame*>(this);
if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
if (f->HasOverflowRect()) {
nsRect overflowArea = f->GetOverflowRect();
fprintf(out, " [overflow=%d,%d,%d,%d]", overflowArea.x, overflowArea.y,
overflowArea.width, overflowArea.height);

View File

@ -105,7 +105,7 @@ public:
/**
* Treat scrollbars as clipping their children; overflowing children
* will not be allowed to make NS_FRAME_OUTSIDE_CHILDREN on this
* will not be allowed to set an overflow rect on this
* frame. This means that when the scroll code decides to hide a
* scrollframe by setting its height or width to zero, that will
* hide the children too.