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