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