Change to how overflow is handled for absolutely positioned elements.

We no longer use nsIAraeFrame and now it's folded into the overflow
area in the reflow metrics
This commit is contained in:
troy%netscape.com 1999-12-06 15:49:53 +00:00
parent 1438c6a790
commit 85012ab550
42 changed files with 685 additions and 623 deletions

View File

@ -104,12 +104,13 @@ LAYOUT_ATOM(textFrame, "TextFrame")
LAYOUT_ATOM(viewportFrame, "ViewportFrame")
// Alphabetical list of frame property names
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty")
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation")
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty")
LAYOUT_ATOM(overflowProperty, "OverflowProperty")
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty")
LAYOUT_ATOM(viewProperty, "ViewProperty")
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
// Alphabetical list of event handler names
LAYOUT_ATOM(onabort, "onabort")

View File

@ -104,12 +104,13 @@ LAYOUT_ATOM(textFrame, "TextFrame")
LAYOUT_ATOM(viewportFrame, "ViewportFrame")
// Alphabetical list of frame property names
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty")
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation")
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty")
LAYOUT_ATOM(overflowProperty, "OverflowProperty")
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty")
LAYOUT_ATOM(viewProperty, "ViewProperty")
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
// Alphabetical list of event handler names
LAYOUT_ATOM(onabort, "onabort")

View File

@ -217,20 +217,23 @@ struct nsHTMLReflowMetrics {
// (generational) bottom margin value.
nscoord mCarriedOutBottomMargin;
// For frames that have children that stick outside their rect
// (NS_FRAME_OUTSIDE_CHILDREN) this rectangle will contain the
// absolute bounds of the frame. Since the frame doesn't know where
// it is going to be positioned in its parent, the assumption is
// that it is placed at 0,0 when computing this area.
nsRect mCombinedArea;
// For frames that have content that overflow their content area
// (NS_FRAME_OUTSIDE_CHILDREN) 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
// least as big as the desired size. If there is no content that overflows,
// then the overflow area is identical to the desired size and should be
// {0, 0, mWidth, mHeight}.
nsRect mOverflowArea;
nsHTMLReflowMetrics(nsSize* aMaxElementSize) {
maxElementSize = aMaxElementSize;
mCarriedOutBottomMargin = 0;
mCombinedArea.x = 0;
mCombinedArea.y = 0;
mCombinedArea.width = 0;
mCombinedArea.height = 0;
mOverflowArea.x = 0;
mOverflowArea.y = 0;
mOverflowArea.width = 0;
mOverflowArea.height = 0;
// XXX These are OUT parameters and so they shouldn't have to be
// initialized, but there are some bad frame classes that aren't

View File

@ -104,12 +104,13 @@ LAYOUT_ATOM(textFrame, "TextFrame")
LAYOUT_ATOM(viewportFrame, "ViewportFrame")
// Alphabetical list of frame property names
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty")
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation")
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty")
LAYOUT_ATOM(overflowProperty, "OverflowProperty")
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty")
LAYOUT_ATOM(viewProperty, "ViewProperty")
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
// Alphabetical list of event handler names
LAYOUT_ATOM(onabort, "onabort")

View File

@ -23,9 +23,6 @@
#include "nsCOMPtr.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIContent.h"
#include "nsIAreaFrame.h"
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
nsresult
NS_NewSelectsAreaFrame(nsIPresShell* aShell, nsIFrame** aNewFrame, PRUint32 aFlags)

View File

@ -19,10 +19,10 @@
*
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsContainerFrame.h"
#include "nsHTMLIIDs.h"
#include "nsIAreaFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsIViewManager.h"
@ -30,8 +30,8 @@
#include "nsIReflowCommand.h"
#include "nsIPresShell.h"
#include "nsHTMLParts.h"
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
#include "nsIPresContext.h"
#include "nsIFrameManager.h"
nsresult
nsAbsoluteContainingBlock::FirstChild(const nsIFrame* aDelegatingFrame,
@ -127,13 +127,62 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame,
return result ? NS_OK : NS_ERROR_FAILURE;
}
// Destructor function for the collapse offset frame property
static void
DestroyRectFunc(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIAtom* aPropertyName,
void* aPropertyValue)
{
delete (nsRect*)aPropertyValue;
}
static nsRect*
GetOverflowAreaProperty(nsIPresContext* aPresContext,
nsIFrame* aFrame,
PRBool aCreateIfNecessary = PR_FALSE)
{
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (presShell) {
nsCOMPtr<nsIFrameManager> frameManager;
presShell->GetFrameManager(getter_AddRefs(frameManager));
if (frameManager) {
void* value;
frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
0, &value);
if (value) {
return (nsRect*)value; // the property already exists
} else if (aCreateIfNecessary) {
// The property isn't set yet, so allocate a new rect, set the property,
// and return the newly allocated rect
nsRect* overflow = new nsRect(0, 0, 0, 0);
frameManager->SetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
overflow, DestroyRectFunc);
return overflow;
}
}
}
return nsnull;
}
nsresult
nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight)
nscoord aContainingBlockHeight,
nsRect& aChildBounds)
{
// Initialize OUT parameter
aChildBounds.SetRect(0, 0, 0, 0);
// Make a copy of the reflow state. If the reason is eReflowReason_Incremental,
// then change it to eReflowReason_Resize
nsHTMLReflowState reflowState(aReflowState);
@ -147,20 +196,73 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
nsReflowStatus kidStatus;
ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, reflowState, aContainingBlockWidth,
aContainingBlockHeight, kidFrame, PR_FALSE, kidStatus);
// Add in the child's bounds
nsRect kidBounds;
kidFrame->GetRect(kidBounds);
aChildBounds.UnionRect(aChildBounds, kidBounds);
// If the frame has visible overflow, then take it into account, too.
nsFrameState kidFrameState;
kidFrame->GetFrameState(&kidFrameState);
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, kidFrame);
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
// it into the parent's coordinate space
nsRect rect(*overflowArea);
rect.MoveBy(kidBounds.x, kidBounds.y);
aChildBounds.UnionRect(aChildBounds, rect);
}
}
}
return NS_OK;
}
void
nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext,
nsRect& aChildBounds)
{
for (nsIFrame* f = mAbsoluteFrames.FirstChild(); f; f->GetNextSibling(&f)) {
// Add in the child's bounds
nsRect bounds;
f->GetRect(bounds);
aChildBounds.UnionRect(aChildBounds, bounds);
// If the frame has visible overflow, then take it into account, too.
nsFrameState frameState;
f->GetFrameState(&frameState);
if (frameState & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, f);
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
// it into the parent's coordinate space
nsRect rect(*overflowArea);
rect.MoveBy(bounds.x, bounds.y);
aChildBounds.UnionRect(aChildBounds, rect);
}
}
}
}
nsresult
nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight,
PRBool& aWasHandled)
PRBool& aWasHandled,
nsRect& aChildBounds)
{
// Initialize the OUT paremeter
// Initialize the OUT paremeters
aWasHandled = PR_FALSE;
aChildBounds.SetRect(0, 0, 0, 0);
// See if the reflow command is targeted at us
nsIFrame* targetFrame;
@ -204,6 +306,9 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatin
// Indicate we handled the reflow command
aWasHandled = PR_TRUE;
// Calculate the total child bounds
CalculateChildBounds(aPresContext, aChildBounds);
}
} else {
@ -226,6 +331,9 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatin
// because it has a view if it changes size the view manager will
// damage the dirty area
aWasHandled = PR_TRUE;
// Calculate the total child bounds
CalculateChildBounds(aPresContext, aChildBounds);
}
}
@ -272,7 +380,6 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
kidReflowState.reason = eReflowReason_Initial;
}
// XXX TROY
// Send the WillReflow() notification and position the frame
aKidFrame->WillReflow(aPresContext);
aKidFrame->MoveTo(aPresContext,
@ -382,49 +489,22 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
&kidDesiredSize.mOverflowArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv;
}
nsresult
nsAbsoluteContainingBlock::GetPositionedInfo(const nsIFrame* aDelegatingFrame,
nscoord& aXMost,
nscoord& aYMost) const
{
aXMost = aYMost = 0;
for (nsIFrame* f = mAbsoluteFrames.FirstChild(); nsnull != f; f->GetNextSibling(&f)) {
// Get the frame's x-most and y-most. This is for its flowed content only
nsRect rect;
f->GetRect(rect);
// If the frame has visible overflow, then store it as a property on the
// frame. This allows us to be able to recover it without having to reflow
// the frame
nsFrameState kidFrameState;
aKidFrame->GetFrameState(&kidFrameState);
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property (creating a rect struct if necessary)
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, aKidFrame, PR_TRUE);
if (rect.XMost() > aXMost) {
aXMost = rect.XMost();
}
if (rect.YMost() > aYMost) {
aYMost = rect.YMost();
}
// If the child frame is also an area frame, then take into account its child
// absolutely positioned elements
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(f->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
nscoord xMost, yMost;
areaFrame->GetPositionedInfo(xMost, yMost);
// Convert to our coordinate space
xMost += rect.x;
yMost += rect.y;
if (xMost > aXMost) {
aXMost = xMost;
}
if (yMost > aYMost) {
aYMost = yMost;
}
if (overflowArea) {
*overflowArea = kidDesiredSize.mOverflowArea;
}
}
return NS_OK;
return rv;
}

