OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2002, 2003 The Karbon Developers | 2 * Copyright (C) 2002, 2003 The Karbon Developers |
3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> | 3 * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> |
4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> | 4 * Copyright (C) 2006, 2007 Rob Buis <buis@kde.org> |
5 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. | 5 * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. |
6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
7 * | 7 * |
8 * This library is free software; you can redistribute it and/or | 8 * This library is free software; you can redistribute it and/or |
9 * modify it under the terms of the GNU Library General Public | 9 * modify it under the terms of the GNU Library General Public |
10 * License as published by the Free Software Foundation; either | 10 * License as published by the Free Software Foundation; either |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 m_currentPoint = normSeg.targetPoint; | 161 m_currentPoint = normSeg.targetPoint; |
162 | 162 |
163 if (!isCubicCommand(segment.command) && !isQuadraticCommand(segment.command)) | 163 if (!isCubicCommand(segment.command) && !isQuadraticCommand(segment.command)) |
164 m_controlPoint = m_currentPoint; | 164 m_controlPoint = m_currentPoint; |
165 | 165 |
166 m_lastCommand = segment.command; | 166 m_lastCommand = segment.command; |
167 } | 167 } |
168 | 168 |
169 // This works by converting the SVG arc to "simple" beziers. | 169 // This works by converting the SVG arc to "simple" beziers. |
170 // Partly adapted from Niko's code in kdelibs/kdecore/svgicons. | 170 // Partly adapted from Niko's code in kdelibs/kdecore/svgicons. |
171 // See also SVG implementation notes: http://www.w3.org/TR/SVG/implnote.html#Arc
ConversionEndpointToCenter | 171 // See also SVG implementation notes: |
| 172 // http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter |
172 bool SVGPathNormalizer::decomposeArcToCubic(const FloatPoint& currentPoint, | 173 bool SVGPathNormalizer::decomposeArcToCubic(const FloatPoint& currentPoint, |
173 const PathSegmentData& arcSegment) { | 174 const PathSegmentData& arcSegment) { |
174 // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a
"lineto") joining the endpoints. | 175 // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a |
| 176 // "lineto") joining the endpoints. |
175 // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters | 177 // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters |
176 float rx = fabsf(arcSegment.arcRadii().x()); | 178 float rx = fabsf(arcSegment.arcRadii().x()); |
177 float ry = fabsf(arcSegment.arcRadii().y()); | 179 float ry = fabsf(arcSegment.arcRadii().y()); |
178 if (!rx || !ry) | 180 if (!rx || !ry) |
179 return false; | 181 return false; |
180 | 182 |
181 // If the current point and target point for the arc are identical, it should
be treated as a zero length | 183 // If the current point and target point for the arc are identical, it should |
182 // path. This ensures continuity in animations. | 184 // be treated as a zero length path. This ensures continuity in animations. |
183 if (arcSegment.targetPoint == currentPoint) | 185 if (arcSegment.targetPoint == currentPoint) |
184 return false; | 186 return false; |
185 | 187 |
186 float angle = arcSegment.arcAngle(); | 188 float angle = arcSegment.arcAngle(); |
187 | 189 |
188 FloatSize midPointDistance = currentPoint - arcSegment.targetPoint; | 190 FloatSize midPointDistance = currentPoint - arcSegment.targetPoint; |
189 midPointDistance.scale(0.5f); | 191 midPointDistance.scale(0.5f); |
190 | 192 |
191 AffineTransform pointTransform; | 193 AffineTransform pointTransform; |
192 pointTransform.rotate(-angle); | 194 pointTransform.rotate(-angle); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 float thetaArc = theta2 - theta1; | 234 float thetaArc = theta2 - theta1; |
233 if (thetaArc < 0 && arcSegment.arcSweep) | 235 if (thetaArc < 0 && arcSegment.arcSweep) |
234 thetaArc += twoPiFloat; | 236 thetaArc += twoPiFloat; |
235 else if (thetaArc > 0 && !arcSegment.arcSweep) | 237 else if (thetaArc > 0 && !arcSegment.arcSweep) |
236 thetaArc -= twoPiFloat; | 238 thetaArc -= twoPiFloat; |
237 | 239 |
238 pointTransform.makeIdentity(); | 240 pointTransform.makeIdentity(); |
239 pointTransform.rotate(angle); | 241 pointTransform.rotate(angle); |
240 pointTransform.scale(rx, ry); | 242 pointTransform.scale(rx, ry); |
241 | 243 |
242 // Some results of atan2 on some platform implementations are not exact enough
. So that we get more | 244 // Some results of atan2 on some platform implementations are not exact |
243 // cubic curves than expected here. Adding 0.001f reduces the count of sgement
s to the correct count. | 245 // enough. So that we get more cubic curves than expected here. Adding 0.001f |
| 246 // reduces the count of sgements to the correct count. |
244 int segments = ceilf(fabsf(thetaArc / (piOverTwoFloat + 0.001f))); | 247 int segments = ceilf(fabsf(thetaArc / (piOverTwoFloat + 0.001f))); |
245 for (int i = 0; i < segments; ++i) { | 248 for (int i = 0; i < segments; ++i) { |
246 float startTheta = theta1 + i * thetaArc / segments; | 249 float startTheta = theta1 + i * thetaArc / segments; |
247 float endTheta = theta1 + (i + 1) * thetaArc / segments; | 250 float endTheta = theta1 + (i + 1) * thetaArc / segments; |
248 | 251 |
249 float t = (8 / 6.f) * tanf(0.25f * (endTheta - startTheta)); | 252 float t = (8 / 6.f) * tanf(0.25f * (endTheta - startTheta)); |
250 if (!std::isfinite(t)) | 253 if (!std::isfinite(t)) |
251 return false; | 254 return false; |
252 float sinStartTheta = sinf(startTheta); | 255 float sinStartTheta = sinf(startTheta); |
253 float cosStartTheta = cosf(startTheta); | 256 float cosStartTheta = cosf(startTheta); |
(...skipping 13 matching lines...) Expand all Loading... |
267 cubicSegment.point1 = pointTransform.mapPoint(point1); | 270 cubicSegment.point1 = pointTransform.mapPoint(point1); |
268 cubicSegment.point2 = pointTransform.mapPoint(point2); | 271 cubicSegment.point2 = pointTransform.mapPoint(point2); |
269 cubicSegment.targetPoint = pointTransform.mapPoint(targetPoint); | 272 cubicSegment.targetPoint = pointTransform.mapPoint(targetPoint); |
270 | 273 |
271 m_consumer->emitSegment(cubicSegment); | 274 m_consumer->emitSegment(cubicSegment); |
272 } | 275 } |
273 return true; | 276 return true; |
274 } | 277 } |
275 | 278 |
276 } // namespace blink | 279 } // namespace blink |
OLD | NEW |