Bug 151375. Implement css2 outline (still called -moz-outline for now). Makes -moz-outline draw outside of the current frame. Improves appearance of focus outline. Lots of help from roc. r+sr=dbaron

This commit is contained in:
aaronleventhal%moonset.net 2004-07-16 16:56:21 +00:00
parent 8fc0356e70
commit 910e44a7d5
49 changed files with 314 additions and 321 deletions

View File

@ -455,6 +455,7 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
DO_STRUCT_DIFFERENCE(Content);
DO_STRUCT_DIFFERENCE(UserInterface);
DO_STRUCT_DIFFERENCE(Visibility);
DO_STRUCT_DIFFERENCE(Outline);
#ifdef MOZ_SVG
DO_STRUCT_DIFFERENCE(SVG);
#endif
@ -489,7 +490,6 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
// UIReset
DO_STRUCT_DIFFERENCE(Color);
DO_STRUCT_DIFFERENCE(Background);
DO_STRUCT_DIFFERENCE(Outline);
DO_STRUCT_DIFFERENCE(UIReset);
#undef DO_STRUCT_DIFFERENCE

View File

@ -640,11 +640,18 @@ nsStyleOutline::RecalcData(void)
nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const
{
if ((mOutlineWidth != aOther.mOutlineWidth) ||
(mOutlineStyle != aOther.mOutlineStyle) ||
PRBool outlineWasVisible =
mCachedOutlineWidth > 0 && mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
PRBool outlineIsVisible =
aOther.mCachedOutlineWidth > 0 && aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
if (outlineWasVisible != outlineIsVisible ||
mOutlineWidth != aOther.mOutlineWidth) {
return NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame);
}
if ((mOutlineStyle != aOther.mOutlineStyle) ||
(mOutlineColor != aOther.mOutlineColor) ||
(mOutlineRadius != aOther.mOutlineRadius)) {
return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816
return nsChangeHint_RepaintFrame;
}
return NS_STYLE_HINT_NONE;
}

View File

