diff --git a/content/svg/content/src/SVGPathSegUtils.cpp b/content/svg/content/src/SVGPathSegUtils.cpp index d3a8c13f71d3..60c74d6b0251 100644 --- a/content/svg/content/src/SVGPathSegUtils.cpp +++ b/content/svg/content/src/SVGPathSegUtils.cpp @@ -4,10 +4,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SVGPathSegUtils.h" + +#include "gfx2DGlue.h" #include "nsSVGPathDataParser.h" #include "nsTextFormatter.h" using namespace mozilla; +using namespace mozilla::gfx; static const float PATH_SEG_LENGTH_TOLERANCE = 0.0000001f; static const uint32_t MAX_RECURSION = 10; @@ -80,14 +83,14 @@ SVGPathSegUtils::GetValueAsString(const float* aSeg, nsAString& aValue) static float -CalcDistanceBetweenPoints(const gfxPoint& aP1, const gfxPoint& aP2) +CalcDistanceBetweenPoints(const Point& aP1, const Point& aP2) { return NS_hypot(aP2.x - aP1.x, aP2.y - aP1.y); } static void -SplitQuadraticBezier(const gfxPoint* aCurve, gfxPoint* aLeft, gfxPoint* aRight) +SplitQuadraticBezier(const Point* aCurve, Point* aLeft, Point* aRight) { aLeft[0].x = aCurve[0].x; aLeft[0].y = aCurve[0].y; @@ -102,9 +105,9 @@ SplitQuadraticBezier(const gfxPoint* aCurve, gfxPoint* aLeft, gfxPoint* aRight) } static void -SplitCubicBezier(const gfxPoint* aCurve, gfxPoint* aLeft, gfxPoint* aRight) +SplitCubicBezier(const Point* aCurve, Point* aLeft, Point* aRight) { - gfxPoint tmp; + Point tmp; tmp.x = (aCurve[1].x + aCurve[2].x) / 4; tmp.y = (aCurve[1].y + aCurve[2].y) / 4; aLeft[0].x = aCurve[0].x; @@ -124,12 +127,12 @@ SplitCubicBezier(const gfxPoint* aCurve, gfxPoint* aLeft, gfxPoint* aRight) } static gfxFloat -CalcBezLengthHelper(gfxPoint* aCurve, uint32_t aNumPts, +CalcBezLengthHelper(const Point* aCurve, uint32_t aNumPts, uint32_t aRecursionCount, - void (*aSplit)(const gfxPoint*, gfxPoint*, gfxPoint*)) + void (*aSplit)(const Point*, Point*, Point*)) { - gfxPoint left[4]; - gfxPoint right[4]; + Point left[4]; + Point right[4]; gfxFloat length = 0, dist; for (uint32_t i = 0; i < aNumPts - 1; i++) { length += CalcDistanceBetweenPoints(aCurve[i], aCurve[i+1]); @@ -146,18 +149,18 @@ CalcBezLengthHelper(gfxPoint* aCurve, uint32_t aNumPts, } static inline gfxFloat -CalcLengthOfCubicBezier(const gfxPoint& aPos, const gfxPoint &aCP1, - const gfxPoint& aCP2, const gfxPoint &aTo) +CalcLengthOfCubicBezier(const Point& aPos, const Point &aCP1, + const Point& aCP2, const Point &aTo) { - gfxPoint curve[4] = { aPos, aCP1, aCP2, aTo }; + Point curve[4] = { aPos, aCP1, aCP2, aTo }; return CalcBezLengthHelper(curve, 4, 0, SplitCubicBezier); } static inline gfxFloat -CalcLengthOfQuadraticBezier(const gfxPoint& aPos, const gfxPoint& aCP, - const gfxPoint& aTo) +CalcLengthOfQuadraticBezier(const Point& aPos, const Point& aCP, + const Point& aTo) { - gfxPoint curve[3] = { aPos, aCP, aTo }; + Point curve[3] = { aPos, aCP, aTo }; return CalcBezLengthHelper(curve, 3, 0, SplitQuadraticBezier); } @@ -175,7 +178,7 @@ TraverseClosePath(const float* aArgs, SVGPathTraversalState& aState) static void TraverseMovetoAbs(const float* aArgs, SVGPathTraversalState& aState) { - aState.start = aState.pos = gfxPoint(aArgs[0], aArgs[1]); + aState.start = aState.pos = Point(aArgs[0], aArgs[1]); if (aState.ShouldUpdateLengthAndControlPoints()) { // aState.length is unchanged, since move commands don't affect path length. aState.cp1 = aState.cp2 = aState.start; @@ -185,7 +188,7 @@ TraverseMovetoAbs(const float* aArgs, SVGPathTraversalState& aState) static void TraverseMovetoRel(const float* aArgs, SVGPathTraversalState& aState) { - aState.start = aState.pos += gfxPoint(aArgs[0], aArgs[1]); + aState.start = aState.pos += Point(aArgs[0], aArgs[1]); if (aState.ShouldUpdateLengthAndControlPoints()) { // aState.length is unchanged, since move commands don't affect path length. aState.cp1 = aState.cp2 = aState.start; @@ -195,7 +198,7 @@ TraverseMovetoRel(const float* aArgs, SVGPathTraversalState& aState) static void TraverseLinetoAbs(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to(aArgs[0], aArgs[1]); + Point to(aArgs[0], aArgs[1]); if (aState.ShouldUpdateLengthAndControlPoints()) { aState.length += CalcDistanceBetweenPoints(aState.pos, to); aState.cp1 = aState.cp2 = to; @@ -206,7 +209,7 @@ TraverseLinetoAbs(const float* aArgs, SVGPathTraversalState& aState) static void TraverseLinetoRel(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to = aState.pos + gfxPoint(aArgs[0], aArgs[1]); + Point to = aState.pos + Point(aArgs[0], aArgs[1]); if (aState.ShouldUpdateLengthAndControlPoints()) { aState.length += CalcDistanceBetweenPoints(aState.pos, to); aState.cp1 = aState.cp2 = to; @@ -217,7 +220,7 @@ TraverseLinetoRel(const float* aArgs, SVGPathTraversalState& aState) static void TraverseLinetoHorizontalAbs(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to(aArgs[0], aState.pos.y); + Point to(aArgs[0], aState.pos.y); if (aState.ShouldUpdateLengthAndControlPoints()) { aState.length += fabs(to.x - aState.pos.x); aState.cp1 = aState.cp2 = to; @@ -238,7 +241,7 @@ TraverseLinetoHorizontalRel(const float* aArgs, SVGPathTraversalState& aState) static void TraverseLinetoVerticalAbs(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to(aState.pos.x, aArgs[0]); + Point to(aState.pos.x, aArgs[0]); if (aState.ShouldUpdateLengthAndControlPoints()) { aState.length += fabs(to.y - aState.pos.y); aState.cp1 = aState.cp2 = to; @@ -259,10 +262,10 @@ TraverseLinetoVerticalRel(const float* aArgs, SVGPathTraversalState& aState) static void TraverseCurvetoCubicAbs(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to(aArgs[4], aArgs[5]); + Point to(aArgs[4], aArgs[5]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp1(aArgs[0], aArgs[1]); - gfxPoint cp2(aArgs[2], aArgs[3]); + Point cp1(aArgs[0], aArgs[1]); + Point cp2(aArgs[2], aArgs[3]); aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to); aState.cp2 = cp2; aState.cp1 = to; @@ -273,10 +276,10 @@ TraverseCurvetoCubicAbs(const float* aArgs, SVGPathTraversalState& aState) static void TraverseCurvetoCubicSmoothAbs(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to(aArgs[2], aArgs[3]); + Point to(aArgs[2], aArgs[3]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp1 = aState.pos - (aState.cp2 - aState.pos); - gfxPoint cp2(aArgs[0], aArgs[1]); + Point cp1 = aState.pos - (aState.cp2 - aState.pos); + Point cp2(aArgs[0], aArgs[1]); aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to); aState.cp2 = cp2; aState.cp1 = to; @@ -287,10 +290,10 @@ TraverseCurvetoCubicSmoothAbs(const float* aArgs, SVGPathTraversalState& aState) static void TraverseCurvetoCubicRel(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to = aState.pos + gfxPoint(aArgs[4], aArgs[5]); + Point to = aState.pos + Point(aArgs[4], aArgs[5]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp1 = aState.pos + gfxPoint(aArgs[0], aArgs[1]); - gfxPoint cp2 = aState.pos + gfxPoint(aArgs[2], aArgs[3]); + Point cp1 = aState.pos + Point(aArgs[0], aArgs[1]); + Point cp2 = aState.pos + Point(aArgs[2], aArgs[3]); aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to); aState.cp2 = cp2; aState.cp1 = to; @@ -301,10 +304,10 @@ TraverseCurvetoCubicRel(const float* aArgs, SVGPathTraversalState& aState) static void TraverseCurvetoCubicSmoothRel(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to = aState.pos + gfxPoint(aArgs[2], aArgs[3]); + Point to = aState.pos + Point(aArgs[2], aArgs[3]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp1 = aState.pos - (aState.cp2 - aState.pos); - gfxPoint cp2 = aState.pos + gfxPoint(aArgs[0], aArgs[1]); + Point cp1 = aState.pos - (aState.cp2 - aState.pos); + Point cp2 = aState.pos + Point(aArgs[0], aArgs[1]); aState.length += (float)CalcLengthOfCubicBezier(aState.pos, cp1, cp2, to); aState.cp2 = cp2; aState.cp1 = to; @@ -315,9 +318,9 @@ TraverseCurvetoCubicSmoothRel(const float* aArgs, SVGPathTraversalState& aState) static void TraverseCurvetoQuadraticAbs(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to(aArgs[2], aArgs[3]); + Point to(aArgs[2], aArgs[3]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp(aArgs[0], aArgs[1]); + Point cp(aArgs[0], aArgs[1]); aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to); aState.cp1 = cp; aState.cp2 = to; @@ -329,9 +332,9 @@ static void TraverseCurvetoQuadraticSmoothAbs(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to(aArgs[0], aArgs[1]); + Point to(aArgs[0], aArgs[1]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp = aState.pos - (aState.cp1 - aState.pos); + Point cp = aState.pos - (aState.cp1 - aState.pos); aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to); aState.cp1 = cp; aState.cp2 = to; @@ -342,9 +345,9 @@ TraverseCurvetoQuadraticSmoothAbs(const float* aArgs, static void TraverseCurvetoQuadraticRel(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to = aState.pos + gfxPoint(aArgs[2], aArgs[3]); + Point to = aState.pos + Point(aArgs[2], aArgs[3]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp = aState.pos + gfxPoint(aArgs[0], aArgs[1]); + Point cp = aState.pos + Point(aArgs[0], aArgs[1]); aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to); aState.cp1 = cp; aState.cp2 = to; @@ -356,9 +359,9 @@ static void TraverseCurvetoQuadraticSmoothRel(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to = aState.pos + gfxPoint(aArgs[0], aArgs[1]); + Point to = aState.pos + Point(aArgs[0], aArgs[1]); if (aState.ShouldUpdateLengthAndControlPoints()) { - gfxPoint cp = aState.pos - (aState.cp1 - aState.pos); + Point cp = aState.pos - (aState.cp1 - aState.pos); aState.length += (float)CalcLengthOfQuadraticBezier(aState.pos, cp, to); aState.cp1 = cp; aState.cp2 = to; @@ -373,39 +376,43 @@ TraverseArcAbs(const float* aArgs, SVGPathTraversalState& aState) if (aState.ShouldUpdateLengthAndControlPoints()) { float dist = 0; gfxPoint radii(aArgs[0], aArgs[1]); - gfxPoint bez[4] = { aState.pos, gfxPoint(0, 0), - gfxPoint(0, 0), gfxPoint(0, 0) }; - nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2], + 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], aArgs[3] != 0, aArgs[4] != 0); while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) { - dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier); + Point moz2dbez[4] = { ToPoint(bez[0]), ToPoint(bez[1]), + ToPoint(bez[2]), ToPoint(bez[3]) }; + dist += CalcBezLengthHelper(moz2dbez, 4, 0, SplitCubicBezier); bez[0] = bez[3]; } aState.length += dist; - aState.cp1 = aState.cp2 = to; + aState.cp1 = aState.cp2 = ToPoint(to); } - aState.pos = to; + aState.pos = ToPoint(to); } static void TraverseArcRel(const float* aArgs, SVGPathTraversalState& aState) { - gfxPoint to = aState.pos + gfxPoint(aArgs[5], aArgs[6]); + gfxPoint to = ThebesPoint(aState.pos + Point(aArgs[5], aArgs[6])); if (aState.ShouldUpdateLengthAndControlPoints()) { float dist = 0; gfxPoint radii(aArgs[0], aArgs[1]); - gfxPoint bez[4] = { aState.pos, gfxPoint(0, 0), - gfxPoint(0, 0), gfxPoint(0, 0) }; - nsSVGArcConverter converter(aState.pos, to, radii, aArgs[2], + 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], aArgs[3] != 0, aArgs[4] != 0); while (converter.GetNextSegment(&bez[1], &bez[2], &bez[3])) { - dist += CalcBezLengthHelper(bez, 4, 0, SplitCubicBezier); + Point moz2dbez[4] = { ToPoint(bez[0]), ToPoint(bez[1]), + ToPoint(bez[2]), ToPoint(bez[3]) }; + dist += CalcBezLengthHelper(moz2dbez, 4, 0, SplitCubicBezier); bez[0] = bez[3]; } aState.length += dist; - aState.cp1 = aState.cp2 = to; + aState.cp1 = aState.cp2 = ToPoint(to); } - aState.pos = to; + aState.pos = ToPoint(to); } diff --git a/content/svg/content/src/SVGPathSegUtils.h b/content/svg/content/src/SVGPathSegUtils.h index f386dd4b8edc..521257cb67cf 100644 --- a/content/svg/content/src/SVGPathSegUtils.h +++ b/content/svg/content/src/SVGPathSegUtils.h @@ -7,6 +7,7 @@ #define MOZILLA_SVGPATHSEGUTILS_H__ #include "gfxPoint.h" +#include "mozilla/gfx/Point.h" #include "nsDebug.h" #include "nsMemory.h" @@ -46,6 +47,8 @@ static const unsigned short PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; */ struct SVGPathTraversalState { + typedef gfx::Point Point; + enum TraversalMode { eUpdateAll, eUpdateOnlyStartAndCurrentPos @@ -62,17 +65,17 @@ struct SVGPathTraversalState bool ShouldUpdateLengthAndControlPoints() { return mode == eUpdateAll; } - gfxPoint start; // start point of current sub path (reset each moveto) + Point start; // start point of current sub path (reset each moveto) - gfxPoint pos; // current position (end point of previous segment) + Point pos; // current position (end point of previous segment) - gfxPoint cp1; // quadratic control point - if the previous segment was a - // quadratic bezier curve then this is set to the absolute - // position of its control point, otherwise its set to pos + Point cp1; // quadratic control point - if the previous segment was a + // quadratic bezier curve then this is set to the absolute + // position of its control point, otherwise its set to pos - gfxPoint cp2; // cubic control point - if the previous segment was a cubic - // bezier curve then this is set to the absolute position of - // its second control point, otherwise it's set to pos + Point cp2; // cubic control point - if the previous segment was a cubic + // bezier curve then this is set to the absolute position of + // its second control point, otherwise it's set to pos float length; // accumulated path length