Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
| 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 "SkMatrix.h" | 8 #include "SkMatrix.h" |
| 9 #include "SkFloatBits.h" | 9 #include "SkFloatBits.h" |
| 10 #include "SkOnce.h" | 10 #include "SkOnce.h" |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1; | 240 fMat[kMScaleX] = fMat[kMScaleY] = fMat[kMPersp2] = 1; |
| 241 fMat[kMSkewX] = fMat[kMSkewY] = | 241 fMat[kMSkewX] = fMat[kMSkewY] = |
| 242 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 242 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
| 243 | 243 |
| 244 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); | 244 this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); |
| 245 } else { | 245 } else { |
| 246 this->reset(); | 246 this->reset(); |
| 247 } | 247 } |
| 248 } | 248 } |
| 249 | 249 |
| 250 bool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { | 250 void SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { |
| 251 if (!dx && !dy) { | |
| 252 return; | |
| 253 } | |
| 254 | |
| 251 if (this->hasPerspective()) { | 255 if (this->hasPerspective()) { |
| 252 SkMatrix m; | 256 SkMatrix m; |
| 253 m.setTranslate(dx, dy); | 257 m.setTranslate(dx, dy); |
| 254 return this->preConcat(m); | 258 this->preConcat(m); |
| 259 } else { | |
| 260 fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy); | |
| 261 fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy); | |
| 262 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | |
| 263 } | |
| 264 } | |
| 265 | |
| 266 void SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { | |
| 267 if (!dx && !dy) { | |
| 268 return; | |
| 255 } | 269 } |
| 256 | 270 |
| 257 if (dx || dy) { | |
| 258 fMat[kMTransX] += sdot(fMat[kMScaleX], dx, fMat[kMSkewX], dy); | |
| 259 fMat[kMTransY] += sdot(fMat[kMSkewY], dx, fMat[kMScaleY], dy); | |
| 260 | |
| 261 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | |
| 262 } | |
| 263 return true; | |
| 264 } | |
| 265 | |
| 266 bool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { | |
| 267 if (this->hasPerspective()) { | 271 if (this->hasPerspective()) { |
| 268 SkMatrix m; | 272 SkMatrix m; |
| 269 m.setTranslate(dx, dy); | 273 m.setTranslate(dx, dy); |
| 270 return this->postConcat(m); | 274 this->postConcat(m); |
| 271 } | 275 } else { |
| 272 | |
| 273 if (dx || dy) { | |
| 274 fMat[kMTransX] += dx; | 276 fMat[kMTransX] += dx; |
| 275 fMat[kMTransY] += dy; | 277 fMat[kMTransY] += dy; |
| 276 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 278 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 277 } | 279 } |
| 278 return true; | |
| 279 } | 280 } |
| 280 | 281 |
| 281 /////////////////////////////////////////////////////////////////////////////// | 282 /////////////////////////////////////////////////////////////////////////////// |
| 282 | 283 |
| 283 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 284 void SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 284 if (1 == sx && 1 == sy) { | 285 if (1 == sx && 1 == sy) { |
| 285 this->reset(); | 286 this->reset(); |
| 286 } else { | 287 } else { |
| 287 fMat[kMScaleX] = sx; | 288 fMat[kMScaleX] = sx; |
| 288 fMat[kMScaleY] = sy; | 289 fMat[kMScaleY] = sy; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 314 } | 315 } |
| 315 | 316 |
| 316 bool SkMatrix::setIDiv(int divx, int divy) { | 317 bool SkMatrix::setIDiv(int divx, int divy) { |
| 317 if (!divx || !divy) { | 318 if (!divx || !divy) { |
| 318 return false; | 319 return false; |
| 319 } | 320 } |
| 320 this->setScale(SkScalarInvert(divx), SkScalarInvert(divy)); | 321 this->setScale(SkScalarInvert(divx), SkScalarInvert(divy)); |
| 321 return true; | 322 return true; |
| 322 } | 323 } |
| 323 | 324 |
| 324 bool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 325 void SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 326 if (1 == sx && 1 == sy) { | |
| 327 return; | |
| 328 } | |
| 329 | |
| 325 SkMatrix m; | 330 SkMatrix m; |
| 326 m.setScale(sx, sy, px, py); | 331 m.setScale(sx, sy, px, py); |
| 327 return this->preConcat(m); | 332 this->preConcat(m); |
| 328 } | 333 } |
| 329 | 334 |
| 330 bool SkMatrix::preScale(SkScalar sx, SkScalar sy) { | 335 void SkMatrix::preScale(SkScalar sx, SkScalar sy) { |
| 331 if (1 == sx && 1 == sy) { | 336 if (1 == sx && 1 == sy) { |
| 332 return true; | 337 return; |
| 333 } | 338 } |
| 334 | 339 |
| 335 // the assumption is that these multiplies are very cheap, and that | 340 // the assumption is that these multiplies are very cheap, and that |
| 336 // a full concat and/or just computing the matrix type is more expensive. | 341 // a full concat and/or just computing the matrix type is more expensive. |
| 337 // Also, the fixed-point case checks for overflow, but the float doesn't, | 342 // Also, the fixed-point case checks for overflow, but the float doesn't, |
| 338 // so we can get away with these blind multiplies. | 343 // so we can get away with these blind multiplies. |
| 339 | 344 |
| 340 fMat[kMScaleX] *= sx; | 345 fMat[kMScaleX] *= sx; |
| 341 fMat[kMSkewY] *= sx; | 346 fMat[kMSkewY] *= sx; |
| 342 fMat[kMPersp0] *= sx; | 347 fMat[kMPersp0] *= sx; |
| 343 | 348 |
| 344 fMat[kMSkewX] *= sy; | 349 fMat[kMSkewX] *= sy; |
| 345 fMat[kMScaleY] *= sy; | 350 fMat[kMScaleY] *= sy; |
| 346 fMat[kMPersp1] *= sy; | 351 fMat[kMPersp1] *= sy; |
| 347 | 352 |
| 348 this->orTypeMask(kScale_Mask); | 353 this->orTypeMask(kScale_Mask); |
| 349 return true; | |
| 350 } | 354 } |
| 351 | 355 |
| 352 bool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 356 void SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 353 if (1 == sx && 1 == sy) { | 357 if (1 == sx && 1 == sy) { |
| 354 return true; | 358 return; |
| 355 } | 359 } |
| 356 SkMatrix m; | 360 SkMatrix m; |
| 357 m.setScale(sx, sy, px, py); | 361 m.setScale(sx, sy, px, py); |
| 358 return this->postConcat(m); | 362 this->postConcat(m); |
| 359 } | 363 } |
| 360 | 364 |
| 361 bool SkMatrix::postScale(SkScalar sx, SkScalar sy) { | 365 void SkMatrix::postScale(SkScalar sx, SkScalar sy) { |
| 362 if (1 == sx && 1 == sy) { | 366 if (1 == sx && 1 == sy) { |
| 363 return true; | 367 return; |
| 364 } | 368 } |
| 365 SkMatrix m; | 369 SkMatrix m; |
| 366 m.setScale(sx, sy); | 370 m.setScale(sx, sy); |
| 367 return this->postConcat(m); | 371 this->postConcat(m); |
| 368 } | 372 } |
| 369 | 373 |
| 370 // this guy perhaps can go away, if we have a fract/high-precision way to | 374 // this guy perhaps can go away, if we have a fract/high-precision way to |
| 371 // scale matrices | 375 // scale matrices |
| 372 bool SkMatrix::postIDiv(int divx, int divy) { | 376 bool SkMatrix::postIDiv(int divx, int divy) { |
| 373 if (divx == 0 || divy == 0) { | 377 if (divx == 0 || divy == 0) { |
| 374 return false; | 378 return false; |
| 375 } | 379 } |
| 376 | 380 |
| 377 const float invX = 1.f / divx; | 381 const float invX = 1.f / divx; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); | 433 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); |
| 430 this->setSinCos(sinV, cosV, px, py); | 434 this->setSinCos(sinV, cosV, px, py); |
| 431 } | 435 } |
| 432 | 436 |
| 433 void SkMatrix::setRotate(SkScalar degrees) { | 437 void SkMatrix::setRotate(SkScalar degrees) { |
| 434 SkScalar sinV, cosV; | 438 SkScalar sinV, cosV; |
| 435 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); | 439 sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); |
| 436 this->setSinCos(sinV, cosV); | 440 this->setSinCos(sinV, cosV); |
| 437 } | 441 } |
| 438 | 442 |
| 439 bool SkMatrix::preRotate(SkScalar degrees, SkScalar px, SkScalar py) { | 443 void SkMatrix::preRotate(SkScalar degrees, SkScalar px, SkScalar py) { |
| 440 SkMatrix m; | 444 SkMatrix m; |
| 441 m.setRotate(degrees, px, py); | 445 m.setRotate(degrees, px, py); |
| 442 return this->preConcat(m); | 446 this->preConcat(m); |
| 443 } | 447 } |
| 444 | 448 |
| 445 bool SkMatrix::preRotate(SkScalar degrees) { | 449 void SkMatrix::preRotate(SkScalar degrees) { |
| 446 SkMatrix m; | 450 SkMatrix m; |
| 447 m.setRotate(degrees); | 451 m.setRotate(degrees); |
| 448 return this->preConcat(m); | 452 this->preConcat(m); |
| 449 } | 453 } |
| 450 | 454 |
| 451 bool SkMatrix::postRotate(SkScalar degrees, SkScalar px, SkScalar py) { | 455 void SkMatrix::postRotate(SkScalar degrees, SkScalar px, SkScalar py) { |
| 452 SkMatrix m; | 456 SkMatrix m; |
| 453 m.setRotate(degrees, px, py); | 457 m.setRotate(degrees, px, py); |
| 454 return this->postConcat(m); | 458 this->postConcat(m); |
| 455 } | 459 } |
| 456 | 460 |
| 457 bool SkMatrix::postRotate(SkScalar degrees) { | 461 void SkMatrix::postRotate(SkScalar degrees) { |
| 458 SkMatrix m; | 462 SkMatrix m; |
| 459 m.setRotate(degrees); | 463 m.setRotate(degrees); |
| 460 return this->postConcat(m); | 464 this->postConcat(m); |
| 461 } | 465 } |
| 462 | 466 |
| 463 //////////////////////////////////////////////////////////////////////////////// //// | 467 //////////////////////////////////////////////////////////////////////////////// //// |
| 464 | 468 |
| 465 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 469 void SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 466 fMat[kMScaleX] = 1; | 470 fMat[kMScaleX] = 1; |
| 467 fMat[kMSkewX] = sx; | 471 fMat[kMSkewX] = sx; |
| 468 fMat[kMTransX] = -sx * py; | 472 fMat[kMTransX] = -sx * py; |
| 469 | 473 |
| 470 fMat[kMSkewY] = sy; | 474 fMat[kMSkewY] = sy; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 485 fMat[kMSkewY] = sy; | 489 fMat[kMSkewY] = sy; |
| 486 fMat[kMScaleY] = 1; | 490 fMat[kMScaleY] = 1; |
| 487 fMat[kMTransY] = 0; | 491 fMat[kMTransY] = 0; |
| 488 | 492 |
| 489 fMat[kMPersp0] = fMat[kMPersp1] = 0; | 493 fMat[kMPersp0] = fMat[kMPersp1] = 0; |
| 490 fMat[kMPersp2] = 1; | 494 fMat[kMPersp2] = 1; |
| 491 | 495 |
| 492 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 496 this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 493 } | 497 } |
| 494 | 498 |
| 495 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 499 void SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 496 SkMatrix m; | 500 SkMatrix m; |
| 497 m.setSkew(sx, sy, px, py); | 501 m.setSkew(sx, sy, px, py); |
| 498 return this->preConcat(m); | 502 this->preConcat(m); |
| 499 } | 503 } |
| 500 | 504 |
| 501 bool SkMatrix::preSkew(SkScalar sx, SkScalar sy) { | 505 void SkMatrix::preSkew(SkScalar sx, SkScalar sy) { |
| 502 SkMatrix m; | 506 SkMatrix m; |
| 503 m.setSkew(sx, sy); | 507 m.setSkew(sx, sy); |
| 504 return this->preConcat(m); | 508 this->preConcat(m); |
| 505 } | 509 } |
| 506 | 510 |
| 507 bool SkMatrix::postSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { | 511 void SkMatrix::postSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { |
| 508 SkMatrix m; | 512 SkMatrix m; |
| 509 m.setSkew(sx, sy, px, py); | 513 m.setSkew(sx, sy, px, py); |
| 510 return this->postConcat(m); | 514 this->postConcat(m); |
| 511 } | 515 } |
| 512 | 516 |
| 513 bool SkMatrix::postSkew(SkScalar sx, SkScalar sy) { | 517 void SkMatrix::postSkew(SkScalar sx, SkScalar sy) { |
| 514 SkMatrix m; | 518 SkMatrix m; |
| 515 m.setSkew(sx, sy); | 519 m.setSkew(sx, sy); |
| 516 return this->postConcat(m); | 520 this->postConcat(m); |
| 517 } | 521 } |
| 518 | 522 |
| 519 /////////////////////////////////////////////////////////////////////////////// | 523 /////////////////////////////////////////////////////////////////////////////// |
| 520 | 524 |
| 521 bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, | 525 bool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, |
| 522 ScaleToFit align) | 526 ScaleToFit align) |
| 523 { | 527 { |
| 524 if (src.isEmpty()) { | 528 if (src.isEmpty()) { |
| 525 this->reset(); | 529 this->reset(); |
| 526 return false; | 530 return false; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 581 } | 585 } |
| 582 this->setTypeMask(mask); | 586 this->setTypeMask(mask); |
| 583 } | 587 } |
| 584 // shared cleanup | 588 // shared cleanup |
| 585 fMat[kMPersp2] = 1; | 589 fMat[kMPersp2] = 1; |
| 586 return true; | 590 return true; |
| 587 } | 591 } |
| 588 | 592 |
| 589 /////////////////////////////////////////////////////////////////////////////// | 593 /////////////////////////////////////////////////////////////////////////////// |
| 590 | 594 |
| 591 static inline int fixmuladdmul(float a, float b, float c, float d, | 595 static inline float muladdmul(float a, float b, float c, float d) { |
| 592 float* result) { | 596 return SkDoubleToFloat((double)a * b + (double)c * d); |
|
scroggo
2014/04/02 14:53:36
I know this is not a change in behavior, but is th
| |
| 593 *result = SkDoubleToFloat((double)a * b + (double)c * d); | |
| 594 return true; | |
| 595 } | 597 } |
| 596 | 598 |
| 597 static inline bool rowcol3(const float row[], const float col[], | 599 static inline float rowcol3(const float row[], const float col[]) { |
| 598 float* result) { | 600 return row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; |
|
scroggo
2014/04/02 14:53:36
Same question.
| |
| 599 *result = row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; | |
| 600 return true; | |
| 601 } | |
| 602 | |
| 603 static inline int negifaddoverflows(float& result, float a, float b) { | |
| 604 result = a + b; | |
| 605 return 0; | |
| 606 } | 601 } |
| 607 | 602 |
| 608 static void normalize_perspective(SkScalar mat[9]) { | 603 static void normalize_perspective(SkScalar mat[9]) { |
| 609 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) { | 604 if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > 1) { |
| 610 for (int i = 0; i < 9; i++) | 605 for (int i = 0; i < 9; i++) |
| 611 mat[i] = SkScalarHalf(mat[i]); | 606 mat[i] = SkScalarHalf(mat[i]); |
| 612 } | 607 } |
| 613 } | 608 } |
| 614 | 609 |
| 615 bool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { | 610 void SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { |
| 616 TypeMask aType = a.getPerspectiveTypeMaskOnly(); | 611 TypeMask aType = a.getPerspectiveTypeMaskOnly(); |
| 617 TypeMask bType = b.getPerspectiveTypeMaskOnly(); | 612 TypeMask bType = b.getPerspectiveTypeMaskOnly(); |
| 618 | 613 |
| 619 if (a.isTriviallyIdentity()) { | 614 if (a.isTriviallyIdentity()) { |
| 620 *this = b; | 615 *this = b; |
| 621 } else if (b.isTriviallyIdentity()) { | 616 } else if (b.isTriviallyIdentity()) { |
| 622 *this = a; | 617 *this = a; |
| 623 } else { | 618 } else { |
| 624 SkMatrix tmp; | 619 SkMatrix tmp; |
| 625 | 620 |
| 626 if ((aType | bType) & kPerspective_Mask) { | 621 if ((aType | bType) & kPerspective_Mask) { |
| 627 if (!rowcol3(&a.fMat[0], &b.fMat[0], &tmp.fMat[kMScaleX])) { | 622 tmp.fMat[kMScaleX] = rowcol3(&a.fMat[0], &b.fMat[0]); |
| 628 return false; | 623 tmp.fMat[kMSkewX] = rowcol3(&a.fMat[0], &b.fMat[1]); |
| 629 } | 624 tmp.fMat[kMTransX] = rowcol3(&a.fMat[0], &b.fMat[2]); |
| 630 if (!rowcol3(&a.fMat[0], &b.fMat[1], &tmp.fMat[kMSkewX])) { | 625 tmp.fMat[kMSkewY] = rowcol3(&a.fMat[3], &b.fMat[0]); |
| 631 return false; | 626 tmp.fMat[kMScaleY] = rowcol3(&a.fMat[3], &b.fMat[1]); |
| 632 } | 627 tmp.fMat[kMTransY] = rowcol3(&a.fMat[3], &b.fMat[2]); |
| 633 if (!rowcol3(&a.fMat[0], &b.fMat[2], &tmp.fMat[kMTransX])) { | 628 tmp.fMat[kMPersp0] = rowcol3(&a.fMat[6], &b.fMat[0]); |
| 634 return false; | 629 tmp.fMat[kMPersp1] = rowcol3(&a.fMat[6], &b.fMat[1]); |
| 635 } | 630 tmp.fMat[kMPersp2] = rowcol3(&a.fMat[6], &b.fMat[2]); |
| 636 | |
| 637 if (!rowcol3(&a.fMat[3], &b.fMat[0], &tmp.fMat[kMSkewY])) { | |
| 638 return false; | |
| 639 } | |
| 640 if (!rowcol3(&a.fMat[3], &b.fMat[1], &tmp.fMat[kMScaleY])) { | |
| 641 return false; | |
| 642 } | |
| 643 if (!rowcol3(&a.fMat[3], &b.fMat[2], &tmp.fMat[kMTransY])) { | |
| 644 return false; | |
| 645 } | |
| 646 | |
| 647 if (!rowcol3(&a.fMat[6], &b.fMat[0], &tmp.fMat[kMPersp0])) { | |
| 648 return false; | |
| 649 } | |
| 650 if (!rowcol3(&a.fMat[6], &b.fMat[1], &tmp.fMat[kMPersp1])) { | |
| 651 return false; | |
| 652 } | |
| 653 if (!rowcol3(&a.fMat[6], &b.fMat[2], &tmp.fMat[kMPersp2])) { | |
| 654 return false; | |
| 655 } | |
| 656 | 631 |
| 657 normalize_perspective(tmp.fMat); | 632 normalize_perspective(tmp.fMat); |
| 658 tmp.setTypeMask(kUnknown_Mask); | 633 tmp.setTypeMask(kUnknown_Mask); |
| 659 } else { // not perspective | 634 } else { // not perspective |
| 660 if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMScaleX], | 635 tmp.fMat[kMScaleX] = muladdmul(a.fMat[kMScaleX], |
| 661 a.fMat[kMSkewX], b.fMat[kMSkewY], &tmp.fMat[kMScaleX])) { | 636 b.fMat[kMScaleX], |
| 662 return false; | 637 a.fMat[kMSkewX], |
| 663 } | 638 b.fMat[kMSkewY]); |
| 664 if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMSkewX], | |
| 665 a.fMat[kMSkewX], b.fMat[kMScaleY], &tmp.fMat[kMSkewX])) { | |
| 666 return false; | |
| 667 } | |
| 668 if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMTransX], | |
| 669 a.fMat[kMSkewX], b.fMat[kMTransY], &tmp.fMat[kMTransX])) { | |
| 670 return false; | |
| 671 } | |
| 672 if (negifaddoverflows(tmp.fMat[kMTransX], tmp.fMat[kMTransX], | |
| 673 a.fMat[kMTransX]) < 0) { | |
| 674 return false; | |
| 675 } | |
| 676 | 639 |
| 677 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMScaleX], | 640 tmp.fMat[kMSkewX] = muladdmul(a.fMat[kMScaleX], |
| 678 a.fMat[kMScaleY], b.fMat[kMSkewY], &tmp.fMat[kMSkewY])) { | 641 b.fMat[kMSkewX], |
| 679 return false; | 642 a.fMat[kMSkewX], |
| 680 } | 643 b.fMat[kMScaleY]); |
| 681 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMSkewX], | |
| 682 a.fMat[kMScaleY], b.fMat[kMScaleY], &tmp.fMat[kMScaleY])) { | |
| 683 return false; | |
| 684 } | |
| 685 if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMTransX], | |
| 686 a.fMat[kMScaleY], b.fMat[kMTransY], &tmp.fMat[kMTransY])) { | |
| 687 return false; | |
| 688 } | |
| 689 if (negifaddoverflows(tmp.fMat[kMTransY], tmp.fMat[kMTransY], | |
| 690 a.fMat[kMTransY]) < 0) { | |
| 691 return false; | |
| 692 } | |
| 693 | 644 |
| 645 tmp.fMat[kMTransX] = muladdmul(a.fMat[kMScaleX], | |
| 646 b.fMat[kMTransX], | |
| 647 a.fMat[kMSkewX], | |
| 648 b.fMat[kMTransY]); | |
| 649 | |
| 650 tmp.fMat[kMTransX] += a.fMat[kMTransX]; | |
| 651 | |
| 652 tmp.fMat[kMSkewY] = muladdmul(a.fMat[kMSkewY], | |
| 653 b.fMat[kMScaleX], | |
| 654 a.fMat[kMScaleY], | |
| 655 b.fMat[kMSkewY]); | |
| 656 | |
| 657 tmp.fMat[kMScaleY] = muladdmul(a.fMat[kMSkewY], | |
| 658 b.fMat[kMSkewX], | |
| 659 a.fMat[kMScaleY], | |
| 660 b.fMat[kMScaleY]); | |
| 661 | |
| 662 tmp.fMat[kMTransY] = muladdmul(a.fMat[kMSkewY], | |
| 663 b.fMat[kMTransX], | |
| 664 a.fMat[kMScaleY], | |
| 665 b.fMat[kMTransY]); | |
| 666 | |
| 667 tmp.fMat[kMTransY] += a.fMat[kMTransY]; | |
| 694 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; | 668 tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; |
| 695 tmp.fMat[kMPersp2] = 1; | 669 tmp.fMat[kMPersp2] = 1; |
| 696 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); | 670 //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); |
| 697 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); | 671 //SkASSERT(!(tmp.getType() & kPerspective_Mask)); |
| 698 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); | 672 tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); |
| 699 } | 673 } |
| 700 *this = tmp; | 674 *this = tmp; |
| 701 } | 675 } |
| 702 return true; | |
| 703 } | 676 } |
| 704 | 677 |
| 705 bool SkMatrix::preConcat(const SkMatrix& mat) { | 678 void SkMatrix::preConcat(const SkMatrix& mat) { |
| 706 // check for identity first, so we don't do a needless copy of ourselves | 679 // check for identity first, so we don't do a needless copy of ourselves |
| 707 // to ourselves inside setConcat() | 680 // to ourselves inside setConcat() |
| 708 return mat.isIdentity() || this->setConcat(*this, mat); | 681 if(!mat.isIdentity()) { |
| 682 this->setConcat(*this, mat); | |
| 683 } | |
| 709 } | 684 } |
| 710 | 685 |
| 711 bool SkMatrix::postConcat(const SkMatrix& mat) { | 686 void SkMatrix::postConcat(const SkMatrix& mat) { |
| 712 // check for identity first, so we don't do a needless copy of ourselves | 687 // check for identity first, so we don't do a needless copy of ourselves |
| 713 // to ourselves inside setConcat() | 688 // to ourselves inside setConcat() |
| 714 return mat.isIdentity() || this->setConcat(mat, *this); | 689 if (!mat.isIdentity()) { |
| 690 this->setConcat(mat, *this); | |
| 691 } | |
| 715 } | 692 } |
| 716 | 693 |
| 717 /////////////////////////////////////////////////////////////////////////////// | 694 /////////////////////////////////////////////////////////////////////////////// |
| 718 | 695 |
| 719 /* Matrix inversion is very expensive, but also the place where keeping | 696 /* Matrix inversion is very expensive, but also the place where keeping |
| 720 precision may be most important (here and matrix concat). Hence to avoid | 697 precision may be most important (here and matrix concat). Hence to avoid |
| 721 bitmap blitting artifacts when walking the inverse, we use doubles for | 698 bitmap blitting artifacts when walking the inverse, we use doubles for |
| 722 the intermediate math, even though we know that is more expensive. | 699 the intermediate math, even though we know that is more expensive. |
| 723 */ | 700 */ |
| 724 | 701 |
| (...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1461 | 1438 |
| 1462 if (!proc(src, &tempMap, scale)) { | 1439 if (!proc(src, &tempMap, scale)) { |
| 1463 return false; | 1440 return false; |
| 1464 } | 1441 } |
| 1465 if (!tempMap.invert(&result)) { | 1442 if (!tempMap.invert(&result)) { |
| 1466 return false; | 1443 return false; |
| 1467 } | 1444 } |
| 1468 if (!proc(dst, &tempMap, scale)) { | 1445 if (!proc(dst, &tempMap, scale)) { |
| 1469 return false; | 1446 return false; |
| 1470 } | 1447 } |
| 1471 if (!result.setConcat(tempMap, result)) { | 1448 this->setConcat(tempMap, result); |
| 1472 return false; | |
| 1473 } | |
| 1474 *this = result; | |
| 1475 return true; | 1449 return true; |
| 1476 } | 1450 } |
| 1477 | 1451 |
| 1478 /////////////////////////////////////////////////////////////////////////////// | 1452 /////////////////////////////////////////////////////////////////////////////// |
| 1479 | 1453 |
| 1480 enum MinOrMax { | 1454 enum MinOrMax { |
| 1481 kMin_MinOrMax, | 1455 kMin_MinOrMax, |
| 1482 kMax_MinOrMax | 1456 kMax_MinOrMax |
| 1483 }; | 1457 }; |
| 1484 | 1458 |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1754 rotation1->fX = cos1; | 1728 rotation1->fX = cos1; |
| 1755 rotation1->fY = sin1; | 1729 rotation1->fY = sin1; |
| 1756 } | 1730 } |
| 1757 if (NULL != rotation2) { | 1731 if (NULL != rotation2) { |
| 1758 rotation2->fX = cos2; | 1732 rotation2->fX = cos2; |
| 1759 rotation2->fY = sin2; | 1733 rotation2->fY = sin2; |
| 1760 } | 1734 } |
| 1761 | 1735 |
| 1762 return true; | 1736 return true; |
| 1763 } | 1737 } |
| OLD | NEW |