View File

@ -71,31 +71,35 @@ public:
// Called by the delegating frame after it has done its reflow first. This
// function will reflow any absolutely positioned child frames that need to
// be reflowed, e.g., because the absolutely positioned child frame has
// 'auto' for an offset, or a percentage based width or height
// 'auto' for an offset, or a percentage based width or height.
// Returns (in the local coordinate space) the bounding rect of the absolutely
// positioned child elements taking into account their overflow area (if it
// is visible)
nsresult Reflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight);
nscoord aContainingBlockHeight,
nsRect& aChildBounds);
// Called only for a reflow reason of eReflowReason_Incremental. The
// aWasHandled return value indicates whether the reflow command was
// handled (i.e., the reflow command involved an absolutely positioned
// child element), or whether the caller should handle it
// child element), or whether the caller should handle it.
// Returns (in the local coordinate space) the bounding rect of the absolutely
// positioned child elements taking into account their overflow area (if it
// is visible). This is only set if the reflow command was handled
nsresult IncrementalReflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight,
PRBool& aWasHandled);
PRBool& aWasHandled,
nsRect& aChildBounds);
void DestroyFrames(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext);
nsresult GetPositionedInfo(const nsIFrame* aDelegatingFrame,
nscoord& aXMost,
nscoord& aYMost) const;
protected:
nsresult ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
@ -106,6 +110,8 @@ protected:
PRBool aInitialReflow,
nsReflowStatus& aStatus);
void CalculateChildBounds(nsIPresContext* aPresContext, nsRect& aChildBounds);
protected:
nsFrameList mAbsoluteFrames; // additional named child list
};

View File

@ -59,23 +59,6 @@ nsAreaFrame::nsAreaFrame()
{
}
/////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMETHODIMP
nsAreaFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIAreaFrameIID)) {
nsIAreaFrame* tmp = (nsIAreaFrame*)this;
*aInstancePtr = (void*)tmp;
return NS_OK;
}
return nsBlockFrame::QueryInterface(aIID, aInstancePtr);
}
/////////////////////////////////////////////////////////////////////////////
// nsIFrame
@ -186,32 +169,6 @@ nsAreaFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const
return nsBlockFrame::FirstChild(aListName, aFirstChild);
}
// Return the x-most and y-most for the child absolutely positioned
// elements
NS_IMETHODIMP
nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const
{
nsresult rv = mAbsoluteContainer.GetPositionedInfo(this, aXMost, aYMost);
// If we have child frames that stick outside of our box, and they should
// be visible, then include them too so the total size is correct
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow) {
if (mCombinedArea.XMost() > aXMost) {
aXMost = mCombinedArea.XMost();
}
if (mCombinedArea.YMost() > aYMost) {
aYMost = mCombinedArea.YMost();
}
}
}
return rv;
}
static void
CalculateContainingBlock(const nsHTMLReflowState& aReflowState,
nscoord aFrameWidth,
@ -244,7 +201,7 @@ CalculateContainingBlock(const nsHTMLReflowState& aReflowState,
NS_IMETHODIMP
nsAreaFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
@ -262,31 +219,55 @@ nsAreaFrame::Reflow(nsIPresContext* aPresContext,
nscoord containingBlockWidth;
nscoord containingBlockHeight;
PRBool handled;
nsRect childBounds;
CalculateContainingBlock(aReflowState, mRect.width, mRect.height,
containingBlockWidth, containingBlockHeight);
mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight,
handled);
handled, childBounds);
// If the incremental reflow command was handled by the absolute positioning
// code, then we're all done
if (handled) {
// Just return our current size as our desired size
aDesiredSize.width = mRect.width;
aDesiredSize.height = mRect.height;
aDesiredSize.ascent = mRect.height;
aDesiredSize.descent = 0;
// Just return our current size as our desired size.
// XXX We need to know the overflow area for the flowed content, and
// we don't have a way to get that currently so for the time being pretend
// a resize reflow occured
#if 0
aMetrics.width = mRect.width;
aMetrics.height = mRect.height;
aMetrics.ascent = mRect.height;
aMetrics.descent = 0;
// Whether or not we're complete hasn't changed
aStatus = (nsnull != mNextInFlow) ? NS_FRAME_NOT_COMPLETE : NS_FRAME_COMPLETE;
#else
nsHTMLReflowState reflowState(aReflowState);
reflowState.reason = eReflowReason_Resize;
reflowState.reflowCommand = nsnull;
rv = nsBlockFrame::Reflow(aPresContext, aMetrics, reflowState, aStatus);
#endif
// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
return rv;
}
}
// Let the block frame do its reflow first
rv = nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
rv = nsBlockFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus);
// Let the absolutely positioned container reflow any absolutely positioned
// child frames that need to be reflowed, e.g., elements with a percentage
@ -294,28 +275,37 @@ nsAreaFrame::Reflow(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(rv)) {
nscoord containingBlockWidth;
nscoord containingBlockHeight;
nsRect childBounds;
CalculateContainingBlock(aReflowState, aDesiredSize.width, aDesiredSize.height,
CalculateContainingBlock(aReflowState, aMetrics.width, aMetrics.height,
containingBlockWidth, containingBlockHeight);
rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight);
containingBlockWidth, containingBlockHeight,
childBounds);
// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
}
#ifdef NOISY_MAX_ELEMENT_SIZE
ListTag(stdout);
printf(": maxElementSize=%d,%d desiredSize=%d,%d\n",
aDesiredSize.maxElementSize ? aDesiredSize.maxElementSize->width : 0,
aDesiredSize.maxElementSize ? aDesiredSize.maxElementSize->height : 0,
aDesiredSize.width, aDesiredSize.height);
aMetrics.maxElementSize ? aMetrics.maxElementSize->width : 0,
aMetrics.maxElementSize ? aMetrics.maxElementSize->height : 0,
aMetrics.width, aMetrics.height);
#endif
// If we have children that stick outside our box, then remember the
// combined area, because we'll need it later when sizing our view
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
mCombinedArea = aDesiredSize.mCombinedArea;
}
return rv;
}

View File

@ -24,7 +24,6 @@
#include "nsBlockFrame.h"
#include "nsVoidArray.h"
#include "nsIAreaFrame.h"
#include "nsAbsoluteContainingBlock.h"
class nsSpaceManager;
@ -44,14 +43,11 @@ struct nsStylePosition;
*
* @see nsLayoutAtoms::absoluteList
*/
class nsAreaFrame : public nsBlockFrame, public nsIAreaFrame
class nsAreaFrame : public nsBlockFrame
{
public:
friend nsresult NS_NewAreaFrame(nsIPresShell* aPresShell, nsIFrame** aResult, PRUint32 aFlags);
// nsISupports
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
// nsIFrame
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
@ -94,15 +90,11 @@ public:
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
// nsIAreaFrame
NS_IMETHOD GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const;
protected:
nsAreaFrame();
private:
nsAbsoluteContainingBlock mAbsoluteContainer;
nsRect mCombinedArea;
};
#endif /* nsAreaFrame_h___ */

View File

@ -1511,7 +1511,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// children, make sure its big enough to include those that stick
// outside the box.
if (NS_FRAME_OUTSIDE_CHILDREN & mState) {
nscoord xMost = aMetrics.mCombinedArea.XMost();
nscoord xMost = aMetrics.mOverflowArea.XMost();
if (xMost > aMetrics.width) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1519,7 +1519,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
#endif
aMetrics.width = xMost;
}
nscoord yMost = aMetrics.mCombinedArea.YMost();
nscoord yMost = aMetrics.mOverflowArea.YMost();
if (yMost > aMetrics.height) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1622,10 +1622,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
aMetrics.mCarriedOutBottomMargin);
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
printf(" combinedArea={%d,%d,%d,%d}",
aMetrics.mCombinedArea.x,
aMetrics.mCombinedArea.y,
aMetrics.mCombinedArea.width,
aMetrics.mCombinedArea.height);
aMetrics.mOverflowArea.x,
aMetrics.mOverflowArea.y,
aMetrics.mOverflowArea.width,
aMetrics.mOverflowArea.height);
}
if (aMetrics.maxElementSize) {
printf(" maxElementSize=%d,%d",
@ -1969,14 +1969,14 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// If the combined area of our children exceeds our bounding box
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
aMetrics.mCombinedArea.x = xa;
aMetrics.mCombinedArea.y = ya;
aMetrics.mCombinedArea.width = xb - xa;
aMetrics.mCombinedArea.height = yb - ya;
if ((aMetrics.mCombinedArea.x < 0) ||
(aMetrics.mCombinedArea.y < 0) ||
(aMetrics.mCombinedArea.XMost() > aMetrics.width) ||
(aMetrics.mCombinedArea.YMost() > aMetrics.height)) {
aMetrics.mOverflowArea.x = xa;
aMetrics.mOverflowArea.y = ya;
aMetrics.mOverflowArea.width = xb - xa;
aMetrics.mOverflowArea.height = yb - ya;
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
}
else {
@ -2000,6 +2000,7 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState)
// XXX Huh, that's not true anymore. We do cache the width component of
// the max-element-size...
if (aState.mComputeMaxElementSize) {
printf("BLOCK: marking all child frames dirty...\n");
return PrepareResizeReflow(aState);
}
@ -4875,7 +4876,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
aMarginResult.left = m.left;
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
aCombinedRect = metrics.mCombinedArea;
aCombinedRect = 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);
@ -4883,7 +4884,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
floater->GetView(aState.mPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, floater, view,
&metrics.mCombinedArea,
&metrics.mOverflowArea,
NS_FRAME_NO_MOVE_VIEW);
}
floater->DidReflow(aState.mPresContext, NS_FRAME_REFLOW_FINISHED);

