180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMatrix.h" 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Sk64.h" 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFloatBits.h" 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkScalarCompare.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkString.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define kMatrix22Elem SK_Scalar1 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline float SkDoubleToFloat(double x) { 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return static_cast<float>(x); 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define kMatrix22Elem SK_Fract1 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* [scale-x skew-x trans-x] [X] [X'] 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru [skew-y scale-y trans-y] * [Y] = [Y'] 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru [persp-0 persp-1 persp-2] [1] [1 ] 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::reset() { 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = fMat[kMSkewY] = 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = fMat[kMTransY] = 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kIdentity_Mask | kRectStaysRect_Mask); 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// this guy aligns with the masks, so we can compute a mask from a varaible 0/1 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruenum { 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kTranslate_Shift, 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kScale_Shift, 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kAffine_Shift, 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kPerspective_Shift, 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru kRectStaysRect_Shift 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int32_t kScalar1Int = 0x3f800000; 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int32_t kPersp1Int = 0x3f800000; 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define scalarAsInt(x) (x) 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int32_t kScalar1Int = (1 << 16); 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const int32_t kPersp1Int = (1 << 30); 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint8_t SkMatrix::computePerspectiveTypeMask() const { 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_SLOW_COMPARES 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarAs2sCompliment(fMat[kMPersp0]) | 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAs2sCompliment(fMat[kMPersp1]) | 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (SkScalarAs2sCompliment(fMat[kMPersp2]) - kPersp1Int)) { 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkToU8(kORableMasks); 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Benchmarking suggests that replacing this set of SkScalarAs2sCompliment 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // is a win, but replacing those below is not. We don't yet understand 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // that result. 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] != kMatrix22Elem) { 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If this is a perspective transform, we return true for all other 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // transform flags - this does not disable any optimizations, respects 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the rule that the type mask must be conservative, and speeds up 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // type mask computation. 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkToU8(kORableMasks); 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkToU8(kOnlyPerspectiveValid_Mask | kUnknown_Mask); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint8_t SkMatrix::computeTypeMask() const { 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned mask = 0; 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_SLOW_COMPARES 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarAs2sCompliment(fMat[kMPersp0]) | 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAs2sCompliment(fMat[kMPersp1]) | 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru (SkScalarAs2sCompliment(fMat[kMPersp2]) - kPersp1Int)) { 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkToU8(kORableMasks); 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarAs2sCompliment(fMat[kMTransX]) | 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAs2sCompliment(fMat[kMTransY])) { 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= kTranslate_Mask; 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fMat[kMPersp0] != 0 || fMat[kMPersp1] != 0 || 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] != kMatrix22Elem) { 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Once it is determined that that this is a perspective transform, 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // all other flags are moot as far as optimizations are concerned. 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkToU8(kORableMasks); 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fMat[kMTransX] != 0 || fMat[kMTransY] != 0) { 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= kTranslate_Mask; 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int m00 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleX]); 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int m01 = SkScalarAs2sCompliment(fMat[SkMatrix::kMSkewX]); 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int m10 = SkScalarAs2sCompliment(fMat[SkMatrix::kMSkewY]); 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int m11 = SkScalarAs2sCompliment(fMat[SkMatrix::kMScaleY]); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (m01 | m10) { 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // The skew components may be scale-inducing, unless we are dealing 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // with a pure rotation. Testing for a pure rotation is expensive, 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // so we opt for being conservative by always setting the scale bit. 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // along with affine. 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // By doing this, we are also ensuring that matrices have the same 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // type masks as their inverses. 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= kAffine_Mask | kScale_Mask; 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // For rectStaysRect, in the affine case, we only need check that 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the primary diagonal is all zeros and that the secondary diagonal 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // is all non-zero. 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // map non-zero to 1 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m01 = m01 != 0; 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m10 = m10 != 0; 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int dp0 = 0 == (m00 | m11) ; // true if both are 0 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int ds1 = m01 & m10; // true if both are 1 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= (dp0 & ds1) << kRectStaysRect_Shift; 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Only test for scale explicitly if not affine, since affine sets the 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // scale bit. 13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((m00 - kScalar1Int) | (m11 - kScalar1Int)) { 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= kScale_Mask; 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Not affine, therefore we already know secondary diagonal is 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // all zeros, so we just need to check that primary diagonal is 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // all non-zero. 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // map non-zero to 1 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m00 = m00 != 0; 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m11 = m11 != 0; 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // record if the (p)rimary diagonal is all non-zero 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= (m00 & m11) << kRectStaysRect_Shift; 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkToU8(mask); 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool operator==(const SkMatrix& a, const SkMatrix& b) { 16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkScalar* SK_RESTRICT ma = a.fMat; 16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkScalar* SK_RESTRICT mb = b.fMat; 16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return ma[0] == mb[0] && ma[1] == mb[1] && ma[2] == mb[2] && 16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ma[3] == mb[3] && ma[4] == mb[4] && ma[5] == mb[5] && 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ma[6] == mb[6] && ma[7] == mb[7] && ma[8] == mb[8]; 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 173d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerbool SkMatrix::isSimilarity(SkScalar tol) const { 174d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // if identity or translate matrix 175d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger TypeMask mask = this->getType(); 176d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (mask <= kTranslate_Mask) { 177d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return true; 178d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 179d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (mask & kPerspective_Mask) { 180d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return false; 181d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 182d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 183d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar mx = fMat[kMScaleX]; 184d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar my = fMat[kMScaleY]; 185d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // if no skew, can just compare scale factors 186d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!(mask & kAffine_Mask)) { 187d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return !SkScalarNearlyZero(mx) && SkScalarNearlyEqual(SkScalarAbs(mx), SkScalarAbs(my)); 188d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 189d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar sx = fMat[kMSkewX]; 190d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar sy = fMat[kMSkewY]; 191d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 192d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // degenerate matrix, non-similarity 193d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (SkScalarNearlyZero(mx) && SkScalarNearlyZero(my) 194d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger && SkScalarNearlyZero(sx) && SkScalarNearlyZero(sy)) { 195d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return false; 196d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 197d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 198d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // it has scales and skews, but it could also be rotation, check it out. 199d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkVector vec[2]; 200d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger vec[0].set(mx, sx); 201d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger vec[1].set(sy, my); 202d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 203d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return SkScalarNearlyZero(vec[0].dot(vec[1]), SkScalarSquare(tol)) && 204d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalarNearlyEqual(vec[0].lengthSqd(), vec[1].lengthSqd(), 205d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalarSquare(tol)); 206d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 207d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 208d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 209d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setTranslate(SkScalar dx, SkScalar dy) { 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) { 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = dx; 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = dy; 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = fMat[kMScaleY] = SK_Scalar1; 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = fMat[kMSkewY] = 21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kTranslate_Mask | kRectStaysRect_Mask); 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(); 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preTranslate(SkScalar dx, SkScalar dy) { 22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this->hasPerspective()) { 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setTranslate(dx, dy); 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->preConcat(m); 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) { 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] += SkScalarMul(fMat[kMScaleX], dx) + 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(fMat[kMSkewX], dy); 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] += SkScalarMul(fMat[kMSkewY], dx) + 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(fMat[kMScaleY], dy); 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postTranslate(SkScalar dx, SkScalar dy) { 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this->hasPerspective()) { 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setTranslate(dx, dy); 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->postConcat(m); 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarToCompareType(dx) || SkScalarToCompareType(dy)) { 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] += dx; 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] += dy; 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(); 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = sx; 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = sy; 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = px - SkScalarMul(sx, px); 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = py - SkScalarMul(sy, py); 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = fMat[kMSkewY] = 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kScale_Mask | kTranslate_Mask | kRectStaysRect_Mask); 27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 27680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 27780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setScale(SkScalar sx, SkScalar sy) { 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(); 28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 28280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = sx; 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = sy; 28480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 28580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = fMat[kMTransY] = 28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = fMat[kMSkewY] = 28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); 29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::setIDiv(int divx, int divy) { 29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!divx || !divy) { 29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setScale(SK_Scalar1 / divx, SK_Scalar1 / divy); 29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 30080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 30380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 30480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setScale(sx, sy, px, py); 30580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->preConcat(m); 30680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 30780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 30880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preScale(SkScalar sx, SkScalar sy) { 30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setScale(sx, sy); 31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->preConcat(m); 31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the assumption is that these multiplies are very cheap, and that 31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // a full concat and/or just computing the matrix type is more expensive. 32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Also, the fixed-point case checks for overflow, but the float doesn't, 32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // so we can get away with these blind multiplies. 32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = SkScalarMul(fMat[kMScaleX], sx); 32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewY] = SkScalarMul(fMat[kMSkewY], sx); 32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = SkScalarMul(fMat[kMPersp0], sx); 32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = SkScalarMul(fMat[kMSkewX], sy); 32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = SkScalarMul(fMat[kMScaleY], sy); 32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp1] = SkScalarMul(fMat[kMPersp1], sy); 33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->orTypeMask(kScale_Mask); 33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setScale(sx, sy, px, py); 34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->postConcat(m); 34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postScale(SkScalar sx, SkScalar sy) { 34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SK_Scalar1 == sx && SK_Scalar1 == sy) { 34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setScale(sx, sy); 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->postConcat(m); 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline SkFixed roundidiv(SkFixed numer, int denom) { 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int ns = numer >> 31; 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int ds = denom >> 31; 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru numer = (numer ^ ns) - ns; 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru denom = (denom ^ ds) - ds; 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed answer = (numer + (denom >> 1)) / denom; 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int as = ns ^ ds; 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (answer ^ as) - as; 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// this guy perhaps can go away, if we have a fract/high-precision way to 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// scale matrices 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postIDiv(int divx, int divy) { 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (divx == 0 || divy == 0) { 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = roundidiv(fMat[kMScaleX], divx); 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = roundidiv(fMat[kMSkewX], divx); 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = roundidiv(fMat[kMTransX], divx); 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = roundidiv(fMat[kMScaleY], divy); 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewY] = roundidiv(fMat[kMSkewY], divy); 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = roundidiv(fMat[kMTransY], divy); 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const float invX = 1.f / divx; 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const float invY = 1.f / divy; 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] *= invX; 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] *= invX; 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] *= invX; 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] *= invY; 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewY] *= invY; 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] *= invY; 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask); 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////////// 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV, 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar px, SkScalar py) { 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkScalar oneMinusCosV = SK_Scalar1 - cosV; 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = cosV; 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = -sinV; 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = SkScalarMul(sinV, py) + SkScalarMul(oneMinusCosV, px); 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewY] = sinV; 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = cosV; 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = SkScalarMul(-sinV, px) + SkScalarMul(oneMinusCosV, py); 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setSinCos(SkScalar sinV, SkScalar cosV) { 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = cosV; 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = -sinV; 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = 0; 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewY] = sinV; 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = cosV; 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = 0; 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setRotate(SkScalar degrees, SkScalar px, SkScalar py) { 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sinV, cosV; 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setSinCos(sinV, cosV, px, py); 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setRotate(SkScalar degrees) { 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sinV, cosV; 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sinV = SkScalarSinCos(SkDegreesToRadians(degrees), &cosV); 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setSinCos(sinV, cosV); 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preRotate(SkScalar degrees, SkScalar px, SkScalar py) { 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setRotate(degrees, px, py); 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->preConcat(m); 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preRotate(SkScalar degrees) { 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setRotate(degrees); 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->preConcat(m); 45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postRotate(SkScalar degrees, SkScalar px, SkScalar py) { 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setRotate(degrees, px, py); 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->postConcat(m); 46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postRotate(SkScalar degrees) { 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setRotate(degrees); 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->postConcat(m); 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//////////////////////////////////////////////////////////////////////////////////// 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = SK_Scalar1; 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = sx; 47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = SkScalarMul(-sx, py); 47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewY] = sy; 47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = SK_Scalar1; 47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = SkScalarMul(-sy, px); 48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::setSkew(SkScalar sx, SkScalar sy) { 48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = SK_Scalar1; 48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = sx; 49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = 0; 49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewY] = sy; 49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = SK_Scalar1; 49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = 0; 49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setSkew(sx, sy, px, py); 50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->preConcat(m); 50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preSkew(SkScalar sx, SkScalar sy) { 50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setSkew(sx, sy); 51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->preConcat(m); 51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postSkew(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py) { 51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setSkew(sx, sy, px, py); 51780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->postConcat(m); 51880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 51980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postSkew(SkScalar sx, SkScalar sy) { 52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix m; 52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.setSkew(sx, sy); 52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return this->postConcat(m); 52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::setRectToRect(const SkRect& src, const SkRect& dst, 52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ScaleToFit align) 53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{ 53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (src.isEmpty()) { 53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(); 53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dst.isEmpty()) { 53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sk_bzero(fMat, 8 * sizeof(SkScalar)); 53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kScale_Mask | kRectStaysRect_Mask); 53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar tx, sx = SkScalarDiv(dst.width(), src.width()); 54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar ty, sy = SkScalarDiv(dst.height(), src.height()); 54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool xLarger = false; 54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (align != kFill_ScaleToFit) { 54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sx > sy) { 54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru xLarger = true; 54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sx = sy; 54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru sy = sx; 55080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tx = dst.fLeft - SkScalarMul(src.fLeft, sx); 55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ty = dst.fTop - SkScalarMul(src.fTop, sy); 55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (align == kCenter_ScaleToFit || align == kEnd_ScaleToFit) { 55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar diff; 55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (xLarger) { 55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru diff = dst.width() - SkScalarMul(src.width(), sy); 56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru diff = dst.height() - SkScalarMul(src.height(), sy); 56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (align == kCenter_ScaleToFit) { 56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru diff = SkScalarHalf(diff); 56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (xLarger) { 56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tx += diff; 57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ty += diff; 57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX] = sx; 57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY] = sy; 57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransX] = tx; 57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMTransY] = ty; 57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMSkewX] = fMat[kMSkewY] = 58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp0] = fMat[kMPersp1] = 0; 58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru unsigned mask = kRectStaysRect_Mask; 58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (sx != SK_Scalar1 || sy != SK_Scalar1) { 58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= kScale_Mask; 58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (tx || ty) { 58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mask |= kTranslate_Mask; 58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(mask); 59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // shared cleanup 59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMPersp2] = kMatrix22Elem; 59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT 59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline int fixmuladdmul(float a, float b, float c, float d, 60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float* result) { 60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *result = SkDoubleToFloat((double)a * b + (double)c * d); 60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline bool rowcol3(const float row[], const float col[], 60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float* result) { 60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *result = row[0] * col[0] + row[1] * col[3] + row[2] * col[6]; 60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline int negifaddoverflows(float& result, float a, float b) { 61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result = a + b; 61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline bool fixmuladdmul(SkFixed a, SkFixed b, SkFixed c, SkFixed d, 61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed* result) { 61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tmp1, tmp2; 61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.setMul(a, b); 62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.setMul(c, d); 62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.add(tmp2); 62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (tmp1.isFixed()) { 62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *result = tmp1.getFixed(); 62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline SkFixed fracmuladdmul(SkFixed a, SkFract b, SkFixed c, 63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFract d) { 63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tmp1, tmp2; 63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.setMul(a, b); 63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.setMul(c, d); 63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.add(tmp2); 63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return tmp1.getFract(); 63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline bool rowcol3(const SkFixed row[], const SkFixed col[], 63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed* result) { 64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tmp1, tmp2; 64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.setMul(row[0], col[0]); // N * fixed 64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.setMul(row[1], col[3]); // N * fixed 64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.add(tmp2); 64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.setMul(row[2], col[6]); // N * fract 64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.roundRight(14); // make it fixed 64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.add(tmp2); 64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (tmp1.isFixed()) { 65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *result = tmp1.getFixed(); 65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static inline int negifaddoverflows(SkFixed& result, SkFixed a, SkFixed b) { 65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed c = a + b; 65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru result = c; 66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (c ^ a) & (c ^ b); 66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void normalize_perspective(SkScalar mat[9]) { 66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarAbs(mat[SkMatrix::kMPersp2]) > kMatrix22Elem) { 66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 9; i++) 66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mat[i] = SkScalarHalf(mat[i]); 66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::setConcat(const SkMatrix& a, const SkMatrix& b) { 67280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TypeMask aType = a.getPerspectiveTypeMaskOnly(); 67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TypeMask bType = b.getPerspectiveTypeMaskOnly(); 67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (a.isTriviallyIdentity()) { 67680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *this = b; 67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else if (b.isTriviallyIdentity()) { 67880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *this = a; 67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 68080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix tmp; 68180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 68280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((aType | bType) & kPerspective_Mask) { 68380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[0], &b.fMat[0], &tmp.fMat[kMScaleX])) { 68480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 68580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[0], &b.fMat[1], &tmp.fMat[kMSkewX])) { 68780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[0], &b.fMat[2], &tmp.fMat[kMTransX])) { 69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 69180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 69280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 69380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[3], &b.fMat[0], &tmp.fMat[kMSkewY])) { 69480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 69580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 69680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[3], &b.fMat[1], &tmp.fMat[kMScaleY])) { 69780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 69880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 69980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[3], &b.fMat[2], &tmp.fMat[kMTransY])) { 70080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 70180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 70280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 70380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[6], &b.fMat[0], &tmp.fMat[kMPersp0])) { 70480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 70580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[6], &b.fMat[1], &tmp.fMat[kMPersp1])) { 70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!rowcol3(&a.fMat[6], &b.fMat[2], &tmp.fMat[kMPersp2])) { 71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru normalize_perspective(tmp.fMat); 71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.setTypeMask(kUnknown_Mask); 71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { // not perspective 71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMScaleX], 71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMSkewX], b.fMat[kMSkewY], &tmp.fMat[kMScaleX])) { 71880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 71980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMSkewX], 72180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMSkewX], b.fMat[kMScaleY], &tmp.fMat[kMSkewX])) { 72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fixmuladdmul(a.fMat[kMScaleX], b.fMat[kMTransX], 72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMSkewX], b.fMat[kMTransY], &tmp.fMat[kMTransX])) { 72680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 72780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (negifaddoverflows(tmp.fMat[kMTransX], tmp.fMat[kMTransX], 72980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMTransX]) < 0) { 73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMScaleX], 73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMScaleY], b.fMat[kMSkewY], &tmp.fMat[kMSkewY])) { 73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMSkewX], 73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMScaleY], b.fMat[kMScaleY], &tmp.fMat[kMScaleY])) { 73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fixmuladdmul(a.fMat[kMSkewY], b.fMat[kMTransX], 74280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMScaleY], b.fMat[kMTransY], &tmp.fMat[kMTransY])) { 74380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 74480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 74580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (negifaddoverflows(tmp.fMat[kMTransY], tmp.fMat[kMTransY], 74680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a.fMat[kMTransY]) < 0) { 74780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 75080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.fMat[kMPersp0] = tmp.fMat[kMPersp1] = 0; 75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.fMat[kMPersp2] = kMatrix22Elem; 75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //SkDebugf("Concat mat non-persp type: %d\n", tmp.getType()); 75380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru //SkASSERT(!(tmp.getType() & kPerspective_Mask)); 75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.setTypeMask(kUnknown_Mask | kOnlyPerspectiveValid_Mask); 75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *this = tmp; 75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 75880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::preConcat(const SkMatrix& mat) { 76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // check for identity first, so we don't do a needless copy of ourselves 76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // to ourselves inside setConcat() 76480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return mat.isIdentity() || this->setConcat(*this, mat); 76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 76680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 76780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::postConcat(const SkMatrix& mat) { 76880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // check for identity first, so we don't do a needless copy of ourselves 76980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // to ourselves inside setConcat() 77080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return mat.isIdentity() || this->setConcat(mat, *this); 77180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 77280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 77380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 77480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 77580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* Matrix inversion is very expensive, but also the place where keeping 77680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru precision may be most important (here and matrix concat). Hence to avoid 77780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bitmap blitting artifacts when walking the inverse, we use doubles for 77880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru the intermediate math, even though we know that is more expensive. 77980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru The fixed counter part is us using Sk64 for temp calculations. 78080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 78180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 78280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT 78380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef double SkDetScalar; 78480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define SkPerspMul(a, b) SkScalarMul(a, b) 78580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define SkScalarMulShift(a, b, s) SkDoubleToFloat((a) * (b)) 78680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static double sk_inv_determinant(const float mat[9], int isPerspective, 78780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int* /* (only used in Fixed case) */) { 78880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double det; 78980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 79080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isPerspective) { 79180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru det = mat[SkMatrix::kMScaleX] * ((double)mat[SkMatrix::kMScaleY] * mat[SkMatrix::kMPersp2] - (double)mat[SkMatrix::kMTransY] * mat[SkMatrix::kMPersp1]) + 79280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mat[SkMatrix::kMSkewX] * ((double)mat[SkMatrix::kMTransY] * mat[SkMatrix::kMPersp0] - (double)mat[SkMatrix::kMSkewY] * mat[SkMatrix::kMPersp2]) + 79380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru mat[SkMatrix::kMTransX] * ((double)mat[SkMatrix::kMSkewY] * mat[SkMatrix::kMPersp1] - (double)mat[SkMatrix::kMScaleY] * mat[SkMatrix::kMPersp0]); 79480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 79580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru det = (double)mat[SkMatrix::kMScaleX] * mat[SkMatrix::kMScaleY] - (double)mat[SkMatrix::kMSkewX] * mat[SkMatrix::kMSkewY]; 79680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 79780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 79880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Since the determinant is on the order of the cube of the matrix members, 79980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // compare to the cube of the default nearly-zero constant (although an 80080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // estimate of the condition number would be better if it wasn't so expensive). 80180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero * SK_ScalarNearlyZero)) { 80280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 80380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 80480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 1.0 / det; 80580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 80680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we declar a,b,c,d to all be doubles, because we want to perform 80780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // double-precision muls and subtract, even though the original values are 80880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // from the matrix, which are floats. 80980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static float inline mul_diff_scale(double a, double b, double c, double d, 81080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru double scale) { 81180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkDoubleToFloat((a * b - c * d) * scale); 81280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 81380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 81480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkFixed SkDetScalar; 81580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define SkPerspMul(a, b) SkFractMul(a, b) 81680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define SkScalarMulShift(a, b, s) SkMulShift(a, b, s) 81780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static void set_muladdmul(Sk64* dst, int32_t a, int32_t b, int32_t c, 81880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t d) { 81980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tmp; 82080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->setMul(a, b); 82180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.setMul(c, d); 82280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->add(tmp); 82380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 82480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 82580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static SkFixed sk_inv_determinant(const SkFixed mat[9], int isPerspective, 82680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int* shift) { 82780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tmp1, tmp2; 82880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 82980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isPerspective) { 83080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.setMul(mat[SkMatrix::kMScaleX], fracmuladdmul(mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp2], -mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp1])); 83180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.setMul(mat[SkMatrix::kMSkewX], fracmuladdmul(mat[SkMatrix::kMTransY], mat[SkMatrix::kMPersp0], -mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp2])); 83280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.add(tmp2); 83380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.setMul(mat[SkMatrix::kMTransX], fracmuladdmul(mat[SkMatrix::kMSkewY], mat[SkMatrix::kMPersp1], -mat[SkMatrix::kMScaleY], mat[SkMatrix::kMPersp0])); 83480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.add(tmp2); 83580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.setMul(mat[SkMatrix::kMScaleX], mat[SkMatrix::kMScaleY]); 83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp2.setMul(mat[SkMatrix::kMSkewX], mat[SkMatrix::kMSkewY]); 83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.sub(tmp2); 83980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 84080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int s = tmp1.getClzAbs(); 84280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *shift = s; 84380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 84480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed denom; 84580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (s <= 32) { 84680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru denom = tmp1.getShiftRight(33 - s); 84780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 84880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru denom = (int32_t)tmp1.fLo << (s - 33); 84980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 85080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 85180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (denom == 0) { 85280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 85380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 85480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** This could perhaps be a special fractdiv function, since both of its 85580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru arguments are known to have bit 31 clear and bit 30 set (when they 85680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru are made positive), thus eliminating the need for calling clz() 85780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 85880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkFractDiv(SK_Fract1, denom); 85980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 86080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 86180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 86280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::SetAffineIdentity(SkScalar affine[6]) { 86380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kAScaleX] = SK_Scalar1; 86480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kASkewY] = 0; 86580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kASkewX] = 0; 86680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kAScaleY] = SK_Scalar1; 86780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kATransX] = 0; 86880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kATransY] = 0; 86980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 87080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 87180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::asAffine(SkScalar affine[6]) const { 87280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this->hasPerspective()) { 87380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 87480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 87580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (affine) { 87680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kAScaleX] = this->fMat[kMScaleX]; 87780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kASkewY] = this->fMat[kMSkewY]; 87880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kASkewX] = this->fMat[kMSkewX]; 87980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kAScaleY] = this->fMat[kMScaleY]; 88080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kATransX] = this->fMat[kMTransX]; 88180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru affine[kATransY] = this->fMat[kMTransY]; 88280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 88380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 88480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 88580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 886363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkMatrix::invertNonIdentity(SkMatrix* inv) const { 887363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkASSERT(!this->isIdentity()); 888d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 889d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger TypeMask mask = this->getType(); 890d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 891d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifndef SK_IGNORE_FAST_SCALEMATRIX_INVERT 892d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (0 == (mask & ~(kScale_Mask | kTranslate_Mask))) { 893d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger bool invertible = true; 894d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (inv) { 895d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (mask & kScale_Mask) { 896d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar invX = fMat[kMScaleX]; 897d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalar invY = fMat[kMScaleY]; 898d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (0 == invX || 0 == invY) { 899d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return false; 900d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 901d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger invX = SkScalarInvert(invX); 902d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger invY = SkScalarInvert(invY); 903d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 904d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // Must be careful when writing to inv, since it may be the 905d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // same memory as this. 906d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 907d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->fMat[kMSkewX] = inv->fMat[kMSkewY] = 908d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->fMat[kMPersp0] = inv->fMat[kMPersp1] = 0; 909d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 910d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->fMat[kMScaleX] = invX; 911d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->fMat[kMScaleY] = invY; 912d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->fMat[kMPersp2] = kMatrix22Elem; 913d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->fMat[kMTransX] = -SkScalarMul(fMat[kMTransX], invX); 914d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->fMat[kMTransY] = -SkScalarMul(fMat[kMTransY], invY); 915d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 916d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->setTypeMask(mask | kRectStaysRect_Mask); 917d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { 918d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // translate only 919d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger inv->setTranslate(-fMat[kMTransX], -fMat[kMTransY]); 920d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 921d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } else { // inv is NULL, just check if we're invertible 922d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!fMat[kMScaleX] || !fMat[kMScaleY]) { 923d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger invertible = false; 924d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 925d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 926d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return invertible; 927d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 928d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 929d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 930d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger int isPersp = mask & kPerspective_Mask; 93180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int shift; 93280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDetScalar scale = sk_inv_determinant(fMat, isPersp, &shift); 93380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 93480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (scale == 0) { // underflow 93580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 93680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 93780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 93880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (inv) { 93980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix tmp; 94080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (inv == this) { 94180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv = &tmp; 94280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 94380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 94480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (isPersp) { 94580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru shift = 61 - shift; 94680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMScaleX] = SkScalarMulShift(SkPerspMul(fMat[kMScaleY], fMat[kMPersp2]) - SkPerspMul(fMat[kMTransY], fMat[kMPersp1]), scale, shift); 94780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMSkewX] = SkScalarMulShift(SkPerspMul(fMat[kMTransX], fMat[kMPersp1]) - SkPerspMul(fMat[kMSkewX], fMat[kMPersp2]), scale, shift); 94880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMTransX] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fMat[kMTransY]) - SkScalarMul(fMat[kMTransX], fMat[kMScaleY]), scale, shift); 94980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 95080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMSkewY] = SkScalarMulShift(SkPerspMul(fMat[kMTransY], fMat[kMPersp0]) - SkPerspMul(fMat[kMSkewY], fMat[kMPersp2]), scale, shift); 95180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMScaleY] = SkScalarMulShift(SkPerspMul(fMat[kMScaleX], fMat[kMPersp2]) - SkPerspMul(fMat[kMTransX], fMat[kMPersp0]), scale, shift); 95280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMTransY] = SkScalarMulShift(SkScalarMul(fMat[kMTransX], fMat[kMSkewY]) - SkScalarMul(fMat[kMScaleX], fMat[kMTransY]), scale, shift); 95380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 95480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMPersp0] = SkScalarMulShift(SkScalarMul(fMat[kMSkewY], fMat[kMPersp1]) - SkScalarMul(fMat[kMScaleY], fMat[kMPersp0]), scale, shift); 95580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMPersp1] = SkScalarMulShift(SkScalarMul(fMat[kMSkewX], fMat[kMPersp0]) - SkScalarMul(fMat[kMScaleX], fMat[kMPersp1]), scale, shift); 95680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMPersp2] = SkScalarMulShift(SkScalarMul(fMat[kMScaleX], fMat[kMScaleY]) - SkScalarMul(fMat[kMSkewX], fMat[kMSkewY]), scale, shift); 95780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 95880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (SkAbs32(inv->fMat[kMPersp2]) > SK_Fixed1) { 95980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tmp; 96080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 96180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.set(SK_Fract1); 96280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.shiftLeft(16); 96380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.div(inv->fMat[kMPersp2], Sk64::kRound_DivOption); 96480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 96580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFract scale = tmp.get32(); 96680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 96780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < 9; i++) { 96880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[i] = SkFractMul(inv->fMat[i], scale); 96980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 97080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 97180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMPersp2] = SkFixedToFract(inv->fMat[kMPersp2]); 97280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 97380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { // not perspective 97480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 97580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tx, ty; 97680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int clzNumer; 97780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 97880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // check the 2x2 for overflow 97980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru { 98080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int32_t value = SkAbs32(fMat[kMScaleY]); 98180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru value |= SkAbs32(fMat[kMSkewX]); 98280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru value |= SkAbs32(fMat[kMScaleX]); 98380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru value |= SkAbs32(fMat[kMSkewY]); 98480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clzNumer = SkCLZ(value); 98580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (shift - clzNumer > 31) 98680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; // overflow 98780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 98880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 98980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru set_muladdmul(&tx, fMat[kMSkewX], fMat[kMTransY], -fMat[kMScaleY], fMat[kMTransX]); 99080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru set_muladdmul(&ty, fMat[kMSkewY], fMat[kMTransX], -fMat[kMScaleX], fMat[kMTransY]); 99180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // check tx,ty for overflow 99280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru clzNumer = SkCLZ(SkAbs32(tx.fHi) | SkAbs32(ty.fHi)); 99380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (shift - clzNumer > 14) { 99480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; // overflow 99580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 99680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 99780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int fixedShift = 61 - shift; 99880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int sk64shift = 44 - shift + clzNumer; 99980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 100080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMScaleX] = SkMulShift(fMat[kMScaleY], scale, fixedShift); 100180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMSkewX] = SkMulShift(-fMat[kMSkewX], scale, fixedShift); 100280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMTransX] = SkMulShift(tx.getShiftRight(33 - clzNumer), scale, sk64shift); 100380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 100480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMSkewY] = SkMulShift(-fMat[kMSkewY], scale, fixedShift); 100580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMScaleY] = SkMulShift(fMat[kMScaleX], scale, fixedShift); 100680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMTransY] = SkMulShift(ty.getShiftRight(33 - clzNumer), scale, sk64shift); 100780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 100880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMScaleX] = SkDoubleToFloat(fMat[kMScaleY] * scale); 100980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMSkewX] = SkDoubleToFloat(-fMat[kMSkewX] * scale); 101080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMTransX] = mul_diff_scale(fMat[kMSkewX], fMat[kMTransY], 101180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleY], fMat[kMTransX], scale); 101280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 101380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMSkewY] = SkDoubleToFloat(-fMat[kMSkewY] * scale); 101480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMScaleY] = SkDoubleToFloat(fMat[kMScaleX] * scale); 101580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMTransY] = mul_diff_scale(fMat[kMSkewY], fMat[kMTransX], 101680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[kMScaleX], fMat[kMTransY], scale); 101780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 101880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMPersp0] = 0; 101980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMPersp1] = 0; 102080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->fMat[kMPersp2] = kMatrix22Elem; 102180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 102280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 102380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 102480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru inv->setTypeMask(fTypeMask); 102580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 102680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (inv == &tmp) { 102780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *(SkMatrix*)this = tmp; 102880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 102980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 103080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 103180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 103280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 103380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 103480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 103580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Identity_pts(const SkMatrix& m, SkPoint dst[], 103680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint src[], int count) { 103780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(m.getType() == 0); 103880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 103980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (dst != src && count > 0) 104080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(dst, src, count * sizeof(SkPoint)); 104180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 104280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 104380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Trans_pts(const SkMatrix& m, SkPoint dst[], 104480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint src[], int count) { 104580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(m.getType() == kTranslate_Mask); 104680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 104780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 0) { 104880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar tx = m.fMat[kMTransX]; 104980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar ty = m.fMat[kMTransY]; 105080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 105180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fY = src->fY + ty; 105280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fX = src->fX + tx; 105380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 1; 105480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 105580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count); 105680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 105780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 105880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 105980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Scale_pts(const SkMatrix& m, SkPoint dst[], 106080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint src[], int count) { 106180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(m.getType() == kScale_Mask); 106280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 106380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 0) { 106480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar mx = m.fMat[kMScaleX]; 106580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar my = m.fMat[kMScaleY]; 106680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 106780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fY = SkScalarMul(src->fY, my); 106880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fX = SkScalarMul(src->fX, mx); 106980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 1; 107080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 107180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count); 107280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 107380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 107480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 107580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::ScaleTrans_pts(const SkMatrix& m, SkPoint dst[], 107680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint src[], int count) { 107780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(m.getType() == (kScale_Mask | kTranslate_Mask)); 107880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 107980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 0) { 108080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar mx = m.fMat[kMScaleX]; 108180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar my = m.fMat[kMScaleY]; 108280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar tx = m.fMat[kMTransX]; 108380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar ty = m.fMat[kMTransY]; 108480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 108580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fY = SkScalarMulAdd(src->fY, my, ty); 108680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fX = SkScalarMulAdd(src->fX, mx, tx); 108780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 1; 108880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 108980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count); 109080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 109180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 109280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 109380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Rot_pts(const SkMatrix& m, SkPoint dst[], 109480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint src[], int count) { 109580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((m.getType() & (kPerspective_Mask | kTranslate_Mask)) == 0); 109680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 109780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 0) { 109880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar mx = m.fMat[kMScaleX]; 109980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar my = m.fMat[kMScaleY]; 110080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar kx = m.fMat[kMSkewX]; 110180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar ky = m.fMat[kMSkewY]; 110280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 110380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sy = src->fY; 110480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sx = src->fX; 110580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 1; 110680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fY = SkScalarMul(sx, ky) + SkScalarMul(sy, my); 110780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fX = SkScalarMul(sx, mx) + SkScalarMul(sy, kx); 110880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 110980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count); 111080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 111180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 111280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::RotTrans_pts(const SkMatrix& m, SkPoint dst[], 111480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint src[], int count) { 111580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(!m.hasPerspective()); 111680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 111780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 0) { 111880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar mx = m.fMat[kMScaleX]; 111980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar my = m.fMat[kMScaleY]; 112080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar kx = m.fMat[kMSkewX]; 112180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar ky = m.fMat[kMSkewY]; 112280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar tx = m.fMat[kMTransX]; 112380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar ty = m.fMat[kMTransY]; 112480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 112580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sy = src->fY; 112680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sx = src->fX; 112780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 1; 112880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fY = SkScalarMul(sx, ky) + SkScalarMulAdd(sy, my, ty); 112980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fX = SkScalarMul(sx, mx) + SkScalarMulAdd(sy, kx, tx); 113080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 113180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count); 113280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 113380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 113480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 113580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Persp_pts(const SkMatrix& m, SkPoint dst[], 113680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint src[], int count) { 113780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(m.hasPerspective()); 113880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 113980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 114080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed persp2 = SkFractToFixed(m.fMat[kMPersp2]); 114180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 114280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 114380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 0) { 114480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru do { 114580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sy = src->fY; 114680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar sx = src->fX; 114780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src += 1; 114880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 114980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + 115080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; 115180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + 115280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; 115380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 115480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed z = SkFractMul(sx, m.fMat[kMPersp0]) + 115580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFractMul(sy, m.fMat[kMPersp1]) + persp2; 115680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 115780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float z = SkScalarMul(sx, m.fMat[kMPersp0]) + 115880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMulAdd(sy, m.fMat[kMPersp1], m.fMat[kMPersp2]); 115980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 116080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (z) { 116180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru z = SkScalarFastInvert(z); 116280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 116380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 116480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fY = SkScalarMul(y, z); 116580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fX = SkScalarMul(x, z); 116680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst += 1; 116780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } while (--count); 116880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 116980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 117080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 117180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkMatrix::MapPtsProc SkMatrix::gMapPtsProcs[] = { 117280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Identity_pts, SkMatrix::Trans_pts, 117380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Scale_pts, SkMatrix::ScaleTrans_pts, 117480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, 117580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Rot_pts, SkMatrix::RotTrans_pts, 117680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // repeat the persp proc 8 times 117780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_pts, SkMatrix::Persp_pts, 117880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_pts, SkMatrix::Persp_pts, 117980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_pts, SkMatrix::Persp_pts, 118080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_pts, SkMatrix::Persp_pts 118180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 118280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::mapPoints(SkPoint dst[], const SkPoint src[], int count) const { 118480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((dst && src && count > 0) || count == 0); 118580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // no partial overlap 118680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(src == dst || SkAbs32((int32_t)(src - dst)) >= count); 118780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 118880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->getMapPtsProc()(*this, dst, src, count); 118980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 119080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 119280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::mapVectors(SkPoint dst[], const SkPoint src[], int count) const { 119480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this->hasPerspective()) { 119580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint origin; 119680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 119780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru MapXYProc proc = this->getMapXYProc(); 119880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru proc(*this, 0, 0, &origin); 119980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = count - 1; i >= 0; --i) { 120180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint tmp; 120280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru proc(*this, src[i].fX, src[i].fY, &tmp); 120480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst[i].set(tmp.fX - origin.fX, tmp.fY - origin.fY); 120580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 120680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 120780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix tmp = *this; 120880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 120980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.fMat[kMTransX] = tmp.fMat[kMTransY] = 0; 121080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.clearTypeMask(kTranslate_Mask); 121180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.mapPoints(dst, src, count); 121280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 121380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 121480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::mapRect(SkRect* dst, const SkRect& src) const { 121680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(dst && &src); 121780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this->rectStaysRect()) { 121980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->mapPoints((SkPoint*)dst, (const SkPoint*)&src, 2); 122080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->sort(); 122180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 122280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 122380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint quad[4]; 122480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 122580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru src.toQuad(quad); 122680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->mapPoints(quad, quad, 4); 122780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->set(quad, 4); 122880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 122980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 123080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 123180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar SkMatrix::mapRadius(SkScalar radius) const { 123380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkVector vec[2]; 123480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vec[0].set(radius, 0); 123680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru vec[1].set(0, radius); 123780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->mapVectors(vec, 2); 123880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 123980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar d0 = vec[0].length(); 124080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar d1 = vec[1].length(); 124180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 124280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkScalarMean(d0, d1); 124380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 124480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 124580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 124680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 124780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Persp_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 124880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint* pt) { 124980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(m.hasPerspective()); 125080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 125180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar x = SkScalarMul(sx, m.fMat[kMScaleX]) + 125280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(sy, m.fMat[kMSkewX]) + m.fMat[kMTransX]; 125380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar y = SkScalarMul(sx, m.fMat[kMSkewY]) + 125480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(sy, m.fMat[kMScaleY]) + m.fMat[kMTransY]; 125580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 125680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed z = SkFractMul(sx, m.fMat[kMPersp0]) + 125780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFractMul(sy, m.fMat[kMPersp1]) + 125880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFractToFixed(m.fMat[kMPersp2]); 125980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 126080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float z = SkScalarMul(sx, m.fMat[kMPersp0]) + 126180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(sy, m.fMat[kMPersp1]) + m.fMat[kMPersp2]; 126280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 126380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (z) { 126480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru z = SkScalarFastInvert(z); 126580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 126680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = SkScalarMul(x, z); 126780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = SkScalarMul(y, z); 126880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 126980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 127180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic SkFixed fixmuladdmul(SkFixed a, SkFixed b, SkFixed c, SkFixed d) { 127280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 tmp, tmp1; 127380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 127480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp.setMul(a, b); 127580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tmp1.setMul(c, d); 127680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return tmp.addGetFixed(tmp1); 127780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// tmp.add(tmp1); 127880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// return tmp.getFixed(); 127980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 128080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 128180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 128280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::RotTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 128380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint* pt) { 128480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask)) == kAffine_Mask); 128580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 128680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 128780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = fixmuladdmul(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]) + 128880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.fMat[kMTransX]; 128980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = fixmuladdmul(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]) + 129080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru m.fMat[kMTransY]; 129180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 129280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + 129380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); 129480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + 129580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); 129680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 129780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 129880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 129980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Rot_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 130080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint* pt) { 130180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((m.getType() & (kAffine_Mask | kPerspective_Mask))== kAffine_Mask); 130280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0 == m.fMat[kMTransX]); 130380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0 == m.fMat[kMTransY]); 130480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 130580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 130680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = fixmuladdmul(sx, m.fMat[kMScaleX], sy, m.fMat[kMSkewX]); 130780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = fixmuladdmul(sx, m.fMat[kMSkewY], sy, m.fMat[kMScaleY]); 130880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 130980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]) + 131080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMulAdd(sy, m.fMat[kMSkewX], m.fMat[kMTransX]); 131180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = SkScalarMul(sx, m.fMat[kMSkewY]) + 131280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); 131380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 131480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 131580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 131680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::ScaleTrans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 131780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint* pt) { 131880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) 131980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru == kScale_Mask); 132080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 132180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = SkScalarMulAdd(sx, m.fMat[kMScaleX], m.fMat[kMTransX]); 132280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = SkScalarMulAdd(sy, m.fMat[kMScaleY], m.fMat[kMTransY]); 132380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 132480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 132580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Scale_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 132680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint* pt) { 132780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT((m.getType() & (kScale_Mask | kAffine_Mask | kPerspective_Mask)) 132880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru == kScale_Mask); 132980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0 == m.fMat[kMTransX]); 133080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0 == m.fMat[kMTransY]); 133180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 133280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = SkScalarMul(sx, m.fMat[kMScaleX]); 133380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = SkScalarMul(sy, m.fMat[kMScaleY]); 133480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 133580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 133680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Trans_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 133780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint* pt) { 133880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(m.getType() == kTranslate_Mask); 133980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 134080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = sx + m.fMat[kMTransX]; 134180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = sy + m.fMat[kMTransY]; 134280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 134380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 134480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::Identity_xy(const SkMatrix& m, SkScalar sx, SkScalar sy, 134580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint* pt) { 134680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(0 == m.getType()); 134780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 134880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fX = sx; 134980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->fY = sy; 135080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 135180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 135280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkMatrix::MapXYProc SkMatrix::gMapXYProcs[] = { 135380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Identity_xy, SkMatrix::Trans_xy, 135480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Scale_xy, SkMatrix::ScaleTrans_xy, 135580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Rot_xy, SkMatrix::RotTrans_xy, 135680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Rot_xy, SkMatrix::RotTrans_xy, 135780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // repeat the persp proc 8 times 135880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_xy, SkMatrix::Persp_xy, 135980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_xy, SkMatrix::Persp_xy, 136080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_xy, SkMatrix::Persp_xy, 136180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_xy, SkMatrix::Persp_xy 136280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 136380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 136480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 136580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 136680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// if its nearly zero (just made up 26, perhaps it should be bigger or smaller) 136780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 136880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkFract SkPerspElemType; 136980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define PerspNearlyZero(x) (SkAbs32(x) < (SK_Fract1 >> 26)) 137080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 137180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef float SkPerspElemType; 137280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru #define PerspNearlyZero(x) SkScalarNearlyZero(x, (1.0f / (1 << 26))) 137380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 137480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 137580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::fixedStepInX(SkScalar y, SkFixed* stepX, SkFixed* stepY) const { 137680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (PerspNearlyZero(fMat[kMPersp0])) { 137780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (stepX || stepY) { 137880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (PerspNearlyZero(fMat[kMPersp1]) && 137980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru PerspNearlyZero(fMat[kMPersp2] - kMatrix22Elem)) { 138080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (stepX) { 138180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *stepX = SkScalarToFixed(fMat[kMScaleX]); 138280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 138380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (stepY) { 138480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *stepY = SkScalarToFixed(fMat[kMSkewY]); 138580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 138680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 138780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 138880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed z = SkFractMul(y, fMat[kMPersp1]) + 138980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFractToFixed(fMat[kMPersp2]); 139080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 139180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float z = y * fMat[kMPersp1] + fMat[kMPersp2]; 139280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 139380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (stepX) { 139480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *stepX = SkScalarToFixed(SkScalarDiv(fMat[kMScaleX], z)); 139580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 139680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (stepY) { 139780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *stepY = SkScalarToFixed(SkScalarDiv(fMat[kMSkewY], z)); 139880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 139980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 140080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 140180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 140280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 140380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 140480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 140580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 140680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 140780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 140880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPerspIter.h" 140980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 141080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPerspIter::SkPerspIter(const SkMatrix& m, SkScalar x0, SkScalar y0, int count) 141180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fMatrix(m), fSX(x0), fSY(y0), fCount(count) { 141280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint pt; 141380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 141480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_xy(m, x0, y0, &pt); 141580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fX = SkScalarToFixed(pt.fX); 141680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fY = SkScalarToFixed(pt.fY); 141780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 141880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 141980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruint SkPerspIter::next() { 142080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int n = fCount; 142180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 142280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == n) { 142380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 0; 142480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 142580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint pt; 142680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed x = fX; 142780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed y = fY; 142880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed dx, dy; 142980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 143080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (n >= kCount) { 143180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru n = kCount; 143280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSX += SkIntToScalar(kCount); 143380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_xy(fMatrix, fSX, fSY, &pt); 143480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fX = SkScalarToFixed(pt.fX); 143580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fY = SkScalarToFixed(pt.fY); 143680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dx = (fX - x) >> kShift; 143780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dy = (fY - y) >> kShift; 143880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 143980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fSX += SkIntToScalar(n); 144080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Persp_xy(fMatrix, fSX, fSY, &pt); 144180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fX = SkScalarToFixed(pt.fX); 144280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fY = SkScalarToFixed(pt.fY); 144380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dx = (fX - x) / n; 144480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dy = (fY - y) / n; 144580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 144680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 144780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed* p = fStorage; 144880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (int i = 0; i < n; i++) { 144980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *p++ = x; x += dx; 145080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *p++ = y; y += dy; 145180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 145280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 145380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCount -= n; 145480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return n; 145580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 145680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 145780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 145880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 145980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FIXED 146080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 146180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool poly_to_point(SkPoint* pt, const SkPoint poly[], int count) { 146280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed x = SK_Fixed1, y = SK_Fixed1; 146380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint pt1, pt2; 146480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru Sk64 w1, w2; 146580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 146680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 1) { 146780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt1.fX = poly[1].fX - poly[0].fX; 146880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt1.fY = poly[1].fY - poly[0].fY; 146980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y = SkPoint::Length(pt1.fX, pt1.fY); 147080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (y == 0) { 147180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 147280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 147380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (count) { 147480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 2: 147580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 147680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 3: 147780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fX = poly[0].fY - poly[2].fY; 147880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fY = poly[2].fX - poly[0].fX; 147980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto CALC_X; 148080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 148180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fX = poly[0].fY - poly[3].fY; 148280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fY = poly[3].fX - poly[0].fX; 148380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CALC_X: 148480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru w1.setMul(pt1.fX, pt2.fX); 148580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru w2.setMul(pt1.fY, pt2.fY); 148680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru w1.add(w2); 148780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru w1.div(y, Sk64::kRound_DivOption); 148880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!w1.is32()) { 148980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 149080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 149180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x = w1.get32(); 149280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 149380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 149480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 149580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->set(x, y); 149680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 149780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 149880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 149980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, 150080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint& scalePt) { 150180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // need to check if SkFixedDiv overflows... 150280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 150380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkFixed scale = scalePt.fY; 150480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleX] = SkFixedDiv(srcPt[1].fY - srcPt[0].fY, scale); 150580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewY] = SkFixedDiv(srcPt[0].fX - srcPt[1].fX, scale); 150680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp0] = 0; 150780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewX] = SkFixedDiv(srcPt[1].fX - srcPt[0].fX, scale); 150880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleY] = SkFixedDiv(srcPt[1].fY - srcPt[0].fY, scale); 150980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp1] = 0; 151080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransX] = srcPt[0].fX; 151180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransY] = srcPt[0].fY; 151280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp2] = SK_Fract1; 151380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->setTypeMask(kUnknown_Mask); 151480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 151580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 151680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 151780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::Poly3Proc(const SkPoint srcPt[], SkMatrix* dst, 151880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint& scale) { 151980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // really, need to check if SkFixedDiv overflow'd 152080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 152180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleX] = SkFixedDiv(srcPt[2].fX - srcPt[0].fX, scale.fX); 152280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewY] = SkFixedDiv(srcPt[2].fY - srcPt[0].fY, scale.fX); 152380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp0] = 0; 152480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewX] = SkFixedDiv(srcPt[1].fX - srcPt[0].fX, scale.fY); 152580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleY] = SkFixedDiv(srcPt[1].fY - srcPt[0].fY, scale.fY); 152680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp1] = 0; 152780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransX] = srcPt[0].fX; 152880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransY] = srcPt[0].fY; 152980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp2] = SK_Fract1; 153080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->setTypeMask(kUnknown_Mask); 153180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 153280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 153380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 153480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::Poly4Proc(const SkPoint srcPt[], SkMatrix* dst, 153580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint& scale) { 153680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFract a1, a2; 153780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed x0, y0, x1, y1, x2, y2; 153880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 153980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x0 = srcPt[2].fX - srcPt[0].fX; 154080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y0 = srcPt[2].fY - srcPt[0].fY; 154180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x1 = srcPt[2].fX - srcPt[1].fX; 154280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y1 = srcPt[2].fY - srcPt[1].fY; 154380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x2 = srcPt[2].fX - srcPt[3].fX; 154480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y2 = srcPt[2].fY - srcPt[3].fY; 154580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 154680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* check if abs(x2) > abs(y2) */ 154780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { 154880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed denom = SkMulDiv(x1, y2, x2) - y1; 154980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == denom) { 155080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 155180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 155280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a1 = SkFractDiv(SkMulDiv(x0 - x1, y2, x2) - y0 + y1, denom); 155380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 155480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed denom = x1 - SkMulDiv(y1, x2, y2); 155580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == denom) { 155680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 155780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 155880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a1 = SkFractDiv(x0 - x1 - SkMulDiv(y0 - y1, x2, y2), denom); 155980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 156080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 156180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* check if abs(x1) > abs(y1) */ 156280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { 156380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed denom = y2 - SkMulDiv(x2, y1, x1); 156480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == denom) { 156580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 156680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 156780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a2 = SkFractDiv(y0 - y2 - SkMulDiv(x0 - x2, y1, x1), denom); 156880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 156980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixed denom = SkMulDiv(y2, x1, y1) - x2; 157080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == denom) { 157180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 157280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 157380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a2 = SkFractDiv(SkMulDiv(y0 - y2, x1, y1) - x0 + x2, denom); 157480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 157580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 157680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // need to check if SkFixedDiv overflows... 157780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleX] = SkFixedDiv(SkFractMul(a2, srcPt[3].fX) + 157880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[3].fX - srcPt[0].fX, scale.fX); 157980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewY] = SkFixedDiv(SkFractMul(a2, srcPt[3].fY) + 158080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[3].fY - srcPt[0].fY, scale.fX); 158180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp0] = SkFixedDiv(a2, scale.fX); 158280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewX] = SkFixedDiv(SkFractMul(a1, srcPt[1].fX) + 158380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[1].fX - srcPt[0].fX, scale.fY); 158480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleY] = SkFixedDiv(SkFractMul(a1, srcPt[1].fY) + 158580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[1].fY - srcPt[0].fY, scale.fY); 158680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp1] = SkFixedDiv(a1, scale.fY); 158780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransX] = srcPt[0].fX; 158880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransY] = srcPt[0].fY; 158980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp2] = SK_Fract1; 159080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->setTypeMask(kUnknown_Mask); 159180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 159280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 159380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 159480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else /* Scalar is float */ 159580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 159680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool checkForZero(float x) { 159780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return x*x == 0; 159880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 159980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 160080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline bool poly_to_point(SkPoint* pt, const SkPoint poly[], int count) { 160180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float x = 1, y = 1; 160280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint pt1, pt2; 160380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 160480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (count > 1) { 160580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt1.fX = poly[1].fX - poly[0].fX; 160680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt1.fY = poly[1].fY - poly[0].fY; 160780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y = SkPoint::Length(pt1.fX, pt1.fY); 160880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (checkForZero(y)) { 160980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 161080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 161180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru switch (count) { 161280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 2: 161380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 161480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru case 3: 161580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fX = poly[0].fY - poly[2].fY; 161680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fY = poly[2].fX - poly[0].fX; 161780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru goto CALC_X; 161880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru default: 161980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fX = poly[0].fY - poly[3].fY; 162080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt2.fY = poly[3].fX - poly[0].fX; 162180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru CALC_X: 162280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x = SkScalarDiv(SkScalarMul(pt1.fX, pt2.fX) + 162380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(pt1.fY, pt2.fY), y); 162480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru break; 162580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 162680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 162780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru pt->set(x, y); 162880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 162980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 163080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 163180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::Poly2Proc(const SkPoint srcPt[], SkMatrix* dst, 163280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint& scale) { 163380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float invScale = 1 / scale.fY; 163480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 163580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleX] = (srcPt[1].fY - srcPt[0].fY) * invScale; 163680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewY] = (srcPt[0].fX - srcPt[1].fX) * invScale; 163780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp0] = 0; 163880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewX] = (srcPt[1].fX - srcPt[0].fX) * invScale; 163980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleY] = (srcPt[1].fY - srcPt[0].fY) * invScale; 164080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp1] = 0; 164180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransX] = srcPt[0].fX; 164280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransY] = srcPt[0].fY; 164380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp2] = 1; 164480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->setTypeMask(kUnknown_Mask); 164580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 164680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 164780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 164880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::Poly3Proc(const SkPoint srcPt[], SkMatrix* dst, 164980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint& scale) { 165080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float invScale = 1 / scale.fX; 165180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleX] = (srcPt[2].fX - srcPt[0].fX) * invScale; 165280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewY] = (srcPt[2].fY - srcPt[0].fY) * invScale; 165380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp0] = 0; 165480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 165580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru invScale = 1 / scale.fY; 165680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewX] = (srcPt[1].fX - srcPt[0].fX) * invScale; 165780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleY] = (srcPt[1].fY - srcPt[0].fY) * invScale; 165880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp1] = 0; 165980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 166080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransX] = srcPt[0].fX; 166180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransY] = srcPt[0].fY; 166280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp2] = 1; 166380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->setTypeMask(kUnknown_Mask); 166480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 166580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 166680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 166780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::Poly4Proc(const SkPoint srcPt[], SkMatrix* dst, 166880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkPoint& scale) { 166980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float a1, a2; 167080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float x0, y0, x1, y1, x2, y2; 167180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 167280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x0 = srcPt[2].fX - srcPt[0].fX; 167380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y0 = srcPt[2].fY - srcPt[0].fY; 167480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x1 = srcPt[2].fX - srcPt[1].fX; 167580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y1 = srcPt[2].fY - srcPt[1].fY; 167680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru x2 = srcPt[2].fX - srcPt[3].fX; 167780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru y2 = srcPt[2].fY - srcPt[3].fY; 167880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 167980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* check if abs(x2) > abs(y2) */ 168080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ( x2 > 0 ? y2 > 0 ? x2 > y2 : x2 > -y2 : y2 > 0 ? -x2 > y2 : x2 < y2) { 168180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float denom = SkScalarMulDiv(x1, y2, x2) - y1; 168280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (checkForZero(denom)) { 168380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 168480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 168580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a1 = SkScalarDiv(SkScalarMulDiv(x0 - x1, y2, x2) - y0 + y1, denom); 168680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 168780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float denom = x1 - SkScalarMulDiv(y1, x2, y2); 168880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (checkForZero(denom)) { 168980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 169080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 169180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a1 = SkScalarDiv(x0 - x1 - SkScalarMulDiv(y0 - y1, x2, y2), denom); 169280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 169380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 169480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /* check if abs(x1) > abs(y1) */ 169580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ( x1 > 0 ? y1 > 0 ? x1 > y1 : x1 > -y1 : y1 > 0 ? -x1 > y1 : x1 < y1) { 169680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float denom = y2 - SkScalarMulDiv(x2, y1, x1); 169780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (checkForZero(denom)) { 169880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 169980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 170080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a2 = SkScalarDiv(y0 - y2 - SkScalarMulDiv(x0 - x2, y1, x1), denom); 170180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 170280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float denom = SkScalarMulDiv(y2, x1, y1) - x2; 170380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (checkForZero(denom)) { 170480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 170580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 170680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru a2 = SkScalarDiv(SkScalarMulDiv(y0 - y2, x1, y1) - x0 + x2, denom); 170780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 170880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 170980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru float invScale = 1 / scale.fX; 171080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleX] = SkScalarMul(SkScalarMul(a2, srcPt[3].fX) + 171180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[3].fX - srcPt[0].fX, invScale); 171280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewY] = SkScalarMul(SkScalarMul(a2, srcPt[3].fY) + 171380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[3].fY - srcPt[0].fY, invScale); 171480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp0] = SkScalarMul(a2, invScale); 171580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru invScale = 1 / scale.fY; 171680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMSkewX] = SkScalarMul(SkScalarMul(a1, srcPt[1].fX) + 171780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[1].fX - srcPt[0].fX, invScale); 171880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMScaleY] = SkScalarMul(SkScalarMul(a1, srcPt[1].fY) + 171980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru srcPt[1].fY - srcPt[0].fY, invScale); 172080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp1] = SkScalarMul(a1, invScale); 172180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransX] = srcPt[0].fX; 172280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMTransY] = srcPt[0].fY; 172380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->fMat[kMPersp2] = 1; 172480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru dst->setTypeMask(kUnknown_Mask); 172580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 172680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 172780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 172880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 172980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 173080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef bool (*PolyMapProc)(const SkPoint[], SkMatrix*, const SkPoint&); 173180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 173280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* Taken from Rob Johnson's original sample code in QuickDraw GX 173380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/ 173480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkMatrix::setPolyToPoly(const SkPoint src[], const SkPoint dst[], 173580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int count) { 173680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if ((unsigned)count > 4) { 173780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("--- SkMatrix::setPolyToPoly count out of range %d\n", count); 173880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 173980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 174080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 174180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (0 == count) { 174280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->reset(); 174380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 174480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 174580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (1 == count) { 174680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTranslate(dst[0].fX - src[0].fX, dst[0].fY - src[0].fY); 174780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 174880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 174980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 175080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkPoint scale; 175180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!poly_to_point(&scale, src, count) || 175280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarNearlyZero(scale.fX) || 175380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarNearlyZero(scale.fY)) { 175480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 175580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 175680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 175780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const PolyMapProc gPolyMapProcs[] = { 175880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix::Poly2Proc, SkMatrix::Poly3Proc, SkMatrix::Poly4Proc 175980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru }; 176080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru PolyMapProc proc = gPolyMapProcs[count - 2]; 176180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkMatrix tempMap, result; 176380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru tempMap.setTypeMask(kUnknown_Mask); 176480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 176580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!proc(src, &tempMap, scale)) { 176680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 176780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 176880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!tempMap.invert(&result)) { 176980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 177080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 177180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!proc(dst, &tempMap, scale)) { 177280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 177380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 177480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!result.setConcat(tempMap, result)) { 177580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return false; 177680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 177780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *this = result; 177880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return true; 177980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 178080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 178180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 178280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 178380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkScalar SkMatrix::getMaxStretch() const { 178480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru TypeMask mask = this->getType(); 178580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 178680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this->hasPerspective()) { 178780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return -SK_Scalar1; 178880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 178980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (this->isIdentity()) { 179080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SK_Scalar1; 179180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 179280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!(mask & kAffine_Mask)) { 179380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkMaxScalar(SkScalarAbs(fMat[kMScaleX]), 179480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarAbs(fMat[kMScaleY])); 179580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 179680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // ignore the translation part of the matrix, just look at 2x2 portion. 179780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // compute singular values, take largest abs value. 179880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // [a b; b c] = A^T*A 179980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar a = SkScalarMul(fMat[kMScaleX], fMat[kMScaleX]) + 180080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(fMat[kMSkewY], fMat[kMSkewY]); 180180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar b = SkScalarMul(fMat[kMScaleX], fMat[kMSkewX]) + 180280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(fMat[kMScaleY], fMat[kMSkewY]); 180380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar c = SkScalarMul(fMat[kMSkewX], fMat[kMSkewX]) + 180480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalarMul(fMat[kMScaleY], fMat[kMScaleY]); 180580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // eigenvalues of A^T*A are the squared singular values of A. 180680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // characteristic equation is det((A^T*A) - l*I) = 0 180780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // l^2 - (a + c)l + (ac-b^2) 180880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // solve using quadratic equation (divisor is non-zero since l^2 has 1 coeff 180980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // and roots are guaraunteed to be pos and real). 181080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar largerRoot; 181180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar bSqd = SkScalarMul(b,b); 181280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // if upper left 2x2 is orthogonal save some math 181380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (bSqd <= SK_ScalarNearlyZero) { 181480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru largerRoot = SkMaxScalar(a, c); 181580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 181680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar aminusc = a - c; 181780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar apluscdiv2 = SkScalarHalf(a + c); 181880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar x = SkScalarHalf(SkScalarSqrt(SkScalarMul(aminusc, aminusc) + 4 * bSqd)); 181980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru largerRoot = apluscdiv2 + x; 182080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 182180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkScalarSqrt(largerRoot); 182280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 182380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 182480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkMatrix& SkMatrix::I() { 182580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static SkMatrix gIdentity; 182680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static bool gOnce; 182780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!gOnce) { 182880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gIdentity.reset(); 182980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gOnce = true; 183080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 183180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return gIdentity; 183280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 183380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 183480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruconst SkMatrix& SkMatrix::InvalidMatrix() { 183580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static SkMatrix gInvalid; 183680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static bool gOnce; 183780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!gOnce) { 183880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gInvalid.setAll(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, 183980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, 184080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SK_ScalarMax, SK_ScalarMax, SK_ScalarMax); 184180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gInvalid.getType(); // force the type to be computed 184280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru gOnce = true; 184380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 184480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return gInvalid; 184580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 184680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 184780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 184880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 184980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint32_t SkMatrix::writeToMemory(void* buffer) const { 185080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // TODO write less for simple matrices 185180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (buffer) { 185280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(buffer, fMat, 9 * sizeof(SkScalar)); 185380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 185480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 9 * sizeof(SkScalar); 185580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 185680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 185780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruuint32_t SkMatrix::readFromMemory(const void* buffer) { 185880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (buffer) { 185980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru memcpy(fMat, buffer, 9 * sizeof(SkScalar)); 186080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->setTypeMask(kUnknown_Mask); 186180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 186280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return 9 * sizeof(SkScalar); 186380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 186480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1865d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEVELOPER 186680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkMatrix::dump() const { 186780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkString str; 1868d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger this->toString(&str); 186980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("%s\n", str.c_str()); 187080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 187180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1872d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergervoid SkMatrix::toString(SkString* str) const { 1873d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger str->appendf("[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]", 187480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_SCALAR_IS_FLOAT 187580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[0], fMat[1], fMat[2], fMat[3], fMat[4], fMat[5], 187680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMat[6], fMat[7], fMat[8]); 187780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else 187880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixedToFloat(fMat[0]), SkFixedToFloat(fMat[1]), SkFixedToFloat(fMat[2]), 187980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFixedToFloat(fMat[3]), SkFixedToFloat(fMat[4]), SkFixedToFloat(fMat[5]), 188080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkFractToFloat(fMat[6]), SkFractToFloat(fMat[7]), SkFractToFloat(fMat[8])); 188180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 188280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 1883d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif 1884d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1885d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 1886d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1887d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#include "SkMatrixUtils.h" 1888d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1889d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerbool SkTreatAsSprite(const SkMatrix& mat, int width, int height, 1890d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger unsigned subpixelBits) { 1891d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // quick reject on affine or perspective 1892d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (mat.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { 1893d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return false; 1894d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1895d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1896d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // quick success check 1897d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (!subpixelBits && !(mat.getType() & ~SkMatrix::kTranslate_Mask)) { 1898d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return true; 1899d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1900d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1901d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // mapRect supports negative scales, so we eliminate those first 1902d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (mat.getScaleX() < 0 || mat.getScaleY() < 0) { 1903d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return false; 1904d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1905d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1906d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkRect dst; 1907d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkIRect isrc = { 0, 0, width, height }; 1908d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1909d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger { 1910d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkRect src; 1911d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger src.set(isrc); 1912d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger mat.mapRect(&dst, src); 1913d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1914d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1915d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger // just apply the translate to isrc 1916d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger isrc.offset(SkScalarRoundToInt(mat.getTranslateX()), 1917d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkScalarRoundToInt(mat.getTranslateY())); 1918d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1919d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (subpixelBits) { 1920d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger isrc.fLeft <<= subpixelBits; 1921d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger isrc.fTop <<= subpixelBits; 1922d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger isrc.fRight <<= subpixelBits; 1923d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger isrc.fBottom <<= subpixelBits; 1924d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1925d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger const float scale = 1 << subpixelBits; 1926d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger dst.fLeft *= scale; 1927d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger dst.fTop *= scale; 1928d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger dst.fRight *= scale; 1929d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger dst.fBottom *= scale; 1930d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 1931d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 1932d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger SkIRect idst; 1933d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger dst.round(&idst); 1934d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return isrc == idst; 1935d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 1936