From f6e81a48e68f7f08cb15805e1708854863e8ed1b Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Tue, 2 Jun 2015 10:47:15 -0400 Subject: [PATCH] Bug 1167026 - Avoid division by zero when flattening a bezier curve segment with equal control points. r=bas --- gfx/2d/Path.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/gfx/2d/Path.cpp b/gfx/2d/Path.cpp index a276609bef15..35c0232b1af2 100644 --- a/gfx/2d/Path.cpp +++ b/gfx/2d/Path.cpp @@ -250,12 +250,19 @@ FlattenBezierCurveSegment(const BezierControlPoints &aControlPoints, Point cp21 = currentCP.mCP2 - currentCP.mCP3; Point cp31 = currentCP.mCP3 - currentCP.mCP1; - Float s3 = (cp31.x * cp21.y - cp31.y * cp21.x) / hypotf(cp21.x, cp21.y); - - t = 2 * Float(sqrt(aTolerance / (3. * std::abs(s3)))); + /* To remove divisions and check for divide-by-zero, this is optimized from: + * Float s3 = (cp31.x * cp21.y - cp31.y * cp21.x) / hypotf(cp21.x, cp21.y); + * t = 2 * Float(sqrt(aTolerance / (3. * std::abs(s3)))); + */ + Float cp21x31 = cp31.x * cp21.y - cp31.y * cp21.x; + Float h = hypotf(cp21.x, cp21.y); + if (cp21x31 * h == 0) { + break; + } + Float s3inv = h / cp21x31; + t = 2 * Float(sqrt(aTolerance * std::abs(s3inv) / 3.)); if (t >= 1.0f) { - aSink->LineTo(aControlPoints.mCP4); break; } @@ -264,6 +271,8 @@ FlattenBezierCurveSegment(const BezierControlPoints &aControlPoints, aSink->LineTo(currentCP.mCP1); } + + aSink->LineTo(currentCP.mCP4); } static inline void