Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Static Public Member Functions | List of all members
SkMatrixPriv Class Reference

#include <SkMatrixPriv.h>

Public Types

enum  { kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t) }
 
typedef SkMatrix::MapXYProc MapXYProc
 
typedef SkMatrix::MapPtsProc MapPtsProc
 

Static Public Member Functions

static size_t WriteToMemory (const SkMatrix &matrix, void *buffer)
 
static size_t ReadFromMemory (SkMatrix *matrix, const void *buffer, size_t length)
 
static MapPtsProc GetMapPtsProc (const SkMatrix &matrix)
 
static MapXYProc GetMapXYProc (const SkMatrix &matrix)
 
static bool InverseMapRect (const SkMatrix &mx, SkRect *dst, const SkRect &src)
 
static void MapPointsWithStride (const SkMatrix &mx, SkPoint pts[], size_t stride, int count)
 
static void MapPointsWithStride (const SkMatrix &mx, SkPoint dst[], size_t dstStride, const SkPoint src[], size_t srcStride, int count)
 
static void MapHomogeneousPointsWithStride (const SkMatrix &mx, SkPoint3 dst[], size_t dstStride, const SkPoint3 src[], size_t srcStride, int count)
 
static bool PostIDiv (SkMatrix *matrix, int divx, int divy)
 
static bool CheapEqual (const SkMatrix &a, const SkMatrix &b)
 
static const SkScalarM44ColMajor (const SkM44 &m)
 
static bool IsScaleTranslateAsM33 (const SkM44 &m)
 
static SkRect MapRect (const SkM44 &m, const SkRect &r)
 
static SkScalar DifferentialAreaScale (const SkMatrix &m, const SkPoint &p)
 
static bool NearlyAffine (const SkMatrix &m, const SkRect &bounds, SkScalar tolerance=SK_ScalarNearlyZero)
 
static SkScalar ComputeResScaleForStroking (const SkMatrix &matrix)
 

Detailed Description

Definition at line 23 of file SkMatrixPriv.h.

Member Typedef Documentation

◆ MapPtsProc

typedef SkMatrix::MapPtsProc SkMatrixPriv::MapPtsProc

Definition at line 39 of file SkMatrixPriv.h.

◆ MapXYProc

typedef SkMatrix::MapXYProc SkMatrixPriv::MapXYProc

Definition at line 38 of file SkMatrixPriv.h.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
Enumerator
kMaxFlattenSize 

Definition at line 25 of file SkMatrixPriv.h.

25 {
26 // writeTo/readFromMemory will never return a value larger than this
27 kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t),
28 };
float SkScalar
Definition extension.cpp:12

Member Function Documentation

◆ CheapEqual()

static bool SkMatrixPriv::CheapEqual ( const SkMatrix a,
const SkMatrix b 
)
inlinestatic

Definition at line 181 of file SkMatrixPriv.h.

181 {
182 return &a == &b || 0 == memcmp(a.fMat, b.fMat, sizeof(a.fMat));
183 }
static bool b
struct MyStruct a[10]

◆ ComputeResScaleForStroking()

SkScalar SkMatrixPriv::ComputeResScaleForStroking ( const SkMatrix matrix)
static

Definition at line 1877 of file SkMatrix.cpp.

1877 {
1878 // Not sure how to handle perspective differently, so we just don't try (yet)
1881 if (SkIsFinite(sx, sy)) {
1882 SkScalar scale = std::max(sx, sy);
1883 if (scale > 0) {
1884 return scale;
1885 }
1886 }
1887 return 1;
1888}
static bool SkIsFinite(T x, Pack... values)
static constexpr int kMScaleX
horizontal scale factor
Definition SkMatrix.h:353
static constexpr int kMSkewY
vertical skew factor
Definition SkMatrix.h:356
static constexpr int kMScaleY
vertical scale factor
Definition SkMatrix.h:357
static constexpr int kMSkewX
horizontal skew factor
Definition SkMatrix.h:354
const Scalar scale
static float Length(float x, float y)
Definition SkPoint.cpp:79

◆ DifferentialAreaScale()

SkScalar SkMatrixPriv::DifferentialAreaScale ( const SkMatrix m,
const SkPoint p 
)
static

Definition at line 1786 of file SkMatrix.cpp.

