mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 530686. Don't redraw box-shadows over the bounding rect of the dirty region; just redraw them over a (somewhat simplified) dirty region. r=dbaron
This commit is contained in:
parent
2775cf57b8
commit
6780628363
@ -815,13 +815,53 @@ nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
|
||||
mFrame->GetSkipSides());
|
||||
}
|
||||
|
||||
// Given a region, compute a conservative approximation to it as a list
|
||||
// of rectangles that aren't vertically adjacent (i.e., vertically
|
||||
// adjacent or overlapping rectangles are combined).
|
||||
// Right now this is only approximate, some vertically overlapping rectangles
|
||||
// aren't guaranteed to be combined.
|
||||
static void
|
||||
ComputeDisjointRectangles(const nsRegion& aRegion,
|
||||
nsTArray<nsRect>* aRects) {
|
||||
nscoord accumulationMargin = nsPresContext::CSSPixelsToAppUnits(25);
|
||||
nsRect accumulated;
|
||||
nsRegionRectIterator iter(aRegion);
|
||||
while (PR_TRUE) {
|
||||
const nsRect* r = iter.Next();
|
||||
if (r && !accumulated.IsEmpty() &&
|
||||
accumulated.YMost() >= r->y - accumulationMargin) {
|
||||
accumulated.UnionRect(accumulated, *r);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!accumulated.IsEmpty()) {
|
||||
aRects->AppendElement(accumulated);
|
||||
accumulated.Empty();
|
||||
}
|
||||
|
||||
if (!r)
|
||||
break;
|
||||
|
||||
accumulated = *r;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx) {
|
||||
nsPoint offset = aBuilder->ToReferenceFrame(mFrame);
|
||||
nsCSSRendering::PaintBoxShadowOuter(mFrame->PresContext(), *aCtx, mFrame,
|
||||
nsRect(offset, mFrame->GetSize()),
|
||||
mVisibleRect);
|
||||
nsRect borderRect = nsRect(offset, mFrame->GetSize());
|
||||
nsPresContext* presContext = mFrame->PresContext();
|
||||
nsAutoTArray<nsRect,10> rects;
|
||||
ComputeDisjointRectangles(mVisibleRegion, &rects);
|
||||
|
||||
for (PRUint32 i = 0; i < rects.Length(); ++i) {
|
||||
aCtx->PushState();
|
||||
aCtx->SetClipRect(rects[i], nsClipCombine_kIntersect);
|
||||
nsCSSRendering::PaintBoxShadowOuter(presContext, *aCtx, mFrame,
|
||||
borderRect, rects[i]);
|
||||
aCtx->PopState();
|
||||
}
|
||||
}
|
||||
|
||||
nsRect
|
||||
@ -840,6 +880,9 @@ nsDisplayBoxShadowOuter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
aVisibleRegionBeforeMove))
|
||||
return PR_FALSE;
|
||||
|
||||
// Store the actual visible region
|
||||
mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
|
||||
|
||||
nsPoint origin = aBuilder->ToReferenceFrame(mFrame);
|
||||
nsRect visibleBounds = aVisibleRegion->GetBounds();
|
||||
if (aVisibleRegionBeforeMove) {
|
||||
@ -866,9 +909,34 @@ void
|
||||
nsDisplayBoxShadowInner::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx) {
|
||||
nsPoint offset = aBuilder->ToReferenceFrame(mFrame);
|
||||
nsCSSRendering::PaintBoxShadowInner(mFrame->PresContext(), *aCtx, mFrame,
|
||||
nsRect(offset, mFrame->GetSize()),
|
||||
mVisibleRect);
|
||||
nsRect borderRect = nsRect(offset, mFrame->GetSize());
|
||||
nsPresContext* presContext = mFrame->PresContext();
|
||||
nsAutoTArray<nsRect,10> rects;
|
||||
ComputeDisjointRectangles(mVisibleRegion, &rects);
|
||||
|
||||
for (PRUint32 i = 0; i < rects.Length(); ++i) {
|
||||
aCtx->PushState();
|
||||
aCtx->SetClipRect(rects[i], nsClipCombine_kIntersect);
|
||||
nsCSSRendering::PaintBoxShadowInner(presContext, *aCtx, mFrame,
|
||||
borderRect, rects[i]);
|
||||
aCtx->PopState();
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDisplayBoxShadowInner::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion,
|
||||
nsRegion* aVisibleRegionBeforeMove) {
|
||||
NS_ASSERTION((aVisibleRegionBeforeMove != nsnull) == aBuilder->HasMovingFrames(),
|
||||
"Should have aVisibleRegionBeforeMove when there are moving frames");
|
||||
|
||||
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
|
||||
aVisibleRegionBeforeMove))
|
||||
return PR_FALSE;
|
||||
|
||||
// Store the actual visible region
|
||||
mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsDisplayWrapList::nsDisplayWrapList(nsIFrame* aFrame, nsDisplayList* aList)
|
||||
|
@ -1212,6 +1212,9 @@ public:
|
||||
nsRegion* aVisibleRegion,
|
||||
nsRegion* aVisibleRegionBeforeMove);
|
||||
NS_DISPLAY_DECL_NAME("BoxShadowOuter")
|
||||
|
||||
private:
|
||||
nsRegion mVisibleRegion;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1229,7 +1232,13 @@ public:
|
||||
#endif
|
||||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx);
|
||||
virtual PRBool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion,
|
||||
nsRegion* aVisibleRegionBeforeMove);
|
||||
NS_DISPLAY_DECL_NAME("BoxShadowInner")
|
||||
|
||||
private:
|
||||
nsRegion mVisibleRegion;
|
||||
};
|
||||
|
||||
/**
|
||||
|
16
layout/reftests/bugs/530686-1-ref.html
Normal file
16
layout/reftests/bugs/530686-1-ref.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
#rear {
|
||||
width: 500px;
|
||||
height: 1500px;
|
||||
-moz-box-shadow: 0 0 100px #667;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="rear"></div>
|
||||
</body>
|
||||
</html>
|
34
layout/reftests/bugs/530686-1.html
Normal file
34
layout/reftests/bugs/530686-1.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
#rear {
|
||||
width: 500px;
|
||||
height: 1500px;
|
||||
-moz-box-shadow: 0 0 100px #667;
|
||||
display: block;
|
||||
}
|
||||
.cover {
|
||||
position: absolute;
|
||||
width: 520px;
|
||||
height: 100px;
|
||||
background: yellow;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function doTest() {
|
||||
var es = document.getElementsByClassName("cover");
|
||||
for (var i = 0; i < es.length; ++i) {
|
||||
es[i].style.display = 'none';
|
||||
}
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
window.addEventListener("MozReftestInvalidate", doTest, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="rear"></div>
|
||||
<div class="cover" style="top:100px"></div>
|
||||
<div class="cover" style="top:300px"></div>
|
||||
</body>
|
||||
</html>
|
@ -1347,3 +1347,4 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") == 488692-1.html 488692-1-ref.html # needs
|
||||
== 528038-1e.html 528038-1-ref.html
|
||||
== 528038-1f.html 528038-1-ref.html
|
||||
== 528038-2.html 528038-2-ref.html
|
||||
== 530686-1.html 503686-1-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user