Bug 930455 - Convert nsSVGArcConverter to Moz2D. r=heycam
authorJonathan Watt <jwatt@jwatt.org>
Thu, 24 Oct 2013 14:46:38 +0200
changeset 166729 17156fbebbc8ab184d214b6190f6ed8582bce219
parent 166728 36f6d6b62494e2d391ae7a348f71c64d44886f93
child 166730 de354010012d8126c4b02e4a2ee353a44089b6ba
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs930455
milestone27.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 930455 - Convert nsSVGArcConverter to Moz2D. r=heycam
content/svg/content/src/SVGPathData.cpp
content/svg/content/src/SVGPathSegUtils.cpp
content/svg/content/src/nsSVGPathDataParser.cpp
content/svg/content/src/nsSVGPathDataParser.h
--- a/content/svg/content/src/SVGPathData.cpp
+++ b/content/svg/content/src/SVGPathData.cpp
@@ -1,26 +1,30 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "SVGPathData.h"
+
+#include "gfx2DGlue.h"
 #include "gfxPlatform.h"
+#include "mozilla/gfx/Point.h"
 #include "nsError.h"
 #include "nsString.h"
 #include "nsSVGPathDataParser.h"
 #include "nsSVGPathGeometryElement.h" // for nsSVGMark
 #include <stdarg.h>
 #include "SVGContentUtils.h"
 #include "SVGPathSegUtils.h"
 #include "gfxContext.h"
 #include <algorithm>
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 static bool IsMoveto(uint16_t aSegType)
 {
   return aSegType == PATHSEG_MOVETO_ABS ||
          aSegType == PATHSEG_MOVETO_REL;
 }
 
 nsresult
@@ -374,24 +378,31 @@ SVGPathData::ConstructPath(gfxContext *a
       segEnd = gfxPoint(mData[i+5], mData[i+6]);
       if (segType == PATHSEG_ARC_REL) {
         segEnd += segStart;
       }
       if (segEnd != segStart) {
         if (radii.x == 0.0f || radii.y == 0.0f) {
           aCtx->LineTo(segEnd);
         } else {
-          nsSVGArcConverter converter(segStart, segEnd, radii, mData[i+2],
+          nsSVGArcConverter converter(ToPoint(segStart), ToPoint(segEnd),
+                                      ToPoint(radii), mData[i+2],
                                       mData[i+3] != 0, mData[i+4] != 0);
-          while (converter.GetNextSegment(&cp1, &cp2, &segEnd)) {
-            aCtx->CurveTo(cp1, cp2, segEnd);
+          Point cp1, cp2, segEnd_;
+          while (converter.GetNextSegment(&cp1, &cp2, &segEnd_)) {
+            aCtx->CurveTo(ThebesPoint(cp1), ThebesPoint(cp2), ThebesPoint(segEnd_));
           }
+          segEnd = ThebesPoint(segEnd_);
         }
       }
       if (!subpathHasLength) {
+        // Round to make sure the current comparison doesn't fail due to
+        // precision issues:
+        // XXX kill after all code is converted to float precision
+        segStart = ThebesPoint(ToPoint(segStart));
         subpathHasLength = (segEnd != segStart);
       }
       break;
     }
 
     case PATHSEG_LINETO_HORIZONTAL_ABS:
       segEnd = gfxPoint(mData[i], segStart.y);
       aCtx->LineTo(segEnd);
--- a/content/svg/content/src/SVGPathSegUtils.cpp
+++ b/content/svg/content/src/SVGPathSegUtils.cpp
@@ -367,57 +367,51 @@ TraverseCurvetoQuadraticSmoothRel(const 
     aState.cp2 = to;
   }
   aState.pos = to;
 }
 
 static void
 TraverseArcAbs(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to(aArgs[5], aArgs[6]);
+  Point to(aArgs[5], aArgs[6]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     float dist = 0;
-    gfxPoint radii(aArgs[0], aArgs[1]);
-    gfxPoint pos = ThebesPoint(aState.pos);
-    gfxPoint bez[4] = { pos, gfxPoint(0, 0), gfxPoint(0, 0), gfxPoint(0, 0) };
-    nsSVGArcConverter converter(pos, to, radii, aArgs[2],
+    Point radii(aArgs[0], aArgs[1]);
+    Point bez[4] = { aState.pos, Point(0, 0), Point(0, 0), Point(0, 0) };
+    nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2],
                                 aArgs[3] != 0, aArgs[4] != 0);
     while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) {
-      Point moz2dbez[4] = { ToPoint(bez[0]), ToPoint(bez[1]),
-                            ToPoint(bez[2]), ToPoint(bez[3]) };
-      dist += CalcBezLengthHelper(moz2dbez, 4, 0, SplitCubicBezier);
+      dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier);
       bez[0] = bez[3];
     }
     aState.length += dist;
-    aState.cp1 = aState.cp2 = ToPoint(to);
+    aState.cp1 = aState.cp2 = to;
   }
