diff --git a/content/svg/content/src/nsSVGForeignObjectElement.cpp b/content/svg/content/src/nsSVGForeignObjectElement.cpp index 73a608739cc..863262fa28c 100644 --- a/content/svg/content/src/nsSVGForeignObjectElement.cpp +++ b/content/svg/content/src/nsSVGForeignObjectElement.cpp @@ -104,21 +104,6 @@ NS_IMETHODIMP nsSVGForeignObjectElement::GetHeight(nsIDOMSVGAnimatedLength * *aH return mLengthAttributes[HEIGHT].ToDOMAnimatedLength(aHeight, this); } -//---------------------------------------------------------------------- -// nsSVGElement methods - -/* virtual */ gfxMatrix -nsSVGForeignObjectElement::PrependLocalTransformTo(const gfxMatrix &aMatrix) -{ - // 'transform' attribute: - gfxMatrix matrix = nsSVGForeignObjectElementBase::PrependLocalTransformTo(aMatrix); - - // now translate by our 'x' and 'y': - float x, y; - GetAnimatedLengthValues(&x, &y, nsnull); - return gfxMatrix().Translate(gfxPoint(x, y)) * matrix; -} - //---------------------------------------------------------------------- // nsIContent methods diff --git a/content/svg/content/src/nsSVGForeignObjectElement.h b/content/svg/content/src/nsSVGForeignObjectElement.h index 76263b0eb46..7b949370bfd 100644 --- a/content/svg/content/src/nsSVGForeignObjectElement.h +++ b/content/svg/content/src/nsSVGForeignObjectElement.h @@ -66,9 +66,6 @@ public: NS_FORWARD_NSIDOMELEMENT(nsSVGForeignObjectElementBase::) NS_FORWARD_NSIDOMSVGELEMENT(nsSVGForeignObjectElementBase::) - // nsSVGElement specializations: - virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix); - // nsIContent interface NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* name) const; diff --git a/layout/reftests/svg/clipPath-basic-05.svg b/layout/reftests/svg/clipPath-basic-05.svg new file mode 100644 index 00000000000..d4240a86234 --- /dev/null +++ b/layout/reftests/svg/clipPath-basic-05.svg @@ -0,0 +1,22 @@ + + + Testcase for basic clipPath on foreignObject + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index d09e307bbd4..ad3383ee665 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -26,6 +26,7 @@ include svg-integration/reftest.list == clipPath-basic-02.svg pass.svg == clipPath-basic-03.svg pass.svg == clipPath-basic-04.svg pass.svg +== clipPath-basic-05.svg pass.svg == clipPath-winding-01.svg pass.svg == clip-surface-clone-01.svg clip-surface-clone-01-ref.svg == conditions-01.svg pass.svg diff --git a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp index 62348b042f1..576cc7b837e 100644 --- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp @@ -206,12 +206,11 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext, if (!kid) return NS_OK; - gfxMatrix matrixForChildren = GetCanvasTMForChildren(); - gfxMatrix matrix = GetCanvasTM(); + gfxMatrix matrix = GetCanvasTMWithTranslation(); nsIRenderingContext *ctx = aContext->GetRenderingContext(this); - if (!ctx || matrixForChildren.IsSingular()) { + if (!ctx || matrix.IsSingular()) { NS_WARNING("Can't render foreignObject element!"); return NS_ERROR_FAILURE; } @@ -237,7 +236,7 @@ nsSVGForeignObjectFrame::PaintSVG(nsSVGRenderState *aContext, nsSVGUtils::SetClipRect(gfx, matrix, clipRect); } - gfx->Multiply(matrixForChildren); + gfx->Multiply(GetScaledMatrixForChildren(matrix)); // Transform the dirty rect into the rectangle containing the // transformed dirty rect. @@ -277,7 +276,7 @@ nsSVGForeignObjectFrame::GetTransformMatrix(nsIFrame **aOutAncestor) NS_ASSERTION(*aOutAncestor, "How did we end up without an outer frame?"); /* Return the matrix back to the root, factoring in the x and y offsets. */ - return GetCanvasTMForChildren(); + return GetScaledMatrixForChildren(GetCanvasTMWithTranslation()); } NS_IMETHODIMP_(nsIFrame*) @@ -290,11 +289,7 @@ nsSVGForeignObjectFrame::GetFrameForPoint(const nsPoint &aPoint) if (!kid) return nsnull; - float x, y, width, height; - static_cast(mContent)-> - GetAnimatedLengthValues(&x, &y, &width, &height, nsnull); - - gfxMatrix tm = GetCanvasTM().Invert(); + gfxMatrix tm = GetCanvasTMWithTranslation().Invert(); if (tm.IsSingular()) return nsnull; @@ -303,6 +298,10 @@ nsSVGForeignObjectFrame::GetFrameForPoint(const nsPoint &aPoint) gfxPoint pt = gfxPoint(aPoint.x, aPoint.y) / PresContext()->AppUnitsPerDevPixel(); pt = tm.Transform(pt); + float x, y, width, height; + static_cast(mContent)-> + GetAnimatedLengthValues(&x, &y, &width, &height, nsnull); + if (!gfxRect(0.0f, 0.0f, width, height).Contains(pt)) return nsnull; @@ -338,8 +337,8 @@ nsSVGForeignObjectFrame::UpdateCoveredRegion() if (w < 0.0f) w = 0.0f; if (h < 0.0f) h = 0.0f; - // GetCanvasTM includes the x,y translation - mRect = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTM(), PresContext()); + mRect = ToCanvasBounds(gfxRect(0.0, 0.0, w, h), GetCanvasTMWithTranslation(), + PresContext()); return NS_OK; } @@ -453,11 +452,9 @@ nsSVGForeignObjectFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace) NS_ASSERTION(!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD), "Should not be calling this on a non-display child"); - nsSVGForeignObjectElement *content = - static_cast(mContent); - float x, y, w, h; - content->GetAnimatedLengthValues(&x, &y, &w, &h, nsnull); + static_cast(mContent)-> + GetAnimatedLengthValues(&x, &y, &w, &h, nsnull); if (w < 0.0f) w = 0.0f; if (h < 0.0f) h = 0.0f; @@ -492,12 +489,22 @@ nsSVGForeignObjectFrame::GetCanvasTM() // Implementation helpers gfxMatrix -nsSVGForeignObjectFrame::GetCanvasTMForChildren() +nsSVGForeignObjectFrame::GetCanvasTMWithTranslation() +{ + float x, y; + static_cast(mContent)-> + GetAnimatedLengthValues(&x, &y, nsnull); + + return (gfxMatrix().Translate(gfxPoint(x, y)) * GetCanvasTM()); +} + +gfxMatrix +nsSVGForeignObjectFrame::GetScaledMatrixForChildren(gfxMatrix canvasTMWithTranslation) const { float cssPxPerDevPx = PresContext()-> AppUnitsToFloatCSSPixels(PresContext()->AppUnitsPerDevPixel()); - return GetCanvasTM().Scale(cssPxPerDevPx, cssPxPerDevPx); + return canvasTMWithTranslation.Scale(cssPxPerDevPx, cssPxPerDevPx); } void nsSVGForeignObjectFrame::RequestReflow(nsIPresShell::IntrinsicDirty aType) @@ -630,7 +637,7 @@ nsSVGForeignObjectFrame::InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter, gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height); r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel()); - nsRect rect = ToCanvasBounds(r, GetCanvasTM(), PresContext()); + nsRect rect = ToCanvasBounds(r, GetCanvasTMWithTranslation(), PresContext()); // Don't invalidate areas outside our bounds: rect.IntersectRect(rect, mRect); diff --git a/layout/svg/base/src/nsSVGForeignObjectFrame.h b/layout/svg/base/src/nsSVGForeignObjectFrame.h index e34a9047023..f68a235eb47 100644 --- a/layout/svg/base/src/nsSVGForeignObjectFrame.h +++ b/layout/svg/base/src/nsSVGForeignObjectFrame.h @@ -145,9 +145,10 @@ protected: void RequestReflow(nsIPresShell::IntrinsicDirty aType); void UpdateGraphic(); - // Returns GetCanvasTM followed by a scale from CSS px to Dev px. Used for - // painting, because children expect to paint to device space, not userspace. - gfxMatrix GetCanvasTMForChildren(); + gfxMatrix GetCanvasTMWithTranslation(); + // Scale TM from CSS px to Dev px. Used for painting, because children + // expect to paint to device space, not userspace. + gfxMatrix GetScaledMatrixForChildren(gfxMatrix canvasTMWithTranslation) const; void InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter, const nsRect& aRect, PRUint32 aFlags); void FlushDirtyRegion();