OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkRRect.h" | 8 #include "SkRRect.h" |
| 9 #include "SkMatrix.h" |
9 | 10 |
10 /////////////////////////////////////////////////////////////////////////////// | 11 /////////////////////////////////////////////////////////////////////////////// |
11 | 12 |
12 void SkRRect::setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { | 13 void SkRRect::setRectXY(const SkRect& rect, SkScalar xRad, SkScalar yRad) { |
13 if (rect.isEmpty()) { | 14 if (rect.isEmpty()) { |
14 this->setEmpty(); | 15 this->setEmpty(); |
15 return; | 16 return; |
16 } | 17 } |
17 | 18 |
18 if (xRad <= 0 || yRad <= 0) { | 19 if (xRad <= 0 || yRad <= 0) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 fType = kOval_Type; | 248 fType = kOval_Type; |
248 } else { | 249 } else { |
249 fType = kSimple_Type; | 250 fType = kSimple_Type; |
250 } | 251 } |
251 return; | 252 return; |
252 } | 253 } |
253 | 254 |
254 fType = kComplex_Type; | 255 fType = kComplex_Type; |
255 } | 256 } |
256 | 257 |
| 258 static bool matrix_only_scale_and_translate(const SkMatrix& matrix) { |
| 259 const SkMatrix::TypeMask m = (SkMatrix::TypeMask) (SkMatrix::kAffine_Mask |
| 260 | SkMatrix::kPerspective_Mask); |
| 261 return (matrix.getType() & m) == 0; |
| 262 } |
| 263 |
| 264 bool SkRRect::transform(const SkMatrix& matrix, SkRRect* dst) const { |
| 265 if (NULL == dst) { |
| 266 dst = const_cast<SkRRect*>(this); |
| 267 } |
| 268 |
| 269 if (matrix.isIdentity()) { |
| 270 *dst = *this; |
| 271 return true; |
| 272 } |
| 273 |
| 274 if (!matrix_only_scale_and_translate(matrix)) { |
| 275 return false; |
| 276 } |
| 277 |
| 278 SkRect newRect; |
| 279 if (!matrix.mapRect(&newRect, fRect)) { |
| 280 return false; |
| 281 } |
| 282 |
| 283 dst->fRect = newRect; |
| 284 |
| 285 // Now scale each corner |
| 286 SkScalar xScale = matrix.getScaleX(); |
| 287 if (xScale < 0) { |
| 288 xScale = -xScale; |
| 289 // Each x radius will swap with its horizontal opposite. |
| 290 const SkScalar upperLeftXRadius = this->radii(kUpperLeft_Corner).fX; |
| 291 const SkScalar upperRightXRadius = this->radii(kUpperRight_Corner).fX; |
| 292 dst->fRadii[(int) kUpperRight_Corner].fX = SkScalarMul(xScale, upperLeft
XRadius); |
| 293 dst->fRadii[(int) kUpperLeft_Corner].fX = SkScalarMul(xScale, upperRight
XRadius); |
| 294 |
| 295 const SkScalar lowerLeftXRadius = this->radii(kLowerLeft_Corner).fX; |
| 296 const SkScalar lowerRightXRadius = this->radii(kLowerRight_Corner).fX; |
| 297 dst->fRadii[(int) kLowerRight_Corner].fX = SkScalarMul(xScale, lowerLeft
XRadius); |
| 298 dst->fRadii[(int) kLowerLeft_Corner].fX = SkScalarMul(xScale, lowerRight
XRadius); |
| 299 } else { |
| 300 dst->fRadii[(int) kUpperLeft_Corner].fX = SkScalarMul(xScale, |
| 301 this->radii(kUpperLeft_Corner).fX); |
| 302 dst->fRadii[(int) kUpperRight_Corner].fX = SkScalarMul(xScale, |
| 303 this->radii(kUpperRight_Corner).fX); |
| 304 dst->fRadii[(int) kLowerRight_Corner].fX = SkScalarMul(xScale, |
| 305 this->radii(kLowerRight_Corner).fX); |
| 306 dst->fRadii[(int) kLowerLeft_Corner].fX = SkScalarMul(xScale, |
| 307 this->radii(kLowerLeft_Corner).fX); |
| 308 } |
| 309 |
| 310 SkScalar yScale = matrix.getScaleY(); |
| 311 if (yScale < 0) { |
| 312 yScale = -yScale; |
| 313 // Each y radius will swap with its vertical opposite. |
| 314 const SkScalar upperLeftYRadius = this->radii(kUpperLeft_Corner).fY; |
| 315 const SkScalar lowerLeftYRadius = this->radii(kLowerLeft_Corner).fY; |
| 316 dst->fRadii[(int) kLowerLeft_Corner].fY = SkScalarMul(yScale, upperLeftY
Radius); |
| 317 dst->fRadii[(int) kUpperLeft_Corner].fY = SkScalarMul(yScale, lowerLeftY
Radius); |
| 318 |
| 319 const SkScalar upperRightYRadius = this->radii(kUpperRight_Corner).fY; |
| 320 const SkScalar lowerRightYRadius = this->radii(kLowerRight_Corner).fY; |
| 321 dst->fRadii[(int) kLowerRight_Corner].fY = SkScalarMul(yScale, upperRigh
tYRadius); |
| 322 dst->fRadii[(int) kUpperRight_Corner].fY = SkScalarMul(yScale, lowerRigh
tYRadius); |
| 323 } else { |
| 324 dst->fRadii[(int) kUpperLeft_Corner].fY = SkScalarMul(yScale, |
| 325 this->radii(kUpperLeft_Corner).fY); |
| 326 dst->fRadii[(int) kUpperRight_Corner].fY = SkScalarMul(yScale, |
| 327 this->radii(kUpperRight_Corner).fY); |
| 328 dst->fRadii[(int) kLowerRight_Corner].fY = SkScalarMul(yScale, |
| 329 this->radii(kLowerRight_Corner).fY); |
| 330 dst->fRadii[(int) kLowerLeft_Corner].fY = SkScalarMul(yScale, |
| 331 this->radii(kLowerLeft_Corner).fY); |
| 332 } |
| 333 |
| 334 return true; |
| 335 } |
| 336 |
257 /////////////////////////////////////////////////////////////////////////////// | 337 /////////////////////////////////////////////////////////////////////////////// |
258 | 338 |
259 void SkRRect::inset(SkScalar dx, SkScalar dy, SkRRect* dst) const { | 339 void SkRRect::inset(SkScalar dx, SkScalar dy, SkRRect* dst) const { |
260 SkRect r = fRect; | 340 SkRect r = fRect; |
261 | 341 |
262 r.inset(dx, dy); | 342 r.inset(dx, dy); |
263 if (r.isEmpty()) { | 343 if (r.isEmpty()) { |
264 dst->setEmpty(); | 344 dst->setEmpty(); |
265 return; | 345 return; |
266 } | 346 } |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); | 432 SkASSERT(!allRadiiZero && !allRadiiSame && !allCornersSquare); |
353 break; | 433 break; |
354 case kUnknown_Type: | 434 case kUnknown_Type: |
355 // no limits on this | 435 // no limits on this |
356 break; | 436 break; |
357 } | 437 } |
358 } | 438 } |
359 #endif // SK_DEBUG | 439 #endif // SK_DEBUG |
360 | 440 |
361 /////////////////////////////////////////////////////////////////////////////// | 441 /////////////////////////////////////////////////////////////////////////////// |
OLD | NEW |