1786 {
1787 // [m00 m01 m02] [f(u,v)]
1788 // Assuming M = [m10 m11 m12], define the projected p'(u,v) = [g(u,v)] where
1789 // [m20 m12 m22]
1790 // [x] [u]
1791 // f(u,v) = x(u,v) / w(u,v), g(u,v) = y(u,v) / w(u,v) and [y] = M*[v]
1792 // [w] [1]
1793 //
1794 // Then the differential scale factor between p = (u,v) and p' is |det J|,
1795 // where J is the Jacobian for p': [df/du dg/du]
1796 // [df/dv dg/dv]
1797 // and df/du = (w*dx/du - x*dw/du)/w^2, dg/du = (w*dy/du - y*dw/du)/w^2
1798 // df/dv = (w*dx/dv - x*dw/dv)/w^2, dg/dv = (w*dy/dv - y*dw/dv)/w^2
1799 //
1800 // From here, |det J| can be rewritten as |det J'/w^3|, where
1801 // [x y w ] [x y w ]
1802 // J' = [dx/du dy/du dw/du] = [m00 m10 m20]
1803 // [dx/dv dy/dv dw/dv] [m01 m11 m21]
1804 SkPoint3 xyw;
1805 m.mapHomogeneousPoints(&xyw, &p, 1);
1806
1807 if (xyw.fZ < SK_ScalarNearlyZero) {
1808 // Reaching the discontinuity of xy/w and where the point would clip to w >= 0
1809 return SK_ScalarInfinity;
1810 }
1811 SkMatrix jacobian = SkMatrix::MakeAll(xyw.fX, xyw.fY, xyw.fZ,
1812 m.getScaleX(), m.getSkewY(), m.getPerspX(),
1813 m.getSkewX(), m.getScaleY(), m.getPerspY());
1814
1815 double denom = 1.0 / xyw.fZ; // 1/w
1816 denom = denom * denom * denom; // 1/w^3
1817 return SkScalarAbs(SkDoubleToScalar(sk_determinant(jacobian.fMat, true) * denom));
1818}
static double sk_determinant(const float mat[9], int isPerspective)
Definition SkMatrix.cpp:714
#define SkDoubleToScalar(x)
Definition SkScalar.h:64
#define SK_ScalarNearlyZero
Definition SkScalar.h:99
#define SK_ScalarInfinity
Definition SkScalar.h:26
#define SkScalarAbs(x)
Definition SkScalar.h:39
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition SkMatrix.h:179
SkScalar fX
Definition SkPoint3.h:16
SkScalar fZ
Definition SkPoint3.h:16
SkScalar fY
Definition SkPoint3.h:16

◆ GetMapPtsProc()

static MapPtsProc SkMatrixPriv::GetMapPtsProc ( const SkMatrix matrix)
inlinestatic

Definition at line 42 of file SkMatrixPriv.h.

42 {
43 return SkMatrix::GetMapPtsProc(matrix.getType());
44 }
unsigned useCenter Optional< SkMatrix > matrix
Definition SkRecords.h:258

◆ GetMapXYProc()

static MapXYProc SkMatrixPriv::GetMapXYProc ( const SkMatrix matrix)
inlinestatic

Definition at line 46 of file SkMatrixPriv.h.

46 {
47 return SkMatrix::GetMapXYProc(matrix.getType());
48 }

◆ InverseMapRect()

static bool SkMatrixPriv::InverseMapRect ( const SkMatrix mx,
SkRect dst,
const SkRect src 
)
inlinestatic

Attempt to map the rect through the inverse of the matrix. If it is not invertible, then this returns false and dst is unchanged.

Definition at line 54 of file SkMatrixPriv.h.

54 {
55 if (mx.isScaleTranslate()) {
56 // A scale-translate matrix with a 0 scale factor is not invertible.
57 if (mx.getScaleX() == 0.f || mx.getScaleY() == 0.f) {
58 return false;
59 }
60
61 const SkScalar tx = mx.getTranslateX();
62 const SkScalar ty = mx.getTranslateY();
63 // mx maps coordinates as ((sx*x + tx), (sy*y + ty)) so the inverse is
64 // ((x - tx)/sx), (y - ty)/sy). If sx or sy are negative, we have to swap the edge
65 // values to maintain a sorted rect.
66 auto inverted = skvx::float4::Load(&src.fLeft);
67 inverted -= skvx::float4(tx, ty, tx, ty);
68
70 const SkScalar sx = 1.f / mx.getScaleX();
71 const SkScalar sy = 1.f / mx.getScaleY();
72 inverted *= skvx::float4(sx, sy, sx, sy);
73 if (sx < 0.f && sy < 0.f) {
74 inverted = skvx::shuffle<2, 3, 0, 1>(inverted); // swap L|R and T|B
75 } else if (sx < 0.f) {
76 inverted = skvx::shuffle<2, 1, 0, 3>(inverted); // swap L|R
77 } else if (sy < 0.f) {
78 inverted = skvx::shuffle<0, 3, 2, 1>(inverted); // swap T|B
79 }
80 }
81 inverted.store(&dst->fLeft);
82 return true;
83 }
84
85 // general case
86 SkMatrix inverse;
87 if (mx.invert(&inverse)) {
88 inverse.mapRect(dst, src);
89 return true;
90 }
91 return false;
92 }
SkScalar getTranslateY() const
Definition SkMatrix.h:452
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
SkScalar getScaleX() const
Definition SkMatrix.h:415
SkScalar getScaleY() const
Definition SkMatrix.h:422
bool isScaleTranslate() const
Definition SkMatrix.h:236
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
SkScalar getTranslateX() const
Definition SkMatrix.h:445
@ kTranslate_Mask
translation SkMatrix
Definition SkMatrix.h:193
TypeMask getType() const
Definition SkMatrix.h:207
dst
Definition cp.py:12
Vec< 4, float > float4
Definition SkVx.h:1146
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
Definition SkVx.h:109

◆ IsScaleTranslateAsM33()

static bool SkMatrixPriv::IsScaleTranslateAsM33 ( const SkM44 m)
inlinestatic

Definition at line 190 of file SkMatrixPriv.h.

190 {
191 return m.rc(1,0) == 0 && m.rc(3,0) == 0 &&
192 m.rc(0,1) == 0 && m.rc(3,1) == 0 &&
193 m.rc(3,3) == 1;
194
195 }

◆ M44ColMajor()

static const SkScalar * SkMatrixPriv::M44ColMajor ( const SkM44 m)
inlinestatic

Definition at line 185 of file SkMatrixPriv.h.

185{ return m.fMat; }

◆ MapHomogeneousPointsWithStride()

void SkMatrixPriv::MapHomogeneousPointsWithStride ( const SkMatrix mx,
SkPoint3  dst[],
size_t  dstStride,
const SkPoint3  src[],
size_t  srcStride,
int  count 
)
static

Definition at line 1026 of file SkMatrix.cpp.

1028 {
1029 SkASSERT((dst && src && count > 0) || 0 == count);
1030 // no partial overlap
1031 SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]);
1032
1033 if (count > 0) {
1034 if (mx.isIdentity()) {
1035 if (src != dst) {
1036 if (srcStride == sizeof(SkPoint3) && dstStride == sizeof(SkPoint3)) {
1037 memcpy(dst, src, count * sizeof(SkPoint3));
1038 } else {
1039 for (int i = 0; i < count; ++i) {
1040 *dst = *src;
1041 dst = reinterpret_cast<SkPoint3*>(reinterpret_cast<char*>(dst) + dstStride);
1042 src = reinterpret_cast<const SkPoint3*>(reinterpret_cast<const char*>(src) +
1043 srcStride);
1044 }
1045 }
1046 }
1047 return;
1048 }
1049 do {
1050 SkScalar sx = src->fX;
1051 SkScalar sy = src->fY;
1052 SkScalar sw = src->fZ;
1053 src = reinterpret_cast<const SkPoint3*>(reinterpret_cast<const char*>(src) + srcStride);
1054 const SkScalar* mat = mx.fMat;
1055 typedef SkMatrix M;
1056 SkScalar x = sdot(sx, mat[M::kMScaleX], sy, mat[M::kMSkewX], sw, mat[M::kMTransX]);
1057 SkScalar y = sdot(sx, mat[M::kMSkewY], sy, mat[M::kMScaleY], sw, mat[M::kMTransY]);
1058 SkScalar w = sdot(sx, mat[M::kMPersp0], sy, mat[M::kMPersp1], sw, mat[M::kMPersp2]);
1059
1060 dst->set(x, y, w);
1061 dst = reinterpret_cast<SkPoint3*>(reinterpret_cast<char*>(dst) + dstStride);
1062 } while (--count);
1063 }
1064}
int count
#define SkASSERT(cond)
Definition SkAssert.h:116
static SkScalar sdot(SkScalar a, SkScalar b, SkScalar c, SkScalar d)
Definition SkMatrix.cpp:241
bool isIdentity() const
Definition SkMatrix.h:223
double y
double x
SkScalar w
#define M(PROC, DITHER)

