зеркало из https://github.com/mozilla/gecko-dev.git
Bug 170330. Factor out overflowArea calculations and take into account overflow:hidden. Also improve calculations of clipping for invalidation in the view manager. r+sr=dbaron
This commit is contained in:
Родитель
89d4967bdf
Коммит
a5a3f217d1
|
@ -794,6 +794,13 @@ public:
|
|||
PRInt32* outFrameContentOffset,
|
||||
nsIFrame* *outChildFrame) = 0;
|
||||
|
||||
/**
|
||||
* Returns true iff the frame has a view (i.e., GetView() returns non-null)
|
||||
*/
|
||||
PRBool HasView() {
|
||||
return (mState & NS_FRAME_HAS_VIEW) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current frame-state value for this frame. aResult is
|
||||
* filled in with the state bits.
|
||||
|
|
|
@ -771,21 +771,16 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Whether or not we're complete hasn't changed
|
||||
aStatus = (nsnull != mNextInFlow) ? NS_FRAME_NOT_COMPLETE : NS_FRAME_COMPLETE;
|
||||
|
||||
// Factor the absolutely positioned child bounds into the overflow area
|
||||
ComputeCombinedArea(aReflowState, aMetrics);
|
||||
|
||||
// Factor the absolutely positioned child bounds into the overflow area
|
||||
nsRect childBounds;
|
||||
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
|
||||
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;
|
||||
}
|
||||
// Finish computing the overflow area, taking account of outline and
|
||||
// overflow:hidden etc
|
||||
ComputeOverflowArea(aMetrics.mOverflowArea, aMetrics.mOverflowArea);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1095,17 +1090,12 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// Area of child content has been computed into mOverflowArea
|
||||
// Finish computing the overflow area, taking account of outline and
|
||||
// overflow:hidden etc
|
||||
ComputeOverflowArea(aMetrics.mOverflowArea, aMetrics.mOverflowArea);
|
||||
|
||||
// Clear the space manager pointer in the block reflow state so we
|
||||
// don't waste time translating the coordinate system back on a dead
|
||||
|
@ -1169,10 +1159,6 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_roc
|
||||
printf("*** Metrics width/height on the way out=%d,%d\n", aMetrics.width, aMetrics.height);
|
||||
#endif
|
||||
|
||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
|
||||
return rv;
|
||||
}
|
||||
|
@ -1546,18 +1532,6 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
|
|||
}
|
||||
|
||||
ComputeCombinedArea(aReflowState, aMetrics);
|
||||
|
||||
// If the combined area of our children exceeds our bounding box
|
||||
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -754,6 +754,55 @@ nsFrame::DisplaySelection(nsIPresContext* aPresContext, PRBool isOkToTurnOn)
|
|||
return selType;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrame::ComputeOverflowArea(nsRect& aOverflowArea,
|
||||
const nsRect& aCombinedChildren)
|
||||
{
|
||||
// the frame's rect in its own coordinate system
|
||||
nsRect r(0, 0, mRect.width, mRect.height);
|
||||
// Make the default combined area: frame U children
|
||||
aOverflowArea.UnionRect(aCombinedChildren, r);
|
||||
// WARNING: aCombinedChildren might be the same rect as aOverflowArea.
|
||||
// It may have been destroyed now. Don't use it below.
|
||||
|
||||
// Don't do the following mildly expensive stuff unless we have a view;
|
||||
// any block frame with overflow:hidden will have a view
|
||||
// (see nsContainerFrame::FrameNeedsView).
|
||||
// HasView() is very cheap; it just checks a bit on mState.
|
||||
if (HasView()) {
|
||||
// The following code is temporarily disabled. We'll turn it on
|
||||
// when proper support for 'outline' lands. Note that it assumes
|
||||
// any frame with 'outline' has a view. --- roc
|
||||
#if 0
|
||||
// Add in the outline width, which overflows our border area
|
||||
const nsStyleOutline* outline;
|
||||
::GetStyleData(mStyleContext, &outline);
|
||||
|
||||
nscoord width;
|
||||
outline->GetOutlineWidth(width);
|
||||
r.Inflate(width, width);
|
||||
#endif
|
||||
|
||||
// overflow:hidden doesn't need to take account of the child area
|
||||
const nsStyleDisplay* display;
|
||||
::GetStyleData(mStyleContext, &display);
|
||||
if (NS_STYLE_OVERFLOW_HIDDEN == display->mOverflow
|
||||
&& (display->IsBlockLevel() || display->IsFloating())) {
|
||||
aOverflowArea = r;
|
||||
}
|
||||
}
|
||||
|
||||
// Set state bit to indicate whether there is any overflow
|
||||
if (aOverflowArea.x < 0
|
||||
|| aOverflowArea.y < 0
|
||||
|| aOverflowArea.XMost() > mRect.width
|
||||
|| aOverflowArea.YMost() > mRect.height) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
} else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext)
|
||||
{
|
||||
|
|
|
@ -348,6 +348,11 @@ public:
|
|||
const nsRect& aDamageRect,
|
||||
PRBool aImmediate = PR_FALSE) const;
|
||||
|
||||
// Helper function to compute the overflow area for a frame,
|
||||
// taking into account overflow:hidden and any outline present.
|
||||
// This sets the frame state bit FRAME_OUTSIDE_CHILDREN if necessary.
|
||||
void ComputeOverflowArea(nsRect& aOverflowArea, const nsRect& aCombinedChildren);
|
||||
|
||||
// Helper function to return the index in parent of the frame's content
|
||||
// object. Returns -1 on error or if the frame doesn't have a content object
|
||||
static PRInt32 ContentIndexInContainer(const nsIFrame* aFrame);
|
||||
|
|
|
@ -794,6 +794,13 @@ public:
|
|||
PRInt32* outFrameContentOffset,
|
||||
nsIFrame* *outChildFrame) = 0;
|
||||
|
||||
/**
|
||||
* Returns true iff the frame has a view (i.e., GetView() returns non-null)
|
||||
*/
|
||||
PRBool HasView() {
|
||||
return (mState & NS_FRAME_HAS_VIEW) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current frame-state value for this frame. aResult is
|
||||
* filled in with the state bits.
|
||||
|
|
|
@ -1311,16 +1311,8 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
|
||||
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
|
||||
// Don't update the overflow area state here. It's done by line layout.
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
@ -1356,16 +1348,8 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// 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
|
||||
// Don't update the overflow area state here. It's done by line layout.
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -1258,16 +1258,11 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
|
|||
nsIView* view;
|
||||
aFrame->GetView(mPresContext, &view);
|
||||
if (view) {
|
||||
nsIViewManager *vm;
|
||||
view->GetViewManager(vm);
|
||||
nsCOMPtr<nsIViewManager> vm;
|
||||
view->GetViewManager(*getter_AddRefs(vm));
|
||||
|
||||
#if 0 // XXX This is the correct code. We'll turn it on later to mitigate risk.
|
||||
vm->ResizeView(view, pfd->mCombinedArea);
|
||||
#else // imitate the old, wrong code
|
||||
nsRect r(0, 0, metrics.width, metrics.height);
|
||||
vm->ResizeView(view, r);
|
||||
#endif
|
||||
NS_RELEASE(vm);
|
||||
nsContainerFrame::SyncFrameViewAfterSizeChange(mPresContext, pfd->mFrame, nsnull, view);
|
||||
}
|
||||
|
||||
// Tell the frame that we're done reflowing it
|
||||
|
@ -3323,20 +3318,26 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
|
|||
}
|
||||
|
||||
// If we just computed a spans combined area, we need to update its
|
||||
// NS_FRAME_OUTSIDE_CHILDREN bit..
|
||||
// NS_FRAME_OUTSIDE_CHILDREN bit. We also may need to take into account
|
||||
// an outline.
|
||||
if (nsnull != psd->mFrame) {
|
||||
pfd = psd->mFrame;
|
||||
nsIFrame* frame = pfd->mFrame;
|
||||
nsFrameState oldState;
|
||||
frame->GetFrameState(&oldState);
|
||||
nsFrameState newState = oldState & ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
if ((minX < 0) || (minY < 0) ||
|
||||
(maxX > pfd->mBounds.width) || (maxY > pfd->mBounds.height)) {
|
||||
newState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
if (newState != oldState) {
|
||||
frame->SetFrameState(newState);
|
||||
}
|
||||
|
||||
// We're conservative here; the combined area for this span/frame
|
||||
// is the union of the area that the frame computed during reflow
|
||||
// and the area that we computed for it here in RelativePositionFrames.
|
||||
// We do this because relatively positioned frames that are also spans
|
||||
// have two contributors to the overflow area: overflowing inline children
|
||||
// and overflowing absolute children.
|
||||
// This could be larger than necessary if inline alignment caused an inline child
|
||||
// to overflow less, because its old overflow would still be counted in
|
||||
// pfd->mCombinedArea.
|
||||
// But in practice it's OK to have an overflow area that's larger than necessary.
|
||||
// (Although if it happens too often it could become a paint performance issue).
|
||||
nsRect children;
|
||||
children.UnionRect(pfd->mCombinedArea, aCombinedArea);
|
||||
NS_STATIC_CAST(nsFrame*, frame)->ComputeOverflowArea(aCombinedArea, children);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -771,21 +771,16 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// Whether or not we're complete hasn't changed
|
||||
aStatus = (nsnull != mNextInFlow) ? NS_FRAME_NOT_COMPLETE : NS_FRAME_COMPLETE;
|
||||
|
||||
// Factor the absolutely positioned child bounds into the overflow area
|
||||
ComputeCombinedArea(aReflowState, aMetrics);
|
||||
|
||||
// Factor the absolutely positioned child bounds into the overflow area
|
||||
nsRect childBounds;
|
||||
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
|
||||
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;
|
||||
}
|
||||
// Finish computing the overflow area, taking account of outline and
|
||||
// overflow:hidden etc
|
||||
ComputeOverflowArea(aMetrics.mOverflowArea, aMetrics.mOverflowArea);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1095,17 +1090,12 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// Area of child content has been computed into mOverflowArea
|
||||
// Finish computing the overflow area, taking account of outline and
|
||||
// overflow:hidden etc
|
||||
ComputeOverflowArea(aMetrics.mOverflowArea, aMetrics.mOverflowArea);
|
||||
|
||||
// Clear the space manager pointer in the block reflow state so we
|
||||
// don't waste time translating the coordinate system back on a dead
|
||||
|
@ -1169,10 +1159,6 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_roc
|
||||
printf("*** Metrics width/height on the way out=%d,%d\n", aMetrics.width, aMetrics.height);
|
||||
#endif
|
||||
|
||||
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
|
||||
return rv;
|
||||
}
|
||||
|
@ -1546,18 +1532,6 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
|
|||
}
|
||||
|
||||
ComputeCombinedArea(aReflowState, aMetrics);
|
||||
|
||||
// If the combined area of our children exceeds our bounding box
|
||||
// then set the NS_FRAME_OUTSIDE_CHILDREN flag, otherwise clear it.
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -754,6 +754,55 @@ nsFrame::DisplaySelection(nsIPresContext* aPresContext, PRBool isOkToTurnOn)
|
|||
return selType;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrame::ComputeOverflowArea(nsRect& aOverflowArea,
|
||||
const nsRect& aCombinedChildren)
|
||||
{
|
||||
// the frame's rect in its own coordinate system
|
||||
nsRect r(0, 0, mRect.width, mRect.height);
|
||||
// Make the default combined area: frame U children
|
||||
aOverflowArea.UnionRect(aCombinedChildren, r);
|
||||
// WARNING: aCombinedChildren might be the same rect as aOverflowArea.
|
||||
// It may have been destroyed now. Don't use it below.
|
||||
|
||||
// Don't do the following mildly expensive stuff unless we have a view;
|
||||
// any block frame with overflow:hidden will have a view
|
||||
// (see nsContainerFrame::FrameNeedsView).
|
||||
// HasView() is very cheap; it just checks a bit on mState.
|
||||
if (HasView()) {
|
||||
// The following code is temporarily disabled. We'll turn it on
|
||||
// when proper support for 'outline' lands. Note that it assumes
|
||||
// any frame with 'outline' has a view. --- roc
|
||||
#if 0
|
||||
// Add in the outline width, which overflows our border area
|
||||
const nsStyleOutline* outline;
|
||||
::GetStyleData(mStyleContext, &outline);
|
||||
|
||||
nscoord width;
|
||||
outline->GetOutlineWidth(width);
|
||||
r.Inflate(width, width);
|
||||
#endif
|
||||
|
||||
// overflow:hidden doesn't need to take account of the child area
|
||||
const nsStyleDisplay* display;
|
||||
::GetStyleData(mStyleContext, &display);
|
||||
if (NS_STYLE_OVERFLOW_HIDDEN == display->mOverflow
|
||||
&& (display->IsBlockLevel() || display->IsFloating())) {
|
||||
aOverflowArea = r;
|
||||
}
|
||||
}
|
||||
|
||||
// Set state bit to indicate whether there is any overflow
|
||||
if (aOverflowArea.x < 0
|
||||
|| aOverflowArea.y < 0
|
||||
|| aOverflowArea.XMost() > mRect.width
|
||||
|| aOverflowArea.YMost() > mRect.height) {
|
||||
mState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
} else {
|
||||
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext)
|
||||
{
|
||||
|
|
|
@ -348,6 +348,11 @@ public:
|
|||
const nsRect& aDamageRect,
|
||||
PRBool aImmediate = PR_FALSE) const;
|
||||
|
||||
// Helper function to compute the overflow area for a frame,
|
||||
// taking into account overflow:hidden and any outline present.
|
||||
// This sets the frame state bit FRAME_OUTSIDE_CHILDREN if necessary.
|
||||
void ComputeOverflowArea(nsRect& aOverflowArea, const nsRect& aCombinedChildren);
|
||||
|
||||
// Helper function to return the index in parent of the frame's content
|
||||
// object. Returns -1 on error or if the frame doesn't have a content object
|
||||
static PRInt32 ContentIndexInContainer(const nsIFrame* aFrame);
|
||||
|
|
|
@ -1311,16 +1311,8 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
|
||||
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
|
||||
// Don't update the overflow area state here. It's done by line layout.
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
@ -1356,16 +1348,8 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// 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
|
||||
// Don't update the overflow area state here. It's done by line layout.
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -1258,16 +1258,11 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
|
|||
nsIView* view;
|
||||
aFrame->GetView(mPresContext, &view);
|
||||
if (view) {
|
||||
nsIViewManager *vm;
|
||||
view->GetViewManager(vm);
|
||||
nsCOMPtr<nsIViewManager> vm;
|
||||
view->GetViewManager(*getter_AddRefs(vm));
|
||||
|
||||
#if 0 // XXX This is the correct code. We'll turn it on later to mitigate risk.
|
||||
vm->ResizeView(view, pfd->mCombinedArea);
|
||||
#else // imitate the old, wrong code
|
||||
nsRect r(0, 0, metrics.width, metrics.height);
|
||||
vm->ResizeView(view, r);
|
||||
#endif
|
||||
NS_RELEASE(vm);
|
||||
nsContainerFrame::SyncFrameViewAfterSizeChange(mPresContext, pfd->mFrame, nsnull, view);
|
||||
}
|
||||
|
||||
// Tell the frame that we're done reflowing it
|
||||
|
@ -3323,20 +3318,26 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
|
|||
}
|
||||
|
||||
// If we just computed a spans combined area, we need to update its
|
||||
// NS_FRAME_OUTSIDE_CHILDREN bit..
|
||||
// NS_FRAME_OUTSIDE_CHILDREN bit. We also may need to take into account
|
||||
// an outline.
|
||||
if (nsnull != psd->mFrame) {
|
||||
pfd = psd->mFrame;
|
||||
nsIFrame* frame = pfd->mFrame;
|
||||
nsFrameState oldState;
|
||||
frame->GetFrameState(&oldState);
|
||||
nsFrameState newState = oldState & ~NS_FRAME_OUTSIDE_CHILDREN;
|
||||
if ((minX < 0) || (minY < 0) ||
|
||||
(maxX > pfd->mBounds.width) || (maxY > pfd->mBounds.height)) {
|
||||
newState |= NS_FRAME_OUTSIDE_CHILDREN;
|
||||
}
|
||||
if (newState != oldState) {
|
||||
frame->SetFrameState(newState);
|
||||
}
|
||||
|
||||
// We're conservative here; the combined area for this span/frame
|
||||
// is the union of the area that the frame computed during reflow
|
||||
// and the area that we computed for it here in RelativePositionFrames.
|
||||
// We do this because relatively positioned frames that are also spans
|
||||
// have two contributors to the overflow area: overflowing inline children
|
||||
// and overflowing absolute children.
|
||||
// This could be larger than necessary if inline alignment caused an inline child
|
||||
// to overflow less, because its old overflow would still be counted in
|
||||
// pfd->mCombinedArea.
|
||||
// But in practice it's OK to have an overflow area that's larger than necessary.
|
||||
// (Although if it happens too often it could become a paint performance issue).
|
||||
nsRect children;
|
||||
children.UnionRect(pfd->mCombinedArea, aCombinedArea);
|
||||
NS_STATIC_CAST(nsFrame*, frame)->ComputeOverflowArea(aCombinedArea, children);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -547,6 +547,9 @@ public:
|
|||
|
||||
};
|
||||
|
||||
//update view as if a child view was being invalidated,
|
||||
//so the view should apply its 'child clip'
|
||||
#define NS_VMREFRESH_FORCHILD 0x0001
|
||||
//update view now?
|
||||
#define NS_VMREFRESH_IMMEDIATE 0x0002
|
||||
//prevent "sync painting"
|
||||
|
|
|
@ -1629,12 +1629,18 @@ NS_IMETHODIMP nsViewManager::UpdateView(nsIView *aView, const nsRect &aRect, PRU
|
|||
}
|
||||
view->ConvertFromParentCoords(&clippedRect.x, &clippedRect.y);
|
||||
|
||||
if ((aUpdateFlags & NS_VMREFRESH_FORCHILD) != 0 && view->GetClipChildren()) {
|
||||
nsRect childClipRect;
|
||||
view->GetChildClip(childClipRect);
|
||||
if (!clippedRect.IntersectRect(clippedRect, childClipRect)) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsRect damagedRect;
|
||||
damagedRect.x = aRect.x;
|
||||
damagedRect.y = aRect.y;
|
||||
damagedRect.width = aRect.width;
|
||||
damagedRect.height = aRect.height;
|
||||
damagedRect.IntersectRect(aRect, clippedRect);
|
||||
if (!damagedRect.IntersectRect(aRect, clippedRect)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If the rectangle is not visible then abort
|
||||
// without invalidating. This is a performance
|
||||
|
@ -2500,10 +2506,10 @@ NS_IMETHODIMP nsViewManager::MoveViewTo(nsIView *aView, nscoord aX, nscoord aY)
|
|||
view->GetVisibility(visibility);
|
||||
if (visibility != nsViewVisibility_kHide) {
|
||||
nsView* parentView = view->GetParent();
|
||||
UpdateView(parentView, oldArea, NS_VMREFRESH_NO_SYNC);
|
||||
UpdateView(parentView, oldArea, NS_VMREFRESH_NO_SYNC | NS_VMREFRESH_FORCHILD);
|
||||
nsRect newArea;
|
||||
view->GetBounds(newArea);
|
||||
UpdateView(parentView, newArea, NS_VMREFRESH_NO_SYNC);
|
||||
UpdateView(parentView, newArea, NS_VMREFRESH_NO_SYNC | NS_VMREFRESH_FORCHILD);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -2564,7 +2570,7 @@ NS_IMETHODIMP nsViewManager::ResizeView(nsIView *aView, const nsRect &aRect, PRB
|
|||
|
||||
UpdateView(view, aRect, NS_VMREFRESH_NO_SYNC);
|
||||
view->ConvertToParentCoords(&oldDimensions.x, &oldDimensions.y);
|
||||
UpdateView(parentView, oldDimensions, NS_VMREFRESH_NO_SYNC);
|
||||
UpdateView(parentView, oldDimensions, NS_VMREFRESH_NO_SYNC | NS_VMREFRESH_FORCHILD);
|
||||
} else {
|
||||
view->SetDimensions(aRect, PR_FALSE);
|
||||
|
||||
|
@ -2572,7 +2578,7 @@ NS_IMETHODIMP nsViewManager::ResizeView(nsIView *aView, const nsRect &aRect, PRB
|
|||
nsRect r = aRect;
|
||||
view->ConvertToParentCoords(&r.x, &r.y);
|
||||
view->ConvertToParentCoords(&oldDimensions.x, &oldDimensions.y);
|
||||
InvalidateRectDifference(parentView, oldDimensions, r, NS_VMREFRESH_NO_SYNC);
|
||||
InvalidateRectDifference(parentView, oldDimensions, r, NS_VMREFRESH_NO_SYNC | NS_VMREFRESH_FORCHILD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2650,7 +2656,8 @@ NS_IMETHODIMP nsViewManager::SetViewChildClipRegion(nsIView *aView, const nsRegi
|
|||
if (parent != nsnull) {
|
||||
view->ConvertToParentCoords(&oldClipRect.x, &oldClipRect.y);
|
||||
view->ConvertToParentCoords(&newClipRect.x, &newClipRect.y);
|
||||
InvalidateRectDifference(parent, oldClipRect, newClipRect, NS_VMREFRESH_NO_SYNC);
|
||||
InvalidateRectDifference(parent, oldClipRect, newClipRect,
|
||||
NS_VMREFRESH_NO_SYNC | NS_VMREFRESH_FORCHILD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2887,7 +2894,7 @@ NS_IMETHODIMP nsViewManager::SetViewVisibility(nsIView *aView, nsViewVisibility
|
|||
if (parentView) {
|
||||
nsRect bounds;
|
||||
view->GetBounds(bounds);
|
||||
UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC);
|
||||
UpdateView(parentView, bounds, NS_VMREFRESH_NO_SYNC | NS_VMREFRESH_FORCHILD);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче