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. |
| 3 * All rights reserved. |
3 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) | 4 * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies) |
4 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 5 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
5 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
6 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> | 7 * Copyright (C) 2008 Dirk Schulze <krit@webkit.org> |
7 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 8 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
8 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. | 9 * Copyright (C) 2012, 2013 Intel Corporation. All rights reserved. |
9 * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved. | 10 * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved. |
10 * | 11 * |
11 * Redistribution and use in source and binary forms, with or without | 12 * Redistribution and use in source and binary forms, with or without |
12 * modification, are permitted provided that the following conditions | 13 * modification, are permitted provided that the following conditions |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 lineTo(x1, y1); | 141 lineTo(x1, y1); |
141 else | 142 else |
142 m_path.addArcTo(p1, p2, r); | 143 m_path.addArcTo(p1, p2, r); |
143 } | 144 } |
144 | 145 |
145 namespace { | 146 namespace { |
146 | 147 |
147 float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise) { | 148 float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise) { |
148 float newEndAngle = endAngle; | 149 float newEndAngle = endAngle; |
149 /* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-elem
ent.html#dom-context-2d-arc | 150 /* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-elem
ent.html#dom-context-2d-arc |
150 * If the anticlockwise argument is false and endAngle-startAngle is equal t
o or greater than 2pi, or, | 151 * If the anticlockwise argument is false and endAngle-startAngle is equal |
151 * if the anticlockwise argument is true and startAngle-endAngle is equal to
or greater than 2pi, | 152 * to or greater than 2pi, or, |
152 * then the arc is the whole circumference of this ellipse, and the point at
startAngle along this circle's circumference, | 153 * if the anticlockwise argument is true and startAngle-endAngle is equal to |
153 * measured in radians clockwise from the ellipse's semi-major axis, acts as
both the start point and the end point. | 154 * or greater than 2pi, |
154 */ | 155 * then the arc is the whole circumference of this ellipse, and the point at |
| 156 * startAngle along this circle's circumference, measured in radians clockwise |
| 157 * from the ellipse's semi-major axis, acts as both the start point and the |
| 158 * end point. |
| 159 */ |
155 if (!anticlockwise && endAngle - startAngle >= twoPiFloat) | 160 if (!anticlockwise && endAngle - startAngle >= twoPiFloat) |
156 newEndAngle = startAngle + twoPiFloat; | 161 newEndAngle = startAngle + twoPiFloat; |
157 else if (anticlockwise && startAngle - endAngle >= twoPiFloat) | 162 else if (anticlockwise && startAngle - endAngle >= twoPiFloat) |
158 newEndAngle = startAngle - twoPiFloat; | 163 newEndAngle = startAngle - twoPiFloat; |
159 | 164 |
160 /* | 165 /* |
161 * Otherwise, the arc is the path along the circumference of this ellipse fr
om the start point to the end point, | 166 * Otherwise, the arc is the path along the circumference of this ellipse |
162 * going anti-clockwise if the anticlockwise argument is true, and clockwise
otherwise. | 167 * from the start point to the end point, going anti-clockwise if the |
163 * Since the points are on the ellipse, as opposed to being simply angles fr
om zero, | 168 * anticlockwise argument is true, and clockwise otherwise. |
164 * the arc can never cover an angle greater than 2pi radians. | 169 * Since the points are on the ellipse, as opposed to being simply angles |
165 */ | 170 * from zero, the arc can never cover an angle greater than 2pi radians. |
166 /* NOTE: When startAngle = 0, endAngle = 2Pi and anticlockwise = true, the spe
c does not indicate clearly. | 171 */ |
167 * We draw the entire circle, because some web sites use arc(x, y, r, 0, 2*M
ath.PI, true) to draw circle. | 172 /* NOTE: When startAngle = 0, endAngle = 2Pi and anticlockwise = true, the |
168 * We preserve backward-compatibility. | 173 * spec does not indicate clearly. |
169 */ | 174 * We draw the entire circle, because some web sites use arc(x, y, r, 0, |
| 175 * 2*Math.PI, true) to draw circle. |
| 176 * We preserve backward-compatibility. |
| 177 */ |
170 else if (!anticlockwise && startAngle > endAngle) | 178 else if (!anticlockwise && startAngle > endAngle) |
171 newEndAngle = | 179 newEndAngle = |
172 startAngle + (twoPiFloat - fmodf(startAngle - endAngle, twoPiFloat)); | 180 startAngle + (twoPiFloat - fmodf(startAngle - endAngle, twoPiFloat)); |
173 else if (anticlockwise && startAngle < endAngle) | 181 else if (anticlockwise && startAngle < endAngle) |
174 newEndAngle = | 182 newEndAngle = |
175 startAngle - (twoPiFloat - fmodf(endAngle - startAngle, twoPiFloat)); | 183 startAngle - (twoPiFloat - fmodf(endAngle - startAngle, twoPiFloat)); |
176 | 184 |
177 ASSERT(ellipseIsRenderable(startAngle, newEndAngle)); | 185 ASSERT(ellipseIsRenderable(startAngle, newEndAngle)); |
178 return newEndAngle; | 186 return newEndAngle; |
179 } | 187 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 * To draw the above example, need to get P that is a local maximum point. | 234 * To draw the above example, need to get P that is a local maximum point. |
227 * Angles for P are 0.5Pi and 1.5Pi in the ellipse coordinates. | 235 * Angles for P are 0.5Pi and 1.5Pi in the ellipse coordinates. |
228 * | 236 * |
229 * If radiusY becomes zero, the result is as follows. | 237 * If radiusY becomes zero, the result is as follows. |
230 * -----__ | 238 * -----__ |
231 * --_ | 239 * --_ |
232 * ---------- | 240 * ---------- |
233 * ``P | 241 * ``P |
234 * Angles for P are 0 and Pi in the ellipse coordinates. | 242 * Angles for P are 0 and Pi in the ellipse coordinates. |
235 * | 243 * |
236 * To handle both cases, degenerateEllipse() lines to start angle, local maximum
points(every 0.5Pi), and end angle. | 244 * To handle both cases, degenerateEllipse() lines to start angle, local maximum |
237 * NOTE: Before ellipse() calls this function, adjustEndAngle() is called, so en
dAngle - startAngle must be equal to or less than 2Pi. | 245 * points(every 0.5Pi), and end angle. |
| 246 * NOTE: Before ellipse() calls this function, adjustEndAngle() is called, so |
| 247 * endAngle - startAngle must be equal to or less than 2Pi. |
238 */ | 248 */ |
239 void degenerateEllipse(CanvasPathMethods* path, | 249 void degenerateEllipse(CanvasPathMethods* path, |
240 float x, | 250 float x, |
241 float y, | 251 float y, |
242 float radiusX, | 252 float radiusX, |
243 float radiusY, | 253 float radiusY, |
244 float rotation, | 254 float rotation, |
245 float startAngle, | 255 float startAngle, |
246 float endAngle, | 256 float endAngle, |
247 bool anticlockwise) { | 257 bool anticlockwise) { |
248 ASSERT(ellipseIsRenderable(startAngle, endAngle)); | 258 ASSERT(ellipseIsRenderable(startAngle, endAngle)); |
249 ASSERT(startAngle >= 0 && startAngle < twoPiFloat); | 259 ASSERT(startAngle >= 0 && startAngle < twoPiFloat); |
250 ASSERT((anticlockwise && (startAngle - endAngle) >= 0) || | 260 ASSERT((anticlockwise && (startAngle - endAngle) >= 0) || |
251 (!anticlockwise && (endAngle - startAngle) >= 0)); | 261 (!anticlockwise && (endAngle - startAngle) >= 0)); |
252 | 262 |
253 FloatPoint center(x, y); | 263 FloatPoint center(x, y); |
254 AffineTransform rotationMatrix; | 264 AffineTransform rotationMatrix; |
255 rotationMatrix.rotateRadians(rotation); | 265 rotationMatrix.rotateRadians(rotation); |
256 // First, if the object's path has any subpaths, then the method must add a st
raight line from the last point in the subpath to the start point of the arc. | 266 // First, if the object's path has any subpaths, then the method must add a |
| 267 // straight line from the last point in the subpath to the start point of the |
| 268 // arc. |
257 lineToFloatPoint(path, center + | 269 lineToFloatPoint(path, center + |
258 rotationMatrix.mapPoint(getPointOnEllipse( | 270 rotationMatrix.mapPoint(getPointOnEllipse( |
259 radiusX, radiusY, startAngle))); | 271 radiusX, radiusY, startAngle))); |
260 if ((!radiusX && !radiusY) || startAngle == endAngle) | 272 if ((!radiusX && !radiusY) || startAngle == endAngle) |
261 return; | 273 return; |
262 | 274 |
263 if (!anticlockwise) { | 275 if (!anticlockwise) { |
264 // startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat is the on
e of (0, 0.5Pi, Pi, 1.5Pi, 2Pi) | 276 // startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat is the |
| 277 // one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi) |
265 // that is the closest to startAngle on the clockwise direction. | 278 // that is the closest to startAngle on the clockwise direction. |
266 for (float angle = | 279 for (float angle = |
267 startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat; | 280 startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat; |
268 angle < endAngle; angle += piOverTwoFloat) | 281 angle < endAngle; angle += piOverTwoFloat) |
269 lineToFloatPoint(path, center + | 282 lineToFloatPoint(path, center + |
270 rotationMatrix.mapPoint(getPointOnEllipse( | 283 rotationMatrix.mapPoint(getPointOnEllipse( |
271 radiusX, radiusY, angle))); | 284 radiusX, radiusY, angle))); |
272 } else { | 285 } else { |
273 for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat); | 286 for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat); |
274 angle > endAngle; angle -= piOverTwoFloat) | 287 angle > endAngle; angle -= piOverTwoFloat) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 String::number(radiusY) + ") is negative."); | 356 String::number(radiusY) + ") is negative."); |
344 return; | 357 return; |
345 } | 358 } |
346 | 359 |
347 if (!isTransformInvertible()) | 360 if (!isTransformInvertible()) |
348 return; | 361 return; |
349 | 362 |
350 canonicalizeAngle(&startAngle, &endAngle); | 363 canonicalizeAngle(&startAngle, &endAngle); |
351 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise); | 364 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise); |
352 if (!radiusX || !radiusY || startAngle == adjustedEndAngle) { | 365 if (!radiusX || !radiusY || startAngle == adjustedEndAngle) { |
353 // The ellipse is empty but we still need to draw the connecting line to sta
rt point. | 366 // The ellipse is empty but we still need to draw the connecting line to |
| 367 // start point. |
354 degenerateEllipse(this, x, y, radiusX, radiusY, rotation, startAngle, | 368 degenerateEllipse(this, x, y, radiusX, radiusY, rotation, startAngle, |
355 adjustedEndAngle, anticlockwise); | 369 adjustedEndAngle, anticlockwise); |
356 return; | 370 return; |
357 } | 371 } |
358 | 372 |
359 m_path.addEllipse(FloatPoint(x, y), radiusX, radiusY, rotation, startAngle, | 373 m_path.addEllipse(FloatPoint(x, y), radiusX, radiusY, rotation, startAngle, |
360 adjustedEndAngle, anticlockwise); | 374 adjustedEndAngle, anticlockwise); |
361 } | 375 } |
362 | 376 |
363 void CanvasPathMethods::rect(float x, float y, float width, float height) { | 377 void CanvasPathMethods::rect(float x, float y, float width, float height) { |
364 if (!isTransformInvertible()) | 378 if (!isTransformInvertible()) |
365 return; | 379 return; |
366 | 380 |
367 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || | 381 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || |
368 !std::isfinite(height)) | 382 !std::isfinite(height)) |
369 return; | 383 return; |
370 | 384 |
371 m_path.addRect(FloatRect(x, y, width, height)); | 385 m_path.addRect(FloatRect(x, y, width, height)); |
372 } | 386 } |
373 } // namespace blink | 387 } // namespace blink |
OLD | NEW |