Fix for bug #2062. When sizing the view, take into account child frames

that stick outside the right/bottom edges of the parent's frame
This commit is contained in:
troy%netscape.com 1999-06-29 03:41:58 +00:00
Родитель 386c052ce9
Коммит d0002c6559
4 изменённых файлов: 168 добавлений и 10 удалений

Просмотреть файл

@ -212,7 +212,25 @@ nsAreaFrame::Paint(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const
{
return mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost);
nsresult rv = mAbsoluteContainer.GetPositionedInfo(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;
}
NS_IMETHODIMP
@ -251,7 +269,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
}
}
// If we have one then set the space manager
// If we have a space manager, then set it in the reflow state
if (nsnull != mSpaceManager) {
// Modify the reflow state and set the space manager
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
@ -270,9 +288,9 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState);
}
// Compute our desired size taking into account floaters that stick outside
// our box. Note that if this frame has a height specified by CSS then we
// don't do this
// Compute our desired size taking into account floaters and child frames
// that stick outside our box. Note that if this frame has a height specified
// by CSS then we don't do this
if ((mFlags & NS_AREA_WRAP_HEIGHT) &&
(NS_UNCONSTRAINEDSIZE == aReflowState.computedHeight) &&
(NS_FRAME_OUTSIDE_CHILDREN & mState)) {
@ -285,6 +303,12 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
}
}
// 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;
}
// XXX This code is really temporary; the lower level frame
// classes need to contribute to the area that needs damage
// repair. This class should only worry about damage repairing
@ -349,6 +373,57 @@ nsAreaFrame::GetFrameType(nsIAtom** aType) const
return NS_OK;
}
NS_IMETHODIMP
nsAreaFrame::DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus)
{
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// If we should position our view, and we have child frames that stick
// outside our box, then we need to size our view large enough to include
// those child frames
if ((mState & NS_FRAME_SYNC_FRAME_AND_VIEW) &&
(mState & NS_FRAME_OUTSIDE_CHILDREN)) {
nsIView* view;
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
GetView(&view);
if (view && (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow)) {
// Don't let our base class position the view since we're doing it
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
// Set the view's bit that indicates that it has transparent content
nsIViewManager* vm;
view->GetViewManager(vm);
vm->SetViewContentTransparency(view, PR_TRUE);
// Position and size view relative to its parent, not relative to our
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
// XXX We need to handle the case where child frames stick out on the
// left and top edges as well...
GetOffsetFromView(origin, &parentWithView);
vm->ResizeView(view, mCombinedArea.XMost(), mCombinedArea.YMost());
vm->MoveViewTo(view, origin.x, origin.y);
NS_RELEASE(vm);
// Call our base class
nsresult rv = nsBlockFrame::DidReflow(aPresContext, aStatus);
// Set the flag again...
mState |= NS_FRAME_SYNC_FRAME_AND_VIEW;
return rv;
}
}
}
return nsBlockFrame::DidReflow(aPresContext, aStatus);
}
/////////////////////////////////////////////////////////////////////////////
// Diagnostics

Просмотреть файл

@ -72,6 +72,9 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus);
#ifdef NS_DEBUG
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
@ -98,6 +101,7 @@ protected:
private:
nsSpaceManager* mSpaceManager;
nsAbsoluteContainingBlock mAbsoluteContainer;
nsRect mCombinedArea;
};
#endif /* nsAreaFrame_h___ */

Просмотреть файл

@ -212,7 +212,25 @@ nsAreaFrame::Paint(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsAreaFrame::GetPositionedInfo(nscoord& aXMost, nscoord& aYMost) const
{
return mAbsoluteContainer.GetPositionedInfo(aXMost, aYMost);
nsresult rv = mAbsoluteContainer.GetPositionedInfo(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;
}
NS_IMETHODIMP
@ -251,7 +269,7 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
}
}
// If we have one then set the space manager
// If we have a space manager, then set it in the reflow state
if (nsnull != mSpaceManager) {
// Modify the reflow state and set the space manager
nsHTMLReflowState& reflowState = (nsHTMLReflowState&)aReflowState;
@ -270,9 +288,9 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
rv = mAbsoluteContainer.Reflow(aPresContext, aReflowState);
}
// Compute our desired size taking into account floaters that stick outside
// our box. Note that if this frame has a height specified by CSS then we
// don't do this
// Compute our desired size taking into account floaters and child frames
// that stick outside our box. Note that if this frame has a height specified
// by CSS then we don't do this
if ((mFlags & NS_AREA_WRAP_HEIGHT) &&
(NS_UNCONSTRAINEDSIZE == aReflowState.computedHeight) &&
(NS_FRAME_OUTSIDE_CHILDREN & mState)) {
@ -285,6 +303,12 @@ nsAreaFrame::Reflow(nsIPresContext& aPresContext,
}
}
// 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;
}
// XXX This code is really temporary; the lower level frame
// classes need to contribute to the area that needs damage
// repair. This class should only worry about damage repairing
@ -349,6 +373,57 @@ nsAreaFrame::GetFrameType(nsIAtom** aType) const
return NS_OK;
}
NS_IMETHODIMP
nsAreaFrame::DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus)
{
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
// If we should position our view, and we have child frames that stick
// outside our box, then we need to size our view large enough to include
// those child frames
if ((mState & NS_FRAME_SYNC_FRAME_AND_VIEW) &&
(mState & NS_FRAME_OUTSIDE_CHILDREN)) {
nsIView* view;
const nsStyleDisplay* display = (const nsStyleDisplay*)
mStyleContext->GetStyleData(eStyleStruct_Display);
GetView(&view);
if (view && (NS_STYLE_OVERFLOW_VISIBLE == display->mOverflow)) {
// Don't let our base class position the view since we're doing it
mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW;
// Set the view's bit that indicates that it has transparent content
nsIViewManager* vm;
view->GetViewManager(vm);
vm->SetViewContentTransparency(view, PR_TRUE);
// Position and size view relative to its parent, not relative to our
// parent frame (our parent frame may not have a view).
nsIView* parentWithView;
nsPoint origin;
// XXX We need to handle the case where child frames stick out on the
// left and top edges as well...
GetOffsetFromView(origin, &parentWithView);
vm->ResizeView(view, mCombinedArea.XMost(), mCombinedArea.YMost());
vm->MoveViewTo(view, origin.x, origin.y);
NS_RELEASE(vm);
// Call our base class
nsresult rv = nsBlockFrame::DidReflow(aPresContext, aStatus);
// Set the flag again...
mState |= NS_FRAME_SYNC_FRAME_AND_VIEW;
return rv;
}
}
}
return nsBlockFrame::DidReflow(aPresContext, aStatus);
}
/////////////////////////////////////////////////////////////////////////////
// Diagnostics

Просмотреть файл

@ -72,6 +72,9 @@ public:
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
nsDidReflowStatus aStatus);
#ifdef NS_DEBUG
NS_IMETHOD Paint(nsIPresContext& aPresContext,
nsIRenderingContext& aRenderingContext,
@ -98,6 +101,7 @@ protected:
private:
nsSpaceManager* mSpaceManager;
nsAbsoluteContainingBlock mAbsoluteContainer;
nsRect mCombinedArea;
};
#endif /* nsAreaFrame_h___ */