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 |