blob: 94fe745edd7790188fae0b1a470d84149e11b814 [file] [log] [blame]
joshualittae5b2c62015-08-19 08:48:41 -07001/*
2 * Copyright 2015 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 GrQuad_DEFINED
9#define GrQuad_DEFINED
10
joshualittae5b2c62015-08-19 08:48:41 -070011#include "SkMatrix.h"
Brian Salomona33b67c2018-05-17 10:42:14 -040012#include "SkNx.h"
13#include "SkPoint.h"
Brian Salomonbe3c1d22018-05-21 12:54:39 -040014#include "SkPoint3.h"
joshualittae5b2c62015-08-19 08:48:41 -070015
Michael Ludwig1f7e4382018-10-19 09:36:57 -040016// Rectangles transformed by matrices (view or local) can be classified in three ways:
17// 1. Stays a rectangle - the matrix rectStaysRect() is true, or x(0) == x(1) && x(2) == x(3)
18// and y(0) == y(2) && y(1) == y(3). Or under mirrors, x(0) == x(2) && x(1) == x(3) and
19// y(0) == y(1) && y(2) == y(3).
20// 2. Is a quadrilateral - the matrix does not have perspective, but may rotate or skew, or
21// ws() == all ones.
22// 3. Is a perspective quad - the matrix has perspective, subsuming all previous quad types.
23enum class GrQuadType {
24 kRect_QuadType,
25 kStandard_QuadType,
26 kPerspective_QuadType
27};
28
29// If an SkRect is transformed by this matrix, what class of quad is required to represent it. Since
30// quadType() is only provided on Gr[Persp]Quad in debug builds, production code should use this
31// to efficiently determine quad types.
32GrQuadType GrQuadTypeForTransformedRect(const SkMatrix& matrix);
33
joshualittae5b2c62015-08-19 08:48:41 -070034/**
Brian Salomon57caa662017-10-18 12:21:05 +000035 * GrQuad is a collection of 4 points which can be used to represent an arbitrary quadrilateral. The
36 * points make a triangle strip with CCW triangles (top-left, bottom-left, top-right, bottom-right).
joshualittae5b2c62015-08-19 08:48:41 -070037 */
38class GrQuad {
39public:
Brian Salomona33b67c2018-05-17 10:42:14 -040040 GrQuad() = default;
joshualitt8cce8f12015-08-26 06:23:39 -070041
Brian Salomona33b67c2018-05-17 10:42:14 -040042 GrQuad(const GrQuad& that) = default;
43
44 explicit GrQuad(const SkRect& rect)
45 : fX{rect.fLeft, rect.fLeft, rect.fRight, rect.fRight}
46 , fY{rect.fTop, rect.fBottom, rect.fTop, rect.fBottom} {}
47
48 /** Sets the quad to the rect as transformed by the matrix. */
49 GrQuad(const SkRect&, const SkMatrix&);
50
51 explicit GrQuad(const SkPoint pts[4])
52 : fX{pts[0].fX, pts[1].fX, pts[2].fX, pts[3].fX}
53 , fY{pts[0].fY, pts[1].fY, pts[2].fY, pts[3].fY} {}
54
55 GrQuad& operator=(const GrQuad& that) = default;
56
57 SkPoint point(int i) const { return {fX[i], fY[i]}; }
58
59 SkRect bounds() const {
60 auto x = this->x4f(), y = this->y4f();
61 return {x.min(), y.min(), x.max(), y.max()};
joshualittae5b2c62015-08-19 08:48:41 -070062 }
63
Brian Salomona33b67c2018-05-17 10:42:14 -040064 float x(int i) const { return fX[i]; }
65 float y(int i) const { return fY[i]; }
joshualittae5b2c62015-08-19 08:48:41 -070066
Brian Salomona33b67c2018-05-17 10:42:14 -040067 Sk4f x4f() const { return Sk4f::Load(fX); }
68 Sk4f y4f() const { return Sk4f::Load(fY); }
joshualitt8cce8f12015-08-26 06:23:39 -070069
Michael Ludwig1f7e4382018-10-19 09:36:57 -040070 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
71 bool aaHasEffectOnRect() const;
72
73#ifdef SK_DEBUG
74 GrQuadType quadType() const;
75#endif
76
joshualittae5b2c62015-08-19 08:48:41 -070077private:
Brian Salomona33b67c2018-05-17 10:42:14 -040078 float fX[4];
79 float fY[4];
joshualittae5b2c62015-08-19 08:48:41 -070080};
81
Brian Salomonbe3c1d22018-05-21 12:54:39 -040082class GrPerspQuad {
83public:
84 GrPerspQuad() = default;
85
86 GrPerspQuad(const SkRect&, const SkMatrix&);
87
88 GrPerspQuad& operator=(const GrPerspQuad&) = default;
89
90 SkPoint3 point(int i) const { return {fX[i], fY[i], fW[i]}; }
91
Brian Salomonb80ffee2018-05-23 16:39:39 -040092 SkRect bounds() const {
Brian Salomonbe3c1d22018-05-21 12:54:39 -040093 auto x = this->x4f() * this->iw4f();
94 auto y = this->y4f() * this->iw4f();
95 return {x.min(), y.min(), x.max(), y.max()};
96 }
97
98 float x(int i) const { return fX[i]; }
99 float y(int i) const { return fY[i]; }
100 float w(int i) const { return fW[i]; }
101 float iw(int i) const { return fIW[i]; }
102
103 Sk4f x4f() const { return Sk4f::Load(fX); }
104 Sk4f y4f() const { return Sk4f::Load(fY); }
105 Sk4f w4f() const { return Sk4f::Load(fW); }
106 Sk4f iw4f() const { return Sk4f::Load(fIW); }
107
Michael Ludwig1f7e4382018-10-19 09:36:57 -0400108 bool hasPerspective() const { return (w4f() != Sk4f(1.f)).anyTrue(); }
109
110 // True if anti-aliasing affects this quad. Requires quadType() == kRect_QuadType
111 bool aaHasEffectOnRect() const;
112
113#ifdef SK_DEBUG
114 GrQuadType quadType() const;
115#endif
116
Brian Salomonbe3c1d22018-05-21 12:54:39 -0400117private:
118 float fX[4];
119 float fY[4];
120 float fW[4];
121 float fIW[4]; // 1/w
122};
123
joshualittae5b2c62015-08-19 08:48:41 -0700124#endif