◆ MapPointsWithStride() [1/2]

static void SkMatrixPriv::MapPointsWithStride ( const SkMatrix mx,
SkPoint  dst[],
size_t  dstStride,
const SkPoint  src[],
size_t  srcStride,
int  count 
)
inlinestatic

Maps src SkPoint array of length count to dst SkPoint array, skipping stride bytes to advance from one SkPoint to the next. Points are mapped by multiplying each SkPoint by SkMatrix. Given:

         | A B C |         | x |
Matrix = | D E F |,  src = | y |
         | G H I |         | 1 |

each resulting dst SkPoint is computed as:

              |A B C| |x|                               Ax+By+C   Dx+Ey+F
Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
              |G H I| |1|                               Gx+Hy+I   Gx+Hy+I
Parameters
mxmatrix used to map the points
dststorage for mapped points
srcpoints to transform
stridesize of record starting with SkPoint, in bytes
countnumber of points to transform

Definition at line 161 of file SkMatrixPriv.h.

162 {
163 SkASSERT(srcStride >= sizeof(SkPoint));
164 SkASSERT(dstStride >= sizeof(SkPoint));
165 SkASSERT(0 == srcStride % sizeof(SkScalar));
166 SkASSERT(0 == dstStride % sizeof(SkScalar));
167 for (int i = 0; i < count; ++i) {
168 mx.mapPoints(dst, src, 1);
169 src = (SkPoint*)((intptr_t)src + srcStride);
170 dst = (SkPoint*)((intptr_t)dst + dstStride);
171 }
172 }
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770

◆ MapPointsWithStride() [2/2]

static void SkMatrixPriv::MapPointsWithStride ( const SkMatrix mx,
SkPoint  pts[],
size_t  stride,
int  count 
)
inlinestatic

Maps count pts, skipping stride bytes to advance from one SkPoint to the next. Points are mapped by multiplying each SkPoint by SkMatrix. Given:

         | A B C |        | x |
Matrix = | D E F |,  pt = | y |
         | G H I |        | 1 |

each resulting pts SkPoint is computed as:

              |A B C| |x|                               Ax+By+C   Dx+Ey+F
Matrix * pt = |D E F| |y| = |Ax+By+C Dx+Ey+F Gx+Hy+I| = ------- , -------
              |G H I| |1|                               Gx+Hy+I   Gx+Hy+I
Parameters
mxmatrix used to map the points
ptsstorage for mapped points
stridesize of record starting with SkPoint, in bytes
countnumber of points to transform

Definition at line 112 of file SkMatrixPriv.h.

112 {
113 SkASSERT(stride >= sizeof(SkPoint));
114 SkASSERT(0 == stride % sizeof(SkScalar));
115
116 SkMatrix::TypeMask tm = mx.getType();
117
118 if (SkMatrix::kIdentity_Mask == tm) {
119 return;
120 }
121 if (SkMatrix::kTranslate_Mask == tm) {
122 const SkScalar tx = mx.getTranslateX();
123 const SkScalar ty = mx.getTranslateY();
124 skvx::float2 trans(tx, ty);
125 for (int i = 0; i < count; ++i) {
126 (skvx::float2::Load(&pts->fX) + trans).store(&pts->fX);
127 pts = (SkPoint*)((intptr_t)pts + stride);
128 }
129 return;
130 }
131 // Insert other special-cases here (e.g. scale+translate)
132
133 // general case
134 SkMatrix::MapXYProc proc = mx.getMapXYProc();
135 for (int i = 0; i < count; ++i) {
136 proc(mx, pts->fX, pts->fY, pts);
137 pts = (SkPoint*)((intptr_t)pts + stride);
138 }
139 }
SI void store(P *ptr, const T &val)
@ kIdentity_Mask
identity SkMatrix; all bits clear
Definition SkMatrix.h:192
float fX
x-axis value
float fY
y-axis value

◆ MapRect()

SkRect SkMatrixPriv::MapRect ( const SkM44 m,
const SkRect r 
)
static

Definition at line 216 of file SkM44.cpp.

