Bug 1319407 - Apply clip-path to each frame when box-decoration-break is clone. r=cjku,heycam
MozReview-Commit-ID: E7IR49MzkWm
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -3905,19 +3905,19 @@ nsLayoutUtils::BinarySearchForPosition(D
aBaseInx, inx, aEndInx, aCursorPos, aIndex,
aTextWidth)) {
return true;
}
}
return false;
}
-static void
-AddBoxesForFrame(nsIFrame* aFrame,
- nsLayoutUtils::BoxCallback* aCallback)
+void
+nsLayoutUtils::AddBoxesForFrame(nsIFrame* aFrame,
+ nsLayoutUtils::BoxCallback* aCallback)
{
nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo();
if (pseudoType == nsCSSAnonBoxes::tableWrapper) {
AddBoxesForFrame(aFrame->PrincipalChildList().FirstChild(), aCallback);
if (aCallback->mIncludeCaptionBoxForTable) {
nsIFrame* kid = aFrame->GetChildList(nsIFrame::kCaptionList).FirstChild();
if (kid) {
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1150,16 +1150,21 @@ public:
* continuations, "drilling down" through table wrapper frames and
* some anonymous blocks since they're not real CSS boxes.
* If aFrame is null, no boxes are returned.
* SVG frames return a single box, themselves.
*/
static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback);
/**
+ * Like GetAllInFlowBoxes, but doesn't include continuations.
+ */
+ static void AddBoxesForFrame(nsIFrame* aFrame, BoxCallback* aCallback);
+
+ /**
* Find the first frame descendant of aFrame (including aFrame) which is
* not an anonymous frame that getBoxQuads/getClientRects should ignore.
*/
static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame);
class RectCallback {
public:
virtual void AddRect(const nsRect& aRect) = 0;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8576,16 +8576,22 @@ nsDisplayMask::~nsDisplayMask()
}
#endif
bool nsDisplayMask::TryMerge(nsDisplayItem* aItem)
{
if (aItem->GetType() != TYPE_MASK)
return false;
+ // Do not merge items for box-decoration-break:clone elements,
+ // since each box should have its own mask in that case.
+ if (mFrame->StyleBorder()->mBoxDecorationBreak == StyleBoxDecorationBreak::Clone) {
+ return false;
+ }
+
// items for the same content element should be merged into a single
// compositing group
// aItem->GetUnderlyingFrame() returns non-null because it's nsDisplaySVGEffects
if (aItem->Frame()->GetContent() != mFrame->GetContent()) {
return false;
}
if (aItem->GetClipChain() != GetClipChain()) {
return false;
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -132,16 +132,31 @@ GetPreEffectsVisualOverflowUnion(nsIFram
aCurrentFramePreEffectsOverflow,
aInReflow);
// Compute union of all overflow areas relative to aFirstContinuation:
nsLayoutUtils::GetAllInFlowBoxes(aFirstContinuation, &collector);
// Return the result in user space:
return collector.GetResult() + aFirstContinuationToUserSpace;
}
+static nsRect
+GetPreEffectsVisualOverflow(nsIFrame* aFirstContinuation,
+ nsIFrame* aCurrentFrame,
+ const nsPoint& aFirstContinuationToUserSpace)
+{
+ PreEffectsVisualOverflowCollector collector(aFirstContinuation,
+ nullptr,
+ nsRect(),
+ false);
+ // Compute overflow areas of current frame relative to aFirstContinuation:
+ nsLayoutUtils::AddBoxesForFrame(aCurrentFrame, &collector);
+ // Return the result in user space:
+ return collector.GetResult() + aFirstContinuationToUserSpace;
+}
+
bool
nsSVGIntegrationUtils::UsingEffectsForFrame(const nsIFrame* aFrame)
{
// Even when SVG display lists are disabled, returning true for SVG frames
// does not adversely affect any of our callers. Therefore we don't bother
// checking the SDL prefs here, since we don't know if we're being called for
// painting or hit-testing anyway.
@@ -206,19 +221,26 @@ nsSVGIntegrationUtils::GetSVGBBoxForNonS
NS_ASSERTION(!(aNonSVGFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT),
"Frames with SVG layout should not get here");
MOZ_ASSERT(!aNonSVGFrame->IsFrameOfType(nsIFrame::eSVG) ||
aNonSVGFrame->IsSVGOuterSVGFrame());
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(aNonSVGFrame);
// 'r' is in "user space":
- nsRect r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(),
- GetOffsetToBoundingBox(firstFrame),
- false);
+ nsRect r;
+ if (aNonSVGFrame->StyleBorder()->mBoxDecorationBreak == StyleBoxDecorationBreak::Clone) {
+ r = GetPreEffectsVisualOverflow(firstFrame, aNonSVGFrame,
+ GetOffsetToBoundingBox(firstFrame));
+ } else {
+ r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(),
+ GetOffsetToBoundingBox(firstFrame),
+ false);
+ }
+
return nsLayoutUtils::RectToGfxRect(r,
aNonSVGFrame->PresContext()->AppUnitsPerCSSPixel());
}
// XXX Since we're called during reflow, this method is broken for frames with
// continuations. When we're called for a frame with continuations, we're
// called for each continuation in turn as it's reflowed. However, it isn't
// until the last continuation is reflowed that this method's