@ -2093,39 +2093,17 @@ nscoord width;
}
}
// This if control whether the outline paints on the inside
// or outside of the frame
// XXX This is temporary fix for nsbeta3+ Bug 48973
// so we can use "mozoutline
#if 0 // outside
nsRect inside(aBorderArea);
nsRect outside(inside);
inside.Inflate(width, width);
outside.Inflate(width, width);
nsRect clipRect(aBorderArea);
clipRect.Inflate(width, width); // make clip extra big for now
#else // inside
nsMargin borderWidth;
aBorderStyle.GetBorder(borderWidth);
nsRect outside(aBorderArea);
outside.Deflate(borderWidth);
nsRect inside(outside);
inside.Deflate(width, width);
nsRect clipRect(outside);
#endif
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace);
// rounded version of the border
for(i=0;i<4;i++){
if(borderRadii[i] > 0){
PaintRoundedBorder(aPresContext,aRenderingContext,aForFrame,aDirtyRect,aBorderArea,nsnull,&aOutlineStyle,aStyleContext,aSkipSides,borderRadii,aGap,PR_TRUE);
aRenderingContext.PopState();
return;
}
}
@ -2137,7 +2115,6 @@ nscoord width;
(outlineStyle == NS_STYLE_BORDER_STYLE_DASHED)) {
DrawDashedSides(0, aRenderingContext, aDirtyRect, ourColor, nsnull, &aOutlineStyle, PR_TRUE,
outside, inside, aSkipSides, aGap);
aRenderingContext.PopState();
return;
}
@ -2192,8 +2169,6 @@ nscoord width;
aRenderingContext.SetPenMode(nsPenMode_kNone);
}
}
// Restore clipping
aRenderingContext.PopState();
}
/* draw the edges of the border described in aBorderEdges one segment at a time.

View File

@ -908,7 +908,8 @@ IncrementalReflow::Dispatch(nsIPresContext *aPresContext,
first->SetSize(nsSize(aDesiredSize.width, aDesiredSize.height));
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(), nsnull);
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(),
&aDesiredSize.mOverflowArea);
first->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
}

View File

@ -49,6 +49,7 @@
#include "nsStyleStruct.h"
#include "nsStyleContext.h"
#include "nsIContent.h"
#include "nsHTMLReflowMetrics.h"
/**
* New rules of reflow:
@ -69,7 +70,6 @@
struct nsHTMLReflowState;
class nsHTMLReflowCommand;
struct nsHTMLReflowMetrics;
class nsIAtom;
class nsIPresContext;
@ -1029,7 +1029,18 @@ public:
* @param if nonnull, we record whether this rect is bigger than the frame's bounds
* @return the rect relative to this frame's origin
*/
nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull) const;
nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull, nsSize *aUseSize = nsnull) const;
/**
* Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area
* as a frame property in the frame manager so that it can be retrieved
* later without reflowing the frame.
*/
void FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize);
void FinishAndStoreOverflow(nsHTMLReflowMetrics* aMetrics) {
FinishAndStoreOverflow(&aMetrics->mOverflowArea, nsSize(aMetrics->width, aMetrics->height));
}
/** Selection related calls
*/
@ -1207,8 +1218,7 @@ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::embeddingLevel))
* @param aCreateIfNecessary create a new nsRect for the overflow area
* @return pointer to the overflow area rectangle
*/
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
PRBool aCreateIfNecessary = PR_FALSE) = 0;
nsRect* GetOverflowAreaProperty(PRBool aCreateIfNecessary = PR_FALSE);
/**
* Return PR_TRUE if and only if this frame obeys visibility:hidden.

View File

@ -605,7 +605,8 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext,
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mLegendFrame);
if (mContentFrame)
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mContentFrame);
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
#ifdef NOISY_REFLOW
printf("FIELDSET: w=%d, maxWidth=%d, MEW=%d\n",
aDesiredSize.width, aDesiredSize.mMaximumWidth,

View File

@ -206,7 +206,7 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
// If the frame has visible overflow, then take it into account, too.
if (kidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = kidFrame->GetOverflowAreaProperty();
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
@ -237,7 +237,7 @@ nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext,
// If the frame has visible overflow, then take it into account, too.
if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = f->GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = f->GetOverflowAreaProperty();
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
@ -489,7 +489,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
// the frame
if (aKidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property (creating a rect struct if necessary)
nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(aPresContext, PR_TRUE);
nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(PR_TRUE);
NS_ASSERTION(overflowArea, "should have created rect");
if (overflowArea) {

View File

@ -651,7 +651,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
StoreOverflow(aPresContext, aMetrics);
FinishAndStoreOverflow(&aMetrics);
return NS_OK;
}
@ -911,7 +911,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// Compute our final size
ComputeFinalSize(aReflowState, state, aMetrics);
StoreOverflow(aPresContext, aMetrics);
FinishAndStoreOverflow(&aMetrics);
// see if verifyReflow is enabled, and if so store off the space manager pointer
#ifdef DEBUG
@ -967,7 +967,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
StoreOverflow(aPresContext, aMetrics);
FinishAndStoreOverflow(&aMetrics);
}
// Clear the space manager pointer in the block reflow state so we
// don't waste time translating the coordinate system back on a dead

View File

@ -772,6 +772,7 @@ nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext)
static void RefreshAllContentFrames(nsIFrame* aFrame, nsIContent* aContent)
{
if (aFrame->GetContent() == aContent) {
// XXX is this necessary?
aFrame->Invalidate(aFrame->GetOutlineRect(), PR_FALSE);
}
@ -2506,11 +2507,15 @@ nsIFrame::Invalidate(const nsRect& aDamageRect,
}
nsRect
nsIFrame::GetOutlineRect(PRBool* aAnyOutline) const
nsIFrame::GetOutlineRect(PRBool* aAnyOutline, nsSize *aUseSize) const
{
const nsStyleOutline* outline = GetStyleOutline();
PRUint8 outlineStyle = outline->GetOutlineStyle();
nsRect r(0, 0, mRect.width, mRect.height);
if (aUseSize) {
r.width = aUseSize->width;
r.height = aUseSize->height;
}
PRBool anyOutline = PR_FALSE;
if (outlineStyle != NS_STYLE_BORDER_STYLE_NONE) {
nscoord width;
@ -2550,11 +2555,6 @@ nsFrame::CheckInvalidateSizeChange(nsIPresContext* aPresContext,
// invalidated)
// Invalidate the entire old frame+outline if the frame has an outline
// This assumes 'outline' is painted outside the element, as CSS2 requires.
// Currently we actually paint 'outline' inside the element so this code
// isn't strictly necessary. But we're trying to get ready to switch to
// CSS2 compliance.
PRBool anyOutline;
nsRect r = GetOutlineRect(&anyOutline);
if (anyOutline) {
@ -4219,14 +4219,13 @@ DestroyRectFunc(nsIPresContext* aPresContext,
}
nsRect*
nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext,
PRBool aCreateIfNecessary)
nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary)
{
if (!((GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) || aCreateIfNecessary)) {
return nsnull;
}
nsFrameManager *frameManager = aPresContext->FrameManager();
nsFrameManager *frameManager = GetPresContext()->FrameManager();
void *value =
frameManager->GetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty,
@ -4248,24 +4247,32 @@ nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext,
}
void
nsFrame::StoreOverflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics)
{
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
nsIFrame::FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize)
{
// This is now called FinishAndStoreOverflow() instead of
// StoreOverflow() because frame-generic ways of adding overflow
// can happen here, e.g. CSS2 outline.
// If we find more things other than outline that need to be added,
// we should think about starting a new method like GetAdditionalOverflow()
PRBool hasOutline;
nsRect outlineRect(GetOutlineRect(&hasOutline, &aNewSize));
if (hasOutline ||
(aOverflowArea->x < 0) ||
(aOverflowArea->y < 0) ||
(aOverflowArea->XMost() > aNewSize.width) ||
(aOverflowArea->YMost() > aNewSize.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
nsRect* overflowArea = GetOverflowAreaProperty(aPresContext, PR_TRUE);
nsRect* overflowArea = GetOverflowAreaProperty(PR_TRUE);
NS_ASSERTION(overflowArea, "should have created rect");
if (overflowArea) {
*overflowArea = aMetrics.mOverflowArea;
}
aOverflowArea->UnionRect(outlineRect, *aOverflowArea);
*overflowArea = *aOverflowArea;
}
else {
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
// remove the previously stored overflow area
aPresContext->FrameManager()->
GetPresContext()->FrameManager()->
RemoveFrameProperty(this, nsLayoutAtoms::overflowAreaProperty);
}
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
@ -4282,7 +4289,7 @@ nsFrame::ConsiderChildOverflow(nsIPresContext* aPresContext,
// don't wrap their content into a scrollable frame if overflow is specified
if (NS_STYLE_OVERFLOW_HIDDEN != disp->mOverflow &&
NS_STYLE_OVERFLOW_SCROLLBARS_NONE != disp->mOverflow) {
nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty();
if (overflowArea) {
nsRect childOverflow(*overflowArea);
childOverflow.MoveBy(aChildFrame->GetPosition());
@ -5336,7 +5343,7 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext,
DR_state->PrettyUC(aMetrics.mOverflowArea.width, width);
DR_state->PrettyUC(aMetrics.mOverflowArea.height, height);
printf("o=(%s,%s) %s x %s", x, y, width, height);
nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(aPresContext);
nsRect* storedOverflow = aFrame->GetOverflowAreaProperty();
if (storedOverflow) {
if (aMetrics.mOverflowArea != *storedOverflow) {
DR_state->PrettyUC(storedOverflow->x, x);

View File

@ -366,17 +366,6 @@ public:
nsIFrame** aProviderFrame,
PRBool* aIsChild);
// Return the previously stored overflow area, if the frame does not
// overflow and a creation is not requested it will return nsnull
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
PRBool aCreateIfNecessary = PR_FALSE);
// Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area
// as a frame property in the frame manager so that it can be retrieved
// later without reflowing the frame.
void StoreOverflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics);
// incorporate the child overflow area into the parent overflow area
// if the child does not have a overflow use the child area
void ConsiderChildOverflow(nsIPresContext* aPresContext,

View File

@ -49,6 +49,7 @@
#include "nsStyleStruct.h"
#include "nsStyleContext.h"
#include "nsIContent.h"
#include "nsHTMLReflowMetrics.h"
/**
* New rules of reflow:
@ -69,7 +70,6 @@
struct nsHTMLReflowState;
class nsHTMLReflowCommand;
struct nsHTMLReflowMetrics;
class nsIAtom;
class nsIPresContext;
@ -1029,7 +1029,18 @@ public:
* @param if nonnull, we record whether this rect is bigger than the frame's bounds
* @return the rect relative to this frame's origin
*/
nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull) const;
nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull, nsSize *aUseSize = nsnull) const;
/**
* Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area
* as a frame property in the frame manager so that it can be retrieved
* later without reflowing the frame.
*/
void FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize);
void FinishAndStoreOverflow(nsHTMLReflowMetrics* aMetrics) {
FinishAndStoreOverflow(&aMetrics->mOverflowArea, nsSize(aMetrics->width, aMetrics->height));
}
/** Selection related calls
*/
@ -1207,8 +1218,7 @@ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::embeddingLevel))
* @param aCreateIfNecessary create a new nsRect for the overflow area
* @return pointer to the overflow area rectangle
*/
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
PRBool aCreateIfNecessary = PR_FALSE) = 0;
nsRect* GetOverflowAreaProperty(PRBool aCreateIfNecessary = PR_FALSE);
/**
* Return PR_TRUE if and only if this frame obeys visibility:hidden.

View File

@ -1012,6 +1012,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext,
if (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH) {
aMetrics.mMaximumWidth = aMetrics.width;
}
FinishAndStoreOverflow(&aMetrics);
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
("exit nsImageFrame::Reflow: size=%d,%d",
@ -1331,7 +1332,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
}
}
else {
PRBool paintOutline = PR_FALSE;
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer && imgCon) {
// Render the image into our content area (the area inside
// the borders and padding)
@ -1383,7 +1383,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
aRenderingContext.DrawImage(imgCon, r, paintArea);
}
paintOutline = PR_TRUE;
}
nsImageMap* map = GetImageMap(aPresContext);
@ -1396,18 +1395,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
aRenderingContext.Translate(inner.x, inner.y);
map->Draw(aPresContext, aRenderingContext);
aRenderingContext.PopState();
paintOutline = PR_TRUE;
}
// paint the outline in the overlay layer (or if there is an image map) until the
// general problem of painting it outside the border box is solved.
if (paintOutline) {
const nsStyleBorder* myBorder = GetStyleBorder();
const nsStyleOutline* myOutline = GetStyleOutline();
nsRect rect(0, 0, mRect.width, mRect.height);
nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *myBorder,
*myOutline, mStyleContext, 0);
}
#ifdef DEBUG

View File

@ -1256,15 +1256,7 @@ 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;
}
FinishAndStoreOverflow(&aDesiredSize);
return rv;
}
}
@ -1302,15 +1294,7 @@ 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;
}
FinishAndStoreOverflow(&aDesiredSize);
}
return rv;

View File

@ -3008,21 +3008,14 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
combinedAreaResult.UnionRect(combinedAreaResult, *r + origin);
}
aCombinedArea = combinedAreaResult;
// If we just computed a spans combined area, we need to update its
// NS_FRAME_OUTSIDE_CHILDREN bit..
if (psd->mFrame) {
PerFrameData* spanPFD = psd->mFrame;
nsIFrame* frame = spanPFD->mFrame;
if ((combinedAreaResult.x < 0) || (combinedAreaResult.y < 0) ||
(combinedAreaResult.XMost() > spanPFD->mBounds.width) ||
(combinedAreaResult.YMost() > spanPFD->mBounds.height)) {
frame->AddStateBits(NS_FRAME_OUTSIDE_CHILDREN);
} else {
frame->RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN);
}
frame->FinishAndStoreOverflow(&combinedAreaResult, frame->GetSize());
}
aCombinedArea = combinedAreaResult;
}
void

View File

@ -206,7 +206,7 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame,
// If the frame has visible overflow, then take it into account, too.
if (kidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = kidFrame->GetOverflowAreaProperty();
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
@ -237,7 +237,7 @@ nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext,
// If the frame has visible overflow, then take it into account, too.
if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property
nsRect* overflowArea = f->GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = f->GetOverflowAreaProperty();
if (overflowArea) {
// The overflow area is in the child's coordinate space, so translate
@ -489,7 +489,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat
// the frame
if (aKidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
// Get the property (creating a rect struct if necessary)
nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(aPresContext, PR_TRUE);
nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(PR_TRUE);
NS_ASSERTION(overflowArea, "should have created rect");
if (overflowArea) {

View File

@ -651,7 +651,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds);
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
StoreOverflow(aPresContext, aMetrics);
FinishAndStoreOverflow(&aMetrics);
return NS_OK;
}
@ -911,7 +911,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// Compute our final size
ComputeFinalSize(aReflowState, state, aMetrics);
StoreOverflow(aPresContext, aMetrics);
FinishAndStoreOverflow(&aMetrics);
// see if verifyReflow is enabled, and if so store off the space manager pointer
#ifdef DEBUG
@ -967,7 +967,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
// Factor the absolutely positioned child bounds into the overflow area
aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds);
StoreOverflow(aPresContext, aMetrics);
FinishAndStoreOverflow(&aMetrics);
}
// Clear the space manager pointer in the block reflow state so we
// don't waste time translating the coordinate system back on a dead

View File

@ -772,6 +772,7 @@ nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext)
static void RefreshAllContentFrames(nsIFrame* aFrame, nsIContent* aContent)
{
if (aFrame->GetContent() == aContent) {
// XXX is this necessary?
aFrame->Invalidate(aFrame->GetOutlineRect(), PR_FALSE);
}
@ -2506,11 +2507,15 @@ nsIFrame::Invalidate(const nsRect& aDamageRect,
}
nsRect
nsIFrame::GetOutlineRect(PRBool* aAnyOutline) const
nsIFrame::GetOutlineRect(PRBool* aAnyOutline, nsSize *aUseSize) const
{
const nsStyleOutline* outline = GetStyleOutline();
PRUint8 outlineStyle = outline->GetOutlineStyle();
nsRect r(0, 0, mRect.width, mRect.height);
if (aUseSize) {
r.width = aUseSize->width;
r.height = aUseSize->height;
}
PRBool anyOutline = PR_FALSE;
if (outlineStyle != NS_STYLE_BORDER_STYLE_NONE) {
nscoord width;
@ -2550,11 +2555,6 @@ nsFrame::CheckInvalidateSizeChange(nsIPresContext* aPresContext,
// invalidated)
// Invalidate the entire old frame+outline if the frame has an outline
// This assumes 'outline' is painted outside the element, as CSS2 requires.
// Currently we actually paint 'outline' inside the element so this code
// isn't strictly necessary. But we're trying to get ready to switch to
// CSS2 compliance.
PRBool anyOutline;
nsRect r = GetOutlineRect(&anyOutline);
if (anyOutline) {
@ -4219,14 +4219,13 @@ DestroyRectFunc(nsIPresContext* aPresContext,
}
nsRect*
nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext,
PRBool aCreateIfNecessary)
nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary)
{
if (!((GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) || aCreateIfNecessary)) {
return nsnull;
}
nsFrameManager *frameManager = aPresContext->FrameManager();
nsFrameManager *frameManager = GetPresContext()->FrameManager();
void *value =
frameManager->GetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty,
@ -4248,24 +4247,32 @@ nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext,
}
void
nsFrame::StoreOverflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics)
{
if ((aMetrics.mOverflowArea.x < 0) ||
(aMetrics.mOverflowArea.y < 0) ||
(aMetrics.mOverflowArea.XMost() > aMetrics.width) ||
(aMetrics.mOverflowArea.YMost() > aMetrics.height)) {
nsIFrame::FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize)
{
// This is now called FinishAndStoreOverflow() instead of
// StoreOverflow() because frame-generic ways of adding overflow
// can happen here, e.g. CSS2 outline.
// If we find more things other than outline that need to be added,
// we should think about starting a new method like GetAdditionalOverflow()
PRBool hasOutline;
nsRect outlineRect(GetOutlineRect(&hasOutline, &aNewSize));
if (hasOutline ||
(aOverflowArea->x < 0) ||
(aOverflowArea->y < 0) ||
(aOverflowArea->XMost() > aNewSize.width) ||
(aOverflowArea->YMost() > aNewSize.height)) {
mState |= NS_FRAME_OUTSIDE_CHILDREN;
nsRect* overflowArea = GetOverflowAreaProperty(aPresContext, PR_TRUE);
nsRect* overflowArea = GetOverflowAreaProperty(PR_TRUE);
NS_ASSERTION(overflowArea, "should have created rect");
if (overflowArea) {
*overflowArea = aMetrics.mOverflowArea;
}
aOverflowArea->UnionRect(outlineRect, *aOverflowArea);
*overflowArea = *aOverflowArea;
}
else {
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
// remove the previously stored overflow area
aPresContext->FrameManager()->
GetPresContext()->FrameManager()->
RemoveFrameProperty(this, nsLayoutAtoms::overflowAreaProperty);
}
mState &= ~NS_FRAME_OUTSIDE_CHILDREN;
@ -4282,7 +4289,7 @@ nsFrame::ConsiderChildOverflow(nsIPresContext* aPresContext,
// don't wrap their content into a scrollable frame if overflow is specified
if (NS_STYLE_OVERFLOW_HIDDEN != disp->mOverflow &&
NS_STYLE_OVERFLOW_SCROLLBARS_NONE != disp->mOverflow) {
nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty();
if (overflowArea) {
nsRect childOverflow(*overflowArea);
childOverflow.MoveBy(aChildFrame->GetPosition());
@ -5336,7 +5343,7 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext,
DR_state->PrettyUC(aMetrics.mOverflowArea.width, width);
DR_state->PrettyUC(aMetrics.mOverflowArea.height, height);
printf("o=(%s,%s) %s x %s", x, y, width, height);
nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(aPresContext);
nsRect* storedOverflow = aFrame->GetOverflowAreaProperty();
if (storedOverflow) {
if (aMetrics.mOverflowArea != *storedOverflow) {
DR_state->PrettyUC(storedOverflow->x, x);

View File

@ -366,17 +366,6 @@ public:
nsIFrame** aProviderFrame,
PRBool* aIsChild);
// Return the previously stored overflow area, if the frame does not
// overflow and a creation is not requested it will return nsnull
virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext,
PRBool aCreateIfNecessary = PR_FALSE);
// Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area
// as a frame property in the frame manager so that it can be retrieved
// later without reflowing the frame.
void StoreOverflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aMetrics);
// incorporate the child overflow area into the parent overflow area
// if the child does not have a overflow use the child area
void ConsiderChildOverflow(nsIPresContext* aPresContext,

View File

@ -1012,6 +1012,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext,
if (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH) {
aMetrics.mMaximumWidth = aMetrics.width;
}
FinishAndStoreOverflow(&aMetrics);
NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
("exit nsImageFrame::Reflow: size=%d,%d",
@ -1331,7 +1332,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
}
}
else {
PRBool paintOutline = PR_FALSE;
if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer && imgCon) {
// Render the image into our content area (the area inside
// the borders and padding)
@ -1383,7 +1383,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
aRenderingContext.DrawImage(imgCon, r, paintArea);
}
paintOutline = PR_TRUE;
}
nsImageMap* map = GetImageMap(aPresContext);
@ -1396,18 +1395,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext,
aRenderingContext.Translate(inner.x, inner.y);
map->Draw(aPresContext, aRenderingContext);
aRenderingContext.PopState();
paintOutline = PR_TRUE;
}
// paint the outline in the overlay layer (or if there is an image map) until the
// general problem of painting it outside the border box is solved.
if (paintOutline) {
const nsStyleBorder* myBorder = GetStyleBorder();
const nsStyleOutline* myOutline = GetStyleOutline();
nsRect rect(0, 0, mRect.width, mRect.height);
nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this,
aDirtyRect, rect, *myBorder,
*myOutline, mStyleContext, 0);
}
#ifdef DEBUG

View File

@ -1256,15 +1256,7 @@ 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;
}
FinishAndStoreOverflow(&aDesiredSize);
return rv;
}
}
@ -1302,15 +1294,7 @@ 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;
}
FinishAndStoreOverflow(&aDesiredSize);
}
return rv;

View File

@ -3008,21 +3008,14 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea)
combinedAreaResult.UnionRect(combinedAreaResult, *r + origin);
}
aCombinedArea = combinedAreaResult;
// If we just computed a spans combined area, we need to update its
// NS_FRAME_OUTSIDE_CHILDREN bit..
if (psd->mFrame) {
PerFrameData* spanPFD = psd->mFrame;
nsIFrame* frame = spanPFD->mFrame;
if ((combinedAreaResult.x < 0) || (combinedAreaResult.y < 0) ||
(combinedAreaResult.XMost() > spanPFD->mBounds.width) ||
(combinedAreaResult.YMost() > spanPFD->mBounds.height)) {
frame->AddStateBits(NS_FRAME_OUTSIDE_CHILDREN);
} else {
frame->RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN);
}
frame->FinishAndStoreOverflow(&combinedAreaResult, frame->GetSize());
}
aCombinedArea = combinedAreaResult;
}
void

View File

@ -908,7 +908,8 @@ IncrementalReflow::Dispatch(nsIPresContext *aPresContext,
first->SetSize(nsSize(aDesiredSize.width, aDesiredSize.height));
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(), nsnull);
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(),
&aDesiredSize.mOverflowArea);
first->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED);
}

View File

@ -605,7 +605,8 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext,
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mLegendFrame);
if (mContentFrame)
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mContentFrame);
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
#ifdef NOISY_REFLOW
printf("FIELDSET: w=%d, maxWidth=%d, MEW=%d\n",
aDesiredSize.width, aDesiredSize.mMaximumWidth,

View File

@ -2093,39 +2093,17 @@ nscoord width;
}
}
// This if control whether the outline paints on the inside
// or outside of the frame
// XXX This is temporary fix for nsbeta3+ Bug 48973
// so we can use "mozoutline
#if 0 // outside
nsRect inside(aBorderArea);
nsRect outside(inside);
inside.Inflate(width, width);
outside.Inflate(width, width);
nsRect clipRect(aBorderArea);
clipRect.Inflate(width, width); // make clip extra big for now
#else // inside
nsMargin borderWidth;
aBorderStyle.GetBorder(borderWidth);
nsRect outside(aBorderArea);
outside.Deflate(borderWidth);
nsRect inside(outside);
inside.Deflate(width, width);
nsRect clipRect(outside);
#endif
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace);
// rounded version of the border
for(i=0;i<4;i++){
if(borderRadii[i] > 0){
PaintRoundedBorder(aPresContext,aRenderingContext,aForFrame,aDirtyRect,aBorderArea,nsnull,&aOutlineStyle,aStyleContext,aSkipSides,borderRadii,aGap,PR_TRUE);
aRenderingContext.PopState();
return;
}
}
@ -2137,7 +2115,6 @@ nscoord width;
(outlineStyle == NS_STYLE_BORDER_STYLE_DASHED)) {
DrawDashedSides(0, aRenderingContext, aDirtyRect, ourColor, nsnull, &aOutlineStyle, PR_TRUE,
outside, inside, aSkipSides, aGap);
aRenderingContext.PopState();
return;
}
@ -2192,8 +2169,6 @@ nscoord width;
aRenderingContext.SetPenMode(nsPenMode_kNone);
}
}
// Restore clipping
aRenderingContext.PopState();
}
/* draw the edges of the border described in aBorderEdges one segment at a time.

View File

@ -598,7 +598,7 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex
desiredSize.height = mRect.height;
desiredSize.mOverflowArea = nsRect(0, 0, mRect.width, mRect.height);
ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, firstKid);
StoreOverflow(aPresContext, desiredSize);
FinishAndStoreOverflow(&desiredSize);
if (kidYTop != kidRect.y) {
// Make sure any child views are correctly positioned. We know the inner table
// cell won't have a view

View File

@ -2098,20 +2098,20 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
nsRect damage(0, 0, PR_MAX(mRect.width, aDesiredSize.width),
PR_MAX(mRect.height, aDesiredSize.height));
damage.UnionRect(damage, aDesiredSize.mOverflowArea);
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
if (oldOverflowArea) {
damage.UnionRect(damage, *oldOverflowArea);
}
Invalidate(damage);
} else {
// use the old overflow area
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
if (oldOverflowArea) {
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, *oldOverflowArea);
}
}
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return rv;
}
@ -3007,7 +3007,8 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) {
ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, kidFrame);
}
StoreOverflow(aPresContext, desiredSize);
FinishAndStoreOverflow(&desiredSize.mOverflowArea,
nsSize(desiredSize.width, desiredSize.height));
}
return rv;
}
@ -3489,13 +3490,15 @@ void ResizeCells(nsTableFrame& aTableFrame,
rgFrame->ConsiderChildOverflow(aPresContext, groupDesiredSize.mOverflowArea, rowFrame);
rowFrame = rowFrame->GetNextRow();
}
rgFrame->StoreOverflow(aPresContext, groupDesiredSize);
rgFrame->FinishAndStoreOverflow(&groupDesiredSize.mOverflowArea,
nsSize(groupDesiredSize.width, groupDesiredSize.height));
// make the coordinates of |desiredSize.mOverflowArea| incorrect
// since it's about to go away:
groupDesiredSize.mOverflowArea.MoveBy(rgFrame->GetPosition());
tableDesiredSize.mOverflowArea.UnionRect(tableDesiredSize.mOverflowArea, groupDesiredSize.mOverflowArea);
}
aTableFrame.StoreOverflow(aPresContext, tableDesiredSize);
aTableFrame.FinishAndStoreOverflow(&tableDesiredSize.mOverflowArea,
nsSize(tableDesiredSize.width, tableDesiredSize.height));
}
void

View File

@ -556,7 +556,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext,
if (aOldOverflowArea) {
damage.UnionRect(damage, *aOldOverflowArea);
}
nsRect* overflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = GetOverflowAreaProperty();
if (overflowArea) {
damage.UnionRect(damage, *overflowArea);
}
@ -1370,7 +1370,7 @@ nsTableOuterFrame::UpdateReflowMetrics(nsIPresContext* aPresContext,
if (mCaptionFrame) {
ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mCaptionFrame);
}
StoreOverflow(aPresContext, aMet);
FinishAndStoreOverflow(&aMet);
}
nsresult
@ -1541,7 +1541,7 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex
rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet,
captionOrigin.x, captionOrigin.y, 0);
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
nsRect* overflowStorage = nsnull;
nsRect overflow;
if (oldOverflowArea) {
@ -1599,7 +1599,7 @@ nsTableOuterFrame::IR_ReflowDirty(nsIPresContext* aPresContext,
aDesiredSize.height = innerRect.YMost() + innerMargin.bottom;
sizeSet = PR_TRUE;
// Repaint the inner's entire bounds if it moved
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
PRBool innerMoved = (innerRect.x != innerOrigin.x) ||
(innerRect.y != innerOrigin.y);
nsSize desSize(aDesiredSize.width, aDesiredSize.height);
@ -1763,7 +1763,7 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext,
if (aOuterMet.mComputeMEW) {
aOuterMet.mMaxElementWidth = innerMet.mMaxElementWidth;
}
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
nsRect* overflowStorage = nsnull;
nsRect overflow;
if (oldOverflowArea) {
@ -1854,7 +1854,7 @@ nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresContext,
rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet,
captionOrigin.x, captionOrigin.y, 0);
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
nsRect* overflowStorage = nsnull;
nsRect overflow;
if (oldOverflowArea) {

View File

@ -398,7 +398,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
// Get the next child
childFrame = iter.Next();
}
StoreOverflow(aPresContext, desiredSize);
FinishAndStoreOverflow(&desiredSize);
if (HasView()) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, this, GetView(), &desiredSize.mOverflowArea, 0);
}
@ -985,7 +985,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
desiredSize.width = cellDesiredSize.width;
desiredSize.height = cellDesiredSize.height;
nsRect *overflowArea =
cellFrame->GetOverflowAreaProperty(aPresContext);
cellFrame->GetOverflowAreaProperty();
if (overflowArea)
desiredSize.mOverflowArea = *overflowArea;
else
@ -1084,7 +1084,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
}
nsRect rowRect(0, 0, aDesiredSize.width, aDesiredSize.height);
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, rowRect);
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
return rv;
}
@ -1318,7 +1318,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
nsIFrame* cellKidFrame = cellFrame->GetFirstChild(nsnull);
if (cellKidFrame) {
cellFrame->ConsiderChildOverflow(aPresContext, cellMet.mOverflowArea, cellKidFrame);
cellFrame->StoreOverflow(aPresContext, cellMet);
cellFrame->FinishAndStoreOverflow(&cellMet);
if (cellFrame->HasView()) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, cellFrame, cellFrame->GetView(), &cellMet.mOverflowArea, 0);
}
@ -1335,7 +1335,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
for (nsIFrame* cell = mFrames.FirstChild(); cell; cell = cell->GetNextSibling()) {
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, cell);
}
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
// When returning whether we're complete we need to look at each of our cell
// frames. If any of them has a continuing frame, then we're not complete. We
// can't just return the status of the cell frame we just reflowed...

View File

@ -1273,7 +1273,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, nsRect(0, 0, aDesiredSize.width,
aDesiredSize.height));
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
#if defined DEBUG_TABLE_REFLOW_TIMING
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
#endif
@ -1698,7 +1698,7 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, rowFrame);
}
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
}
}

View File

@ -176,6 +176,15 @@ printf("\n");
aDesiredSize.mMaxElementWidth = childDesiredSize.mMaxElementWidth;
}
FinishAndStoreOverflow(&aDesiredSize);
// Act as if there is overflow no matter what. This is a
// safety measure to cater for math fonts with metrics that sometimes
// cause glyphs in the text frames to protrude outside. Without this,
// such glyphs may be clipped at the painting stage
// This flag has already been set on the children as well in
// SetInitialChildList()
mState |= NS_FRAME_OUTSIDE_CHILDREN;
// cache the frame's mBoundingMetrics
mBoundingMetrics = aDesiredSize.mBoundingMetrics;

View File

@ -471,15 +471,7 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext,
mReference.x = 0;
mReference.y = aDesiredSize.ascent;
// If we have tweaked things so that our children now stick outside,
// we need to update our NS_FRAME_OUTSIDE_CHILDREN bit
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;
FinishAndStoreOverflow(&aDesiredSize);
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return NS_OK;

View File

@ -455,6 +455,7 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
DO_STRUCT_DIFFERENCE(Content);
DO_STRUCT_DIFFERENCE(UserInterface);
DO_STRUCT_DIFFERENCE(Visibility);
DO_STRUCT_DIFFERENCE(Outline);
#ifdef MOZ_SVG
DO_STRUCT_DIFFERENCE(SVG);
#endif
@ -489,7 +490,6 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther)
// UIReset
DO_STRUCT_DIFFERENCE(Color);
DO_STRUCT_DIFFERENCE(Background);
DO_STRUCT_DIFFERENCE(Outline);
DO_STRUCT_DIFFERENCE(UIReset);
#undef DO_STRUCT_DIFFERENCE

View File

@ -640,11 +640,18 @@ nsStyleOutline::RecalcData(void)
nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const
{
if ((mOutlineWidth != aOther.mOutlineWidth) ||
(mOutlineStyle != aOther.mOutlineStyle) ||
PRBool outlineWasVisible =
mCachedOutlineWidth > 0 && mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
PRBool outlineIsVisible =
aOther.mCachedOutlineWidth > 0 && aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE;
if (outlineWasVisible != outlineIsVisible ||
mOutlineWidth != aOther.mOutlineWidth) {
return NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame);
}
if ((mOutlineStyle != aOther.mOutlineStyle) ||
(mOutlineColor != aOther.mOutlineColor) ||
(mOutlineRadius != aOther.mOutlineRadius)) {
return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816
return nsChangeHint_RepaintFrame;
}
return NS_STYLE_HINT_NONE;
}

View File

@ -598,7 +598,7 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex
desiredSize.height = mRect.height;
desiredSize.mOverflowArea = nsRect(0, 0, mRect.width, mRect.height);
ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, firstKid);
StoreOverflow(aPresContext, desiredSize);
FinishAndStoreOverflow(&desiredSize);
if (kidYTop != kidRect.y) {
// Make sure any child views are correctly positioned. We know the inner table
// cell won't have a view

View File

@ -2098,20 +2098,20 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
nsRect damage(0, 0, PR_MAX(mRect.width, aDesiredSize.width),
PR_MAX(mRect.height, aDesiredSize.height));
damage.UnionRect(damage, aDesiredSize.mOverflowArea);
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
if (oldOverflowArea) {
damage.UnionRect(damage, *oldOverflowArea);
}
Invalidate(damage);
} else {
// use the old overflow area
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
if (oldOverflowArea) {
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, *oldOverflowArea);
}
}
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
return rv;
}
@ -3007,7 +3007,8 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) {
ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, kidFrame);
}
StoreOverflow(aPresContext, desiredSize);
FinishAndStoreOverflow(&desiredSize.mOverflowArea,
nsSize(desiredSize.width, desiredSize.height));
}
return rv;
}
@ -3489,13 +3490,15 @@ void ResizeCells(nsTableFrame& aTableFrame,
rgFrame->ConsiderChildOverflow(aPresContext, groupDesiredSize.mOverflowArea, rowFrame);
rowFrame = rowFrame->GetNextRow();
}
rgFrame->StoreOverflow(aPresContext, groupDesiredSize);
rgFrame->FinishAndStoreOverflow(&groupDesiredSize.mOverflowArea,
nsSize(groupDesiredSize.width, groupDesiredSize.height));
// make the coordinates of |desiredSize.mOverflowArea| incorrect
// since it's about to go away:
groupDesiredSize.mOverflowArea.MoveBy(rgFrame->GetPosition());
tableDesiredSize.mOverflowArea.UnionRect(tableDesiredSize.mOverflowArea, groupDesiredSize.mOverflowArea);
}
aTableFrame.StoreOverflow(aPresContext, tableDesiredSize);
aTableFrame.FinishAndStoreOverflow(&tableDesiredSize.mOverflowArea,
nsSize(tableDesiredSize.width, tableDesiredSize.height));
}
void

View File

@ -556,7 +556,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext,
if (aOldOverflowArea) {
damage.UnionRect(damage, *aOldOverflowArea);
}
nsRect* overflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* overflowArea = GetOverflowAreaProperty();
if (overflowArea) {
damage.UnionRect(damage, *overflowArea);
}
@ -1370,7 +1370,7 @@ nsTableOuterFrame::UpdateReflowMetrics(nsIPresContext* aPresContext,
if (mCaptionFrame) {
ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mCaptionFrame);
}
StoreOverflow(aPresContext, aMet);
FinishAndStoreOverflow(&aMet);
}
nsresult
@ -1541,7 +1541,7 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex
rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet,
captionOrigin.x, captionOrigin.y, 0);
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
nsRect* overflowStorage = nsnull;
nsRect overflow;
if (oldOverflowArea) {
@ -1599,7 +1599,7 @@ nsTableOuterFrame::IR_ReflowDirty(nsIPresContext* aPresContext,
aDesiredSize.height = innerRect.YMost() + innerMargin.bottom;
sizeSet = PR_TRUE;
// Repaint the inner's entire bounds if it moved
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
PRBool innerMoved = (innerRect.x != innerOrigin.x) ||
(innerRect.y != innerOrigin.y);
nsSize desSize(aDesiredSize.width, aDesiredSize.height);
@ -1763,7 +1763,7 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext,
if (aOuterMet.mComputeMEW) {
aOuterMet.mMaxElementWidth = innerMet.mMaxElementWidth;
}
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
nsRect* overflowStorage = nsnull;
nsRect overflow;
if (oldOverflowArea) {
@ -1854,7 +1854,7 @@ nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresContext,
rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet,
captionOrigin.x, captionOrigin.y, 0);
nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext);
nsRect* oldOverflowArea = GetOverflowAreaProperty();
nsRect* overflowStorage = nsnull;
nsRect overflow;
if (oldOverflowArea) {

View File

@ -398,7 +398,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
// Get the next child
childFrame = iter.Next();
}
StoreOverflow(aPresContext, desiredSize);
FinishAndStoreOverflow(&desiredSize);
if (HasView()) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, this, GetView(), &desiredSize.mOverflowArea, 0);
}
@ -985,7 +985,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
desiredSize.width = cellDesiredSize.width;
desiredSize.height = cellDesiredSize.height;
nsRect *overflowArea =
cellFrame->GetOverflowAreaProperty(aPresContext);
cellFrame->GetOverflowAreaProperty();
if (overflowArea)
desiredSize.mOverflowArea = *overflowArea;
else
@ -1084,7 +1084,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext,
}
nsRect rowRect(0, 0, aDesiredSize.width, aDesiredSize.height);
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, rowRect);
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
return rv;
}
@ -1318,7 +1318,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
nsIFrame* cellKidFrame = cellFrame->GetFirstChild(nsnull);
if (cellKidFrame) {
cellFrame->ConsiderChildOverflow(aPresContext, cellMet.mOverflowArea, cellKidFrame);
cellFrame->StoreOverflow(aPresContext, cellMet);
cellFrame->FinishAndStoreOverflow(&cellMet);
if (cellFrame->HasView()) {
nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, cellFrame, cellFrame->GetView(), &cellMet.mOverflowArea, 0);
}
@ -1335,7 +1335,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
for (nsIFrame* cell = mFrames.FirstChild(); cell; cell = cell->GetNextSibling()) {
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, cell);
}
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
// When returning whether we're complete we need to look at each of our cell
// frames. If any of them has a continuing frame, then we're not complete. We
// can't just return the status of the cell frame we just reflowed...

View File

@ -1273,7 +1273,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, nsRect(0, 0, aDesiredSize.width,
aDesiredSize.height));
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
#if defined DEBUG_TABLE_REFLOW_TIMING
nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus);
#endif
@ -1698,7 +1698,7 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, rowFrame);
}
StoreOverflow(aPresContext, aDesiredSize);
FinishAndStoreOverflow(&aDesiredSize);
}
}

View File

@ -49,6 +49,8 @@
#include "nsHTMLContainerFrame.h"
#include "nsINameSpaceManager.h"
#include "nsHTMLAtoms.h"
#include "nsFrameManager.h"
#include "nsLayoutAtoms.h"
#include "nsXULAtoms.h"
#include "nsIDOMNode.h"
#include "nsIDOMNamedNodeMap.h"
@ -540,7 +542,7 @@ nsBox::GetBounds(nsRect& aRect)
}
NS_IMETHODIMP
nsBox::SetBounds(nsBoxLayoutState& aState, const nsRect& aRect)
nsBox::SetBounds(nsBoxLayoutState& aState, const nsRect& aRect, PRBool aRemoveOverflowArea)
{
NS_BOX_ASSERTION(this, aRect.width >=0 && aRect.height >= 0, "SetBounds Size < 0");
@ -564,7 +566,15 @@ nsBox::SetBounds(nsBoxLayoutState& aState, const nsRect& aRect)
else
frame->SetRect(aRect);
// Nuke the overflow area. The caller is responsible for restoring
// it if necessary.
if (aRemoveOverflowArea && (frame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN)) {
// remove the previously stored overflow area
frame->GetPresContext()->FrameManager()->
RemoveFrameProperty(frame, nsLayoutAtoms::overflowAreaProperty);
frame->RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN);
}
if (!(flags & NS_FRAME_NO_MOVE_VIEW))
{
nsContainerFrame::PositionFrameView(presContext, frame);
@ -773,7 +783,7 @@ nsBox::Collapse(nsBoxLayoutState& aState)
SetWasCollapsed(aState, PR_TRUE);
nsIFrame* frame;
GetFrame(&frame);
SetBounds(aState, nsRect(0,0,0,0));
SetBounds(aState, nsRect(0,0,0,0), PR_TRUE);
return CollapseChild(aState, frame, PR_TRUE);
}
@ -1025,8 +1035,6 @@ nsBox::SyncLayout(nsBoxLayoutState& aState)
| NS_FRAME_FIRST_REFLOW | NS_FRAME_IN_REFLOW);
nsIPresContext* presContext = aState.PresContext();
nsRect rect(0,0,0,0);
GetBounds(rect);
PRUint32 flags = 0;
GetLayoutFlags(flags);
@ -1035,21 +1043,48 @@ nsBox::SyncLayout(nsBoxLayoutState& aState)
flags |= stateFlags;
nsIView* view = frame->GetView();
nsRect rect(nsPoint(0, 0), frame->GetSize());
/*
// only if the origin changed
if ((mX != rect.x) || (mY != rect.y)) {
if (view) {
nsContainerFrame::PositionFrameView(presContext, frame, view);
} else
nsContainerFrame::PositionChildViews(presContext, frame);
mX = rect.x;
mY = rect.y;
if (ComputesOwnOverflowArea()) {
if (frame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
nsRect* overflow = frame->GetOverflowAreaProperty();
NS_ASSERTION(overflow, "should have overflow area property");
rect = *overflow;
}
*/
} else {
if (!DoesClipChildren()) {
// See if our child frames caused us to overflow after being laid
// out. If so, store the overflow area. This normally can't happen
// in XUL, but it can happen with the CSS 'outline' property and
// possibly with other exotic stuff (e.g. relatively positioned
// frames in HTML inside XUL).
nsIBox* box;
GetChildBox(&box);
while (box)
{
nsIFrame* f = nsnull;
box->GetFrame(&f);
if (f) {
nsRect bounds;
if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) {
nsRect* overflowArea = f->GetOverflowAreaProperty();
NS_ASSERTION(overflowArea, "Should have created property for overflowing frame");
bounds = *overflowArea + f->GetPosition();
} else {
bounds = f->GetRect();
}
rect.UnionRect(rect, bounds);
}
box->GetNextBox(&box);
}
}
frame->FinishAndStoreOverflow(&rect, frame->GetSize());
}
nsIView* view = frame->GetView();
if (view) {
// Make sure the frame's view is properly sized and positioned and has
// things like opacity correct
@ -1057,7 +1092,7 @@ nsBox::SyncLayout(nsBoxLayoutState& aState)
presContext,
frame,
view,
nsnull,
&rect,
flags);
}
@ -1085,18 +1120,8 @@ nsBox::Redraw(nsBoxLayoutState& aState,
nsRect damageRect(0,0,0,0);
if (aDamageRect)
damageRect = *aDamageRect;
else
GetContentRect(damageRect);
// Checks to see if the damaged rect should be infalted
// to include the outline
// XXX This makes NO SENSE. if the damage rect is just a small part of
// this frame's rect then adding the outline width doesn't make any sense.
nscoord width;
frame->GetStyleOutline()->GetOutlineWidth(width);
if (width > 0) {
damageRect.Inflate(width, width);
}
else
damageRect = frame->GetOutlineRect();
frame->Invalidate(damageRect, aImmediate);

View File

@ -59,7 +59,8 @@ public:
NS_IMETHOD HasDirtyChildren(PRBool& aIsDirty);
NS_IMETHOD MarkDirty(nsBoxLayoutState& aState);
NS_IMETHOD MarkDirtyChildren(nsBoxLayoutState& aState);
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect);
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
PRBool aRemoveOverflowArea = PR_FALSE);
NS_IMETHOD GetBounds(nsRect& aRect);
NS_IMETHOD GetBorderAndPadding(nsMargin& aBorderAndPadding);
NS_IMETHOD GetBorder(nsMargin& aBorderAndPadding);
@ -111,6 +112,12 @@ public:
nsBox(nsIPresShell* aShell);
virtual ~nsBox();
/**
* Returns PR_TRUE if this box clips its children, e.g., if this box is an scrollbox.
*/
virtual PRBool DoesClipChildren() { return PR_FALSE; }
virtual PRBool ComputesOwnOverflowArea() { return PR_FALSE; }
virtual nsresult SyncLayout(nsBoxLayoutState& aBoxLayoutState);
virtual PRBool DoesNeedRecalc(const nsSize& aSize);

