26#include <initializer_list>
35 for (
int i = 0; i < 9; i++) {
37 SkDebugf(
"matrices not equal [%d] %g %g\n", i, (
float)
a[i], (
float)
b[i]);
55 if (
equal != cheapEqual) {
57 bool foundZeroSignDiff =
false;
58 for (
int i = 0; i < 9; ++i) {
59 float aVal =
a.get(i);
60 float bVal =
b.get(i);
63 if (0 == aVal && 0 == bVal && aValI != bValI) {
64 foundZeroSignDiff =
true;
71 bool foundNaN =
false;
72 for (
int i = 0; i < 9; ++i) {
73 float aVal =
a.get(i);
74 float bVal =
b.get(i);
77 if (std::isnan(aVal) && aValI == bValI) {
126 assert9(
reporter, m, 1, 0, 0, 0, 1, 0, 0, 0, 1);
129 assert9(
reporter, m, 2, 0, 0, 0, 3, 0, 0, 0, 1);
131 m.postTranslate(4, 5);
132 assert9(
reporter, m, 2, 0, 4, 0, 3, 5, 0, 0, 1);
148 src.setLTRB(0, 0, 10, 10);
166 dst.fRight = src.fRight * 2;
200 success = identity.getMinMaxScales(scales);
207 success =
scale.getMinMaxScales(scales);
221 success =
rotate.getMinMaxScales(scales);
242 big.
setAll(2.39394089e+36f, 8.85347779e+36f, 9.26526204e+36f,
243 3.9159619e+36f, 1.44823453e+37f, 1.51559342e+37f,
250 givingNegativeNearlyZeros.
setAll(0.00436534f, 0.114138f, 0.37141f,
251 0.00358857f, 0.0936228f, -0.0174198f,
266 translate, perspX, perspY};
267 SkMatrix mats[2*std::size(baseMats)];
268 for (
size_t i = 0; i < std::size(baseMats); ++i) {
269 mats[i] = baseMats[i];
270 bool invertible = mats[i].
invert(&mats[i + std::size(baseMats)]);
274 for (
int m = 0; m < 1000; ++m) {
277 for (
int i = 0; i < 4; ++i) {
278 int x = rand.
nextU() % std::size(mats);
302 for (
size_t i = 0; i < std::size(vectors); ++i) {
311 for (
size_t i = 0; i < std::size(vectors); ++i) {
396 for (
int angle = 0; angle < 360; ++angle) {
404 for (
int i = 1; i < 360; i++) {
431 mat.
setAll(0, 0, 0, 0, 0, 0, 0, 0, 0);
436 mat.
setAll(0, 0, 0, 0, 0, 0, 0, 0, 1);
461 if (diff < tolerance) {
470 if (diff <= largest*tolerance) {
490 scaleX*c1*c2 - scaleY*s1*s2) &&
492 -scaleX*s1*c2 - scaleY*c1*s2) &&
494 scaleX*c1*s2 + scaleY*s1*c2) &&
496 -scaleX*s1*s2 + scaleY*c1*c2);
504 const float kRotation0 = 15.5f;
505 const float kRotation1 = -50.f;
506 const float kScale0 = 5000.f;
507 const float kScale1 = 0.001f;
588 for (
int m = 0; m < 1000; ++m) {
636 for (
int i = 0; i <
count; ++i) {
658 res.
fX = src.fX * ms[0] + src.fY * ms[1] + src.fZ * ms[2];
659 res.
fY = src.fX * ms[3] + src.fY * ms[4] + src.fZ * ms[5];
660 res.
fZ = src.fX * ms[6] + src.fY * ms[7] + src.fZ * ms[8];
667 const float kRotation0 = 15.5f;
668 const float kRotation1 = -50.f;
669 const float kScale0 = 5000.f;
671#if defined(SK_BUILD_FOR_GOOGLE3)
673 const int kTripleCount = 100;
676 const int kTripleCount = 1000;
682 for (
int i = 0; i < kTripleCount; ++i) {
690 for (
int j = 0; j < 9; ++j) {
703 const SkPoint3 zeros = {0.f, 0.f, 0.f};
706 mat.
setAll(0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f);
709 for (
int i = 0; i < kTripleCount; ++i) {
732 SkPoint3 src = {randTriples[0].
fX, randTriples[0].
fY, 1.f};
734 pnt.
set(src.fX, src.fY);
746 SkPoint3 src = {randTriples[0].
fX, randTriples[0].
fY, 1.f};
748 pnt.
set(src.fX, src.fY);
762 SkPoint3 src = {randTriples[0].
fX, randTriples[0].
fY, 1.f};
764 pnt.
set(src.fX, src.fY);
775 for (
int j = 0; j < kTripleCount; ++j) {
792 if (
scale.width() <= 0 ||
scale.height() <= 0) {
807 static const int kNumPoints = 5;
808 const SkPoint testPts[kNumPoints] = {
817 original.
mapPoints(v1, testPts, kNumPoints);
827 for (
int i = 0; i < kNumPoints; ++i) {
843 m.setRotate(35, 0, 0);
849 m.setRotate(35, 0, 0).preScale(2, 3);
852 m.setRotate(35, 0, 0).postScale(2, 3);
857 SkMatrix mat, inverse, iden1, iden2;
895 mat.
setAll(0.0f, 1.0f, 2.0f,
896 0.0f, 1.0f, -3.40277175e+38f,
897 1.00003040f, 1.0f, 0.0f);
903 static const struct {
907 gRectStaysRectSamples[] = {
908 { 0, 0, 0, 0,
false },
909 { 0, 0, 0, 1,
false },
910 { 0, 0, 1, 0,
false },
911 { 0, 0, 1, 1,
false },
912 { 0, 1, 0, 0,
false },
913 { 0, 1, 0, 1,
false },
914 { 0, 1, 1, 0,
true },
915 { 0, 1, 1, 1,
false },
916 { 1, 0, 0, 0,
false },
917 { 1, 0, 0, 1,
true },
918 { 1, 0, 1, 0,
false },
919 { 1, 0, 1, 1,
false },
920 { 1, 1, 0, 0,
false },
921 { 1, 1, 0, 1,
false },
922 { 1, 1, 1, 0,
false },
923 { 1, 1, 1, 1,
false }
926 for (
size_t i = 0; i < std::size(gRectStaysRectSamples); i++) {
935 m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
949 #define affineEqual(e) affine[SkMatrix::kA##e] == mat.get(SkMatrix::kM##e)
990 a.setTranslate(10, 20);
1009 for (
int i = 0; i < 10000; ++i) {
1033 for (
const auto& m : { m0, m1 }) {
1034 SkRect rect = { 0, 0, 1e20f, 1e20f };
1036 rect = m.mapRect(rect);
1050 -1.75697533e-05f, 0.000157153074f, -1.10847975e-06f,
1051 -6.00415362e-08f, 0.00000000f, 0.000169880834f);
1052 SkRect out = m.mapRect(rect);
1072 for (
float deg = 90.0f; deg <= 1080.0f; deg += 90.0f) {
1094 const SkRect src = {0.f,0.f,10.f,10.f};
1103 SkMatrix nonRectMatrix = rectMatrix;
1107 nonRectMatrix = rectMatrix;
1111 nonRectMatrix = rectMatrix;
1118 m.setScale(0.f, 0.f);
1124 m.setScale(0.f, 2.f);
1130 m.setScale(2.f, 0.f);
1136 m.setScaleTranslate(0.f, 0.f, 10.f, 10.f);
1142 m.setScaleTranslate(0.f, 2.f, 10.f, 10.f);
1148 m.setScaleTranslate(2.f, 0.f, 10.f, 10.f);
static bool equal(const SkBitmap &a, const SkBitmap &b)
static void test_set9(skiatest::Reporter *reporter)
static void assert9(skiatest::Reporter *reporter, const SkMatrix &m, SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar e, SkScalar f, SkScalar g, SkScalar h, SkScalar i)
static void test_matrix_recttorect(skiatest::Reporter *reporter)
static bool point3_array_nearly_equal_relative(const SkPoint3 a[], const SkPoint3 b[], int count)
static void test_matrix_preserve_shape(skiatest::Reporter *reporter)
static void test_matrix_homogeneous(skiatest::Reporter *reporter)
static bool check_matrix_recomposition(const SkMatrix &mat, const SkPoint &rotation1, const SkPoint &scale, const SkPoint &rotation2)
static bool nearly_equal(const SkMatrix &a, const SkMatrix &b)
static void test_flatten(skiatest::Reporter *reporter, const SkMatrix &m)
static bool are_equal(skiatest::Reporter *reporter, const SkMatrix &a, const SkMatrix &b)
static void test_matrix_decomposition(skiatest::Reporter *reporter)
static bool naive_homogeneous_mapping(const SkMatrix &m, const SkPoint3 &src, const SkPoint3 &dst)
static void test_matrix_min_max_scale(skiatest::Reporter *reporter)
static bool nearly_equal_scalar(SkScalar a, SkScalar b)
static bool check_decompScale(const SkMatrix &original)
static int float_bits(float f)
static bool is_identity(const SkMatrix &m)
static bool scalar_nearly_equal_relative(SkScalar a, SkScalar b, SkScalar tolerance=SK_ScalarNearlyZero)
static void test_decompScale(skiatest::Reporter *reporter)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static void normalize(int n, double *gauss)
static void sk_bzero(void *buffer, size_t size)
bool SkDecomposeUpper2x2(const SkMatrix &matrix, SkPoint *rotation1, SkPoint *scale, SkPoint *rotation2)
static bool rotate(const SkDCubic &cubic, int zero, int index, SkDCubic &rotPath)
static bool SkScalarNearlyZero(SkScalar x, SkScalar tolerance=SK_ScalarNearlyZero)
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
#define SK_ScalarNearlyZero
static const size_t kBufferSize
#define DEF_TEST(name, reporter)
#define REPORTER_ASSERT(r, cond,...)
static SkM44 LookAt(const SkV3 &eye, const SkV3 ¢er, const SkV3 &up)
static size_t WriteToMemory(const SkMatrix &matrix, void *buffer)
static bool CheapEqual(const SkMatrix &a, const SkMatrix &b)
static size_t ReadFromMemory(SkMatrix *matrix, const void *buffer, size_t length)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
SkMatrix & postRotate(SkScalar degrees, SkScalar px, SkScalar py)
static constexpr int kMScaleX
horizontal scale factor
static constexpr int kMTransY
vertical translation
SkMatrix & postConcat(const SkMatrix &other)
bool getMinMaxScales(SkScalar scaleFactors[2]) const
SkMatrix & postScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
void mapHomogeneousPoints(SkPoint3 dst[], const SkPoint3 src[], int count) const
static constexpr int kMPersp1
input y perspective factor
void mapVectors(SkVector dst[], const SkVector src[], int count) const
SkMatrix & setPerspX(SkScalar v)
SkMatrix & setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar persp0, SkScalar persp1, SkScalar persp2)
SkMatrix & set(int index, SkScalar value)
void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty)
bool preservesRightAngles(SkScalar tol=SK_ScalarNearlyZero) const
bool asAffine(SkScalar affine[6]) const
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
SkMatrix & setTranslate(SkScalar dx, SkScalar dy)
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
bool invert(SkMatrix *inverse) const
bool rectStaysRect() const
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
SkScalar getMinScale() const
SkMatrix & setPerspY(SkScalar v)
static const SkMatrix & I()
bool decomposeScale(SkSize *scale, SkMatrix *remaining=nullptr) const
static constexpr int kMPersp0
input x perspective factor
void mapRectScaleTranslate(SkRect *dst, const SkRect &src) const
SkMatrix & setSkew(SkScalar kx, SkScalar ky, SkScalar px, SkScalar py)
SkScalar getMaxScale() const
static constexpr int kMPersp2
perspective bias
static constexpr int kMTransX
horizontal translation
bool hasPerspective() const
static constexpr int kMSkewY
vertical skew factor
static constexpr int kMScaleY
vertical scale factor
bool isSimilarity(SkScalar tol=SK_ScalarNearlyZero) const
static constexpr int kMSkewX
horizontal skew factor
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
@ kTranslate_Mask
translation SkMatrix
@ kScale_Mask
scale SkMatrix
@ kIdentity_Mask
identity SkMatrix; all bits clear
SkMatrix & setConcat(const SkMatrix &a, const SkMatrix &b)
static bool EqualsWithinTolerance(const SkPoint &p1, const SkPoint &p2)
float nextRangeF(float min, float max)
static constexpr int kMatrixCount
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
static const uint8_t buffer[]
static float max(float r, float g, float b)
static float min(float r, float g, float b)
void set(float x, float y)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)