View File

@ -317,11 +317,11 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
aFrame->GetFrameState(&state);
if (0 == (NS_FRAME_OUTSIDE_CHILDREN & state)) {
// Provide combined area for child that doesn't have any
mMetrics.mCombinedArea.x = 0;
mMetrics.mCombinedArea.y = 0;
mMetrics.mCombinedArea.width = mMetrics.width;
mMetrics.mCombinedArea.height = mMetrics.height;
// Provide overflow area for child that doesn't have any
mMetrics.mOverflowArea.x = 0;
mMetrics.mOverflowArea.y = 0;
mMetrics.mOverflowArea.width = mMetrics.width;
mMetrics.mOverflowArea.height = mMetrics.height;
}
// Now that frame has been reflowed at least one time make sure that
@ -376,8 +376,8 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
nscoord x = mX;
nscoord y = mY;
// When deciding whether it's an empty paragraph we also need to take into
// account the combined area
if ((0 == mMetrics.height) && (0 == mMetrics.mCombinedArea.height)) {
// account the overflow area
if ((0 == mMetrics.height) && (0 == mMetrics.mOverflowArea.height)) {
if (IsHTMLParagraph(mFrame)) {
// Special "feature" for HTML compatability - empty paragraphs
// collapse into nothingness, including their margins. Signal
@ -432,7 +432,7 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
// Retain combined area information in case we contain a floater
// and nothing else.
aCombinedRect = mMetrics.mCombinedArea;
aCombinedRect = mMetrics.mOverflowArea;
aCombinedRect.x += x;
aCombinedRect.y += y;
}
@ -549,10 +549,10 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
// Compute combined-rect in callers coordinate system. The value
// returned in the reflow metrics is relative to the child
// frame.
aCombinedRect.x = mMetrics.mCombinedArea.x + x;
aCombinedRect.y = mMetrics.mCombinedArea.y + y;
aCombinedRect.width = mMetrics.mCombinedArea.width;
aCombinedRect.height = mMetrics.mCombinedArea.height;
aCombinedRect.x = mMetrics.mOverflowArea.x + x;
aCombinedRect.y = mMetrics.mOverflowArea.y + y;
aCombinedRect.width = mMetrics.mOverflowArea.width;
aCombinedRect.height = mMetrics.mOverflowArea.height;
// Now place the frame and complete the reflow process
nsContainerFrame::FinishReflowChild(mFrame, mPresContext, mMetrics, x, y, 0);

View File

@ -1511,7 +1511,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// children, make sure its big enough to include those that stick
// outside the box.
if (NS_FRAME_OUTSIDE_CHILDREN & mState) {
nscoord xMost = aMetrics.mCombinedArea.XMost();
nscoord xMost = aMetrics.mOverflowArea.XMost();
if (xMost > aMetrics.width) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1519,7 +1519,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
#endif
aMetrics.width = xMost;
}
nscoord yMost = aMetrics.mCombinedArea.YMost();
nscoord yMost = aMetrics.mOverflowArea.YMost();
if (yMost > aMetrics.height) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1622,10 +1622,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
aMetrics.mCarriedOutBottomMargin);
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
printf(" combinedArea={%d,%d,%d,%d}",
aMetrics.mCombinedArea.x,
aMetrics.mCombinedArea.y,
aMetrics.mCombinedArea.width,
aMetrics.mCombinedArea.height);
aMetrics.mOverflowArea.x,
aMetrics.mOverflowArea.y,
aMetrics.mOverflowArea.width,
aMetrics.mOverflowArea.height);
}
if (aMetrics.maxElementSize) {
printf(" maxElementSize=%d,%d",
@ -1969,14 +1969,14 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// If the combined area of our children exceeds our bounding box
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
aMetrics.mCombinedArea.x = xa;
aMetrics.mCombinedArea.y = ya;
aMetrics.mCombinedArea.width = xb - xa;
aMetrics.mCombinedArea.height = yb - ya;
if ((aMetrics.mCombinedArea.x < 0) ||
(aMetrics.mCombinedArea.y < 0) ||
(aMetrics.mCombinedArea.XMost() > aMetrics.width) ||
(aMetrics.mCombinedArea.YMost() > aMetrics.height)) {
aMetrics.mOverflowArea.x = xa;
aMetrics.mOverflowArea.y = ya;
aMetrics.mOverflowArea.width = xb - xa;
aMetrics.mOverflowArea.height = yb - ya;
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
}
else {
@ -2000,6 +2000,7 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState)
// XXX Huh, that's not true anymore. We do cache the width component of
// the max-element-size...
if (aState.mComputeMaxElementSize) {
printf("BLOCK: marking all child frames dirty...\n");
return PrepareResizeReflow(aState);
}
@ -4875,7 +4876,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
aMarginResult.left = m.left;
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
aCombinedRect = metrics.mCombinedArea;
aCombinedRect = 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);
@ -4883,7 +4884,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
floater->GetView(aState.mPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, floater, view,
&metrics.mCombinedArea,
&metrics.mOverflowArea,
NS_FRAME_NO_MOVE_VIEW);
}
floater->DidReflow(aState.mPresContext, NS_FRAME_REFLOW_FINISHED);

View File

@ -1511,7 +1511,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// children, make sure its big enough to include those that stick
// outside the box.
if (NS_FRAME_OUTSIDE_CHILDREN & mState) {
nscoord xMost = aMetrics.mCombinedArea.XMost();
nscoord xMost = aMetrics.mOverflowArea.XMost();
if (xMost > aMetrics.width) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1519,7 +1519,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
#endif
aMetrics.width = xMost;
}
nscoord yMost = aMetrics.mCombinedArea.YMost();
nscoord yMost = aMetrics.mOverflowArea.YMost();
if (yMost > aMetrics.height) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1622,10 +1622,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
aMetrics.mCarriedOutBottomMargin);
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
printf(" combinedArea={%d,%d,%d,%d}",
aMetrics.mCombinedArea.x,
aMetrics.mCombinedArea.y,
aMetrics.mCombinedArea.width,
aMetrics.mCombinedArea.height);
aMetrics.mOverflowArea.x,
aMetrics.mOverflowArea.y,
aMetrics.mOverflowArea.width,
aMetrics.mOverflowArea.height);
}
if (aMetrics.maxElementSize) {
printf(" maxElementSize=%d,%d",
@ -1969,14 +1969,14 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// If the combined area of our children exceeds our bounding box
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
aMetrics.mCombinedArea.x = xa;
aMetrics.mCombinedArea.y = ya;
aMetrics.mCombinedArea.width = xb - xa;
aMetrics.mCombinedArea.height = yb - ya;
if ((aMetrics.mCombinedArea.x < 0) ||
(aMetrics.mCombinedArea.y < 0) ||
(aMetrics.mCombinedArea.XMost() > aMetrics.width) ||
(aMetrics.mCombinedArea.YMost() > aMetrics.height)) {
aMetrics.mOverflowArea.x = xa;
aMetrics.mOverflowArea.y = ya;
aMetrics.mOverflowArea.width = xb - xa;
aMetrics.mOverflowArea.height = yb - ya;
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
}
else {
@ -2000,6 +2000,7 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState)
// XXX Huh, that's not true anymore. We do cache the width component of
// the max-element-size...
if (aState.mComputeMaxElementSize) {
printf("BLOCK: marking all child frames dirty...\n");
return PrepareResizeReflow(aState);
}
@ -4875,7 +4876,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
aMarginResult.left = m.left;
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
aCombinedRect = metrics.mCombinedArea;
aCombinedRect = 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);
@ -4883,7 +4884,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
floater->GetView(aState.mPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, floater, view,
&metrics.mCombinedArea,
&metrics.mOverflowArea,
NS_FRAME_NO_MOVE_VIEW);
}
floater->DidReflow(aState.mPresContext, NS_FRAME_REFLOW_FINISHED);

View File

