Bug 350148. Fix scrolling in IFRAMEs with borders or outlines, by having OptimizeVisibility take account of the fact that borders or outlines whose inner rectangle entirely encloses the visible area are not, in fact, visible. r+sr=dbaron

This commit is contained in:
roc+%cs.cmu.edu 2006-09-19 21:58:52 +00:00
parent 7fd3c13bfa
commit 8339688ad2
2 changed files with 51 additions and 7 deletions

View File

@ -486,15 +486,15 @@ NonZeroStyleCoord(const nsStyleCoord& aCoord) {
}
static PRBool
HasNonZeroBorderRadius(const nsStyleBorder* aBorder) {
HasNonZeroSide(const nsStyleSides& aSides) {
nsStyleCoord coord;
aBorder->mBorderRadius.GetTop(coord);
aSides.GetTop(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aBorder->mBorderRadius.GetRight(coord);
aSides.GetRight(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aBorder->mBorderRadius.GetBottom(coord);
aSides.GetBottom(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
aBorder->mBorderRadius.GetLeft(coord);
aSides.GetLeft(coord);
if (NonZeroStyleCoord(coord)) return PR_TRUE;
return PR_FALSE;
@ -512,7 +512,7 @@ nsDisplayBackground::IsOpaque(nsDisplayListBuilder* aBuilder) {
nsCSSRendering::FindBackground(mFrame->GetPresContext(), mFrame, &bg, &isCanvas);
if (!hasBG || (bg->mBackgroundFlags & NS_STYLE_BG_COLOR_TRANSPARENT) ||
bg->mBackgroundClip != NS_STYLE_BG_CLIP_BORDER ||
HasNonZeroBorderRadius(mFrame->GetStyleBorder()) ||
HasNonZeroSide(mFrame->GetStyleBorder()->mBorderRadius) ||
NS_GET_A(bg->mBackgroundColor) < 255)
return PR_FALSE;
return PR_TRUE;
@ -531,7 +531,7 @@ nsDisplayBackground::IsUniform(nsDisplayListBuilder* aBuilder) {
if (!hasBG)
return PR_TRUE;
if ((bg->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE) &&
!HasNonZeroBorderRadius(mFrame->GetStyleBorder()) &&
!HasNonZeroSide(mFrame->GetStyleBorder()->mBorderRadius) &&
bg->mBackgroundClip == NS_STYLE_BG_CLIP_BORDER)
return PR_TRUE;
return PR_FALSE;
@ -589,6 +589,28 @@ nsDisplayOutline::Paint(nsDisplayListBuilder* aBuilder,
mFrame->GetStyleContext(), 0);
}
PRBool
nsDisplayOutline::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::OptimizeVisibility(aBuilder, aVisibleRegion))
return PR_FALSE;
const nsStyleOutline* outline = mFrame->GetStyleOutline();
nsPoint origin = aBuilder->ToReferenceFrame(mFrame);
if (nsRect(origin, mFrame->GetSize()).Contains(aVisibleRegion->GetBounds()) &&
!HasNonZeroSide(outline->mOutlineRadius)) {
nscoord outlineOffset;
outline->GetOutlineOffset(outlineOffset);
if (outlineOffset >= 0) {
// the visible region is entirely inside the border-rect, and the outline
// isn't rendered inside the border-rect, so the outline is not visible
return PR_FALSE;
}
}
return PR_TRUE;
}
void
nsDisplayCaret::Paint(nsDisplayListBuilder* aBuilder,
nsIRenderingContext* aCtx, const nsRect& aDirtyRect) {
@ -598,6 +620,26 @@ nsDisplayCaret::Paint(nsDisplayListBuilder* aBuilder,
mFrame->GetStyleColor()->mColor);
}
PRBool
nsDisplayBorder::OptimizeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::OptimizeVisibility(aBuilder, aVisibleRegion))
return PR_FALSE;
const nsStyleBorder* border = mFrame->GetStyleBorder();
nsRect contentRect = GetBounds(aBuilder);
contentRect.Deflate(border->GetBorder());
if (contentRect.Contains(aVisibleRegion->GetBounds()) &&
!HasNonZeroSide(border->mBorderRadius)) {
// the visible region is entirely inside the content rect, and no part
// of the border is rendered inside the content rect, so we are not
// visible
return PR_FALSE;
}
return PR_TRUE;
}
void
nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
nsIRenderingContext* aCtx, const nsRect& aDirtyRect) {

View File

@ -935,6 +935,7 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
const nsRect& aDirtyRect);
virtual PRBool OptimizeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion);
NS_DISPLAY_DECL_NAME("Border")
};
@ -980,6 +981,7 @@ public:
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx,
const nsRect& aDirtyRect);
virtual PRBool OptimizeVisibility(nsDisplayListBuilder* aBuilder, nsRegion* aVisibleRegion);
NS_DISPLAY_DECL_NAME("Outline")
};