From 3cfd9bd4ee26fb08d9d684db6871803ef586e05d Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Mon, 20 Oct 2008 09:42:03 +0100 Subject: [PATCH] Bug 459758 - effects on outer svg frames only work accidentally. r+sr=roc --- layout/svg/base/src/nsISVGChildFrame.h | 7 ++++--- layout/svg/base/src/nsSVGContainerFrame.cpp | 4 ++-- layout/svg/base/src/nsSVGContainerFrame.h | 3 ++- layout/svg/base/src/nsSVGForeignObjectFrame.cpp | 2 +- layout/svg/base/src/nsSVGForeignObjectFrame.h | 3 ++- layout/svg/base/src/nsSVGGlyphFrame.cpp | 3 ++- layout/svg/base/src/nsSVGGlyphFrame.h | 3 ++- layout/svg/base/src/nsSVGGradientFrame.h | 6 ------ layout/svg/base/src/nsSVGImageFrame.cpp | 5 +++-- layout/svg/base/src/nsSVGInnerSVGFrame.cpp | 5 +++-- layout/svg/base/src/nsSVGIntegrationUtils.cpp | 3 ++- layout/svg/base/src/nsSVGIntegrationUtils.h | 3 +++ layout/svg/base/src/nsSVGMarkerFrame.cpp | 2 +- layout/svg/base/src/nsSVGMaskFrame.cpp | 2 +- layout/svg/base/src/nsSVGOuterSVGFrame.cpp | 16 +++++++++------- layout/svg/base/src/nsSVGPathGeometryFrame.cpp | 2 +- layout/svg/base/src/nsSVGPathGeometryFrame.h | 3 ++- layout/svg/base/src/nsSVGPatternFrame.cpp | 2 +- layout/svg/base/src/nsSVGSwitchFrame.cpp | 7 ++++--- layout/svg/base/src/nsSVGTextFrame.cpp | 3 ++- layout/svg/base/src/nsSVGTextFrame.h | 3 ++- layout/svg/base/src/nsSVGUtils.cpp | 4 ++-- layout/svg/base/src/nsSVGUtils.h | 4 ++-- 23 files changed, 53 insertions(+), 42 deletions(-) diff --git a/layout/svg/base/src/nsISVGChildFrame.h b/layout/svg/base/src/nsISVGChildFrame.h index 563b8a15438a..551c1b243a33 100644 --- a/layout/svg/base/src/nsISVGChildFrame.h +++ b/layout/svg/base/src/nsISVGChildFrame.h @@ -51,8 +51,8 @@ class nsIDOMSVGMatrix; class nsSVGRenderState; #define NS_ISVGCHILDFRAME_IID \ -{ 0x91253119, 0x4fe4, 0x4628, \ - { 0xaf, 0x25, 0x4e, 0x4b, 0x43, 0x5f, 0x66, 0xf2 } } +{ 0xfc3ee9b2, 0xaf40, 0x416d, \ + { 0xa8, 0x51, 0xb4, 0x68, 0xa4, 0xe4, 0x8b, 0xcd } } class nsISVGChildFrame : public nsISupports { public: @@ -61,7 +61,8 @@ public: // Paint this frame - aDirtyRect is the area being redrawn, in frame // offset pixel coordinates - NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, nsIntRect *aDirtyRect)=0; + NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, + const nsIntRect *aDirtyRect)=0; // Check if this frame or children contain the given point, // specified in app units relative to the origin of the outer diff --git a/layout/svg/base/src/nsSVGContainerFrame.cpp b/layout/svg/base/src/nsSVGContainerFrame.cpp index 78bb09672dae..7a0b52b58a2d 100644 --- a/layout/svg/base/src/nsSVGContainerFrame.cpp +++ b/layout/svg/base/src/nsSVGContainerFrame.cpp @@ -166,7 +166,7 @@ nsSVGDisplayContainerFrame::RemoveFrame(nsIAtom* aListName, NS_IMETHODIMP nsSVGDisplayContainerFrame::PaintSVG(nsSVGRenderState* aContext, - nsIntRect *aDirtyRect) + const nsIntRect *aDirtyRect) { const nsStyleDisplay *display = mStyleContext->GetStyleDisplay(); if (display->mOpacity == 0.0) @@ -174,7 +174,7 @@ nsSVGDisplayContainerFrame::PaintSVG(nsSVGRenderState* aContext, for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) { - nsSVGUtils::PaintChildWithEffects(aContext, aDirtyRect, kid); + nsSVGUtils::PaintFrameWithEffects(aContext, aDirtyRect, kid); } return NS_OK; diff --git a/layout/svg/base/src/nsSVGContainerFrame.h b/layout/svg/base/src/nsSVGContainerFrame.h index 0058b06f23d2..9be1181d38e2 100644 --- a/layout/svg/base/src/nsSVGContainerFrame.h +++ b/layout/svg/base/src/nsSVGContainerFrame.h @@ -102,7 +102,8 @@ public: nsIFrame* aPrevInFlow); // nsISVGChildFrame interface: - NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, + const nsIntRect *aDirtyRect); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); NS_IMETHOD_(nsRect) GetCoveredRegion(); NS_IMETHOD UpdateCoveredRegion(); diff --git a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp index 4e314ca21d97..6737fbd46832 100644 --- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp @@ -229,7 +229,7 @@ GetTransformedRegion(float aX, float aY, float aWidth, float aHeight, NS_IMETHODIMP nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext, - nsIntRect *aDirtyRect) + const nsIntRect *aDirtyRect) { if (IsDisabled()) return NS_OK; diff --git a/layout/svg/base/src/nsSVGForeignObjectFrame.h b/layout/svg/base/src/nsSVGForeignObjectFrame.h index 59e6dcb8ecc7..510ab9afc620 100644 --- a/layout/svg/base/src/nsSVGForeignObjectFrame.h +++ b/layout/svg/base/src/nsSVGForeignObjectFrame.h @@ -120,7 +120,8 @@ public: #endif // nsISVGChildFrame interface: - NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); NS_IMETHOD_(nsRect) GetCoveredRegion(); NS_IMETHOD UpdateCoveredRegion(); diff --git a/layout/svg/base/src/nsSVGGlyphFrame.cpp b/layout/svg/base/src/nsSVGGlyphFrame.cpp index cef9fb155863..4fd458f9ca0b 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -298,7 +298,8 @@ nsSVGGlyphFrame::GetType() const // nsISVGChildFrame methods NS_IMETHODIMP -nsSVGGlyphFrame::PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect) +nsSVGGlyphFrame::PaintSVG(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect) { if (!GetStyleVisibility()->IsVisible()) return NS_OK; diff --git a/layout/svg/base/src/nsSVGGlyphFrame.h b/layout/svg/base/src/nsSVGGlyphFrame.h index 927260fb951f..d86b2056a839 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.h +++ b/layout/svg/base/src/nsSVGGlyphFrame.h @@ -115,7 +115,8 @@ public: // nsISVGChildFrame interface: // These four always use the global transform, even if NS_STATE_NONDISPLAY_CHILD - NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); NS_IMETHOD UpdateCoveredRegion(); NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval); diff --git a/layout/svg/base/src/nsSVGGradientFrame.h b/layout/svg/base/src/nsSVGGradientFrame.h index c0855ed46216..5b81e305c4d8 100644 --- a/layout/svg/base/src/nsSVGGradientFrame.h +++ b/layout/svg/base/src/nsSVGGradientFrame.h @@ -79,12 +79,6 @@ public: } #endif // DEBUG - // nsISVGChildFrame interface: - NS_IMETHOD PaintSVG(gfxContext* aContext) - { - return NS_OK; // override - our frames don't directly render - } - private: // Parse our xlink:href and set up our nsSVGPaintingProperty if we diff --git a/layout/svg/base/src/nsSVGImageFrame.cpp b/layout/svg/base/src/nsSVGImageFrame.cpp index a52e5815466d..03b6e2a3f48f 100644 --- a/layout/svg/base/src/nsSVGImageFrame.cpp +++ b/layout/svg/base/src/nsSVGImageFrame.cpp @@ -85,7 +85,7 @@ protected: public: // nsISVGChildFrame interface: - NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, const nsIntRect *aDirtyRect); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); // nsSVGPathGeometryFrame methods: @@ -224,7 +224,8 @@ nsSVGImageFrame::GetImageTransform() //---------------------------------------------------------------------- // nsISVGChildFrame methods: NS_IMETHODIMP -nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect) +nsSVGImageFrame::PaintSVG(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect) { nsresult rv = NS_OK; diff --git a/layout/svg/base/src/nsSVGInnerSVGFrame.cpp b/layout/svg/base/src/nsSVGInnerSVGFrame.cpp index 1da3d4c27375..317fefc61055 100644 --- a/layout/svg/base/src/nsSVGInnerSVGFrame.cpp +++ b/layout/svg/base/src/nsSVGInnerSVGFrame.cpp @@ -83,7 +83,7 @@ public: #endif // nsISVGChildFrame interface: - NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, const nsIntRect *aDirtyRect); virtual void NotifySVGChanged(PRUint32 aFlags); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); @@ -147,7 +147,8 @@ nsSVGInnerSVGFrame::GetType() const // nsISVGChildFrame methods NS_IMETHODIMP -nsSVGInnerSVGFrame::PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect) +nsSVGInnerSVGFrame::PaintSVG(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect) { gfxContextAutoSaveRestore autoSR; diff --git a/layout/svg/base/src/nsSVGIntegrationUtils.cpp b/layout/svg/base/src/nsSVGIntegrationUtils.cpp index f4e35c2c14dd..3372bf08494e 100644 --- a/layout/svg/base/src/nsSVGIntegrationUtils.cpp +++ b/layout/svg/base/src/nsSVGIntegrationUtils.cpp @@ -54,7 +54,8 @@ PRBool nsSVGIntegrationUtils::UsingEffectsForFrame(const nsIFrame* aFrame) { const nsStyleSVGReset *style = aFrame->GetStyleSVGReset(); - return style->mFilter || style->mClipPath || style->mMask; + return (style->mFilter || style->mClipPath || style->mMask) && + !aFrame->IsFrameOfType(nsIFrame::eSVG); } // Get the union the frame border-box rects over all continuations, diff --git a/layout/svg/base/src/nsSVGIntegrationUtils.h b/layout/svg/base/src/nsSVGIntegrationUtils.h index 2a6c19a973bc..a5b27fff476c 100644 --- a/layout/svg/base/src/nsSVGIntegrationUtils.h +++ b/layout/svg/base/src/nsSVGIntegrationUtils.h @@ -53,6 +53,9 @@ class nsIDOMSVGMatrix; class nsSVGIntegrationUtils { public: + /** + * Returns true if a non-SVG frame has SVG effects. + */ static PRBool UsingEffectsForFrame(const nsIFrame* aFrame); diff --git a/layout/svg/base/src/nsSVGMarkerFrame.cpp b/layout/svg/base/src/nsSVGMarkerFrame.cpp index 4755790ddd54..7fec0c90707d 100644 --- a/layout/svg/base/src/nsSVGMarkerFrame.cpp +++ b/layout/svg/base/src/nsSVGMarkerFrame.cpp @@ -204,7 +204,7 @@ nsSVGMarkerFrame::PaintMark(nsSVGRenderState *aContext, // The CTM of each frame referencing us may be different. SVGFrame->NotifySVGChanged(nsISVGChildFrame::SUPPRESS_INVALIDATION | nsISVGChildFrame::TRANSFORM_CHANGED); - nsSVGUtils::PaintChildWithEffects(aContext, nsnull, kid); + nsSVGUtils::PaintFrameWithEffects(aContext, nsnull, kid); } } diff --git a/layout/svg/base/src/nsSVGMaskFrame.cpp b/layout/svg/base/src/nsSVGMaskFrame.cpp index acc96094b377..0cda9d6d1a83 100644 --- a/layout/svg/base/src/nsSVGMaskFrame.cpp +++ b/layout/svg/base/src/nsSVGMaskFrame.cpp @@ -103,7 +103,7 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsSVGRenderState *aContext, for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) { - nsSVGUtils::PaintChildWithEffects(aContext, nsnull, kid); + nsSVGUtils::PaintFrameWithEffects(aContext, nsnull, kid); } gfxRect clipExtents = gfx->GetClipExtents(); diff --git a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp index 7e534f1c8faf..e5d555f8586c 100644 --- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp +++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp @@ -448,7 +448,7 @@ public: virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt, HitTestState* aState); virtual void Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx, - const nsRect& aDirtyRect); + const nsRect& aDirtyRect); NS_DISPLAY_DECL_NAME("SVGEventReceiver") }; @@ -462,7 +462,7 @@ nsDisplaySVG::HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt, void nsDisplaySVG::Paint(nsDisplayListBuilder* aBuilder, nsIRenderingContext* aCtx, - const nsRect& aDirtyRect) + const nsRect& aDirtyRect) { static_cast(mFrame)-> Paint(*aCtx, aDirtyRect, aBuilder->ToReferenceFrame(mFrame)); @@ -572,11 +572,7 @@ nsSVGOuterSVGFrame::Paint(nsIRenderingContext& aRenderingContext, } #endif - // paint children: - for (nsIFrame* kid = mFrames.FirstChild(); kid; - kid = kid->GetNextSibling()) { - nsSVGUtils::PaintChildWithEffects(&ctx, &dirtyRect, kid); - } + nsSVGUtils::PaintFrameWithEffects(&ctx, &dirtyRect, this); #ifdef XP_MACOSX if (mEnableBitmapFallback) { @@ -758,6 +754,12 @@ nsSVGOuterSVGFrame::NotifyViewportChange() already_AddRefed nsSVGOuterSVGFrame::GetCanvasTM() { + if (!GetMatrixPropagation()) { + nsIDOMSVGMatrix *retval; + NS_NewSVGMatrix(&retval); + return retval; + } + if (!mCanvasTM) { nsSVGSVGElement *svgElement = static_cast(mContent); diff --git a/layout/svg/base/src/nsSVGPathGeometryFrame.cpp b/layout/svg/base/src/nsSVGPathGeometryFrame.cpp index b8753be314c8..6a503ac1a2f8 100644 --- a/layout/svg/base/src/nsSVGPathGeometryFrame.cpp +++ b/layout/svg/base/src/nsSVGPathGeometryFrame.cpp @@ -114,7 +114,7 @@ nsSVGPathGeometryFrame::GetType() const NS_IMETHODIMP nsSVGPathGeometryFrame::PaintSVG(nsSVGRenderState *aContext, - nsIntRect *aDirtyRect) + const nsIntRect *aDirtyRect) { if (!GetStyleVisibility()->IsVisible()) return NS_OK; diff --git a/layout/svg/base/src/nsSVGPathGeometryFrame.h b/layout/svg/base/src/nsSVGPathGeometryFrame.h index a9a823d313f3..1535338ca952 100644 --- a/layout/svg/base/src/nsSVGPathGeometryFrame.h +++ b/layout/svg/base/src/nsSVGPathGeometryFrame.h @@ -101,7 +101,8 @@ public: protected: // nsISVGChildFrame interface: - NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); NS_IMETHOD_(nsRect) GetCoveredRegion(); NS_IMETHOD UpdateCoveredRegion(); diff --git a/layout/svg/base/src/nsSVGPatternFrame.cpp b/layout/svg/base/src/nsSVGPatternFrame.cpp index cb8327f199a1..f19ce0897b03 100644 --- a/layout/svg/base/src/nsSVGPatternFrame.cpp +++ b/layout/svg/base/src/nsSVGPatternFrame.cpp @@ -293,7 +293,7 @@ nsSVGPatternFrame::PaintPattern(gfxASurface** surface, mPaintLoopFlag = PR_TRUE; for (nsIFrame* kid = firstKid; kid; kid = kid->GetNextSibling()) { - nsSVGUtils::PaintChildWithEffects(&tmpState, nsnull, kid); + nsSVGUtils::PaintFrameWithEffects(&tmpState, nsnull, kid); } mPaintLoopFlag = PR_FALSE; } diff --git a/layout/svg/base/src/nsSVGSwitchFrame.cpp b/layout/svg/base/src/nsSVGSwitchFrame.cpp index 5d7f327d08c1..5e5ffeacb7d5 100644 --- a/layout/svg/base/src/nsSVGSwitchFrame.cpp +++ b/layout/svg/base/src/nsSVGSwitchFrame.cpp @@ -66,7 +66,7 @@ public: #endif // nsISVGChildFrame interface: - NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, const nsIntRect *aDirtyRect); NS_IMETHODIMP_(nsIFrame*) GetFrameForPoint(const nsPoint &aPoint); NS_IMETHODIMP_(nsRect) GetCoveredRegion(); NS_IMETHOD UpdateCoveredRegion(); @@ -100,7 +100,8 @@ nsSVGSwitchFrame::GetType() const } NS_IMETHODIMP -nsSVGSwitchFrame::PaintSVG(nsSVGRenderState* aContext, nsIntRect *aDirtyRect) +nsSVGSwitchFrame::PaintSVG(nsSVGRenderState* aContext, + const nsIntRect *aDirtyRect) { const nsStyleDisplay *display = mStyleContext->GetStyleDisplay(); if (display->mOpacity == 0.0) @@ -108,7 +109,7 @@ nsSVGSwitchFrame::PaintSVG(nsSVGRenderState* aContext, nsIntRect *aDirtyRect) nsIFrame *kid = GetActiveChildFrame(); if (kid) { - nsSVGUtils::PaintChildWithEffects(aContext, aDirtyRect, kid); + nsSVGUtils::PaintFrameWithEffects(aContext, aDirtyRect, kid); } return NS_OK; } diff --git a/layout/svg/base/src/nsSVGTextFrame.cpp b/layout/svg/base/src/nsSVGTextFrame.cpp index 997c054c049f..c632453165d8 100644 --- a/layout/svg/base/src/nsSVGTextFrame.cpp +++ b/layout/svg/base/src/nsSVGTextFrame.cpp @@ -213,7 +213,8 @@ nsSVGTextFrame::NotifyRedrawUnsuspended() } NS_IMETHODIMP -nsSVGTextFrame::PaintSVG(nsSVGRenderState* aContext, nsIntRect *aDirtyRect) +nsSVGTextFrame::PaintSVG(nsSVGRenderState* aContext, + const nsIntRect *aDirtyRect) { UpdateGlyphPositioning(PR_TRUE); diff --git a/layout/svg/base/src/nsSVGTextFrame.h b/layout/svg/base/src/nsSVGTextFrame.h index b4d4f2754e2b..62b5c62bfe2e 100644 --- a/layout/svg/base/src/nsSVGTextFrame.h +++ b/layout/svg/base/src/nsSVGTextFrame.h @@ -79,7 +79,8 @@ public: NS_IMETHOD NotifyRedrawUnsuspended(); // Override these four to ensure that UpdateGlyphPositioning is called // to bring glyph positions up to date - NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, nsIntRect *aDirtyRect); + NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, + const nsIntRect *aDirtyRect); NS_IMETHOD_(nsIFrame*) GetFrameForPoint(const nsPoint & aPoint); NS_IMETHOD UpdateCoveredRegion(); NS_IMETHOD InitialUpdate(); diff --git a/layout/svg/base/src/nsSVGUtils.cpp b/layout/svg/base/src/nsSVGUtils.cpp index ff77bc86f44d..c3e83886b9ed 100644 --- a/layout/svg/base/src/nsSVGUtils.cpp +++ b/layout/svg/base/src/nsSVGUtils.cpp @@ -962,8 +962,8 @@ public: }; void -nsSVGUtils::PaintChildWithEffects(nsSVGRenderState *aContext, - nsIntRect *aDirtyRect, +nsSVGUtils::PaintFrameWithEffects(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect, nsIFrame *aFrame) { nsISVGChildFrame *svgChildFrame; diff --git a/layout/svg/base/src/nsSVGUtils.h b/layout/svg/base/src/nsSVGUtils.h index e300879dd514..68ce78a188e4 100644 --- a/layout/svg/base/src/nsSVGUtils.h +++ b/layout/svg/base/src/nsSVGUtils.h @@ -333,8 +333,8 @@ public: /* Paint SVG frame with SVG effects - aDirtyRect is the area being * redrawn, in device pixel coordinates relative to the outer svg */ static void - PaintChildWithEffects(nsSVGRenderState *aContext, - nsIntRect *aDirtyRect, + PaintFrameWithEffects(nsSVGRenderState *aContext, + const nsIntRect *aDirtyRect, nsIFrame *aFrame); /* Hit testing - check if point hits the clipPath of indicated