@ -718,7 +718,7 @@ nsContainerFrame::FinishReflowChild(nsIFrame* aKidFrame,
// Make sure the frame's view is properly sized and positioned and has
// things like opacity correct
SyncFrameViewAfterReflow(aPresContext, aKidFrame, view,
&aDesiredSize.mCombinedArea,
&aDesiredSize.mOverflowArea,
aFlags);
} else if (0 == (aFlags & NS_FRAME_NO_MOVE_CHILD_VIEWS)) {

View File

@ -1567,10 +1567,10 @@ nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
aMetrics.ascent = 0;
aMetrics.descent = 0;
aMetrics.mCarriedOutBottomMargin = 0;
aMetrics.mCombinedArea.x = 0;
aMetrics.mCombinedArea.y = 0;
aMetrics.mCombinedArea.width = 0;
aMetrics.mCombinedArea.height = 0;
aMetrics.mOverflowArea.x = 0;
aMetrics.mOverflowArea.y = 0;
aMetrics.mOverflowArea.width = 0;
aMetrics.mOverflowArea.height = 0;
if (aMetrics.maxElementSize) {
aMetrics.maxElementSize->width = 0;
aMetrics.maxElementSize->height = 0;

View File

@ -34,7 +34,6 @@
#include "nsCSSRendering.h"
#include "nsIScrollableView.h"
#include "nsWidgetsCID.h"
#include "nsIAreaFrame.h"
#include "nsGfxScrollFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIXMLContent.h"
@ -54,7 +53,6 @@ static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID);
@ -893,23 +891,8 @@ nsGfxScrollFrameInner::CalculateChildTotalSize(nsIFrame* aKidFrame,
nsFrameState kidState;
aKidFrame->GetFrameState(&kidState);
if (NS_FRAME_OUTSIDE_CHILDREN & kidState) {
aKidReflowMetrics.width = aKidReflowMetrics.mCombinedArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mCombinedArea.height;
}
// If it's an area frame, then get the total size which includes the
// space taken up by absolutely positioned child elements
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(aKidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
nscoord xMost, yMost;
areaFrame->GetPositionedInfo(xMost, yMost);
if (xMost > aKidReflowMetrics.width) {
aKidReflowMetrics.width = xMost;
}
if (yMost > aKidReflowMetrics.height) {
aKidReflowMetrics.height = yMost;
}
aKidReflowMetrics.width = aKidReflowMetrics.mOverflowArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mOverflowArea.height;
}
return NS_OK;

View File

@ -41,12 +41,10 @@
#include "nsIEventStateManager.h"
#include "nsIDeviceContext.h"
#include "nsIScrollableView.h"
#include "nsIAreaFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIPresShell.h"
// Interface IDs
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
@ -345,36 +343,16 @@ RootFrame::Reflow(nsIPresContext* aPresContext,
nscoord paddingEdgeX = kidDesiredSize.width - border.right;
nscoord paddingEdgeY = kidDesiredSize.height - border.bottom;
if (kidDesiredSize.mCombinedArea.XMost() > paddingEdgeX) {
kidDesiredSize.width = kidDesiredSize.mCombinedArea.XMost() +
if (kidDesiredSize.mOverflowArea.XMost() > paddingEdgeX) {
kidDesiredSize.width = kidDesiredSize.mOverflowArea.XMost() +
border.right;
}
if (kidDesiredSize.mCombinedArea.YMost() > paddingEdgeY) {
kidDesiredSize.height = kidDesiredSize.mCombinedArea.YMost() +
if (kidDesiredSize.mOverflowArea.YMost() > paddingEdgeY) {
kidDesiredSize.height = kidDesiredSize.mOverflowArea.YMost() +
border.bottom;
}
}
// XXX It would be nice if this were also part of the reflow metrics...
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(kidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
// Get the x-most and y-most of the absolutely positioned children
nscoord positionedXMost, positionedYMost;
areaFrame->GetPositionedInfo(positionedXMost, positionedYMost);
// The background covers the content area and padding area, so check
// for children sticking outside the padding edge
nscoord paddingEdgeX = kidDesiredSize.width - border.right;
nscoord paddingEdgeY = kidDesiredSize.height - border.bottom;
if (positionedXMost > paddingEdgeX) {
kidDesiredSize.width = positionedXMost + border.right;
}
if (positionedYMost > paddingEdgeY) {
kidDesiredSize.height = positionedYMost + border.bottom;
}
}
// If our height is fixed, then make sure the child frame plus its top and
// bottom margin is at least that high as well...
if (NS_AUTOHEIGHT != aReflowState.mComputedHeight) {

View File

@ -217,20 +217,23 @@ struct nsHTMLReflowMetrics {
// (generational) bottom margin value.
nscoord mCarriedOutBottomMargin;
// For frames that have children that stick outside their rect
// (NS_FRAME_OUTSIDE_CHILDREN) this rectangle will contain the
// absolute bounds of the frame. Since the frame doesn't know where
// it is going to be positioned in its parent, the assumption is
// that it is placed at 0,0 when computing this area.
nsRect mCombinedArea;
// For frames that have content that overflow their content area
// (NS_FRAME_OUTSIDE_CHILDREN) 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
// least as big as the desired size. If there is no content that overflows,
// then the overflow area is identical to the desired size and should be
// {0, 0, mWidth, mHeight}.
nsRect mOverflowArea;
nsHTMLReflowMetrics(nsSize* aMaxElementSize) {
maxElementSize = aMaxElementSize;
mCarriedOutBottomMargin = 0;
mCombinedArea.x = 0;
mCombinedArea.y = 0;
mCombinedArea.width = 0;
mCombinedArea.height = 0;
mOverflowArea.x = 0;
mOverflowArea.y = 0;
mOverflowArea.width = 0;
mOverflowArea.height = 0;
// XXX These are OUT parameters and so they shouldn't have to be
// initialized, but there are some bad frame classes that aren't

View File

@ -461,12 +461,12 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext,
}
}
// For now our combined area is zero. The real value will be
// For now our overflow area is zero. The real value will be
// computed during vertical alignment of the line we are on.
aMetrics.mCombinedArea.x = 0;
aMetrics.mCombinedArea.y = 0;
aMetrics.mCombinedArea.width = aMetrics.width;
aMetrics.mCombinedArea.height = aMetrics.height;
aMetrics.mOverflowArea.x = 0;
aMetrics.mOverflowArea.y = 0;
aMetrics.mOverflowArea.width = aMetrics.width;
aMetrics.mOverflowArea.height = aMetrics.height;
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -973,12 +973,13 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
// Give the absolute positioning code a chance to handle it
PRBool handled;
nsRect childBounds;
nscoord containingBlockWidth = -1;
nscoord containingBlockHeight = -1;
mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight,
handled);
handled, childBounds);
// If the incremental reflow command was handled by the absolute positioning
// code, then we're all done
@ -989,7 +990,25 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowState reflowState(aReflowState);
reflowState.reason = eReflowReason_Resize;
reflowState.reflowCommand = nsnull;
return nsInlineFrame::Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
// XXX Although this seems like the correct thing to do the line layout
// code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored
#if 0
// Factor the absolutely positioned child bounds into the overflow area
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aDesiredSize.mOverflowArea.x < 0) ||
(aDesiredSize.mOverflowArea.y < 0) ||
(aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) ||
(aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
#endif
return rv;
}
}
@ -1001,9 +1020,28 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(rv)) {
nscoord containingBlockWidth = -1;
nscoord containingBlockHeight = -1;
nsRect childBounds;
rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight);
containingBlockWidth, containingBlockHeight,
childBounds);
// XXX Although this seems like the correct thing to do the line layout
// code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored
#if 0
// Factor the absolutely positioned child bounds into the overflow area
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aDesiredSize.mOverflowArea.x < 0) ||
(aDesiredSize.mOverflowArea.y < 0) ||
(aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) ||
(aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
#endif
}
return rv;

View File

