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, ExceptionCode& ec) | 133 static float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise ) |
134 { | |
135 // If 'startAngle' and 'endAngle' differ by more than 2Pi, just add a circle starting/ending at 'startAngle'. | |
136 if (anticlockwise && startAngle - endAngle >= 2 * piFloat) | |
137 return startAngle - 2 * piFloat; | |
138 if (!anticlockwise && endAngle - startAngle >= 2 * piFloat) | |
139 return startAngle + 2 * piFloat; | |
140 return endAngle; | |
141 } | |
142 | |
143 void CanvasPathMethods::arc(float x, float y, float radius, float startAngle, fl oat endAngle, bool anticlockwise, ExceptionCode& ec) | |
134 { | 144 { |
135 ec = 0; | 145 ec = 0; |
136 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(r) || !std::isf inite(sa) || !std::isfinite(ea)) | 146 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radius) || !std ::isfinite(startAngle) || !std::isfinite(endAngle)) |
137 return; | 147 return; |
138 | 148 |
139 if (r < 0) { | 149 if (radius < 0) { |
140 ec = INDEX_SIZE_ERR; | 150 ec = INDEX_SIZE_ERR; |
141 return; | 151 return; |
142 } | 152 } |
143 | 153 |
144 if (!r || sa == ea) { | 154 if (!radius || startAngle == endAngle) { |
145 // The arc is empty but we still need to draw the connecting line. | 155 // The arc is empty but we still need to draw the connecting line. |
146 lineTo(x + r * cosf(sa), y + r * sinf(sa)); | 156 lineTo(x + radius * cosf(startAngle), y + radius * sinf(startAngle)); |
147 return; | 157 return; |
148 } | 158 } |
149 | 159 |
150 if (!isTransformInvertible()) | 160 if (!isTransformInvertible()) |
151 return; | 161 return; |
152 | 162 |
153 // If 'sa' and 'ea' differ by more than 2Pi, just add a circle starting/endi ng at 'sa'. | 163 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise) ; |
154 if (anticlockwise && sa - ea >= 2 * piFloat) { | 164 m_path.addArc(FloatPoint(x, y), radius, startAngle, adjustedEndAngle, anticl ockwise); |
155 m_path.addArc(FloatPoint(x, y), r, sa, sa - 2 * piFloat, anticlockwise); | 165 } |
166 | |
167 static void degenerateEllipse(CanvasPathMethods* path, float x, float y, float r adiusX, float radiusY, float rotation, float startAngle, float endAngle, bool an ticlockwise) | |
168 { | |
169 ASSERT((radiusX || radiusY) && startAngle != endAngle); | |
170 float sweep = endAngle - startAngle; | |
171 if (anticlockwise) | |
172 sweep = startAngle - endAngle; | |
173 | |
174 if (sweep < 0) | |
175 sweep = std::fmod(-sweep, piFloat * 2); | |
176 | |
177 if (sweep <= piFloat * 0.5) { | |
178 path->lineTo(x + radiusX * cosf(endAngle + rotation), y + radiusY * sinf (endAngle + rotation)); | |
alph
2013/07/09 16:21:23
Here's a counter example:
rotation = x = y = 0;
st
| |
179 } else if (sweep <= piFloat) { | |
180 path->lineTo(x + radiusX * cosf(piFloat * 0.5), y + radiusY * sinf(piFlo at * 0.5)); | |
181 path->lineTo(x + radiusX * cosf(endAngle + rotation), y + radiusY * sinf (endAngle + rotation)); | |
182 } else if (sweep <= piFloat * 1.5) { | |
183 path->lineTo(x + radiusX * cosf(piFloat * 0.5), y + radiusY * sinf(piFlo at * 0.5)); | |
184 path->lineTo(x + radiusX * cosf(piFloat), y + radiusY * sinf(piFloat)); | |
185 path->lineTo(x + radiusX * cosf(endAngle + rotation), y + radiusY * sinf (endAngle + rotation)); | |
186 } else if (sweep <= piFloat * 2) { | |
187 path->lineTo(x + radiusX * cosf(piFloat * 0.5), y + radiusY * sinf(piFlo at * 0.5)); | |
188 path->lineTo(x + radiusX * cosf(piFloat), y + radiusY * sinf(piFloat)); | |
189 path->lineTo(x + radiusX * cosf(piFloat * 1.5), y + radiusY * sinf(piFlo at * 1.5)); | |
190 path->lineTo(x + radiusX * cosf(endAngle + rotation), y + radiusY * sinf (endAngle + rotation)); | |
191 } else { // sweep > piFloat * 2 | |
192 path->lineTo(x + radiusX * cosf(piFloat * 0.5), y + radiusY * sinf(piFlo at * 0.5)); | |
193 path->lineTo(x + radiusX * cosf(piFloat), y + radiusY * sinf(piFloat)); | |
194 path->lineTo(x + radiusX * cosf(piFloat * 1.5), y + radiusY * sinf(piFlo at * 1.5)); | |
195 path->lineTo(x + radiusX * cosf(piFloat * 2), y + radiusY * sinf(piFloat * 2)); | |
196 path->lineTo(x + radiusX * cosf(endAngle + rotation), y + radiusY * sinf (endAngle + rotation)); | |
197 } | |
198 } | |
199 | |
200 void CanvasPathMethods::ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise, ExceptionC ode& ec) | |
201 { | |
202 ec = 0; | |
203 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(radiusX) || !st d::isfinite(radiusY) || !std::isfinite(rotation) || !std::isfinite(startAngle) | | !std::isfinite(endAngle)) | |
156 return; | 204 return; |
157 } | 205 |
158 if (!anticlockwise && ea - sa >= 2 * piFloat) { | 206 if (radiusX < 0 || radiusY < 0) { |
159 m_path.addArc(FloatPoint(x, y), r, sa, sa + 2 * piFloat, anticlockwise); | 207 ec = INDEX_SIZE_ERR; |
160 return; | 208 return; |
161 } | 209 } |
162 | 210 |
163 m_path.addArc(FloatPoint(x, y), r, sa, ea, anticlockwise); | 211 if (!radiusX || !radiusY || startAngle == endAngle) { |
212 // The ellipse is empty but we still need to draw the connecting line to start point. | |
213 lineTo(x + radiusX * cosf(startAngle + rotation), y + radiusY * sinf(sta rtAngle + rotation)); | |
alph
2013/07/09 16:21:23
It still does not take into account axes rotation.
| |
214 if ((radiusX || radiusY) && startAngle != endAngle) | |
215 degenerateEllipse(this, x, y, radiusX, radiusY, rotation, startAngle , endAngle, anticlockwise); | |
dshwang
2013/07/09 15:48:02
@alph yes, you are right. I understand what you sa
alph
2013/07/09 16:21:23
degenerateEllipse already looks scary to me despit
| |
216 return; | |
217 } | |
218 | |
219 if (!isTransformInvertible()) | |
220 return; | |
221 | |
222 float adjustedEndAngle = adjustEndAngle(startAngle, endAngle, anticlockwise) ; | |
223 m_path.addEllipse(FloatPoint(x, y), radiusX, radiusY, rotation, startAngle, adjustedEndAngle, anticlockwise); | |
164 } | 224 } |
165 | 225 |
166 void CanvasPathMethods::rect(float x, float y, float width, float height) | 226 void CanvasPathMethods::rect(float x, float y, float width, float height) |
167 { | 227 { |
168 if (!isTransformInvertible()) | 228 if (!isTransformInvertible()) |
169 return; | 229 return; |
170 | 230 |
171 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || !std: :isfinite(height)) | 231 if (!std::isfinite(x) || !std::isfinite(y) || !std::isfinite(width) || !std: :isfinite(height)) |
172 return; | 232 return; |
173 | 233 |
174 if (!width && !height) { | 234 if (!width && !height) { |
175 m_path.moveTo(FloatPoint(x, y)); | 235 m_path.moveTo(FloatPoint(x, y)); |
176 return; | 236 return; |
177 } | 237 } |
178 | 238 |
179 m_path.addRect(FloatRect(x, y, width, height)); | 239 m_path.addRect(FloatRect(x, y, width, height)); |
180 } | 240 } |
181 } | 241 } |
OLD | NEW |