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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 FloatPoint p2 = FloatPoint(x2, y2); | 123 FloatPoint p2 = FloatPoint(x2, y2); |
124 | 124 |
125 if (!m_path.hasCurrentPoint()) | 125 if (!m_path.hasCurrentPoint()) |
126 m_path.moveTo(p1); | 126 m_path.moveTo(p1); |
127 else if (p1 == m_path.currentPoint() || p1 == p2 || !r) | 127 else if (p1 == m_path.currentPoint() || p1 == p2 || !r) |
128 lineTo(x1, y1); | 128 lineTo(x1, y1); |
129 else | 129 else |
130 m_path.addArcTo(p1, p2, r); | 130 m_path.addArcTo(p1, p2, r); |
131 } | 131 } |
132 | 132 |
133 void CanvasPathMethods::arc(float x, float y, float r, float sa, float ea, bool
anticlockwise, ExceptionState& es) | 133 static float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise
) |
134 { | 134 { |
135 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(r) || !std::isf
inite(sa) || !std::isfinite(ea)) | 135 float twoPi = 2 * piFloat; |
| 136 float newEndAngle = endAngle; |
| 137 /* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-el
ement.html#dom-context-2d-arc |
| 138 * If the anticlockwise argument is false and endAngle-startAngle is equal t
o or greater than 2pi, or, |
| 139 * if the anticlockwise argument is true and startAngle-endAngle is equal to
or greater than 2pi, |
| 140 * then the arc is the whole circumference of this ellipse. |
| 141 */ |
| 142 if (!anticlockwise && endAngle - startAngle >= twoPi) |
| 143 newEndAngle = startAngle + twoPi + fmodf(endAngle - startAngle, twoPi); |
| 144 else if (anticlockwise && startAngle - endAngle >= twoPi) |
| 145 newEndAngle = startAngle - twoPi - fmodf(startAngle - endAngle, twoPi); |
| 146 |
| 147 /* |
| 148 * Otherwise, the arc is the path along the circumference of this ellipse fr
om the start point to the end point, |
| 149 * going anti-clockwise if the anticlockwise argument is true, and clockwise
otherwise. |
| 150 * Since the points are on the ellipse, as opposed to being simply angles fr
om zero, |
| 151 * the arc can never cover an angle greater than 2pi radians. |
| 152 */ |
| 153 /* NOTE: When startAngle = 0, endAngle = 2Pi and anticlockwise = true, the s
pec does not indicate clearly. |
| 154 * We draw the entire circle, because some web sites use arc(x, y, r, 0, 2*M
ath.PI, true) to draw circle. |
| 155 * We preserve backward-compatibility. |
| 156 */ |
| 157 else if (!anticlockwise && startAngle > endAngle) |
| 158 newEndAngle = startAngle + (twoPi - fmodf(startAngle - endAngle, twoPi))
; |
| 159 else if (anticlockwise && startAngle < endAngle) |
| 160 newEndAngle = startAngle - (twoPi - fmodf(endAngle - startAngle, twoPi))
; |
| 161 |
| 162 ASSERT(std::abs(newEndAngle - startAngle) < 4 * piFloat); |
| 163 return newEndAngle; |
| 164 } |
| 165 |
| 166 void CanvasPathMethods::arc(float x, float y, float radius, float startAngle, fl
oat endAngle, bool anticlockwise, ExceptionState& es) |
| 167 { |
| 168 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radius) || !std
::isfinite(startAngle) || !std::isfinite(endAngle)) |
136 return; | 169 return; |
137 | 170 |
138 if (r < 0) { | 171 if (radius < 0) { |
139 es.throwDOMException(IndexSizeError); | 172 es.throwDOMException(IndexSizeError); |
140 return; | 173 return; |
141 } | 174 } |
142 | 175 |
143 if (!r || sa == ea) { | |
144 // The arc is empty but we still need to draw the connecting line. | |
145 lineTo(x + r * cosf(sa), y + r * sinf(sa)); | |
146 return; | |
147 } | |
148 | |
149 if (!isTransformInvertible()) | 176 if (!isTransformInvertible()) |
150 return; | 177 return; |
151 | 178 |
152 // If 'sa' and 'ea' differ by more than 2Pi, just add a circle starting/endi
ng at 'sa'. | 179 if (!radius || startAngle == endAngle) { |
153 if (anticlockwise && sa - ea >= 2 * piFloat) { | 180 // The arc is empty but we still need to draw the connecting line. |
154 m_path.addArc(FloatPoint(x, y), r, sa, sa - 2 * piFloat, anticlockwise); | 181 lineTo(x + radius * cosf(startAngle), y + radius * sinf(startAngle)); |
155 return; | |
156 } | |
157 if (!anticlockwise && ea - sa >= 2 * piFloat) { | |
158 m_path.addArc(FloatPoint(x, y), r, sa, sa + 2 * piFloat, anticlockwise); | |
159 return; | 182 return; |
160 } | 183 } |
161 | 184 |
162 m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise); | 185 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise)
; |
| 186 m_path.addArc(FloatPoint(x, y), radius, startAngle, adjustedEndAngle, anticl
ockwise); |
163 } | 187 } |
164 | 188 |
165 void CanvasPathMethods::rect(float x, float y, float width, float height) | 189 void CanvasPathMethods::rect(float x, float y, float width, float height) |
166 { | 190 { |
167 if (!isTransformInvertible()) | 191 if (!isTransformInvertible()) |
168 return; | 192 return; |
169 | 193 |
170 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || !std:
:isfinite(height)) | 194 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || !std:
:isfinite(height)) |
171 return; | 195 return; |
172 | 196 |
173 if (!width && !height) { | 197 if (!width && !height) { |
174 m_path.moveTo(FloatPoint(x, y)); | 198 m_path.moveTo(FloatPoint(x, y)); |
175 return; | 199 return; |
176 } | 200 } |
177 | 201 |
178 m_path.addRect(FloatRect(x, y, width, height)); | 202 m_path.addRect(FloatRect(x, y, width, height)); |
179 } | 203 } |
180 } | 204 } |
OLD | NEW |