/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef skgpu_geom_Transform_DEFINED #define skgpu_geom_Transform_DEFINED #include "include/core/SkM44.h" namespace skgpu { class Rect; // Transform encapsulates an SkM44 matrix, its inverse, and other properties dependent on the // original matrix value that are useful when rendering. class Transform { public: // Type classifies the transform into coarse categories so that certain optimizations or // properties can be queried efficiently enum class Type : unsigned { // Applying the matrix to a vector or point is a no-op, so could be skipped entirely. kIdentity, // The matrix transforms a rect to another rect, without mirrors or rotations, so both // pre-and-post transform coordinates can be exactly represented as rects. kSimpleRectStaysRect, // The matrix transforms a rect to another rect, but may mirror or rotate the corners // relative to each other. This means that the post-transformed rect completely fills // that space. kRectStaysRect, // The matrix transform may have skew or rotation, so a mapped rect does not fill space, // but there is no need to perform perspective division or w-plane clipping. kAffine, // The matrix includes perspective, so care must be taken when w is less than or near 0, // and perspective division and interpolation are needed for correct rendering. kPerspective, // The matrix is not invertible or not finite, so should not be used to draw. kInvalid, }; explicit Transform(const SkM44& m); Transform(const Transform& t) = default; Transform& operator=(const Transform& t) = default; operator const SkM44&() const { return fM; } operator SkMatrix() const { return fM.asM33(); } bool operator==(const Transform& t) const; bool operator!=(const Transform& t) const { return !(*this == t); } const SkM44& matrix() const { return fM; } const SkM44& inverse() const { return fInvM; } const SkV2& scaleFactors() const { return fScale; } float maxScaleFactor() const { return std::max(fScale.x, fScale.y); } Type type() const { return fType; } bool valid() const { return fType != Type::kInvalid; } Rect mapRect(const Rect& rect) const; Rect inverseMapRect(const Rect& rect) const; private: SkM44 fM; SkM44 fInvM; // M^-1 Type fType; // TODO: It would be nice to have a scale factor for perspective too, and there is // SkMatrixPriv::DifferentialAreaScale but that requires a specific location. SkV2 fScale; // always > 0 }; } // namespace skgpu #endif // skgpu_geom_Transform_DEFINED