1 /* 2 * Copyright 2020 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrVectorXform_DEFINED 9 #define GrVectorXform_DEFINED 10 11 #include "include/core/SkMatrix.h" 12 #include "include/private/SkVx.h" 13 14 // Represents the upper-left 2x2 matrix of an affine transform for applying to vectors: 15 // 16 // VectorXform(p1 - p0) == M * float3(p1, 1) - M * float3(p0, 1) 17 // 18 class GrVectorXform { 19 public: 20 using float2 = skvx::Vec<2, float>; 21 using float4 = skvx::Vec<4, float>; GrVectorXform()22 explicit GrVectorXform() : fType(Type::kIdentity) {} GrVectorXform(const SkMatrix & m)23 explicit GrVectorXform(const SkMatrix& m) { 24 SkASSERT(!m.hasPerspective()); 25 if (m.getType() & SkMatrix::kAffine_Mask) { 26 fType = Type::kAffine; 27 fScaleXSkewY = {m.getScaleX(), m.getSkewY()}; 28 fSkewXScaleY = {m.getSkewX(), m.getScaleY()}; 29 fScaleXYXY = {m.getScaleX(), m.getScaleY(), m.getScaleX(), m.getScaleY()}; 30 fSkewXYXY = {m.getSkewX(), m.getSkewY(), m.getSkewX(), m.getSkewY()}; 31 } else if (m.getType() & SkMatrix::kScale_Mask) { 32 fType = Type::kScale; 33 fScaleXY = {m.getScaleX(), m.getScaleY()}; 34 fScaleXYXY = {m.getScaleX(), m.getScaleY(), m.getScaleX(), m.getScaleY()}; 35 } else { 36 SkASSERT(!(m.getType() & ~SkMatrix::kTranslate_Mask)); 37 fType = Type::kIdentity; 38 } 39 } operator()40 float2 operator()(float2 vector) const { 41 switch (fType) { 42 case Type::kIdentity: 43 return vector; 44 case Type::kScale: 45 return fScaleXY * vector; 46 case Type::kAffine: 47 return fScaleXSkewY * float2(vector[0]) + fSkewXScaleY * vector[1]; 48 } 49 SkUNREACHABLE; 50 } operator()51 float4 operator()(float4 vectors) const { 52 switch (fType) { 53 case Type::kIdentity: 54 return vectors; 55 case Type::kScale: 56 return vectors * fScaleXYXY; 57 case Type::kAffine: 58 return fScaleXYXY * vectors + fSkewXYXY * skvx::shuffle<1,0,3,2>(vectors); 59 } 60 SkUNREACHABLE; 61 } 62 private: 63 enum class Type { kIdentity, kScale, kAffine } fType; 64 union { float2 fScaleXY, fScaleXSkewY; }; 65 float2 fSkewXScaleY; 66 float4 fScaleXYXY; 67 float4 fSkewXYXY; 68 }; 69 70 #endif 71