Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
GrPathUtils::QuadUVMatrix Class Reference

#include <GrPathUtils.h>

Public Member Functions

 QuadUVMatrix ()
 
 QuadUVMatrix (const SkPoint controlPts[3])
 
void set (const SkPoint controlPts[3])
 
void apply (void *vertices, int vertexCount, size_t stride, size_t uvOffset) const
 

Detailed Description

Definition at line 72 of file GrPathUtils.h.

Constructor & Destructor Documentation

◆ QuadUVMatrix() [1/2]

GrPathUtils::QuadUVMatrix::QuadUVMatrix ( )
inline

Definition at line 74 of file GrPathUtils.h.

74{}

◆ QuadUVMatrix() [2/2]

GrPathUtils::QuadUVMatrix::QuadUVMatrix ( const SkPoint  controlPts[3])
inline

Definition at line 76 of file GrPathUtils.h.

76{ this->set(controlPts); }
void set(const SkPoint controlPts[3])

Member Function Documentation

◆ apply()

void GrPathUtils::QuadUVMatrix::apply ( void *  vertices,
int  vertexCount,
size_t  stride,
size_t  uvOffset 
) const
inline

Applies the matrix to vertex positions to compute UV coords.

vertices is a pointer to the first vertex. vertexCount is the number of vertices. stride is the size of each vertex. uvOffset is the offset of the UV values within each vertex.

Definition at line 87 of file GrPathUtils.h.

87 {
88 intptr_t xyPtr = reinterpret_cast<intptr_t>(vertices);
89 intptr_t uvPtr = reinterpret_cast<intptr_t>(vertices) + uvOffset;
90 float sx = fM[0];
91 float kx = fM[1];
92 float tx = fM[2];
93 float ky = fM[3];
94 float sy = fM[4];
95 float ty = fM[5];
96 for (int i = 0; i < vertexCount; ++i) {
97 const SkPoint* xy = reinterpret_cast<const SkPoint*>(xyPtr);
98 SkPoint* uv = reinterpret_cast<SkPoint*>(uvPtr);
99 uv->fX = sx * xy->fX + kx * xy->fY + tx;
100 uv->fY = ky * xy->fX + sy * xy->fY + ty;
101 xyPtr += stride;
102 uvPtr += stride;
103 }
104 }
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165

◆ set()

void GrPathUtils::QuadUVMatrix::set ( const SkPoint  controlPts[3])

Definition at line 138 of file GrPathUtils.cpp.

138 {
139 // We want M such that M * xy_pt = uv_pt
140 // We know M * control_pts = [0 1/2 1]
141 // [0 0 1]
142 // [1 1 1]
143 // And control_pts = [x0 x1 x2]
144 // [y0 y1 y2]
145 // [1 1 1 ]
146 // We invert the control pt matrix and post concat to both sides to get M.
147 // Using the known form of the control point matrix and the result, we can
148 // optimize and improve precision.
149
150 double x0 = qPts[0].fX;
151 double y0 = qPts[0].fY;
152 double x1 = qPts[1].fX;
153 double y1 = qPts[1].fY;
154 double x2 = qPts[2].fX;
155 double y2 = qPts[2].fY;
156
157 // pre-calculate some adjugate matrix factors for determinant
158 double a2 = x1*y2-x2*y1;
159 double a5 = x2*y0-x0*y2;
160 double a8 = x0*y1-x1*y0;
161 double det = a2 + a5 + a8;
162
163 if (!SkIsFinite(det)
165 // The quad is degenerate. Hopefully this is rare. Find the pts that are
166 // farthest apart to compute a line (unless it is really a pt).
167 SkScalar maxD = SkPointPriv::DistanceToSqd(qPts[0], qPts[1]);
168 int maxEdge = 0;
169 SkScalar d = SkPointPriv::DistanceToSqd(qPts[1], qPts[2]);
170 if (d > maxD) {
171 maxD = d;
172 maxEdge = 1;
173 }
174 d = SkPointPriv::DistanceToSqd(qPts[2], qPts[0]);
175 if (d > maxD) {
176 maxD = d;
177 maxEdge = 2;
178 }
179 // We could have a tolerance here, not sure if it would improve anything
180 if (maxD > 0) {
181 // Set the matrix to give (u = 0, v = distance_to_line)
182 SkVector lineVec = qPts[(maxEdge + 1)%3] - qPts[maxEdge];
183 // when looking from the point 0 down the line we want positive
184 // distances to be to the left. This matches the non-degenerate
185 // case.
187 // first row
188 fM[0] = 0;
189 fM[1] = 0;
190 fM[2] = 0;
191 // second row
192 fM[3] = lineVec.fX;
193 fM[4] = lineVec.fY;
194 fM[5] = -lineVec.dot(qPts[maxEdge]);
195 } else {
196 // It's a point. It should cover zero area. Just set the matrix such
197 // that (u, v) will always be far away from the quad.
198 fM[0] = 0; fM[1] = 0; fM[2] = 100.f;
199 fM[3] = 0; fM[4] = 0; fM[5] = 100.f;
200 }
201 } else {
202 double scale = 1.0/det;
203
204 // compute adjugate matrix
205 double a3, a4, a6, a7;
206 a3 = y2-y0;
207 a4 = x0-x2;
208
209 a6 = y0-y1;
210 a7 = x1-x0;
211
212 // this performs the uv_pts*adjugate(control_pts) multiply,
213 // then does the scale by 1/det afterwards to improve precision
214 fM[0] = (float)((0.5*a3 + a6)*scale);
215 fM[1] = (float)((0.5*a4 + a7)*scale);
216 fM[2] = (float)((0.5*a5 + a8)*scale);
217 fM[3] = (float)(a6*scale);
218 fM[4] = (float)(a7*scale);
219 fM[5] = (float)(a8*scale);
220 }
221}
static bool SkIsFinite(T x, Pack... values)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:101
#define SK_ScalarNearlyZero
Definition: SkScalar.h:99
static SkPoint MakeOrthog(const SkPoint &vec, Side side=kLeft_Side)
Definition: SkPointPriv.h:96
static SkScalar DistanceToSqd(const SkPoint &pt, const SkPoint &a)
Definition: SkPointPriv.h:48
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
float SkScalar
Definition: extension.cpp:12
const Scalar scale
float dot(const SkVector &vec) const
Definition: SkPoint_impl.h:554

The documentation for this class was generated from the following files: