mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 800041 - Make nsDisplayWrapList set its own reference frame correctly, and sanity check during ComputeVisibilityForSublist. r=roc
This commit is contained in:
parent
4bc9400593
commit
68ac6cb0e7
@ -852,7 +852,7 @@ nsDisplayList::ComputeVisibilityForRoot(nsDisplayListBuilder* aBuilder,
|
||||
SAMPLE_LABEL("nsDisplayList", "ComputeVisibilityForRoot");
|
||||
nsRegion r;
|
||||
r.And(*aVisibleRegion, GetBounds(aBuilder));
|
||||
return ComputeVisibilityForSublist(aBuilder, aVisibleRegion, r.GetBounds(), r.GetBounds());
|
||||
return ComputeVisibilityForSublist(aBuilder, nullptr, aVisibleRegion, r.GetBounds(), r.GetBounds());
|
||||
}
|
||||
|
||||
static nsRegion
|
||||
@ -897,6 +897,7 @@ GetDisplayPortBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
|
||||
|
||||
bool
|
||||
nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aForItem,
|
||||
nsRegion* aVisibleRegion,
|
||||
const nsRect& aListVisibleBounds,
|
||||
const nsRect& aAllowVisibleRegionExpansion) {
|
||||
@ -919,6 +920,13 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* item = elements[i];
|
||||
nsDisplayItem* belowItem = i < 1 ? nullptr : elements[i - 1];
|
||||
|
||||
NS_ASSERTION(!aForItem ||
|
||||
item->GetType() != nsDisplayItem::TYPE_TRANSFORM ||
|
||||
item->GetUnderlyingFrame() != aForItem->GetUnderlyingFrame() ||
|
||||
aForItem->ReferenceFrame() != aForItem->GetUnderlyingFrame(),
|
||||
"If we have an nsDisplayTransform child (for the same frame),"
|
||||
"then we shouldn't be our own reference frame!");
|
||||
|
||||
nsDisplayList* list = item->GetList();
|
||||
if (aBuilder->AllowMergingAndFlattening()) {
|
||||
if (belowItem && item->TryMerge(aBuilder, belowItem)) {
|
||||
@ -2374,11 +2382,55 @@ nsDisplayBoxShadowInner::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
return true;
|
||||
}
|
||||
|
||||
nsIFrame *GetTransformRootFrame(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
while (parent && parent->Preserves3DChildren()) {
|
||||
parent = nsLayoutUtils::GetCrossDocParentFrame(parent);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayList* aList)
|
||||
: nsDisplayItem(aBuilder, aFrame) {
|
||||
mList.AppendToTop(aList);
|
||||
UpdateBounds(aBuilder);
|
||||
|
||||
if (!aFrame || !aFrame->IsTransformed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the frame is a preserve-3d parent, then we will create transforms
|
||||
// inside this list afterwards (see WrapPreserve3DList in nsFrame.cpp).
|
||||
// In this case we will always be outside of the transform, so share
|
||||
// our parents reference frame.
|
||||
if (aFrame->Preserves3DChildren()) {
|
||||
mReferenceFrame =
|
||||
aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame));
|
||||
mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're a transformed frame, then we need to find out if we're inside
|
||||
// the nsDisplayTransform or outside of it. Frames inside the transform
|
||||
// need mReferenceFrame == mFrame, outside needs the next ancestor
|
||||
// reference frame.
|
||||
// If we're inside the transform, then the nsDisplayItem constructor
|
||||
// will have done the right thing.
|
||||
// If we're outside the transform, then we should have only one child
|
||||
// (since nsDisplayTransform wraps all actual content), and that child
|
||||
// will have the correct reference frame set (since nsDisplayTransform
|
||||
// handles this explictly).
|
||||
//
|
||||
// Preserve-3d can cause us to have multiple nsDisplayTransform
|
||||
// children.
|
||||
nsDisplayItem *i = mList.GetBottom();
|
||||
if (i && (!i->GetAbove() || i->GetType() == TYPE_TRANSFORM) &&
|
||||
i->GetUnderlyingFrame() == mFrame) {
|
||||
mReferenceFrame = i->ReferenceFrame();
|
||||
mToReferenceFrame = i->ToReferenceFrame();
|
||||
}
|
||||
}
|
||||
|
||||
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
|
||||
@ -2386,6 +2438,23 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
|
||||
: nsDisplayItem(aBuilder, aFrame) {
|
||||
mList.AppendToTop(aItem);
|
||||
UpdateBounds(aBuilder);
|
||||
|
||||
if (!aFrame || !aFrame->IsTransformed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aFrame->Preserves3DChildren()) {
|
||||
mReferenceFrame =
|
||||
aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame));
|
||||
mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame);
|
||||
return;
|
||||
}
|
||||
|
||||
// See the previous nsDisplayWrapList constructor
|
||||
if (aItem->GetUnderlyingFrame() == aFrame) {
|
||||
mReferenceFrame = aItem->ReferenceFrame();
|
||||
mToReferenceFrame = aItem->ToReferenceFrame();
|
||||
}
|
||||
}
|
||||
|
||||
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
|
||||
@ -2417,7 +2486,7 @@ bool
|
||||
nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
nsRegion* aVisibleRegion,
|
||||
const nsRect& aAllowVisibleRegionExpansion) {
|
||||
return mList.ComputeVisibilityForSublist(aBuilder, aVisibleRegion,
|
||||
return mList.ComputeVisibilityForSublist(aBuilder, this, aVisibleRegion,
|
||||
mVisibleRect,
|
||||
aAllowVisibleRegionExpansion);
|
||||
}
|
||||
@ -2780,11 +2849,6 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
NS_ASSERTION(mScrolledFrame && mScrolledFrame->GetContent(),
|
||||
"Need a child frame with content");
|
||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aForFrame);
|
||||
NS_ASSERTION(parent, "Must have a parent!");
|
||||
mReferenceFrame =
|
||||
aBuilder->FindReferenceFrameFor(parent);
|
||||
mToReferenceFrame = aForFrame->GetOffsetToCrossDoc(mReferenceFrame);
|
||||
}
|
||||
|
||||
nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
||||
@ -2802,11 +2866,6 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
NS_ASSERTION(mScrolledFrame && mScrolledFrame->GetContent(),
|
||||
"Need a child frame with content");
|
||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aForFrame);
|
||||
NS_ASSERTION(parent, "Must have a parent!");
|
||||
mReferenceFrame =
|
||||
aBuilder->FindReferenceFrameFor(parent);
|
||||
mToReferenceFrame = aForFrame->GetOffsetToCrossDoc(mReferenceFrame);
|
||||
}
|
||||
|
||||
nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
||||
@ -2823,11 +2882,6 @@ nsDisplayScrollLayer::nsDisplayScrollLayer(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
NS_ASSERTION(mScrolledFrame && mScrolledFrame->GetContent(),
|
||||
"Need a child frame with content");
|
||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aForFrame);
|
||||
NS_ASSERTION(parent, "Must have a parent!");
|
||||
mReferenceFrame =
|
||||
aBuilder->FindReferenceFrameFor(parent);
|
||||
mToReferenceFrame = aForFrame->GetOffsetToCrossDoc(mReferenceFrame);
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
@ -2883,7 +2937,7 @@ nsDisplayScrollLayer::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
childVisibleRegion.GetBounds().Intersect(mList.GetBounds(aBuilder));
|
||||
nsRect allowExpansion = boundedRect.Intersect(aAllowVisibleRegionExpansion);
|
||||
bool visible = mList.ComputeVisibilityForSublist(
|
||||
aBuilder, &childVisibleRegion, boundedRect, allowExpansion);
|
||||
aBuilder, this, &childVisibleRegion, boundedRect, allowExpansion);
|
||||
mVisibleRect = boundedRect;
|
||||
|
||||
return visible;
|
||||
@ -3232,7 +3286,7 @@ bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
|
||||
nsRect allowExpansion =
|
||||
aAllowVisibleRegionExpansion.ConvertAppUnitsRoundIn(mParentAPD, mAPD);
|
||||
bool retval =
|
||||
mList.ComputeVisibilityForSublist(aBuilder, &visibleRegion,
|
||||
mList.ComputeVisibilityForSublist(aBuilder, this, &visibleRegion,
|
||||
transformedVisibleRect,
|
||||
allowExpansion);
|
||||
|
||||
@ -3320,15 +3374,6 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame)
|
||||
|
||||
#endif
|
||||
|
||||
nsIFrame *GetTransformRootFrame(nsIFrame* aFrame)
|
||||
{
|
||||
nsIFrame *parent = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
while (parent && parent->Preserves3DChildren()) {
|
||||
parent = nsLayoutUtils::GetCrossDocParentFrame(parent);
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
|
||||
nsDisplayList *aList, ComputeTransformFunction aTransformGetter,
|
||||
uint32_t aIndex)
|
||||
@ -4240,7 +4285,7 @@ bool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||
// not allow them to subtract area from aVisibleRegion.
|
||||
nsRegion childrenVisible(dirtyRect);
|
||||
nsRect r = dirtyRect.Intersect(mList.GetBounds(aBuilder));
|
||||
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r, nsRect());
|
||||
mList.ComputeVisibilityForSublist(aBuilder, this, &childrenVisible, r, nsRect());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -692,6 +692,8 @@ public:
|
||||
if (aFrame) {
|
||||
mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame);
|
||||
mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame);
|
||||
} else {
|
||||
mReferenceFrame = nullptr;
|
||||
}
|
||||
}
|
||||
nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
@ -1297,6 +1299,7 @@ public:
|
||||
* @return true if any item in the list is visible.
|
||||
*/
|
||||
bool ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aForItem,
|
||||
nsRegion* aVisibleRegion,
|
||||
const nsRect& aListVisibleBounds,
|
||||
const nsRect& aAllowVisibleRegionExpansion);
|
||||
|
Loading…
Reference in New Issue
Block a user