Bug 1320036 - Part 1. Correct objectBoundingBox region of a filter applied to an outer SVG element.
MozReview-Commit-ID: 8frACVe2gFE
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -177,17 +177,19 @@ nsFilterInstance::nsFilterInstance(nsIFr
, mPaintCallback(aPaintCallback)
, mPaintTransform(aPaintTransform)
, mInitialized(false)
{
if (aOverrideBBox) {
mTargetBBox = *aOverrideBBox;
} else {
MOZ_ASSERT(mTargetFrame, "Need to supply a frame when there's no aOverrideBBox");
- mTargetBBox = nsSVGUtils::GetBBox(mTargetFrame);
+ mTargetBBox = nsSVGUtils::GetBBox(mTargetFrame,
+ nsSVGUtils::eUseFrameBoundsForOuterSVG |
+ nsSVGUtils::eBBoxIncludeFillGeometry);
}
// Compute user space to filter space transforms.
if (!ComputeUserSpaceToFilterSpaceScale()) {
return;
}
if (!ComputeTargetBBoxInFilterSpace()) {
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -187,18 +187,18 @@ nsSVGIntegrationUtils::GetSVGCoordContex
nsPresContext* presContext = firstFrame->PresContext();
return gfx::Size(presContext->AppUnitsToFloatCSSPixels(r.width),
presContext->AppUnitsToFloatCSSPixels(r.height));
}
gfxRect
nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(nsIFrame* aNonSVGFrame)
{
- NS_ASSERTION(!aNonSVGFrame->IsFrameOfType(nsIFrame::eSVG),
- "SVG frames should not get here");
+ NS_ASSERTION(!(aNonSVGFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT),
+ "Frames with SVG layout should not get here");
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(aNonSVGFrame);
// 'r' is in "user space":
nsRect r = GetPreEffectsVisualOverflowUnion(firstFrame, nullptr, nsRect(),
GetOffsetToBoundingBox(firstFrame));
return nsLayoutUtils::RectToGfxRect(r,
aNonSVGFrame->PresContext()->AppUnitsPerCSSPixel());
}
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1092,17 +1092,20 @@ nsSVGUtils::SetClipRect(gfxContext *aCon
gfxRect
nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags)
{
if (aFrame->GetContent()->IsNodeOfType(nsINode::eTEXT)) {
aFrame = aFrame->GetParent();
}
gfxRect bbox;
nsISVGChildFrame *svg = do_QueryFrame(aFrame);
- if (svg || aFrame->IsSVGText()) {
+ const bool hasSVGLayout = aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT;
+ if (hasSVGLayout || aFrame->IsSVGText() ||
+ // if we evaluate the following, |svg| can only be an outer-<svg> or null
+ (svg && !(aFlags & eUseFrameBoundsForOuterSVG))) {
// It is possible to apply a gradient, pattern, clipping path, mask or
// filter to text. When one of these facilities is applied to text
// the bounding box is the entire text element in all
// cases.
if (aFrame->IsSVGText()) {
nsIFrame* ancestor = GetFirstNonAAncestorFrame(aFrame);
if (ancestor && ancestor->IsSVGText()) {
while (ancestor->GetType() != nsGkAtoms::svgTextFrame) {
--- a/layout/svg/nsSVGUtils.h
+++ b/layout/svg/nsSVGUtils.h
@@ -398,17 +398,21 @@ public:
nsIFrame *aFrame);
enum BBoxFlags {
eBBoxIncludeFill = 1 << 0,
eBBoxIncludeFillGeometry = 1 << 1,
eBBoxIncludeStroke = 1 << 2,
eBBoxIncludeStrokeGeometry = 1 << 3,
eBBoxIncludeMarkers = 1 << 4,
- eBBoxIncludeClipped = 1 << 5
+ eBBoxIncludeClipped = 1 << 5,
+ // Normally a getBBox call on outer-<svg> should only return the
+ // bounds of the elements children. This flag will cause the
+ // element's bounds to be returned instead.
+ eUseFrameBoundsForOuterSVG = 1 << 6
};
/**
* Get the SVG bbox (the SVG spec's simplified idea of bounds) of aFrame in
* aFrame's userspace.
*/
static gfxRect GetBBox(nsIFrame *aFrame,
// If the default arg changes, update the handling for
// ObjectBoundingBoxProperty() in the implementation.