36 auto p = (c0 * in[
i].
x) + (c1 * in[
i].
y) + (c2 * in[
i].
z) + (c3 * in[
i].
w);
43std::pair<float, float> compute_svd(
float m00,
float m01,
float m10,
float m11) {
46 float s1 = m00*m00 + m01*m01 + m10*m10 + m11*m11;
48 float e = m00*m00 + m01*m01 - m10*m10 - m11*m11;
49 float f = m00*m10 + m01*m11;
57std::pair<float, float> sort_scale(
float sx,
float sy) {
70 static constexpr SkV4 kNoPerspective = {0.f, 0.f, 0.f, 1.f};
71 static constexpr SkV4 kNoZ = {0.f, 0.f, 1.f, 0.f};
72 if (
m.row(3) != kNoPerspective) {
75 if (
m.invert(&fInvM)) {
81 }
else if (
m.col(2) != kNoZ ||
m.row(2) != kNoZ) {
84 if (
m.invert(&fInvM)) {
88 std::tie(fMinScaleFactor, fMaxScaleFactor) = compute_svd(
m.rc(0,0),
m.rc(0,1),
89 m.rc(1,0),
m.rc(1,1));
102 const float sx =
m.rc(0, 0);
103 const float sy =
m.rc(1, 1);
104 const float kx =
m.rc(0, 1);
105 const float ky =
m.rc(1, 0);
106 const float tx =
m.rc(0, 3);
107 const float ty =
m.rc(1, 3);
108 if (kx == 0.f && ky == 0.f) {
110 if (sx == 0.f || sy == 0.f) {
113 }
else if (sx == 1.f && sy == 1.f && tx == 0.f && ty == 0.f) {
117 const float ix = 1.f / sx;
118 const float iy = 1.f / sy;
121 fInvM =
SkM44(ix, 0.f, 0.f, -ix*tx,
122 0.f, iy, 0.f, -iy*ty,
125 std::tie(fMinScaleFactor, fMaxScaleFactor) = sort_scale(sx, sy);
127 }
else if (sx == 0.f && sy == 0.f) {
130 if (kx == 0.f || ky == 0.f) {
134 const float ix = 1.f / kx;
135 const float iy = 1.f / ky;
137 fInvM =
SkM44(0.f, iy, 0.f, -iy*ty,
138 ix, 0.f, 0.f, -ix*tx,
141 std::tie(fMinScaleFactor, fMaxScaleFactor) = sort_scale(kx, ky);
145 float upper[4] = {sx, ky, kx, sy};
152 fInvM =
SkM44(invUpper[0], invUpper[2], 0.f, -invUpper[0]*tx - invUpper[2]*ty,
153 invUpper[1], invUpper[3], 0.f, -invUpper[1]*tx - invUpper[3]*ty,
156 std::tie(fMinScaleFactor, fMaxScaleFactor) = compute_svd(sx, kx, ky, sy);
164 return {fMinScaleFactor, fMaxScaleFactor};
194 const float dxdu = fM.
rc(0,0);
195 const float dxdv = fM.
rc(0,1);
196 const float dydu = fM.
rc(1,0);
197 const float dydv = fM.
rc(1,1);
198 const float dwdu = fM.
rc(3,0);
199 const float dwdv = fM.
rc(3,1);
203 float dfdu = (devP.
w*dxdu - devP.
x*dwdu) * invW2;
204 float dfdv = (devP.
w*dxdv - devP.
x*dwdv) * invW2;
205 float dgdu = (devP.
w*dydu - devP.
y*dwdu) * invW2;
206 float dgdv = (devP.
w*dydv - devP.
y*dwdv) * invW2;
210 return compute_svd(dfdu, dfdv, dgdu, dgdv);
219 min = fMinScaleFactor;
246 return map_rect(fM,
rect);
253 return map_rect(fInvM,
rect);
258 SkV2 localCorners[4] = {{localRect.
left(), localRect.
top()},
259 {localRect.
right(), localRect.
top()},
260 {localRect.
right(), localRect.
bot()},
261 {localRect.
left(), localRect.
bot()}};
262 this->
mapPoints(localCorners, deviceOut, 4);
274 auto p = c0 * localIn[
i].
x + c1 * localIn[
i].
y + c3 ;
275 p.store(deviceOut +
i);
281 return map_points(fM, localIn, deviceOut,
count);
286 return map_points(fInvM, deviceIn, localOut,
count);
constexpr float SK_FloatInfinity
static bool SkIsFinite(T x, Pack... values)
static constexpr float sk_ieee_float_divide(float numer, float denom)
SkScalar SkInvert2x2Matrix(const SkScalar inMatrix[4], SkScalar outMatrix[4])
SkV4 map(float x, float y, float z, float w) const
SkScalar rc(int r, int c) const
static SkRect MapRect(const SkM44 &m, const SkRect &r)
static const SkScalar * M44ColMajor(const SkM44 &m)
static float max(float r, float g, float b)
static float min(float r, float g, float b)
Optional< SkRect > bounds
sk_sp< SkBlender > blender SkRect rect
const myers::Point & get< 0 >(const myers::Segment &s)
SIN Vec< N, float > abs(const Vec< N, float > &x)
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)