Bug 1087956: Fix clipping of position:fixed layers inside displayports. r=roc

This commit is contained in:
Matt Woodrow 2015-02-20 10:55:28 -08:00
Родитель cd23dedd4c
Коммит c2394710e5
2 изменённых файлов: 33 добавлений и 8 удалений

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

@ -21,9 +21,7 @@ namespace mozilla {
void
DisplayItemClip::SetTo(const nsRect& aRect)
{
mHaveClipRect = true;
mClipRect = aRect;
mRoundedClipRects.Clear();
SetTo(aRect, nullptr);
}
void
@ -31,9 +29,13 @@ DisplayItemClip::SetTo(const nsRect& aRect, const nscoord* aRadii)
{
mHaveClipRect = true;
mClipRect = aRect;
mRoundedClipRects.SetLength(1);
mRoundedClipRects[0].mRect = aRect;
memcpy(mRoundedClipRects[0].mRadii, aRadii, sizeof(nscoord)*8);
if (aRadii) {
mRoundedClipRects.SetLength(1);
mRoundedClipRects[0].mRect = aRect;
memcpy(mRoundedClipRects[0].mRadii, aRadii, sizeof(nscoord)*8);
} else {
mRoundedClipRects.Clear();
}
}
void

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

@ -641,6 +641,8 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
const nsRect& aDirtyRect)
{
nsRect dirtyRectRelativeToDirtyFrame = aDirtyRect;
DisplayItemClip clip;
const DisplayItemClip* clipPtr = nullptr;
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
IsPaintingToWindow()) {
NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame");
@ -654,6 +656,19 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
} else {
dirtyRectRelativeToDirtyFrame.SizeTo(aDirtyFrame->GetSize());
}
// Always clip fixed items to the root scroll frame's scrollport, because
// we skip setting the clip in ScrollFrameHelper if we have a displayport.
nsIFrame* rootScroll = aFrame->PresContext()->PresShell()->GetRootScrollFrame();
if (rootScroll) {
nsIScrollableFrame* scrollable = do_QueryFrame(rootScroll);
nsRect clipRect = scrollable->GetScrollPortRect() + ToReferenceFrame(rootScroll);
nscoord radii[8];
bool haveRadii = rootScroll->GetPaddingBoxBorderRadii(radii);
clip.SetTo(clipRect, haveRadii ? radii : nullptr);
clipPtr = &clip;
}
}
nsRect dirty = dirtyRectRelativeToDirtyFrame - aFrame->GetOffsetTo(aDirtyFrame);
@ -672,8 +687,16 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
if (!dirty.IntersectRect(dirty, overflowRect))
return;
const DisplayItemClip* clip = mClipState.GetClipForContainingBlockDescendants();
OutOfFlowDisplayData* data = clip ? new OutOfFlowDisplayData(*clip, dirty)
// Combine clips if necessary
const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
if (clipPtr && oldClip) {
clip.IntersectWith(*oldClip);
} else if (oldClip) {
clipPtr = oldClip;
}
OutOfFlowDisplayData* data = clipPtr ? new OutOfFlowDisplayData(*clipPtr, dirty)
: new OutOfFlowDisplayData(dirty);
aFrame->Properties().Set(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);