@ -1062,7 +1062,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
aFrame->GetFrameState(&state);
if (NS_FRAME_OUTSIDE_CHILDREN & state) {
pfd->mCombinedArea = metrics.mCombinedArea;
pfd->mCombinedArea = metrics.mOverflowArea;
}
else {
pfd->mCombinedArea.x = 0;
@ -1480,7 +1480,7 @@ nsLineLayout::AddBulletFrame(nsIFrame* aFrame,
// Note: y value will be updated during vertical alignment
aFrame->GetRect(pfd->mBounds);
pfd->mCombinedArea = aMetrics.mCombinedArea;
pfd->mCombinedArea = aMetrics.mOverflowArea;
if (mComputeMaxElementSize) {
pfd->mMaxElementSize.SizeTo(aMetrics.width, aMetrics.height);
}

View File

@ -375,7 +375,7 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext* aPresContext,
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
&kidDesiredSize.mOverflowArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv;
}

View File

@ -19,10 +19,10 @@
*
* Contributor(s):
*/
#include "nsCOMPtr.h"
#include "nsAbsoluteContainingBlock.h"
#include "nsContainerFrame.h"
#include "nsHTMLIIDs.h"
#include "nsIAreaFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsIViewManager.h"
@ -30,8 +30,8 @@
#include "nsIReflowCommand.h"
#include "nsIPresShell.h"
#include "nsHTMLParts.h"
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
#include "nsIPresContext.h"
#include "nsIFrameManager.h"
nsresult
nsAbsoluteContainingBlock::FirstChild(const nsIFrame* aDelegatingFrame,
@ -127,13 +127,62 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame,
return result ? NS_OK : NS_ERROR_FAILURE;
}
// Destructor function for the collapse offset frame property
static void
DestroyRectFunc(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIAtom* aPropertyName,
void* aPropertyValue)
{
delete (nsRect*)aPropertyValue;
}
static nsRect*
GetOverflowAreaProperty(nsIPresContext* aPresContext,
nsIFrame* aFrame,
PRBool aCreateIfNecessary = PR_FALSE)
{
nsCOMPtr<nsIPresShell> presShell;
aPresContext->GetShell(getter_AddRefs(presShell));
if (presShell) {
nsCOMPtr<nsIFrameManager> frameManager;
presShell->GetFrameManager(getter_AddRefs(frameManager));
if (frameManager) {
void* value;
frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
0, &value);
if (value) {
return (nsRect*)value; // the property already exists
} else if (aCreateIfNecessary) {
// The property isn't set yet, so allocate a new rect, set the property,
// and return the newly allocated rect
nsRect* overflow = new nsRect(0, 0, 0, 0);
frameManager->SetFrameProperty(aFrame, nsLayoutAtoms::overflowAreaProperty,
overflow, DestroyRectFunc);
return overflow;
}
}
}
return nsnull;
}
nsresult
nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight)
nscoord aContainingBlockHeight,
nsRect& aChildBounds)
{
// Initialize OUT parameter
aChildBounds.SetRect(0, 0, 0, 0);
// Make a copy of the reflow state. If the reason is eReflowReason_Incremental,
// then change it to eReflowReason_Resize
nsHTMLReflowState reflowState(aReflowState);
@ -147,20 +196,73 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
nsReflowStatus kidStatus;
ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, reflowState, aContainingBlockWidth,
aContainingBlockHeight, kidFrame, PR_FALSE, kidStatus);
// Add in the child's bounds
nsRect kidBounds;
kidFrame->GetRect(kidBounds);
aChildBounds.UnionRect(aChildBounds, kidBounds);
// If the frame has visible overflow, then take it into account, too.
nsFrameState kidFrameState;
kidFrame->GetFrameState(&kidFrameState);
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, kidFrame);
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
// it into the parent's coordinate space
nsRect rect(*overflowArea);
rect.MoveBy(kidBounds.x, kidBounds.y);
aChildBounds.UnionRect(aChildBounds, rect);
}
}
}
return NS_OK;
}
void
nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext,
nsRect& aChildBounds)
{
for (nsIFrame* f = mAbsoluteFrames.FirstChild(); f; f->GetNextSibling(&f)) {
// Add in the child's bounds
nsRect bounds;
f->GetRect(bounds);
aChildBounds.UnionRect(aChildBounds, bounds);
// If the frame has visible overflow, then take it into account, too.
nsFrameState frameState;
f->GetFrameState(&frameState);
if (frameState & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, f);
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
// it into the parent's coordinate space
nsRect rect(*overflowArea);
rect.MoveBy(bounds.x, bounds.y);
aChildBounds.UnionRect(aChildBounds, rect);
}
}
}
}
nsresult
nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight,
PRBool& aWasHandled)
PRBool& aWasHandled,
nsRect& aChildBounds)
{
// Initialize the OUT paremeter
// Initialize the OUT paremeters
aWasHandled = PR_FALSE;
aChildBounds.SetRect(0, 0, 0, 0);
// See if the reflow command is targeted at us
nsIFrame* targetFrame;
@ -204,6 +306,9 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatin
// Indicate we handled the reflow command
aWasHandled = PR_TRUE;
// Calculate the total child bounds
CalculateChildBounds(aPresContext, aChildBounds);
}
} else {
@ -226,6 +331,9 @@ nsAbsoluteContainingBlock::IncrementalReflow(nsIFrame* aDelegatin
// because it has a view if it changes size the view manager will
// damage the dirty area
aWasHandled = PR_TRUE;
// Calculate the total child bounds
CalculateChildBounds(aPresContext, aChildBounds);
}
}
@ -272,7 +380,6 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
kidReflowState.reason = eReflowReason_Initial;
}
// XXX TROY
// Send the WillReflow() notification and position the frame
aKidFrame->WillReflow(aPresContext);
aKidFrame->MoveTo(aPresContext,
@ -382,49 +489,22 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
&kidDesiredSize.mOverflowArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv;
}
nsresult
nsAbsoluteContainingBlock::GetPositionedInfo(const nsIFrame* aDelegatingFrame,
nscoord& aXMost,
nscoord& aYMost) const
{
aXMost = aYMost = 0;
for (nsIFrame* f = mAbsoluteFrames.FirstChild(); nsnull != f; f->GetNextSibling(&f)) {
// Get the frame's x-most and y-most. This is for its flowed content only
nsRect rect;
f->GetRect(rect);
// If the frame has visible overflow, then store it as a property on the
// frame. This allows us to be able to recover it without having to reflow
// the frame
nsFrameState kidFrameState;
aKidFrame->GetFrameState(&kidFrameState);
if (kidFrameState & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property (creating a rect struct if necessary)
nsRect* overflowArea = ::GetOverflowAreaProperty(aPresContext, aKidFrame, PR_TRUE);
if (rect.XMost() > aXMost) {
aXMost = rect.XMost();
}
if (rect.YMost() > aYMost) {
aYMost = rect.YMost();
}
// If the child frame is also an area frame, then take into account its child
// absolutely positioned elements
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(f->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
nscoord xMost, yMost;
areaFrame->GetPositionedInfo(xMost, yMost);
// Convert to our coordinate space
xMost += rect.x;
yMost += rect.y;
if (xMost > aXMost) {
aXMost = xMost;
}
if (yMost > aYMost) {
aYMost = yMost;
}
if (overflowArea) {
*overflowArea = kidDesiredSize.mOverflowArea;
}
}
return NS_OK;
return rv;
}

View File

@ -71,31 +71,35 @@ public:
// Called by the delegating frame after it has done its reflow first. This
// function will reflow any absolutely positioned child frames that need to
// be reflowed, e.g., because the absolutely positioned child frame has
// 'auto' for an offset, or a percentage based width or height
// 'auto' for an offset, or a percentage based width or height.
// Returns (in the local coordinate space) the bounding rect of the absolutely
// positioned child elements taking into account their overflow area (if it
// is visible)
nsresult Reflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight);
nscoord aContainingBlockHeight,
nsRect& aChildBounds);
// Called only for a reflow reason of eReflowReason_Incremental. The
// aWasHandled return value indicates whether the reflow command was
// handled (i.e., the reflow command involved an absolutely positioned
// child element), or whether the caller should handle it
// child element), or whether the caller should handle it.
// Returns (in the local coordinate space) the bounding rect of the absolutely
// positioned child elements taking into account their overflow area (if it
// is visible). This is only set if the reflow command was handled
nsresult IncrementalReflow(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState,
nscoord aContainingBlockWidth,
nscoord aContainingBlockHeight,
PRBool& aWasHandled);
PRBool& aWasHandled,
nsRect& aChildBounds);
void DestroyFrames(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext);
nsresult GetPositionedInfo(const nsIFrame* aDelegatingFrame,
nscoord& aXMost,
nscoord& aYMost) const;
protected:
nsresult ReflowAbsoluteFrame(nsIFrame* aDelegatingFrame,
nsIPresContext* aPresContext,
@ -106,6 +110,8 @@ protected:
PRBool aInitialReflow,
nsReflowStatus& aStatus);
void CalculateChildBounds(nsIPresContext* aPresContext, nsRect& aChildBounds);
protected:
nsFrameList mAbsoluteFrames; // additional named child list
};

View File

