| 359 | } |
| 360 | |
| 361 | bool Matrix::invertNonIdentity(Matrix* inverse) const { |
| 362 | TypeMask mask = this->getType(); |
| 363 | // Optimized invert for only scale and/or translation matrices. |
| 364 | if (0 == (mask & ~(ScaleMask | TranslateMask))) { |
| 365 | if (mask & ScaleMask) { |
| 366 | if (values[SCALE_X] == 0 || values[SCALE_Y] == 0) { |
| 367 | return false; |
| 368 | } |
| 369 | float invSX = 1 / values[SCALE_X]; |
| 370 | float invSY = 1 / values[SCALE_Y]; |
| 371 | float invTX = -values[TRANS_X] * invSX; |
| 372 | float invTY = -values[TRANS_Y] * invSY; |
| 373 | if (inverse) { |
| 374 | inverse->values[SKEW_X] = inverse->values[SKEW_Y] = 0; |
| 375 | inverse->values[SCALE_X] = invSX; |
| 376 | inverse->values[SCALE_Y] = invSY; |
| 377 | inverse->values[TRANS_X] = invTX; |
| 378 | inverse->values[TRANS_Y] = invTY; |
| 379 | inverse->setTypeMask(mask | RectStayRectMask); |
| 380 | } |
| 381 | return true; |
| 382 | } |
| 383 | if (inverse) { |
| 384 | inverse->setTranslate(-values[TRANS_X], -values[TRANS_Y]); |
| 385 | } |
| 386 | return true; |
| 387 | } |
| 388 | float determinant = values[SCALE_X] * values[SCALE_Y] - values[SKEW_X] * values[SKEW_Y]; |
| 389 | if (FloatNearlyZero(determinant, FLOAT_NEARLY_ZERO * FLOAT_NEARLY_ZERO * FLOAT_NEARLY_ZERO)) { |
| 390 | return false; |
| 391 | } |
| 392 | determinant = 1 / determinant; |
| 393 | auto sx = values[SCALE_Y] * determinant; |
| 394 | auto ky = -values[SKEW_Y] * determinant; |
| 395 | auto kx = -values[SKEW_X] * determinant; |
| 396 | auto sy = values[SCALE_X] * determinant; |
| 397 | auto tx = -(sx * values[TRANS_X] + kx * values[TRANS_Y]); |
| 398 | auto ty = -(ky * values[TRANS_X] + sy * values[TRANS_Y]); |
| 399 | if (inverse) { |
| 400 | inverse->setAll(sx, kx, tx, ky, sy, ty); |
| 401 | inverse->setTypeMask(typeMask); |
| 402 | } |
| 403 | return true; |
| 404 | } |
| 405 | |
| 406 | void Matrix::mapPoints(Point dst[], const Point src[], int count) const { |
| 407 | this->getMapPtsProc()(*this, dst, src, count); |
no test coverage detected