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 "Sk64.h" | 9 #include "Sk64.h" |
10 #include "SkFloatBits.h" | 10 #include "SkFloatBits.h" |
(...skipping 1948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1959 dst.fLeft *= scale; | 1959 dst.fLeft *= scale; |
1960 dst.fTop *= scale; | 1960 dst.fTop *= scale; |
1961 dst.fRight *= scale; | 1961 dst.fRight *= scale; |
1962 dst.fBottom *= scale; | 1962 dst.fBottom *= scale; |
1963 } | 1963 } |
1964 | 1964 |
1965 SkIRect idst; | 1965 SkIRect idst; |
1966 dst.round(&idst); | 1966 dst.round(&idst); |
1967 return isrc == idst; | 1967 return isrc == idst; |
1968 } | 1968 } |
| 1969 |
| 1970 bool SkDecomposeUpper2x2(const SkMatrix& matrix, |
| 1971 SkScalar* rotation0, |
| 1972 SkScalar* xScale, SkScalar* yScale, |
| 1973 SkScalar* rotation1) { |
| 1974 |
| 1975 // borrowed from Jim Blinn's article "Consider the Lowly 2x2 Matrix" |
| 1976 // Note: he uses row vectors, so we have to do some swapping of terms |
| 1977 SkScalar A = matrix[SkMatrix::kMScaleX]; |
| 1978 SkScalar B = matrix[SkMatrix::kMSkewX]; |
| 1979 SkScalar C = matrix[SkMatrix::kMSkewY]; |
| 1980 SkScalar D = matrix[SkMatrix::kMScaleY]; |
| 1981 |
| 1982 SkScalar E = SK_ScalarHalf*(A + D); |
| 1983 SkScalar F = SK_ScalarHalf*(A - D); |
| 1984 SkScalar G = SK_ScalarHalf*(C + B); |
| 1985 SkScalar H = SK_ScalarHalf*(C - B); |
| 1986 |
| 1987 SkScalar sqrt0 = SkScalarSqrt(E*E + H*H); |
| 1988 SkScalar sqrt1 = SkScalarSqrt(F*F + G*G); |
| 1989 |
| 1990 SkScalar xs, ys, r0, r1; |
| 1991 |
| 1992 // can't have zero yScale, must be degenerate |
| 1993 if (SkScalarNearlyEqual(sqrt0, sqrt1)) { |
| 1994 return false; |
| 1995 } |
| 1996 xs = sqrt0 + sqrt1; |
| 1997 ys = sqrt0 - sqrt1; |
| 1998 |
| 1999 // uniformly scaled rotation |
| 2000 if (SkScalarNearlyZero(F) && SkScalarNearlyZero(G)) { |
| 2001 SkASSERT(!SkScalarNearlyZero(E)); |
| 2002 r0 = SkScalarATan2(H, E); |
| 2003 r1 = 0; |
| 2004 // uniformly scaled reflection |
| 2005 } else if (SkScalarNearlyZero(E) && SkScalarNearlyZero(H)) { |
| 2006 SkASSERT(!SkScalarNearlyZero(F)); |
| 2007 r0 = -SkScalarATan2(G, F); |
| 2008 r1 = 0; |
| 2009 } else { |
| 2010 SkASSERT(!SkScalarNearlyZero(E)); |
| 2011 SkASSERT(!SkScalarNearlyZero(F)); |
| 2012 |
| 2013 SkScalar arctan0 = SkScalarATan2(H, E); |
| 2014 SkScalar arctan1 = SkScalarATan2(G, F); |
| 2015 r0 = SK_ScalarHalf*(arctan0 - arctan1); |
| 2016 r1 = SK_ScalarHalf*(arctan0 + arctan1); |
| 2017 |
| 2018 // simplify the results |
| 2019 const SkScalar kHalfPI = SK_ScalarHalf*SK_ScalarPI; |
| 2020 if (SkScalarNearlyEqual(SkScalarAbs(r0), kHalfPI)) { |
| 2021 SkScalar tmp = xs; |
| 2022 xs = ys; |
| 2023 ys = tmp; |
| 2024 |
| 2025 r1 += r0; |
| 2026 r0 = 0; |
| 2027 } else if (SkScalarNearlyEqual(SkScalarAbs(r1), kHalfPI)) { |
| 2028 SkScalar tmp = xs; |
| 2029 xs = ys; |
| 2030 ys = tmp; |
| 2031 |
| 2032 r0 += r1; |
| 2033 r1 = 0; |
| 2034 } |
| 2035 } |
| 2036 |
| 2037 if (NULL != xScale) { |
| 2038 *xScale = xs; |
| 2039 } |
| 2040 if (NULL != yScale) { |
| 2041 *yScale = ys; |
| 2042 } |
| 2043 if (NULL != rotation0) { |
| 2044 *rotation0 = r0; |
| 2045 } |
| 2046 if (NULL != rotation1) { |
| 2047 *rotation1 = r1; |
| 2048 } |
| 2049 |
| 2050 return true; |
| 2051 } |
OLD | NEW |