1 /* 2 * Copyright 2021 Google LLC 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 skgpu_geom_Transform_DEFINED 9 #define skgpu_geom_Transform_DEFINED 10 11 #include "include/core/SkM44.h" 12 13 namespace skgpu { 14 15 class Rect; 16 17 // Transform encapsulates an SkM44 matrix, its inverse, and other properties dependent on the 18 // original matrix value that are useful when rendering. 19 class Transform { 20 public: 21 // Type classifies the transform into coarse categories so that certain optimizations or 22 // properties can be queried efficiently 23 enum class Type : unsigned { 24 // Applying the matrix to a vector or point is a no-op, so could be skipped entirely. 25 kIdentity, 26 // The matrix transforms a rect to another rect, without mirrors or rotations, so both 27 // pre-and-post transform coordinates can be exactly represented as rects. 28 kSimpleRectStaysRect, 29 // The matrix transforms a rect to another rect, but may mirror or rotate the corners 30 // relative to each other. This means that the post-transformed rect completely fills 31 // that space. 32 kRectStaysRect, 33 // The matrix transform may have skew or rotation, so a mapped rect does not fill space, 34 // but there is no need to perform perspective division or w-plane clipping. 35 kAffine, 36 // The matrix includes perspective, so care must be taken when w is less than or near 0, 37 // and perspective division and interpolation are needed for correct rendering. 38 kPerspective, 39 // The matrix is not invertible or not finite, so should not be used to draw. 40 kInvalid, 41 }; 42 43 explicit Transform(const SkM44& m); 44 Transform(const Transform& t) = default; 45 46 Transform& operator=(const Transform& t) = default; 47 48 operator const SkM44&() const { return fM; } SkMatrix()49 operator SkMatrix() const { return fM.asM33(); } 50 51 bool operator==(const Transform& t) const; 52 bool operator!=(const Transform& t) const { return !(*this == t); } 53 matrix()54 const SkM44& matrix() const { return fM; } inverse()55 const SkM44& inverse() const { return fInvM; } 56 scaleFactors()57 const SkV2& scaleFactors() const { return fScale; } maxScaleFactor()58 float maxScaleFactor() const { return std::max(fScale.x, fScale.y); } 59 type()60 Type type() const { return fType; } valid()61 bool valid() const { return fType != Type::kInvalid; } 62 63 Rect mapRect(const Rect& rect) const; 64 Rect inverseMapRect(const Rect& rect) const; 65 66 private: 67 SkM44 fM; 68 SkM44 fInvM; // M^-1 69 Type fType; 70 // TODO: It would be nice to have a scale factor for perspective too, and there is 71 // SkMatrixPriv::DifferentialAreaScale but that requires a specific location. 72 SkV2 fScale; // always > 0 73 }; 74 75 } // namespace skgpu 76 77 #endif // skgpu_geom_Transform_DEFINED 78