View File

@ -895,6 +895,13 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.ascent = ascent;
aDesiredSize.descent = r.height - ascent;
// NS_FRAME_OUTSIDE_CHILDREN is set in SetBounds() above
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
nsRect* overflowArea = GetOverflowAreaProperty();
NS_ASSERTION(overflowArea, "Failed to set overflow area property");
aDesiredSize.mOverflowArea = *overflowArea;
}
// max sure the max element size reflects
// our min width
nscoord* maxElementWidth = state.GetMaxElementWidth();

View File

@ -65,6 +65,9 @@ public:
void* operator new(size_t sz, nsIPresShell* aPresShell) CPP_THROW_NEW;
void operator delete(void* aPtr, size_t sz);
// We compute and store the HTML content's overflow area. So don't
// try to compute it in the box code.
virtual PRBool ComputesOwnOverflowArea() { return PR_TRUE; }
nsBoxToBlockAdaptor(nsIPresShell* aShell, nsIFrame* aFrame);
virtual ~nsBoxToBlockAdaptor();

View File

@ -93,7 +93,13 @@ public:
NS_IMETHOD IsCollapsed(nsBoxLayoutState& aBoxLayoutState, PRBool& aCollapsed)=0;
NS_IMETHOD Collapse(nsBoxLayoutState& aBoxLayoutState)=0;
NS_IMETHOD UnCollapse(nsBoxLayoutState& aBoxLayoutState)=0;
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect)=0;
// This does not alter the overflow area. If the caller is changing
// the box size, the caller is responsible for updating the overflow
// area. It's enough to just call Layout or SyncLayout on the
// box. You can pass PR_TRUE to aRemoveOverflowArea as a
// convenience.
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
PRBool aRemoveOverflowArea = PR_FALSE)=0;
NS_IMETHOD GetBounds(nsRect& aRect)=0;
NS_IMETHOD Layout(nsBoxLayoutState& aBoxLayoutState)=0;
NS_IMETHOD IsDirty(PRBool& aIsDirty)=0;

