Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(590)

Side by Side Diff: Source/core/html/canvas/CanvasPathMethods.cpp

Issue 14298022: Add support for new canvas ellipse method. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase to upstream. Make canvas-ellipse-circumference cover more extensive cases. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698