Bug 643419 - pathLength should affect stroke-dasharray. r=dholbert
authorRobert Longson <longsonr@gmail.com>
Sun, 01 May 2011 19:26:20 +0100
changeset 68841 13304071441177c847c415ebbd5f14b65f4fefbe
parent 68840 24966d9165554515f2b0a1118af80e8b320b99d6
child 68845 4947d988f65779b722af90175c37fb011bfaac65
push id19774
push userjacek@codeweavers.com
push dateMon, 02 May 2011 11:27:05 +0000
treeherdermozilla-central@133040714411 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs643419
milestone6.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 643419 - pathLength should affect stroke-dasharray. r=dholbert
content/svg/content/src/nsSVGNumber2.cpp
content/svg/content/src/nsSVGNumber2.h
content/svg/content/src/nsSVGPathElement.cpp
content/svg/content/src/nsSVGPathElement.h
content/svg/content/test/Makefile.in
content/svg/content/test/test_pointAtLength.xhtml
layout/reftests/svg/pathLength-01.svg
layout/reftests/svg/pathLength-02.svg
layout/reftests/svg/reftest.list
layout/reftests/svg/smil/motion/animateMotion-mpath-pathLength-1.svg
layout/reftests/svg/smil/motion/reftest.list
layout/reftests/svg/textPath-01-ref.svg
layout/reftests/svg/textPath-01.svg
layout/svg/base/src/nsSVGGeometryFrame.cpp
layout/svg/base/src/nsSVGTextPathFrame.cpp
layout/svg/base/src/nsSVGTextPathFrame.h
--- a/content/svg/content/src/nsSVGNumber2.cpp
+++ b/content/svg/content/src/nsSVGNumber2.cpp
@@ -122,16 +122,17 @@ nsSVGNumber2::SetBaseValueString(const n
   nsresult rv = GetValueFromString(
     aValueAsString, aSVGElement->NumberAttrAllowsPercentage(mAttrEnum), &val);
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   mBaseVal = val;
+  mIsBaseSet = PR_TRUE;
   if (!mIsAnimated) {
     mAnimVal = mBaseVal;
   }
 #ifdef MOZ_SMIL
   else {
     aSVGElement->AnimationNeedsResample();
   }
 #endif
@@ -150,16 +151,17 @@ nsSVGNumber2::GetBaseValueString(nsAStri
 }
 
 void
 nsSVGNumber2::SetBaseValue(float aValue,
                            nsSVGElement *aSVGElement,
                            PRBool aDoSetAttr)
 {
   mBaseVal = aValue;
+  mIsBaseSet = PR_TRUE;
   if (!mIsAnimated) {
     mAnimVal = mBaseVal;
   }
 #ifdef MOZ_SMIL
   else {
     aSVGElement->AnimationNeedsResample();
   }
 #endif
--- a/content/svg/content/src/nsSVGNumber2.h
+++ b/content/svg/content/src/nsSVGNumber2.h
@@ -51,43 +51,53 @@ class nsISMILType;
 class nsSVGNumber2
 {
 
 public:
   void Init(PRUint8 aAttrEnum = 0xff, float aValue = 0) {
     mAnimVal = mBaseVal = aValue;
     mAttrEnum = aAttrEnum;
     mIsAnimated = PR_FALSE;
+    mIsBaseSet = PR_FALSE;
   }
 
   nsresult SetBaseValueString(const nsAString& aValue,
                               nsSVGElement *aSVGElement,
                               PRBool aDoSetAttr);
   void GetBaseValueString(nsAString& aValue);
 
   void SetBaseValue(float aValue, nsSVGElement *aSVGElement, PRBool aDoSetAttr);
   float GetBaseValue() const
     { return mBaseVal; }
   void SetAnimValue(float aValue, nsSVGElement *aSVGElement);
   float GetAnimValue() const
     { return mAnimVal; }
 
+  // Returns PR_TRUE if the animated value of this number has been explicitly
+  // set (either by animation, or by taking on the base value which has been
+  // explicitly set by markup or a DOM call), PR_FALSE otherwise.
+  // If this returns PR_FALSE, the animated value is still valid, that is,
+  // useable, and represents the default base value of the attribute.
+  PRBool IsExplicitlySet() const
+    { return mIsAnimated || mIsBaseSet; }
+
   nsresult ToDOMAnimatedNumber(nsIDOMSVGAnimatedNumber **aResult,
                                nsSVGElement* aSVGElement);
 #ifdef MOZ_SMIL
   // Returns a new nsISMILAttr object that the caller must delete
   nsISMILAttr* ToSMILAttr(nsSVGElement* aSVGElement);
 #endif // MOZ_SMIL
 
 private:
 
   float mAnimVal;
   float mBaseVal;
   PRUint8 mAttrEnum; // element specified tracking for attribute
   PRPackedBool mIsAnimated;
+  PRPackedBool mIsBaseSet;
 
 public:
   struct DOMAnimatedNumber : public nsIDOMSVGAnimatedNumber
   {
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_CYCLE_COLLECTION_CLASS(DOMAnimatedNumber)
 
     DOMAnimatedNumber(nsSVGNumber2* aVal, nsSVGElement *aSVGElement)
--- a/content/svg/content/src/nsSVGPathElement.cpp
+++ b/content/svg/content/src/nsSVGPathElement.cpp
@@ -117,18 +117,21 @@ nsSVGPathElement::GetPointAtLength(float
 {
   NS_ENSURE_FINITE(distance, NS_ERROR_ILLEGAL_VALUE);
 
   nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(gfxMatrix());
   if (!flat)
     return NS_ERROR_FAILURE;
 
   float totalLength = flat->GetLength();
-  if (HasAttr(kNameSpaceID_None, nsGkAtoms::pathLength)) {
+  if (mPathLength.IsExplicitlySet()) {
     float pathLength = mPathLength.GetAnimValue();
+    if (pathLength <= 0) {
+      return NS_ERROR_FAILURE;
+    }
     distance *= totalLength / pathLength;
   }
   distance = NS_MAX(0.f,         distance);
   distance = NS_MIN(totalLength, distance);
 
   NS_ADDREF(*_retval = new DOMSVGPoint(flat->FindPoint(gfxPoint(distance, 0))));
   return NS_OK;
 }
@@ -395,21 +398,18 @@ nsSVGPathElement::GetFlattenedPath(const
 }
 
 //----------------------------------------------------------------------
 // nsSVGPathGeometryElement methods
 
 PRBool
 nsSVGPathElement::AttributeDefinesGeometry(const nsIAtom *aName)
 {
-  if (aName == nsGkAtoms::d ||
-      aName == nsGkAtoms::pathLength)
-    return PR_TRUE;
-
-  return PR_FALSE;
+  return aName == nsGkAtoms::d ||
+         aName == nsGkAtoms::pathLength;
 }
 
 PRBool
 nsSVGPathElement::IsMarkable()
 {
   return PR_TRUE;
 }
 
@@ -420,8 +420,23 @@ nsSVGPathElement::GetMarkPoints(nsTArray
 }
 
 void
 nsSVGPathElement::ConstructPath(gfxContext *aCtx)
 {
   mD.GetAnimValue().ConstructPath(aCtx);
 }
 
+gfxFloat
+nsSVGPathElement::GetScale()
+{
+  if (mPathLength.IsExplicitlySet()) {
+
+    nsRefPtr<gfxFlattenedPath> flat =
+      GetFlattenedPath(PrependLocalTransformTo(gfxMatrix()));
+    float pathLength = mPathLength.GetAnimValue();
+
+    if (flat && pathLength != 0) {
+      return flat->GetLength() / pathLength;
+    }
+  }
+  return 1.0;
+}
--- a/content/svg/content/src/nsSVGPathElement.h
+++ b/content/svg/content/src/nsSVGPathElement.h
@@ -50,17 +50,16 @@ class gfxContext;
 
 typedef nsSVGPathGeometryElement nsSVGPathElementBase;
 
 class nsSVGPathElement : public nsSVGPathElementBase,
                          public nsIDOMSVGPathElement,
                          public nsIDOMSVGAnimatedPathData
 {
 friend class nsSVGPathFrame;
-friend class nsSVGTextPathFrame;
 
 protected:
   friend nsresult NS_NewSVGPathElement(nsIContent **aResult,
                                        already_AddRefed<nsINodeInfo> aNodeInfo);
   nsSVGPathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   typedef mozilla::SVGAnimatedPathSegList SVGAnimatedPathSegList;
@@ -94,16 +93,18 @@ public:
   virtual SVGAnimatedPathSegList* GetAnimPathSegList() {
     return &mD;
   }
 
   virtual nsIAtom* GetPathDataAttrName() const {
     return nsGkAtoms::d;
   }
 
+  gfxFloat GetScale();
+
 protected:
 
   // nsSVGElement method
   virtual NumberAttributesInfo GetNumberInfo();
 
   SVGAnimatedPathSegList mD;
   nsSVGNumber2 mPathLength;
   static NumberInfo sNumberInfo;
--- a/content/svg/content/test/Makefile.in
+++ b/content/svg/content/test/Makefile.in
@@ -68,16 +68,17 @@ include $(topsrcdir)/config/rules.mk
 		getCTM-helper.svg \
 		test_getCTM.html \
 		test_getSubStringLength.xhtml \
 		getSubStringLength-helper.svg \
 		test_isSupported.xhtml \
 		test_nonAnimStrings.xhtml \
 		test_pathAnimInterpolation.xhtml \
 		test_pathSeg.xhtml \
+		test_pointAtLength.xhtml \
 		test_pointer-events.xhtml \
 		test_pointer-events-2.xhtml \
 		test_scientific.html \
 		scientific-helper.svg \
 		test_SVGAnimatedImageSMILDisabled.html \
 		animated-svg-image-helper.html \
 		animated-svg-image-helper.svg \
 		test_stroke-linecap-hit-testing.xhtml \
new file mode 100644
--- /dev/null
+++ b/content/svg/content/test/test_pointAtLength.xhtml
@@ -0,0 +1,50 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=643419
+-->
+<head>
+  <title>Test getPointAtLength</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="text/javascript">
+<![CDATA[
+
+SimpleTest.waitForExplicitFinish();
+
+function run()
+{
+  var p1 = document.getElementById("p1");
+  var point = p1.getPointAtLength(200);
+  is(point.x, 200);
+  is(point.y, 50);
+
+  // set the pathLength to twice its actual length
+  p1.setAttribute("pathLength", "800");
+  var point = p1.getPointAtLength(200);
+  is(point.x, 100);
+  is(point.y, 50);
+
+  SimpleTest.finish();
+}
+
+window.addEventListener("load", run, false);
+]]>
+</script>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=643419">Mozilla Bug 643419</a>
+<p id="display"></p>
+<div id="content">
+
+  <svg xmlns="http://www.w3.org/2000/svg" width="750">
+    <defs>
+      <path id="p1" d="M 0 50 h 400"/>
+    </defs>
+  </svg>
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/pathLength-01.svg
@@ -0,0 +1,12 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg viewBox="0 0 100 2" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
+  <rect width="100%" height="100%" fill="red"/>
+  <!-- This path is really 400 units long (and its halfway point is at the
+       right edge of our viewBox). We use pathLength to normalize its length
+       to 20, though, so the first 10-unit-long dash in stroke-dasharray ends
+       up covering 10/20 = 1/2 of the path. This covers the whole viewBox. -->
+	<path d="M-100,1 h400" pathLength="20" stroke-dasharray="10" fill="none" stroke="lime" stroke-width="2"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/pathLength-02.svg
@@ -0,0 +1,13 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg viewBox="0 0 100 2" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
+  <rect width="100%" height="100%" fill="lime"/>
+  <!-- This path is really 400 units long (and its halfway point is at the
+       right edge of our viewBox). We use pathLength to normalize its length
+       to 20, though, so the first 5-unit-long dash in stroke-dasharray ends
+       up covering 5/20 = 1/4 of the path. The hole in the dasharray spans 
+       the viewBox -->
+	<path d="M-100,1 h400" pathLength="20" stroke-dasharray="5" fill="none" stroke="red" stroke-width="2"/>
+</svg>
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -147,16 +147,18 @@ random-if(gtk2Widget) == objectBoundingB
 == opacity-and-gradient-01.svg pass.svg
 == opacity-and-gradient-02.svg opacity-and-gradient-02-ref.svg
 == opacity-and-pattern-01.svg pass.svg
 == outer-svg-border-and-padding-01.svg outer-svg-border-and-padding-01-ref.svg 
 == path-01.svg path-01-ref.svg
 == path-02.svg pass.svg
 == path-03.svg pass.svg
 == path-04.svg pass.svg
+== pathLength-01.svg pass.svg
+== pathLength-02.svg pass.svg
 == pattern-invalid-01.svg pattern-invalid-01-ref.svg
 == pattern-live-01a.svg pattern-live-01-ref.svg
 == pattern-live-01b.svg pattern-live-01-ref.svg
 == pattern-live-01c.svg pattern-live-01-ref.svg
 == polygon-marker-01.svg pass.svg
 == polygon-points-negative-01.svg pass.svg
 == polyline-points-invalid-01.svg pass.svg
 == pseudo-classes-01.svg pass.svg
@@ -193,16 +195,17 @@ fails-if(Android) != text-language-00.xh
 fails-if(Android) random-if(gtk2Widget) != text-language-01.xhtml text-language-01-ref.xhtml # Fails on Linux tryserver due to lack of CJK fonts.
 == text-layout-01.svg text-layout-01-ref.svg
 == text-layout-02.svg text-layout-02-ref.svg
 == text-layout-03.svg text-layout-03-ref.svg
 == text-scale-01.svg text-scale-01-ref.svg
 == text-stroke-scaling-01.svg text-stroke-scaling-01-ref.svg
 == stroke-linecap-square-w-zero-length-segs-01.svg pass.svg
 == stroke-linecap-square-w-zero-length-segs-02.svg pass.svg
+== textPath-01.svg textPath-01-ref.svg
 == text-style-01a.svg text-style-01-ref.svg
 == text-style-01b.svg text-style-01-ref.svg
 == text-style-01c.svg text-style-01-ref.svg
 == text-style-01d.svg text-style-01-ref.svg
 == text-style-01e.svg text-style-01-ref.svg
 == thin-stroke-01.svg pass.svg
 == tspan-dxdy-01.svg tspan-dxdy-ref.svg
 == tspan-dxdy-02.svg tspan-dxdy-ref.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/smil/motion/animateMotion-mpath-pathLength-1.svg
@@ -0,0 +1,31 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+     xmlns:xlink="http://www.w3.org/1999/xlink" class="reftest-wait">
+  <title>Test that pathLength of paths has no effect in animation</title>
+  <defs>
+    <path id="path" pathLength="100" d="M-200,0 h400" />
+  </defs>
+  <script xlink:href="../smil-util.js" type="text/javascript"/>
+  <script type="text/javascript">
+    function doTest() {
+      setTimeAndSnapshot(0.5, true);
+    }
+    window.addEventListener("MozReftestInvalidate", doTest, false);
+  </script>
+  <rect width="100%" height="100%" fill="lime"/>
+
+  <!-- calcMode="linear" -->
+  <rect x="10" y="10" width="100" height="100" fill="red"/>
+  <rect x="10" y="10" width="100" height="100" fill="lime">
+    <animateMotion dur="1s" keyPoints="0;1" keyTimes="0;1" calcMode="linear">
+      <mpath xlink:href="#path" />
+    </animateMotion>
+  </rect>
+
+  <!-- calcMode="paced" -->
+  <rect x="10" y="110" width="100" height="100" fill="red"/>
+  <rect x="10" y="110" width="100" height="100" fill="lime">
+    <animateMotion dur="1s">
+      <mpath xlink:href="#path" />
+    </animateMotion>
+  </rect>
+</svg>
--- a/layout/reftests/svg/smil/motion/reftest.list
+++ b/layout/reftests/svg/smil/motion/reftest.list
@@ -1,15 +1,16 @@
 # Tests related to SVG Animation (using SMIL), focusing on the animateMotion
 # element.
 
 == animateMotion-by-1.svg      lime.svg
 == animateMotion-from-to-1.svg lime.svg
-== animateMotion-mpath-target-transform-1.svg lime.svg
 == animateMotion-rotate-1a.svg lime.svg
 == animateMotion-rotate-1b.svg lime.svg
 == animateMotion-rotate-2.svg  lime.svg
 == animateMotion-values-linear-1.svg animateMotion-values-linear-1-ref.svg
 == animateMotion-values-paced-1a.svg animateMotion-values-paced-1-ref.svg
 == animateMotion-values-paced-1b.svg animateMotion-values-paced-1-ref.svg
 
 # Tests involving <mpath> sub-element
+== animateMotion-mpath-pathLength-1.svg lime.svg
 == animateMotion-mpath-targetChange-1.svg lime.svg
+== animateMotion-mpath-target-transform-1.svg lime.svg
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/textPath-01-ref.svg
@@ -0,0 +1,16 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <title>Reference to check that percentage startOffset ignores pathLength</title>
+
+  <defs>
+    <path id="x" d="M 0 100 h 400"/>
+  </defs>
+
+  <text>
+    <textPath xlink:href="#x" font-size="20" fill="black" startOffset="50%">Should see this</textPath>
+  </text>
+
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/textPath-01.svg
@@ -0,0 +1,16 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/licenses/publicdomain/
+-->
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <title>Testcase to check that percentage startOffset ignores pathLength</title>
+
+  <defs>
+    <path id="x" pathLength="20" d="M 0 100 h 400"/>
+  </defs>
+	
+  <text>
+    <textPath xlink:href="#x" font-size="20" fill="black" startOffset="50%">Should see this</textPath>
+  </text>
+
+</svg>
--- a/layout/svg/base/src/nsSVGGeometryFrame.cpp
+++ b/layout/svg/base/src/nsSVGGeometryFrame.cpp
@@ -30,16 +30,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsPresContext.h"
+#include "nsSVGPathElement.h"
 #include "nsSVGUtils.h"
 #include "nsSVGGeometryFrame.h"
 #include "nsSVGPaintServerFrame.h"
 #include "nsContentUtils.h"
 #include "gfxContext.h"
 #include "nsSVGEffects.h"
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGGeometryFrame)
@@ -111,23 +112,32 @@ nsSVGGeometryFrame::GetStrokeDashArray(g
   PRUint32 count = GetStyleSVG()->mStrokeDasharrayLength;
   gfxFloat *dashes = nsnull;
 
   if (count) {
     const nsStyleCoord *dasharray = GetStyleSVG()->mStrokeDasharray;
     nsPresContext *presContext = PresContext();
     gfxFloat totalLength = 0.0f;
 
+    gfxFloat pathScale = 1.0;
+
+    if (mContent->Tag() == nsGkAtoms::path) {
+      pathScale = static_cast<nsSVGPathElement*>(mContent)->GetScale();
+      if (pathScale <= 0) {
+        return NS_OK;
+      }
+    }
+
     dashes = new gfxFloat[count];
     if (dashes) {
       for (PRUint32 i = 0; i < count; i++) {
         dashes[i] =
           nsSVGUtils::CoordToFloat(presContext,
                                    ctx,
-                                   dasharray[i]);
+                                   dasharray[i]) * pathScale;
         if (dashes[i] < 0.0f) {
           delete [] dashes;
           return NS_OK;
         }
         totalLength += dashes[i];
       }
     } else {
       return NS_ERROR_OUT_OF_MEMORY;
--- a/layout/svg/base/src/nsSVGTextPathFrame.cpp
+++ b/layout/svg/base/src/nsSVGTextPathFrame.cpp
@@ -137,63 +137,51 @@ nsSVGTextPathFrame::GetPathFrame()
 
   return property->GetReferencedFrame(nsGkAtoms::svgPathGeometryFrame, nsnull);
 }
 
 already_AddRefed<gfxFlattenedPath>
 nsSVGTextPathFrame::GetFlattenedPath()
 {
   nsIFrame *path = GetPathFrame();
-  return path ? GetFlattenedPath(path) : nsnull;
+
+  if (path) {
+    nsSVGPathGeometryElement *element =
+      static_cast<nsSVGPathGeometryElement*>(path->GetContent());
+
+    return element->GetFlattenedPath(element->PrependLocalTransformTo(gfxMatrix()));
+  }
+  return nsnull;
 }
  
-already_AddRefed<gfxFlattenedPath>
-nsSVGTextPathFrame::GetFlattenedPath(nsIFrame *path)
-{
-  NS_PRECONDITION(path, "Unexpected null path");
-
-  nsSVGPathGeometryElement *element =
-    static_cast<nsSVGPathGeometryElement*>(path->GetContent());
-
-  return element->GetFlattenedPath(element->PrependLocalTransformTo(gfxMatrix()));
-}
-
 gfxFloat
 nsSVGTextPathFrame::GetStartOffset()
 {
   nsSVGTextPathElement *tp = static_cast<nsSVGTextPathElement*>(mContent);
   nsSVGLength2 *length = &tp->mLengthAttributes[nsSVGTextPathElement::STARTOFFSET];
   float val = length->GetAnimValInSpecifiedUnits();
 
   if (val == 0.0f)
     return 0.0;
 
   if (length->IsPercentage()) {
     nsRefPtr<gfxFlattenedPath> data = GetFlattenedPath();
     return data ? (val * data->GetLength() / 100.0) : 0.0;
-  } else {
-    return val * GetPathScale();
   }
+  return val * GetPathScale();
 }
 
 gfxFloat
 nsSVGTextPathFrame::GetPathScale() 
 {
   nsIFrame *pathFrame = GetPathFrame();
   if (!pathFrame)
     return 1.0;
 
-  nsSVGPathElement *path = static_cast<nsSVGPathElement*>(pathFrame->GetContent());
-  float pl = path->mPathLength.GetAnimValue();
-
-  if (pl == 0.0f)
-    return 1.0;
-
-  nsRefPtr<gfxFlattenedPath> data = GetFlattenedPath(pathFrame);
-  return data ? data->GetLength() / pl : 1.0; 
+  return static_cast<nsSVGPathElement*>(pathFrame->GetContent())->GetScale();
 }
 
 //----------------------------------------------------------------------
 // nsIFrame methods
 
 NS_IMETHODIMP
 nsSVGTextPathFrame::AttributeChanged(PRInt32         aNameSpaceID,
                                      nsIAtom*        aAttribute,
--- a/layout/svg/base/src/nsSVGTextPathFrame.h
+++ b/layout/svg/base/src/nsSVGTextPathFrame.h
@@ -86,14 +86,11 @@ public:
 
   gfxFloat GetStartOffset();
   gfxFloat GetPathScale();
 protected:
 
   virtual void GetXY(SVGUserUnitList *aX, SVGUserUnitList *aY);
   virtual void GetDxDy(SVGUserUnitList *aDx, SVGUserUnitList *aDy);
   virtual const SVGNumberList *GetRotate();
-
-private:
-  already_AddRefed<gfxFlattenedPath> GetFlattenedPath(nsIFrame *path);
 };
 
 #endif