View File

@ -335,6 +335,13 @@ nsLeafBoxFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.ascent = ascent;
aDesiredSize.descent = 0;
// NS_FRAME_OUTSIDE_CHILDREN is set in SetBounds() above
if (mState & NS_FRAME_OUTSIDE_CHILDREN) {
nsRect* overflowArea = GetOverflowAreaProperty();
NS_ASSERTION(overflowArea, "Failed to set overflow area property");
aDesiredSize.mOverflowArea = *overflowArea;
}
// max sure the max element size reflects
// our min width
nscoord* maxElementWidth = state.GetMaxElementWidth();

View File

@ -347,7 +347,9 @@ nsScrollBoxFrame::DoLayout(nsBoxLayoutState& aState)
clientRect.Deflate(margin);
kid->SetBounds(aState, childRect);
// remove overflow area when we update the bounds,
// because we've already accounted for it
kid->SetBounds(aState, childRect, PR_TRUE);
}
aState.SetLayoutFlags(oldflags);

View File

@ -99,6 +99,11 @@ public:
*/
virtual nsIAtom* GetType() const;
/**
* This frame does clip its child (the scrolled frame).
*/
virtual PRBool DoesClipChildren() { return PR_TRUE; }
#ifdef NS_DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif
@ -117,7 +122,6 @@ public:
virtual nsresult GetContentOf(nsIContent** aContent);
protected:
nsScrollBoxFrame(nsIPresShell* aShell);

