Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. |
| 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) |
| 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
| 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
| 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> | 6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> |
| 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
| 8 * Copyright (C) 2012 Intel Corporation. All rights reserved. | 8 * Copyright (C) 2012 Intel Corporation. All rights reserved. |
| 9 * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved. | 9 * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved. |
| 10 * | 10 * |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 31 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 32 * SUCH DAMAGE. | 32 * SUCH DAMAGE. |
| 33 */ | 33 */ |
| 34 | 34 |
| 35 #include "config.h" | 35 #include "config.h" |
| 36 #include "core/html/canvas/CanvasPathMethods.h" | 36 #include "core/html/canvas/CanvasPathMethods.h" |
| 37 | 37 |
| 38 #include "bindings/v8/ExceptionState.h" | 38 #include "bindings/v8/ExceptionState.h" |
| 39 #include "core/dom/ExceptionCode.h" | 39 #include "core/dom/ExceptionCode.h" |
| 40 #include "core/platform/graphics/FloatRect.h" | 40 #include "core/platform/graphics/FloatRect.h" |
| 41 #include "core/platform/graphics/transforms/AffineTransform.h" | |
| 41 #include "wtf/MathExtras.h" | 42 #include "wtf/MathExtras.h" |
| 42 | 43 |
| 43 namespace WebCore { | 44 namespace WebCore { |
| 44 | 45 |
| 45 void CanvasPathMethods::closePath() | 46 void CanvasPathMethods::closePath() |
| 46 { | 47 { |
| 47 if (m_path.isEmpty()) | 48 if (m_path.isEmpty()) |
| 48 return; | 49 return; |
| 49 | 50 |
| 50 FloatRect boundRect = m_path.boundingRect(); | 51 FloatRect boundRect = m_path.boundingRect(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 if (!radius || startAngle == endAngle) { | 180 if (!radius || startAngle == endAngle) { |
| 180 // The arc is empty but we still need to draw the connecting line. | 181 // The arc is empty but we still need to draw the connecting line. |
| 181 lineTo(x + radius * cosf(startAngle), y + radius * sinf(startAngle)); | 182 lineTo(x + radius * cosf(startAngle), y + radius * sinf(startAngle)); |
| 182 return; | 183 return; |
| 183 } | 184 } |
| 184 | 185 |
| 185 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise) ; | 186 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise) ; |
| 186 m_path.addArc(FloatPoint(x, y), radius, startAngle, adjustedEndAngle, anticl ockwise); | 187 m_path.addArc(FloatPoint(x, y), radius, startAngle, adjustedEndAngle, anticl ockwise); |
| 187 } | 188 } |
| 188 | 189 |
| 190 inline static void lineToFloatPoint(CanvasPathMethods* path, const FloatPoint& p ) | |
| 191 { | |
| 192 path->lineTo(p.x(), p.y()); | |
| 193 } | |
| 194 | |
| 195 inline static FloatPoint getPointOnEllipse(float radiusX, float radiusY, float t heta) | |
| 196 { | |
| 197 return FloatPoint(radiusX * cosf(theta), radiusY * sinf(theta)); | |
| 198 } | |
| 199 | |
| 200 inline static void canonicalizeAngle(float* startAngle, float* endAngle) | |
| 201 { | |
| 202 // Make 0 <= startAngle < 2*PI | |
| 203 float twoPi = 2 * piFloat; | |
| 204 float newStartAngle = *startAngle; | |
| 205 if (newStartAngle < 0) | |
| 206 newStartAngle = twoPi + fmodf(newStartAngle, -twoPi); | |
| 207 else | |
| 208 newStartAngle = fmodf(newStartAngle, twoPi); | |
| 209 | |
| 210 float delta = newStartAngle - *startAngle; | |
| 211 *startAngle = newStartAngle; | |
| 212 *endAngle = *endAngle + delta; | |
| 213 } | |
| 214 | |
| 215 static void degenerateEllipse(CanvasPathMethods* path, float x, float y, float r adiusX, float radiusY, float rotation, float startAngle, float endAngle, bool an ticlockwise) | |
| 216 { | |
| 217 ASSERT(std::abs(endAngle - startAngle) < 4 * piFloat); | |
| 218 | |
| 219 FloatPoint center(x, y); | |
| 220 AffineTransform rotationMatrix; | |
| 221 rotationMatrix.rotate(rad2deg(rotation)); | |
| 222 lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(ra diusX, radiusY, startAngle))); | |
| 223 if ((!radiusX && !radiusY) || startAngle == endAngle) | |
| 224 return; | |
| 225 | |
| 226 canonicalizeAngle(&startAngle, &endAngle); | |
| 227 ASSERT(std::abs(endAngle - startAngle) < 4 * piFloat); | |
| 228 | |
| 229 float halfPiFloat = piFloat * 0.5; | |
| 230 if (!anticlockwise) { | |
| 231 for (float angle = startAngle - fmodf(startAngle, halfPiFloat) + halfPiF loat; angle < endAngle; angle += halfPiFloat) | |
|
Stephen White
2013/08/27 14:23:50
I'm a little confused by this loop (and the one be
Justin Novosad
2013/08/27 17:51:03
I think the idea to to generate a flat quad to dra
dshwang
2013/08/27 18:54:17
I added detail explanations as comments.
To verify
| |
| 232 lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEl lipse(radiusX, radiusY, angle))); | |
| 233 } else { | |
| 234 for (float angle = startAngle - fmodf(startAngle, halfPiFloat); angle > endAngle; angle -= halfPiFloat) | |
| 235 lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEl lipse(radiusX, radiusY, angle))); | |
| 236 } | |
| 237 | |
| 238 lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(ra diusX, radiusY, endAngle))); | |
| 239 } | |
| 240 | |
| 241 void CanvasPathMethods::ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise, ExceptionS tate& es) | |
| 242 { | |
| 243 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radiusX) || !st d::isfinite(radiusY) || !std::isfinite(rotation) || !std::isfinite(startAngle) | | !std::isfinite(endAngle)) | |
| 244 return; | |
| 245 | |
| 246 if (radiusX < 0 || radiusY < 0) { | |
| 247 es.throwDOMException(IndexSizeError); | |
| 248 return; | |
| 249 } | |
| 250 | |
| 251 if (!isTransformInvertible()) | |
|
Justin Novosad
2013/08/27 17:51:03
This early exit is not in the spec. If the implem
dshwang
2013/08/27 18:54:17
Good concern.
However, all primitives early exit a
| |
| 252 return; | |
| 253 | |
| 254 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise) ; | |
| 255 if (!radiusX || !radiusY || startAngle == adjustedEndAngle) { | |
| 256 // The ellipse is empty but we still need to draw the connecting line to start point. | |
| 257 degenerateEllipse(this, x, y, radiusX, radiusY, rotation, startAngle, ad justedEndAngle, anticlockwise); | |
| 258 return; | |
| 259 } | |
| 260 | |
| 261 m_path.addEllipse(FloatPoint(x, y), radiusX, radiusY, rotation, startAngle, adjustedEndAngle, anticlockwise); | |
| 262 } | |
| 263 | |
| 189 void CanvasPathMethods::rect(float x, float y, float width, float height) | 264 void CanvasPathMethods::rect(float x, float y, float width, float height) |
| 190 { | 265 { |
| 191 if (!isTransformInvertible()) | 266 if (!isTransformInvertible()) |
| 192 return; | 267 return; |
| 193 | 268 |
| 194 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || !std: :isfinite(height)) | 269 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || !std: :isfinite(height)) |
| 195 return; | 270 return; |
| 196 | 271 |
| 197 if (!width && !height) { | 272 if (!width && !height) { |
| 198 m_path.moveTo(FloatPoint(x, y)); | 273 m_path.moveTo(FloatPoint(x, y)); |
| 199 return; | 274 return; |
| 200 } | 275 } |
| 201 | 276 |
| 202 m_path.addRect(FloatRect(x, y, width, height)); | 277 m_path.addRect(FloatRect(x, y, width, height)); |
| 203 } | 278 } |
| 204 } | 279 } |
| OLD | NEW |