@ -59,23 +59,6 @@ nsAreaFrame::nsAreaFrame()
{
}
/////////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMETHODIMP
nsAreaFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIAreaFrameIID)) {
nsIAreaFrame* tmp = (nsIAreaFrame*)this;
*aInstancePtr = (void*)tmp;
return NS_OK;
}
return nsBlockFrame::QueryInterface(aIID, aInstancePtr);
}
/////////////////////////////////////////////////////////////////////////////
// nsIFrame
@ -186,32 +169,6 @@ nsAreaFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const
return nsBlockFrame::FirstChild(aListName, aFirstChild);
}
// Return the x-most and y-most for the child absolutely positioned
// elements
NS_IMETHODIMP
nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const
{
nsresult rv = mAbsoluteContainer.GetPositionedInfo(this, aXMost, aYMost);
// If we have child frames that stick outside of our box, and they should
// be visible, then include them too so the total size is correct
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
if (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow) {
if (mCombinedArea.XMost() > aXMost) {
aXMost = mCombinedArea.XMost();
}
if (mCombinedArea.YMost() > aYMost) {
aYMost = mCombinedArea.YMost();
}
}
}
return rv;
}
static void
CalculateContainingBlock(const nsHTMLReflowState& aReflowState,
nscoord aFrameWidth,
@ -244,7 +201,7 @@ CalculateContainingBlock(const nsHTMLReflowState& aReflowState,
NS_IMETHODIMP
nsAreaFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
nsHTMLReflowMetrics& aMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
@ -262,31 +219,55 @@ nsAreaFrame::Reflow(nsIPresContext* aPresContext,
nscoord containingBlockWidth;
nscoord containingBlockHeight;
PRBool handled;
nsRect childBounds;
CalculateContainingBlock(aReflowState, mRect.width, mRect.height,
containingBlockWidth, containingBlockHeight);
mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight,
handled);
handled, childBounds);
// If the incremental reflow command was handled by the absolute positioning
// code, then we're all done
if (handled) {
// Just return our current size as our desired size
aDesiredSize.width = mRect.width;
aDesiredSize.height = mRect.height;
aDesiredSize.ascent = mRect.height;
aDesiredSize.descent = 0;
// Just return our current size as our desired size.
// XXX We need to know the overflow area for the flowed content, and
// we don't have a way to get that currently so for the time being pretend
// a resize reflow occured
#if 0
aMetrics.width = mRect.width;
aMetrics.height = mRect.height;
aMetrics.ascent = mRect.height;
aMetrics.descent = 0;
// Whether or not we're complete hasn't changed
aStatus = (nsnull != mNextInFlow) ? NS_FRAME_NOT_COMPLETE : NS_FRAME_COMPLETE;
#else
nsHTMLReflowState reflowState(aReflowState);
reflowState.reason = eReflowReason_Resize;
reflowState.reflowCommand = nsnull;
rv = nsBlockFrame::Reflow(aPresContext, aMetrics, reflowState, aStatus);
#endif
// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
return rv;
}
}
// Let the block frame do its reflow first
rv = nsBlockFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
rv = nsBlockFrame::Reflow(aPresContext, aMetrics, aReflowState, aStatus);
// Let the absolutely positioned container reflow any absolutely positioned
// child frames that need to be reflowed, e.g., elements with a percentage
@ -294,28 +275,37 @@ nsAreaFrame::Reflow(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(rv)) {
nscoord containingBlockWidth;
nscoord containingBlockHeight;
nsRect childBounds;
CalculateContainingBlock(aReflowState, aDesiredSize.width, aDesiredSize.height,
CalculateContainingBlock(aReflowState, aMetrics.width, aMetrics.height,
containingBlockWidth, containingBlockHeight);
rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight);
containingBlockWidth, containingBlockHeight,
childBounds);
// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
}
#ifdef NOISY_MAX_ELEMENT_SIZE
ListTag(stdout);
printf(": maxElementSize=%d,%d desiredSize=%d,%d\n",
aDesiredSize.maxElementSize ? aDesiredSize.maxElementSize->width : 0,
aDesiredSize.maxElementSize ? aDesiredSize.maxElementSize->height : 0,
aDesiredSize.width, aDesiredSize.height);
aMetrics.maxElementSize ? aMetrics.maxElementSize->width : 0,
aMetrics.maxElementSize ? aMetrics.maxElementSize->height : 0,
aMetrics.width, aMetrics.height);
#endif
// If we have children that stick outside our box, then remember the
// combined area, because we'll need it later when sizing our view
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
mCombinedArea = aDesiredSize.mCombinedArea;
}
return rv;
}

View File

@ -24,7 +24,6 @@
#include "nsBlockFrame.h"
#include "nsVoidArray.h"
#include "nsIAreaFrame.h"
#include "nsAbsoluteContainingBlock.h"
class nsSpaceManager;
@ -44,14 +43,11 @@ struct nsStylePosition;
*
* @see nsLayoutAtoms::absoluteList
*/
class nsAreaFrame : public nsBlockFrame, public nsIAreaFrame
class nsAreaFrame : public nsBlockFrame
{
public:
friend nsresult NS_NewAreaFrame(nsIPresShell* aPresShell, nsIFrame** aResult, PRUint32 aFlags);
// nsISupports
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
// nsIFrame
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
@ -94,15 +90,11 @@ public:
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
// nsIAreaFrame
NS_IMETHOD GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const;
protected:
nsAreaFrame();
private:
nsAbsoluteContainingBlock mAbsoluteContainer;
nsRect mCombinedArea;
};
#endif /* nsAreaFrame_h___ */

View File

@ -1511,7 +1511,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// children, make sure its big enough to include those that stick
// outside the box.
if (NS_FRAME_OUTSIDE_CHILDREN & mState) {
nscoord xMost = aMetrics.mCombinedArea.XMost();
nscoord xMost = aMetrics.mOverflowArea.XMost();
if (xMost > aMetrics.width) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1519,7 +1519,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
#endif
aMetrics.width = xMost;
}
nscoord yMost = aMetrics.mCombinedArea.YMost();
nscoord yMost = aMetrics.mOverflowArea.YMost();
if (yMost > aMetrics.height) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1622,10 +1622,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
aMetrics.mCarriedOutBottomMargin);
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
printf(" combinedArea={%d,%d,%d,%d}",
aMetrics.mCombinedArea.x,
aMetrics.mCombinedArea.y,
aMetrics.mCombinedArea.width,
aMetrics.mCombinedArea.height);
aMetrics.mOverflowArea.x,
aMetrics.mOverflowArea.y,
aMetrics.mOverflowArea.width,
aMetrics.mOverflowArea.height);
}
if (aMetrics.maxElementSize) {
printf(" maxElementSize=%d,%d",
@ -1969,14 +1969,14 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// If the combined area of our children exceeds our bounding box
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
aMetrics.mCombinedArea.x = xa;
aMetrics.mCombinedArea.y = ya;
aMetrics.mCombinedArea.width = xb - xa;
aMetrics.mCombinedArea.height = yb - ya;
if ((aMetrics.mCombinedArea.x < 0) ||
(aMetrics.mCombinedArea.y < 0) ||
(aMetrics.mCombinedArea.XMost() > aMetrics.width) ||
(aMetrics.mCombinedArea.YMost() > aMetrics.height)) {
aMetrics.mOverflowArea.x = xa;
aMetrics.mOverflowArea.y = ya;
aMetrics.mOverflowArea.width = xb - xa;
aMetrics.mOverflowArea.height = yb - ya;
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
}
else {
@ -2000,6 +2000,7 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState)
// XXX Huh, that's not true anymore. We do cache the width component of
// the max-element-size...
if (aState.mComputeMaxElementSize) {
printf("BLOCK: marking all child frames dirty...\n");
return PrepareResizeReflow(aState);
}
@ -4875,7 +4876,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
aMarginResult.left = m.left;
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
aCombinedRect = metrics.mCombinedArea;
aCombinedRect = 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);
@ -4883,7 +4884,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
floater->GetView(aState.mPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, floater, view,
&metrics.mCombinedArea,
&metrics.mOverflowArea,
NS_FRAME_NO_MOVE_VIEW);
}
floater->DidReflow(aState.mPresContext, NS_FRAME_REFLOW_FINISHED);

View File

