mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-06 00:31:27 +00:00
Bug 475968. Eliminate NS_FRAME_OUTSIDE_CHILDREN flag, store small overflow areas cheaply within the frame. r+sr=roc
This commit is contained in:
parent
e56a5f719d
commit
68b13a1a71
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user