View File

@ -106,6 +106,16 @@ public:
NS_IMETHOD SetScrollbarMediator(nsIScrollbarMediator* aMediator) { mScrollbarMediator = aMediator; return NS_OK; };
NS_IMETHOD GetScrollbarMediator(nsIScrollbarMediator** aResult) { *aResult = mScrollbarMediator; return NS_OK; };
// nsBox methods
/**
* Treat scrollbars as clipping their children; overflowing children
* will not be allowed to make NS_FRAME_OUTSIDE_CHILDREN on this
* frame. This means that when the scroll code decides to hide a
* scrollframe by setting its height or width to zero, that will
* hide the children too.
*/
virtual PRBool DoesClipChildren() { return PR_TRUE; }
private:
nsIScrollbarMediator* mScrollbarMediator;
}; // class nsScrollbarFrame

View File

@ -449,14 +449,15 @@ nsTreeBodyFrame::EnsureView()
}
NS_IMETHODIMP
nsTreeBodyFrame::SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect)
nsTreeBodyFrame::SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
PRBool aRemoveOverflowArea)
{
if (aRect != mRect && !mReflowCallbackPosted) {
mReflowCallbackPosted = PR_TRUE;
mPresContext->PresShell()->PostReflowCallback(this);
}
return nsLeafBoxFrame::SetBounds(aBoxLayoutState, aRect);
return nsLeafBoxFrame::SetBounds(aBoxLayoutState, aRect, aRemoveOverflowArea);
}
@ -465,8 +466,13 @@ nsTreeBodyFrame::ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag)
{
if (mView) {
CalcInnerBox();
if (!mHasFixedRowCount)
if (!mHasFixedRowCount) {
#ifdef DEBUG_roc
printf("*** SETTING mPageLength in ReflowFinished, mInnerBox=%d,%d,%d,%d\n",
mInnerBox.x, mInnerBox.y, mInnerBox.width, mInnerBox.height);
#endif
mPageLength = mInnerBox.height / mRowHeight;
}
PRInt32 lastPageTopRow = PR_MAX(0, mRowCount - mPageLength);
if (mTopRowIndex > lastPageTopRow)

View File

@ -70,7 +70,8 @@ public:
// nsIBox
NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize);
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect);
NS_IMETHOD SetBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
PRBool aRemoveOverflowArea = PR_FALSE);
// nsIReflowCallback
NS_IMETHOD ReflowFinished(nsIPresShell* aPresShell, PRBool* aFlushFlag);