@ -317,11 +317,11 @@ nsBlockReflowContext::ReflowBlock(nsIFrame* aFrame,
aFrame->GetFrameState(&state);
if (0 == (NS_FRAME_OUTSIDE_CHILDREN & state)) {
// Provide combined area for child that doesn't have any
mMetrics.mCombinedArea.x = 0;
mMetrics.mCombinedArea.y = 0;
mMetrics.mCombinedArea.width = mMetrics.width;
mMetrics.mCombinedArea.height = mMetrics.height;
// Provide overflow area for child that doesn't have any
mMetrics.mOverflowArea.x = 0;
mMetrics.mOverflowArea.y = 0;
mMetrics.mOverflowArea.width = mMetrics.width;
mMetrics.mOverflowArea.height = mMetrics.height;
}
// Now that frame has been reflowed at least one time make sure that
@ -376,8 +376,8 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
nscoord x = mX;
nscoord y = mY;
// When deciding whether it's an empty paragraph we also need to take into
// account the combined area
if ((0 == mMetrics.height) && (0 == mMetrics.mCombinedArea.height)) {
// account the overflow area
if ((0 == mMetrics.height) && (0 == mMetrics.mOverflowArea.height)) {
if (IsHTMLParagraph(mFrame)) {
// Special "feature" for HTML compatability - empty paragraphs
// collapse into nothingness, including their margins. Signal
@ -432,7 +432,7 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
// Retain combined area information in case we contain a floater
// and nothing else.
aCombinedRect = mMetrics.mCombinedArea;
aCombinedRect = mMetrics.mOverflowArea;
aCombinedRect.x += x;
aCombinedRect.y += y;
}
@ -549,10 +549,10 @@ nsBlockReflowContext::PlaceBlock(PRBool aForceFit,
// Compute combined-rect in callers coordinate system. The value
// returned in the reflow metrics is relative to the child
// frame.
aCombinedRect.x = mMetrics.mCombinedArea.x + x;
aCombinedRect.y = mMetrics.mCombinedArea.y + y;
aCombinedRect.width = mMetrics.mCombinedArea.width;
aCombinedRect.height = mMetrics.mCombinedArea.height;
aCombinedRect.x = mMetrics.mOverflowArea.x + x;
aCombinedRect.y = mMetrics.mOverflowArea.y + y;
aCombinedRect.width = mMetrics.mOverflowArea.width;
aCombinedRect.height = mMetrics.mOverflowArea.height;
// Now place the frame and complete the reflow process
nsContainerFrame::FinishReflowChild(mFrame, mPresContext, mMetrics, x, y, 0);

View File

@ -1511,7 +1511,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// children, make sure its big enough to include those that stick
// outside the box.
if (NS_FRAME_OUTSIDE_CHILDREN & mState) {
nscoord xMost = aMetrics.mCombinedArea.XMost();
nscoord xMost = aMetrics.mOverflowArea.XMost();
if (xMost > aMetrics.width) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1519,7 +1519,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
#endif
aMetrics.width = xMost;
}
nscoord yMost = aMetrics.mCombinedArea.YMost();
nscoord yMost = aMetrics.mOverflowArea.YMost();
if (yMost > aMetrics.height) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1622,10 +1622,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
aMetrics.mCarriedOutBottomMargin);
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
printf(" combinedArea={%d,%d,%d,%d}",
aMetrics.mCombinedArea.x,
aMetrics.mCombinedArea.y,
aMetrics.mCombinedArea.width,
aMetrics.mCombinedArea.height);
aMetrics.mOverflowArea.x,
aMetrics.mOverflowArea.y,
aMetrics.mOverflowArea.width,
aMetrics.mOverflowArea.height);
}
if (aMetrics.maxElementSize) {
printf(" maxElementSize=%d,%d",
@ -1969,14 +1969,14 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// If the combined area of our children exceeds our bounding box
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
aMetrics.mCombinedArea.x = xa;
aMetrics.mCombinedArea.y = ya;
aMetrics.mCombinedArea.width = xb - xa;
aMetrics.mCombinedArea.height = yb - ya;
if ((aMetrics.mCombinedArea.x < 0) ||
(aMetrics.mCombinedArea.y < 0) ||
(aMetrics.mCombinedArea.XMost() > aMetrics.width) ||
(aMetrics.mCombinedArea.YMost() > aMetrics.height)) {
aMetrics.mOverflowArea.x = xa;
aMetrics.mOverflowArea.y = ya;
aMetrics.mOverflowArea.width = xb - xa;
aMetrics.mOverflowArea.height = yb - ya;
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
}
else {
@ -2000,6 +2000,7 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState)
// XXX Huh, that's not true anymore. We do cache the width component of
// the max-element-size...
if (aState.mComputeMaxElementSize) {
printf("BLOCK: marking all child frames dirty...\n");
return PrepareResizeReflow(aState);
}
@ -4875,7 +4876,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
aMarginResult.left = m.left;
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
aCombinedRect = metrics.mCombinedArea;
aCombinedRect = 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);
@ -4883,7 +4884,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
floater->GetView(aState.mPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, floater, view,
&metrics.mCombinedArea,
&metrics.mOverflowArea,
NS_FRAME_NO_MOVE_VIEW);
}
floater->DidReflow(aState.mPresContext, NS_FRAME_REFLOW_FINISHED);

View File

@ -1511,7 +1511,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// children, make sure its big enough to include those that stick
// outside the box.
if (NS_FRAME_OUTSIDE_CHILDREN & mState) {
nscoord xMost = aMetrics.mCombinedArea.XMost();
nscoord xMost = aMetrics.mOverflowArea.XMost();
if (xMost > aMetrics.width) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1519,7 +1519,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
#endif
aMetrics.width = xMost;
}
nscoord yMost = aMetrics.mCombinedArea.YMost();
nscoord yMost = aMetrics.mOverflowArea.YMost();
if (yMost > aMetrics.height) {
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -1622,10 +1622,10 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
aMetrics.mCarriedOutBottomMargin);
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
printf(" combinedArea={%d,%d,%d,%d}",
aMetrics.mCombinedArea.x,
aMetrics.mCombinedArea.y,
aMetrics.mCombinedArea.width,
aMetrics.mCombinedArea.height);
aMetrics.mOverflowArea.x,
aMetrics.mOverflowArea.y,
aMetrics.mOverflowArea.width,
aMetrics.mOverflowArea.height);
}
if (aMetrics.maxElementSize) {
printf(" maxElementSize=%d,%d",
@ -1969,14 +1969,14 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// If the combined area of our children exceeds our bounding box
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
aMetrics.mCombinedArea.x = xa;
aMetrics.mCombinedArea.y = ya;
aMetrics.mCombinedArea.width = xb - xa;
aMetrics.mCombinedArea.height = yb - ya;
if ((aMetrics.mCombinedArea.x < 0) ||
(aMetrics.mCombinedArea.y < 0) ||
(aMetrics.mCombinedArea.XMost() > aMetrics.width) ||
(aMetrics.mCombinedArea.YMost() > aMetrics.height)) {
aMetrics.mOverflowArea.x = xa;
aMetrics.mOverflowArea.y = ya;
aMetrics.mOverflowArea.width = xb - xa;
aMetrics.mOverflowArea.height = yb - ya;
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
}
else {
@ -2000,6 +2000,7 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState)
// XXX Huh, that's not true anymore. We do cache the width component of
// the max-element-size...
if (aState.mComputeMaxElementSize) {
printf("BLOCK: marking all child frames dirty...\n");
return PrepareResizeReflow(aState);
}
@ -4875,7 +4876,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
aMarginResult.left = m.left;
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
aCombinedRect = metrics.mCombinedArea;
aCombinedRect = 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);
@ -4883,7 +4884,7 @@ nsBlockFrame::ReflowFloater(nsBlockReflowState& aState,
floater->GetView(aState.mPresContext, &view);
if (view) {
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, floater, view,
&metrics.mCombinedArea,
&metrics.mOverflowArea,
NS_FRAME_NO_MOVE_VIEW);
}
floater->DidReflow(aState.mPresContext, NS_FRAME_REFLOW_FINISHED);

View File

@ -718,7 +718,7 @@ nsContainerFrame::FinishReflowChild(nsIFrame* aKidFrame,
// Make sure the frame's view is properly sized and positioned and has
// things like opacity correct
SyncFrameViewAfterReflow(aPresContext, aKidFrame, view,
&aDesiredSize.mCombinedArea,
&aDesiredSize.mOverflowArea,
aFlags);
} else if (0 == (aFlags & NS_FRAME_NO_MOVE_CHILD_VIEWS)) {

View File

@ -1567,10 +1567,10 @@ nsFrame::IsFrameTreeTooDeep(const nsHTMLReflowState& aReflowState,
aMetrics.ascent = 0;
aMetrics.descent = 0;
aMetrics.mCarriedOutBottomMargin = 0;
aMetrics.mCombinedArea.x = 0;
aMetrics.mCombinedArea.y = 0;
aMetrics.mCombinedArea.width = 0;
aMetrics.mCombinedArea.height = 0;
aMetrics.mOverflowArea.x = 0;
aMetrics.mOverflowArea.y = 0;
aMetrics.mOverflowArea.width = 0;
aMetrics.mOverflowArea.height = 0;
if (aMetrics.maxElementSize) {
aMetrics.maxElementSize->width = 0;
aMetrics.maxElementSize->height = 0;

View File

@ -34,7 +34,6 @@
#include "nsCSSRendering.h"
#include "nsIScrollableView.h"
#include "nsWidgetsCID.h"
#include "nsIAreaFrame.h"
#include "nsGfxScrollFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIXMLContent.h"
@ -54,7 +53,6 @@ static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID);
@ -893,23 +891,8 @@ nsGfxScrollFrameInner::CalculateChildTotalSize(nsIFrame* aKidFrame,
nsFrameState kidState;
aKidFrame->GetFrameState(&kidState);
if (NS_FRAME_OUTSIDE_CHILDREN & kidState) {
aKidReflowMetrics.width = aKidReflowMetrics.mCombinedArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mCombinedArea.height;
}
// If it's an area frame, then get the total size which includes the
// space taken up by absolutely positioned child elements
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(aKidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
nscoord xMost, yMost;
areaFrame->GetPositionedInfo(xMost, yMost);
if (xMost > aKidReflowMetrics.width) {
aKidReflowMetrics.width = xMost;
}
if (yMost > aKidReflowMetrics.height) {
aKidReflowMetrics.height = yMost;
}
aKidReflowMetrics.width = aKidReflowMetrics.mOverflowArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mOverflowArea.height;
}
return NS_OK;

View File

@ -41,12 +41,10 @@
#include "nsIEventStateManager.h"
#include "nsIDeviceContext.h"
#include "nsIScrollableView.h"
#include "nsIAreaFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIPresShell.h"
// Interface IDs
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
@ -345,36 +343,16 @@ RootFrame::Reflow(nsIPresContext* aPresContext,
nscoord paddingEdgeX = kidDesiredSize.width - border.right;
nscoord paddingEdgeY = kidDesiredSize.height - border.bottom;
if (kidDesiredSize.mCombinedArea.XMost() > paddingEdgeX) {
kidDesiredSize.width = kidDesiredSize.mCombinedArea.XMost() +
if (kidDesiredSize.mOverflowArea.XMost() > paddingEdgeX) {
kidDesiredSize.width = kidDesiredSize.mOverflowArea.XMost() +
border.right;
}
if (kidDesiredSize.mCombinedArea.YMost() > paddingEdgeY) {
kidDesiredSize.height = kidDesiredSize.mCombinedArea.YMost() +
if (kidDesiredSize.mOverflowArea.YMost() > paddingEdgeY) {
kidDesiredSize.height = kidDesiredSize.mOverflowArea.YMost() +
border.bottom;
}
}
// XXX It would be nice if this were also part of the reflow metrics...
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(kidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
// Get the x-most and y-most of the absolutely positioned children
nscoord positionedXMost, positionedYMost;
areaFrame->GetPositionedInfo(positionedXMost, positionedYMost);
// The background covers the content area and padding area, so check
// for children sticking outside the padding edge
nscoord paddingEdgeX = kidDesiredSize.width - border.right;
nscoord paddingEdgeY = kidDesiredSize.height - border.bottom;
if (positionedXMost > paddingEdgeX) {
kidDesiredSize.width = positionedXMost + border.right;
}
if (positionedYMost > paddingEdgeY) {
kidDesiredSize.height = positionedYMost + border.bottom;
}
}
// If our height is fixed, then make sure the child frame plus its top and
// bottom margin is at least that high as well...
if (NS_AUTOHEIGHT != aReflowState.mComputedHeight) {

View File

@ -23,10 +23,8 @@
#include "nsIHTMLContent.h"
#include "nsIPageSequenceFrame.h"
#include "nsITextContent.h"
#include "nsIAreaFrame.h"
const nsIID kIHTMLContentIID = NS_IHTMLCONTENT_IID;
const nsIID kIPageSequenceFrameIID = NS_IPAGESEQUENCEFRAME_IID;
const nsIID kIStyledContentIID = NS_ISTYLEDCONTENT_IID;
const nsIID kITextContentIID = NS_ITEXT_CONTENT_IID;
const nsIID kIAreaFrameIID = NS_IAREAFRAME_IID;

View File

@ -1,45 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#ifndef nsIAreaFrame_h___
#define nsIAreaFrame_h___
#include "nsIFrame.h"
// 7327a0a0-bc8d-11d1-8539-00a02468fab6
#define NS_IAREAFRAME_IID \
{ 0xa6cf90de, 0x15b3, 0x11d2, {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
/**
* An interface for managing anchored items. Note that this interface is not
* an nsISupports interface, and therefore you cannot QueryInterface() back
*/
class nsIAreaFrame
{
public:
/**
* Returns the x-most and y-most for the child absoolutely positioned
* elements
*/
NS_IMETHOD GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const = 0;
};
#endif /* nsIAreaFrame_h___ */

View File

@ -461,12 +461,12 @@ nsInlineFrame::ReflowFrames(nsIPresContext* aPresContext,
}
}
// For now our combined area is zero. The real value will be
// For now our overflow area is zero. The real value will be
// computed during vertical alignment of the line we are on.
aMetrics.mCombinedArea.x = 0;
aMetrics.mCombinedArea.y = 0;
aMetrics.mCombinedArea.width = aMetrics.width;
aMetrics.mCombinedArea.height = aMetrics.height;
aMetrics.mOverflowArea.x = 0;
aMetrics.mOverflowArea.y = 0;
aMetrics.mOverflowArea.width = aMetrics.width;
aMetrics.mOverflowArea.height = aMetrics.height;
#ifdef NOISY_FINAL_SIZE
ListTag(stdout);
@ -973,12 +973,13 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Incremental == aReflowState.reason) {
// Give the absolute positioning code a chance to handle it
PRBool handled;
nsRect childBounds;
nscoord containingBlockWidth = -1;
nscoord containingBlockHeight = -1;
mAbsoluteContainer.IncrementalReflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight,
handled);
handled, childBounds);
// If the incremental reflow command was handled by the absolute positioning
// code, then we're all done
@ -989,7 +990,25 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowState reflowState(aReflowState);
reflowState.reason = eReflowReason_Resize;
reflowState.reflowCommand = nsnull;
return nsInlineFrame::Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, reflowState, aStatus);
// XXX Although this seems like the correct thing to do the line layout
// code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored
#if 0
// Factor the absolutely positioned child bounds into the overflow area
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aDesiredSize.mOverflowArea.x < 0) ||
(aDesiredSize.mOverflowArea.y < 0) ||
(aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) ||
(aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
#endif
return rv;
}
}
@ -1001,9 +1020,28 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
if (NS_SUCCEEDED(rv)) {
nscoord containingBlockWidth = -1;
nscoord containingBlockHeight = -1;
nsRect childBounds;
rv = mAbsoluteContainer.Reflow(this, aPresContext, aReflowState,
containingBlockWidth, containingBlockHeight);
containingBlockWidth, containingBlockHeight,
childBounds);
// XXX Although this seems like the correct thing to do the line layout
// code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored
#if 0
// Factor the absolutely positioned child bounds into the overflow area
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds);
// Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly
if ((aDesiredSize.mOverflowArea.x < 0) ||
(aDesiredSize.mOverflowArea.y < 0) ||
(aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) ||
(aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
} else {
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
}
#endif
}
return rv;

View File

@ -1062,7 +1062,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
aFrame->GetFrameState(&state);
if (NS_FRAME_OUTSIDE_CHILDREN & state) {
pfd->mCombinedArea = metrics.mCombinedArea;
pfd->mCombinedArea = metrics.mOverflowArea;
}
else {
pfd->mCombinedArea.x = 0;
@ -1480,7 +1480,7 @@ nsLineLayout::AddBulletFrame(nsIFrame* aFrame,
// Note: y value will be updated during vertical alignment
aFrame->GetRect(pfd->mBounds);
pfd->mCombinedArea = aMetrics.mCombinedArea;
pfd->mCombinedArea = aMetrics.mOverflowArea;
if (mComputeMaxElementSize) {
pfd->mMaxElementSize.SizeTo(aMetrics.width, aMetrics.height);
}

View File

@ -34,7 +34,6 @@
#include "nsCSSRendering.h"
#include "nsIScrollableView.h"
#include "nsWidgetsCID.h"
#include "nsIAreaFrame.h"
#include "nsScrollFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIWebShell.h"
@ -50,7 +49,6 @@ static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
//----------------------------------------------------------------------
@ -437,23 +435,8 @@ nsScrollFrame::CalculateChildTotalSize(nsIFrame* aKidFrame,
nsFrameState kidState;
aKidFrame->GetFrameState(&kidState);
if (NS_FRAME_OUTSIDE_CHILDREN & kidState) {
aKidReflowMetrics.width = aKidReflowMetrics.mCombinedArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mCombinedArea.height;
}
// If it's an area frame, then get the total size which includes the
// space taken up by absolutely positioned child elements
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(aKidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
nscoord xMost, yMost;
areaFrame->GetPositionedInfo(xMost, yMost);
if (xMost > aKidReflowMetrics.width) {
aKidReflowMetrics.width = xMost;
}
if (yMost > aKidReflowMetrics.height) {
aKidReflowMetrics.height = yMost;
}
aKidReflowMetrics.width = aKidReflowMetrics.mOverflowArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mOverflowArea.height;
}
return NS_OK;

View File

@ -34,7 +34,6 @@
#include "nsCSSRendering.h"
#include "nsIScrollableView.h"
#include "nsWidgetsCID.h"
#include "nsIAreaFrame.h"
#include "nsScrollPortFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIBox.h"
@ -58,7 +57,6 @@ static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
//----------------------------------------------------------------------
@ -311,23 +309,8 @@ nsScrollPortFrame::CalculateChildTotalSize(nsIFrame* aKidFrame,
nsFrameState kidState;
aKidFrame->GetFrameState(&kidState);
if (NS_FRAME_OUTSIDE_CHILDREN & kidState) {
aKidReflowMetrics.width = aKidReflowMetrics.mCombinedArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mCombinedArea.height;
}
// If it's an area frame, then get the total size which includes the
// space taken up by absolutely positioned child elements
nsIAreaFrame* areaFrame;
if (NS_SUCCEEDED(aKidFrame->QueryInterface(kAreaFrameIID, (void**)&areaFrame))) {
nscoord xMost, yMost;
areaFrame->GetPositionedInfo(xMost, yMost);
if (xMost > aKidReflowMetrics.width) {
aKidReflowMetrics.width = xMost;
}
if (yMost > aKidReflowMetrics.height) {
aKidReflowMetrics.height = yMost;
}
aKidReflowMetrics.width = aKidReflowMetrics.mOverflowArea.width;
aKidReflowMetrics.height = aKidReflowMetrics.mOverflowArea.height;
}
return NS_OK;

View File

@ -23,9 +23,6 @@
#include "nsCOMPtr.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIContent.h"
#include "nsIAreaFrame.h"
static NS_DEFINE_IID(kAreaFrameIID, NS_IAREAFRAME_IID);
nsresult
NS_NewSelectsAreaFrame(nsIPresShell* aShell, nsIFrame** aNewFrame, PRUint32 aFlags)

View File

@ -375,7 +375,7 @@ ViewportFrame::ReflowFixedFrame(nsIPresContext* aPresContext,
// Size and position the view and set its opacity, visibility, content
// transparency, and clip
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, aKidFrame, kidView,
&kidDesiredSize.mCombinedArea);
&kidDesiredSize.mOverflowArea);
aKidFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
return rv;
}

View File

@ -1130,8 +1130,8 @@ nsBoxFrame::FlowChildAt(nsIFrame* childFrame,
// printf("width: %d, height: %d\n", desiredSize.mCombinedArea.width, desiredSize.mCombinedArea.height);
if (kidState & NS_FRAME_OUTSIDE_CHILDREN) {
desiredSize.width = desiredSize.mCombinedArea.width;
desiredSize.height = desiredSize.mCombinedArea.height;
desiredSize.width = desiredSize.mOverflowArea.width;
desiredSize.height = desiredSize.mOverflowArea.height;
}