-  aState.pos = ToPoint(to);
+  aState.pos = to;
 }
 
 static void
 TraverseArcRel(const float* aArgs, SVGPathTraversalState& aState)
 {
-  gfxPoint to = ThebesPoint(aState.pos + Point(aArgs[5], aArgs[6]));
+  Point to = aState.pos + Point(aArgs[5], aArgs[6]);
   if (aState.ShouldUpdateLengthAndControlPoints()) {
     float dist = 0;
-    gfxPoint radii(aArgs[0], aArgs[1]);
-    gfxPoint pos = ThebesPoint(aState.pos);
-    gfxPoint bez[4] = { pos, gfxPoint(0, 0), gfxPoint(0, 0), gfxPoint(0, 0) };
-    nsSVGArcConverter converter(pos, to, radii, aArgs[2],
+    Point radii(aArgs[0], aArgs[1]);
+    Point bez[4] = { aState.pos, Point(0, 0), Point(0, 0), Point(0, 0) };
+    nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2],
                                 aArgs[3] != 0, aArgs[4] != 0);
     while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) {
-      Point moz2dbez[4] = { ToPoint(bez[0]), ToPoint(bez[1]),
-                            ToPoint(bez[2]), ToPoint(bez[3]) };
-      dist += CalcBezLengthHelper(moz2dbez, 4, 0, SplitCubicBezier);
+      dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier);
       bez[0] = bez[3];
     }
     aState.length += dist;
-    aState.cp1 = aState.cp2 = ToPoint(to);
+    aState.cp1 = aState.cp2 = to;
   }
-  aState.pos = ToPoint(to);
+  aState.pos = to;
 }
 
 
 typedef void (*TraverseFunc)(const float*, SVGPathTraversalState&);
 
 static TraverseFunc gTraverseFuncTable[NS_SVG_PATH_SEG_TYPE_COUNT] = {
   nullptr, //  0 == PATHSEG_UNKNOWN
   TraverseClosePath,
--- a/content/svg/content/src/nsSVGPathDataParser.cpp
+++ b/content/svg/content/src/nsSVGPathDataParser.cpp
@@ -1,21 +1,24 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsSVGPathDataParser.h"
+
+#include "mozilla/gfx/Point.h"
 #include "nsSVGDataParser.h"
 #include "SVGPathData.h"
 #include "SVGPathSegUtils.h"
 #include <stdlib.h>
 #include <math.h>
 
 using namespace mozilla;
+using namespace mozilla::gfx;
 
 nsresult nsSVGPathDataParser::Match()
 {
   return MatchSvgPath();
 }
 
 //----------------------------------------------------------------------
 
@@ -837,19 +840,19 @@ CalcVectorAngle(double ux, double uy, do
   double ta = atan2(uy, ux);
   double tb = atan2(vy, vx);
   if (tb >= ta)
     return tb-ta;
   return 2 * M_PI - (ta-tb);
 }
 
 
-nsSVGArcConverter::nsSVGArcConverter(const gfxPoint &from,
-                                     const gfxPoint &to,
-                                     const gfxPoint &radii,
+nsSVGArcConverter::nsSVGArcConverter(const Point& from,
+                                     const Point& to,
+                                     const Point& radii,
                                      double angle,
                                      bool largeArcFlag,
                                      bool sweepFlag)
 {
   const double radPerDeg = M_PI/180.0;
   mSegIndex = 0;
 
   if (from == to) {
@@ -909,17 +912,17 @@ nsSVGArcConverter::nsSVGArcConverter(con
   mNumSegs = static_cast<int>(ceil(fabs(dtheta/(M_PI/2.0))));
   mDelta = dtheta/mNumSegs;
   mT = 8.0/3.0 * sin(mDelta/4.0) * sin(mDelta/4.0) / sin(mDelta/2.0);
 
   mFrom = from;
 }
 
 bool
-nsSVGArcConverter::GetNextSegment(gfxPoint *cp1, gfxPoint *cp2, gfxPoint *to)
+nsSVGArcConverter::GetNextSegment(Point* cp1, Point* cp2, Point* to)
 {
   if (mSegIndex == mNumSegs) {
     return false;
   }
   
   double cosTheta1 = cos(mTheta);
   double sinTheta1 = sin(mTheta);
   double theta2 = mTheta + mDelta;
--- a/content/svg/content/src/nsSVGPathDataParser.h
+++ b/content/svg/content/src/nsSVGPathDataParser.h
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef __NS_SVGPATHDATAPARSER_H__
 #define __NS_SVGPATHDATAPARSER_H__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/gfx/Point.h"
 #include "gfxPoint.h"
 #include "nsSVGDataParser.h"
 
 namespace mozilla {
 class SVGPathData;
 }
 
 ////////////////////////////////////////////////////////////////////////
@@ -104,30 +105,32 @@ protected:
                                  float* r1, float* r2, float* angle,
                                  bool* largeArcFlag, bool* sweepFlag);
   bool IsTokenEllipticalArcArgStarter();
   
  };
 
 class nsSVGArcConverter
 {
+  typedef mozilla::gfx::Point Point;
+
 public:
-  nsSVGArcConverter(const gfxPoint &from,
-                    const gfxPoint &to,
-                    const gfxPoint &radii,
+  nsSVGArcConverter(const Point& from,
+                    const Point& to,
+                    const Point& radii,
                     double angle,
                     bool largeArcFlag,
                     bool sweepFlag);
-  bool GetNextSegment(gfxPoint *cp1, gfxPoint *cp2, gfxPoint *to);
+  bool GetNextSegment(Point* cp1, Point* cp2, Point* to);
 protected:
   int32_t mNumSegs, mSegIndex;
   double mTheta, mDelta, mT;
   double mSinPhi, mCosPhi;
   double mRx, mRy;
-  gfxPoint mFrom, mC;
+  Point mFrom, mC;
 };
 
 class nsSVGPathDataParserToInternal : public nsSVGPathDataParser
 {
 public:
   nsSVGPathDataParserToInternal(mozilla::SVGPathData *aList)
     : mPathSegList(aList)
   {}