216 {
217 const bool hasPerspective =
218 m.fMat[3] != 0 || m.fMat[7] != 0 || m.fMat[11] != 0 || m.fMat[15] != 1;
219 if (hasPerspective) {
220 return map_rect_perspective(src, m.fMat);
221 } else {
222 return map_rect_affine(src, m.fMat);
223 }
224}
static SkRect map_rect_affine(const SkRect &src, const float mat[16])
Definition SkM44.cpp:140
static SkRect map_rect_perspective(const SkRect &src, const float mat[16])
Definition SkM44.cpp:164

◆ NearlyAffine()

bool SkMatrixPriv::NearlyAffine ( const SkMatrix m,
const SkRect bounds,
SkScalar  tolerance = SK_ScalarNearlyZero 
)
static

Definition at line 1820 of file SkMatrix.cpp.

1822 {
1823 if (!m.hasPerspective()) {
1824 return true;
1825 }
1826
1827 // The idea here is that we are computing the differential area scale at each corner,
1828 // and comparing them with some tolerance value. If they are similar, then we can say
1829 // that the transformation is nearly affine.
1830
1831 // We can map the four points simultaneously.
1832 SkPoint quad[4];
1833 bounds.toQuad(quad);
1834 SkPoint3 xyw[4];
1835 m.mapHomogeneousPoints(xyw, quad, 4);
1836
1837 // Since the Jacobian is a 3x3 matrix, the determinant is a scalar triple product,
1838 // and the initial cross product is constant across all four points.
1839 SkPoint3 v1{m.getScaleX(), m.getSkewY(), m.getPerspX()};
1840 SkPoint3 v2{m.getSkewX(), m.getScaleY(), m.getPerspY()};
1841 SkPoint3 detCrossProd = v1.cross(v2);
1842
1843 // Start with the calculations at P0.
1844 if (xyw[0].fZ < SK_ScalarNearlyZero) {
1845 // Reaching the discontinuity of xy/w and where the point would clip to w >= 0
1846 return false;
1847 }
1848
1849 // Performing a dot product with the pre-w divide transformed point completes
1850 // the scalar triple product and the determinant calculation.
1851 double det = detCrossProd.dot(xyw[0]);
1852 // From that we can compute the differential area scale at P0.
1853 double denom = 1.0 / xyw[0].fZ; // 1/w
1854 denom = denom * denom * denom; // 1/w^3
1855 SkScalar a0 = SkScalarAbs(SkDoubleToScalar(det*denom));
1856
1857 // Now we compare P0's scale with that at the other three points
1858 tolerance *= tolerance; // squared tolerance since we're comparing area
1859 for (int i = 1; i < 4; ++i) {
1860 if (xyw[i].fZ < SK_ScalarNearlyZero) {
1861 // Reaching the discontinuity of xy/w and where the point would clip to w >= 0
1862 return false;
1863 }
1864
1865 det = detCrossProd.dot(xyw[i]); // completing scalar triple product
1866 denom = 1.0 / xyw[i].fZ; // 1/w
1867 denom = denom * denom * denom; // 1/w^3
1868 SkScalar a = SkScalarAbs(SkDoubleToScalar(det*denom));
1869 if (!SkScalarNearlyEqual(a0, a, tolerance)) {
1870 return false;
1871 }
1872 }
1873
1874 return true;
1875}
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition SkScalar.h:107
Vec2Value v2
Optional< SkRect > bounds
Definition SkRecords.h:189
SkPoint3 cross(const SkPoint3 &vec) const
Definition SkPoint3.h:141
SkScalar dot(const SkPoint3 &vec) const
Definition SkPoint3.h:126

◆ PostIDiv()

static bool SkMatrixPriv::PostIDiv ( SkMatrix matrix,
int  divx,
int  divy 
)
inlinestatic

Definition at line 177 of file SkMatrixPriv.h.

177 {
178 return matrix->postIDiv(divx, divy);
179 }

◆ ReadFromMemory()

static size_t SkMatrixPriv::ReadFromMemory ( SkMatrix matrix,
const void *  buffer,
size_t  length 
)
inlinestatic

Definition at line 34 of file SkMatrixPriv.h.

34 {
35 return matrix->readFromMemory(buffer, length);
36 }
static const uint8_t buffer[]
size_t length

◆ WriteToMemory()

static size_t SkMatrixPriv::WriteToMemory ( const SkMatrix matrix,
void *  buffer 
)
inlinestatic

Definition at line 30 of file SkMatrixPriv.h.

30 {
31 return matrix.writeToMemory(buffer);
32 }

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