diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list
index c400b775f565..e39261d96ffd 100644
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -149,6 +149,7 @@ fails == inline-in-xul-basic-01.xul pass.svg
random-if(gtk2Widget) == text-font-weight-01.svg text-font-weight-01-ref.svg # bug 386713
== switch-01.svg pass.svg
== text-gradient-01.svg text-gradient-01-ref.svg
+== text-gradient-02.svg text-gradient-02-ref.svg
== text-in-link-01.svg text-in-link-01-ref.svg
== text-in-link-02.svg text-in-link-02-ref.svg
== text-in-link-03.svg text-in-link-03-ref.svg
diff --git a/layout/reftests/svg/text-gradient-02-ref.svg b/layout/reftests/svg/text-gradient-02-ref.svg
new file mode 100644
index 000000000000..38f78b520e8f
--- /dev/null
+++ b/layout/reftests/svg/text-gradient-02-ref.svg
@@ -0,0 +1,22 @@
+
+
diff --git a/layout/reftests/svg/text-gradient-02.svg b/layout/reftests/svg/text-gradient-02.svg
new file mode 100644
index 000000000000..70a71102a544
--- /dev/null
+++ b/layout/reftests/svg/text-gradient-02.svg
@@ -0,0 +1,23 @@
+
+
diff --git a/layout/svg/base/src/nsSVGContainerFrame.cpp b/layout/svg/base/src/nsSVGContainerFrame.cpp
index a72a182183cd..f92d20d32f6e 100644
--- a/layout/svg/base/src/nsSVGContainerFrame.cpp
+++ b/layout/svg/base/src/nsSVGContainerFrame.cpp
@@ -270,13 +270,10 @@ nsSVGDisplayContainerFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspac
nsISVGChildFrame* svgKid = do_QueryFrame(kid);
if (svgKid) {
gfxMatrix transform = aToBBoxUserspace;
- // nsSVGGlyphFrame's mContent is a nsTextNode!
- if (kid->GetType() != nsGkAtoms::svgGlyphFrame) {
- nsIContent *content = kid->GetContent();
- if (content->IsSVG()) {
- transform = static_cast(content)->
- PrependLocalTransformTo(aToBBoxUserspace);
- }
+ nsIContent *content = kid->GetContent();
+ if (content->IsSVG() && !content->IsNodeOfType(nsINode::eTEXT)) {
+ transform = static_cast(content)->
+ PrependLocalTransformTo(aToBBoxUserspace);
}
bboxUnion = bboxUnion.Union(svgKid->GetBBoxContribution(transform));
}
diff --git a/layout/svg/base/src/nsSVGGeometryFrame.cpp b/layout/svg/base/src/nsSVGGeometryFrame.cpp
index faed7435099b..fab303edc355 100644
--- a/layout/svg/base/src/nsSVGGeometryFrame.cpp
+++ b/layout/svg/base/src/nsSVGGeometryFrame.cpp
@@ -88,7 +88,7 @@ float
nsSVGGeometryFrame::GetStrokeWidth()
{
nsSVGElement *ctx = static_cast
- (GetType() == nsGkAtoms::svgGlyphFrame ?
+ (mContent->IsNodeOfType(nsINode::eTEXT) ?
mContent->GetParent() : mContent);
return
@@ -101,7 +101,7 @@ nsresult
nsSVGGeometryFrame::GetStrokeDashArray(gfxFloat **aDashes, PRUint32 *aCount)
{
nsSVGElement *ctx = static_cast
- (GetType() == nsGkAtoms::svgGlyphFrame ?
+ (mContent->IsNodeOfType(nsINode::eTEXT) ?
mContent->GetParent() : mContent);
*aDashes = nsnull;
*aCount = 0;
@@ -147,7 +147,7 @@ float
nsSVGGeometryFrame::GetStrokeDashoffset()
{
nsSVGElement *ctx = static_cast
- (GetType() == nsGkAtoms::svgGlyphFrame ?
+ (mContent->IsNodeOfType(nsINode::eTEXT) ?
mContent->GetParent() : mContent);
return
diff --git a/layout/svg/base/src/nsSVGGradientFrame.cpp b/layout/svg/base/src/nsSVGGradientFrame.cpp
index 18367346fd91..a652e6d04e93 100644
--- a/layout/svg/base/src/nsSVGGradientFrame.cpp
+++ b/layout/svg/base/src/nsSVGGradientFrame.cpp
@@ -164,9 +164,7 @@ nsSVGGradientFrame::GetGradientTransform(nsIFrame *aSource,
"Unknown gradientUnits type");
// objectBoundingBox is the default anyway
- nsIFrame *frame = aSource->GetContent()->IsNodeOfType(nsINode::eTEXT) ?
- aSource->GetParent() : aSource;
- gfxRect bbox = aOverrideBounds ? *aOverrideBounds : nsSVGUtils::GetBBox(frame);
+ gfxRect bbox = aOverrideBounds ? *aOverrideBounds : nsSVGUtils::GetBBox(aSource);
bboxMatrix = gfxMatrix(bbox.Width(), 0, 0, bbox.Height(), bbox.X(), bbox.Y());
}
diff --git a/layout/svg/base/src/nsSVGPatternFrame.cpp b/layout/svg/base/src/nsSVGPatternFrame.cpp
index af759101c40c..ceb9da10f5a3 100644
--- a/layout/svg/base/src/nsSVGPatternFrame.cpp
+++ b/layout/svg/base/src/nsSVGPatternFrame.cpp
@@ -614,17 +614,7 @@ nsSVGPatternFrame::GetTargetGeometry(gfxMatrix *aCTM,
nsIFrame *aTarget,
const gfxRect *aOverrideBounds)
{
- // If we are attempting to paint a pattern for text, then the content will be
- // the #text, so we actually want the parent, which should be the
- // or element.
- if (aTarget->GetContent()->IsNodeOfType(nsINode::eTEXT)) {
- *aBBox = nsSVGUtils::GetBBox(aTarget->GetParent());
- } else {
- *aBBox = nsSVGUtils::GetBBox(aTarget);
- }
- if (aOverrideBounds) {
- *aBBox = *aOverrideBounds;
- }
+ *aBBox = aOverrideBounds ? *aOverrideBounds : nsSVGUtils::GetBBox(aTarget);
// Sanity check
PRUint16 type = GetPatternUnits();
diff --git a/layout/svg/base/src/nsSVGUtils.cpp b/layout/svg/base/src/nsSVGUtils.cpp
index 955513c10b9b..b9a86e7e779c 100644
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -67,6 +67,7 @@
#include "nsSVGClipPathFrame.h"
#include "nsSVGMaskFrame.h"
#include "nsSVGContainerFrame.h"
+#include "nsSVGTextContainerFrame.h"
#include "nsSVGLength2.h"
#include "nsGenericElement.h"
#include "nsSVGGraphicElement.h"
@@ -1357,9 +1358,23 @@ nsSVGUtils::ClipToGfxRect(nsIntRect* aRect, const gfxRect& aGfxRect)
gfxRect
nsSVGUtils::GetBBox(nsIFrame *aFrame)
{
+ if (aFrame->GetContent()->IsNodeOfType(nsINode::eTEXT)) {
+ aFrame = aFrame->GetParent();
+ }
gfxRect bbox;
nsISVGChildFrame *svg = do_QueryFrame(aFrame);
if (svg) {
+ // 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.
+ nsSVGTextContainerFrame* metrics = do_QueryFrame(aFrame);
+ if (metrics) {
+ while (aFrame->GetType() != nsGkAtoms::svgTextFrame) {
+ aFrame = aFrame->GetParent();
+ }
+ svg = do_QueryFrame(aFrame);
+ }
bbox = svg->GetBBoxContribution(gfxMatrix());
} else {
bbox = nsSVGIntegrationUtils::GetSVGBBoxForNonSVGFrame(aFrame);