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 @@
+
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();