diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2021-04-15 03:56:04 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-15 17:50:16 +0200 |
commit | 1ea466661f83f8866dfbe60307d015aaafddfb8f (patch) | |
tree | fc123c497bf4049626dcb9fca3702b15aa467cd2 /Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp | |
parent | cb04a441cf1d581585aecc05bac22e42b254a252 (diff) | |
download | serenity-1ea466661f83f8866dfbe60307d015aaafddfb8f.zip |
LibGfx+LibWeb: Move out the EllipticArcTo() logic into Path
At its previous state, the interface allowed invalid "ellipses" to be
specified, instead of doing that, simply use the parameters that SVG
uses :^)
Diffstat (limited to 'Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp')
-rw-r--r-- | Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp | 69 |
1 files changed, 1 insertions, 68 deletions
diff --git a/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp b/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp index 07773c0f72..a6a718aa8d 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGPathElement.cpp @@ -519,10 +519,6 @@ Gfx::Path& SVGPathElement::get_path() double x_axis_rotation = data[2] * M_DEG2RAD; double large_arc_flag = data[3]; double sweep_flag = data[4]; - - double x_axis_rotation_c = cos(x_axis_rotation); - double x_axis_rotation_s = sin(x_axis_rotation); - auto& last_point = path.segments().last().point(); Gfx::FloatPoint next_point; @@ -533,70 +529,7 @@ Gfx::Path& SVGPathElement::get_path() next_point = { data[5] + last_point.x(), data[6] + last_point.y() }; } - // Step 1 of out-of-range radii correction - if (rx == 0.0 || ry == 0.0) { - path.line_to(next_point); - break; - } - - // Step 2 of out-of-range radii correction - if (rx < 0) - rx *= -1.0; - if (ry < 0) - ry *= -1.0; - - // Find (cx, cy), theta_1, theta_delta - // Step 1: Compute (x1', y1') - auto x_avg = (last_point.x() - next_point.x()) / 2.0f; - auto y_avg = (last_point.y() - next_point.y()) / 2.0f; - auto x1p = x_axis_rotation_c * x_avg + x_axis_rotation_s * y_avg; - auto y1p = -x_axis_rotation_s * x_avg + x_axis_rotation_c * y_avg; - - // Step 2: Compute (cx', cy') - double x1p_sq = pow(x1p, 2.0); - double y1p_sq = pow(y1p, 2.0); - double rx_sq = pow(rx, 2.0); - double ry_sq = pow(ry, 2.0); - - // Step 3 of out-of-range radii correction - double lambda = x1p_sq / rx_sq + y1p_sq / ry_sq; - double multiplier; - - if (lambda > 1.0) { - auto lambda_sqrt = sqrt(lambda); - rx *= lambda_sqrt; - ry *= lambda_sqrt; - multiplier = 0.0; - } else { - double numerator = rx_sq * ry_sq - rx_sq * y1p_sq - ry_sq * x1p_sq; - double denominator = rx_sq * y1p_sq + ry_sq * x1p_sq; - multiplier = sqrt(numerator / denominator); - } - - if (large_arc_flag == sweep_flag) - multiplier *= -1.0; - - double cxp = multiplier * rx * y1p / ry; - double cyp = multiplier * -ry * x1p / rx; - - // Step 3: Compute (cx, cy) from (cx', cy') - x_avg = (last_point.x() + next_point.x()) / 2.0f; - y_avg = (last_point.y() + next_point.y()) / 2.0f; - double cx = x_axis_rotation_c * cxp - x_axis_rotation_s * cyp + x_avg; - double cy = x_axis_rotation_s * cxp + x_axis_rotation_c * cyp + y_avg; - - double theta_1 = atan2((y1p - cyp) / ry, (x1p - cxp) / rx); - double theta_2 = atan2((-y1p - cyp) / ry, (-x1p - cxp) / rx); - - auto theta_delta = theta_2 - theta_1; - - if (sweep_flag == 0 && theta_delta > 0.0f) { - theta_delta -= M_TAU; - } else if (sweep_flag != 0 && theta_delta < 0) { - theta_delta += M_TAU; - } - - path.elliptical_arc_to(next_point, { cx, cy }, { rx, ry }, x_axis_rotation, theta_1, theta_delta); + path.elliptical_arc_to(next_point, { rx, ry }, x_axis_rotation, large_arc_flag != 0, sweep_flag != 0); break; } |