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/SkNx.h" |
13 | |
14 | // We enclose this class in the anonymous namespace so it can have Sk2f/Sk4f members. |
15 | namespace { // NOLINT(google-build-namespaces) |
16 | |
17 | // Represents the upper-left 2x2 matrix of an affine transform for applying to vectors: |
18 | // |
19 | // VectorXform(p1 - p0) == M * float3(p1, 1) - M * float3(p0, 1) |
20 | // |
21 | class GrVectorXform { |
22 | public: |
23 | explicit GrVectorXform() : fType(Type::kIdentity) {} |
24 | explicit GrVectorXform(const SkMatrix& m) { |
25 | SkASSERT(!m.hasPerspective()); |
26 | if (m.getType() & SkMatrix::kAffine_Mask) { |
27 | fType = Type::kAffine; |
28 | fScaleXSkewY = {m.getScaleX(), m.getSkewY()}; |
29 | fSkewXScaleY = {m.getSkewX(), m.getScaleY()}; |
30 | fScaleXYXY = {m.getScaleX(), m.getScaleY(), m.getScaleX(), m.getScaleY()}; |
31 | fSkewXYXY = {m.getSkewX(), m.getSkewY(), m.getSkewX(), m.getSkewY()}; |
32 | } else if (m.getType() & SkMatrix::kScale_Mask) { |
33 | fType = Type::kScale; |
34 | fScaleXY = {m.getScaleX(), m.getScaleY()}; |
35 | fScaleXYXY = {m.getScaleX(), m.getScaleY(), m.getScaleX(), m.getScaleY()}; |
36 | } else { |
37 | SkASSERT(!(m.getType() & ~SkMatrix::kTranslate_Mask)); |
38 | fType = Type::kIdentity; |
39 | } |
40 | } |
41 | Sk2f operator()(const Sk2f& vector) const { |
42 | switch (fType) { |
43 | case Type::kIdentity: |
44 | return vector; |
45 | case Type::kScale: |
46 | return fScaleXY * vector; |
47 | case Type::kAffine: |
48 | return fScaleXSkewY * vector[0] + fSkewXScaleY * vector[1]; |
49 | } |
50 | SkUNREACHABLE; |
51 | } |
52 | Sk4f operator()(const Sk4f& vectors) const { |
53 | switch (fType) { |
54 | case Type::kIdentity: |
55 | return vectors; |
56 | case Type::kScale: |
57 | return vectors * fScaleXYXY; |
58 | case Type::kAffine: |
59 | return fScaleXYXY * vectors + fSkewXYXY * SkNx_shuffle<1,0,3,2>(vectors); |
60 | } |
61 | SkUNREACHABLE; |
62 | } |
63 | private: |
64 | enum class Type { kIdentity, kScale, kAffine } fType; |
65 | union { Sk2f fScaleXY, fScaleXSkewY; }; |
66 | Sk2f fSkewXScaleY; |
67 | Sk4f fScaleXYXY; |
68 | Sk4f fSkewXYXY; |
69 | }; |
70 | |
71 | } // namespace |
72 | |
73 | #endif |
74 | |