2009-02-27 16:24:51 +00:00
|
|
|
#include "Test.h"
|
|
|
|
#include "SkMatrix.h"
|
|
|
|
|
|
|
|
static bool nearly_equal_scalar(SkScalar a, SkScalar b) {
|
|
|
|
#ifdef SK_SCALAR_IS_FLOAT
|
|
|
|
const float tolerance = 0.000005f;
|
|
|
|
#else
|
2011-02-09 02:24:26 +00:00
|
|
|
const int32_t tolerance = 8;
|
2009-02-27 16:24:51 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
return SkScalarAbs(a - b) <= tolerance;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool nearly_equal(const SkMatrix& a, const SkMatrix& b) {
|
|
|
|
for (int i = 0; i < 9; i++) {
|
|
|
|
if (!nearly_equal_scalar(a[i], b[i])) {
|
2011-02-09 02:24:26 +00:00
|
|
|
printf("not equal %g %g\n", (float)a[i], (float)b[i]);
|
2009-02-27 16:24:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool is_identity(const SkMatrix& m) {
|
|
|
|
SkMatrix identity;
|
2009-04-02 16:59:40 +00:00
|
|
|
identity.reset();
|
2009-02-27 16:24:51 +00:00
|
|
|
return nearly_equal(m, identity);
|
|
|
|
}
|
|
|
|
|
2009-06-29 16:14:41 +00:00
|
|
|
static void test_flatten(skiatest::Reporter* reporter, const SkMatrix& m) {
|
|
|
|
// add 100 in case we have a bug, I don't want to kill my stack in the test
|
|
|
|
char buffer[SkMatrix::kMaxFlattenSize + 100];
|
|
|
|
uint32_t size1 = m.flatten(NULL);
|
|
|
|
uint32_t size2 = m.flatten(buffer);
|
|
|
|
REPORTER_ASSERT(reporter, size1 == size2);
|
|
|
|
REPORTER_ASSERT(reporter, size1 <= SkMatrix::kMaxFlattenSize);
|
|
|
|
|
|
|
|
SkMatrix m2;
|
|
|
|
uint32_t size3 = m2.unflatten(buffer);
|
|
|
|
REPORTER_ASSERT(reporter, size1 == size2);
|
|
|
|
REPORTER_ASSERT(reporter, m == m2);
|
|
|
|
|
|
|
|
char buffer2[SkMatrix::kMaxFlattenSize + 100];
|
|
|
|
size3 = m2.flatten(buffer2);
|
|
|
|
REPORTER_ASSERT(reporter, size1 == size2);
|
|
|
|
REPORTER_ASSERT(reporter, memcmp(buffer, buffer2, size1) == 0);
|
|
|
|
}
|
|
|
|
|
2009-02-27 16:24:51 +00:00
|
|
|
void TestMatrix(skiatest::Reporter* reporter) {
|
|
|
|
SkMatrix mat, inverse, iden1, iden2;
|
|
|
|
|
|
|
|
mat.reset();
|
|
|
|
mat.setTranslate(SK_Scalar1, SK_Scalar1);
|
|
|
|
mat.invert(&inverse);
|
|
|
|
iden1.setConcat(mat, inverse);
|
|
|
|
REPORTER_ASSERT(reporter, is_identity(iden1));
|
|
|
|
|
|
|
|
mat.setScale(SkIntToScalar(2), SkIntToScalar(2));
|
|
|
|
mat.invert(&inverse);
|
|
|
|
iden1.setConcat(mat, inverse);
|
|
|
|
REPORTER_ASSERT(reporter, is_identity(iden1));
|
2009-06-29 16:14:41 +00:00
|
|
|
test_flatten(reporter, mat);
|
2009-02-27 16:24:51 +00:00
|
|
|
|
|
|
|
mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
|
|
|
|
mat.invert(&inverse);
|
|
|
|
iden1.setConcat(mat, inverse);
|
|
|
|
REPORTER_ASSERT(reporter, is_identity(iden1));
|
2009-06-29 16:14:41 +00:00
|
|
|
test_flatten(reporter, mat);
|
2009-02-27 16:24:51 +00:00
|
|
|
|
|
|
|
mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
|
|
|
|
mat.postRotate(SkIntToScalar(25));
|
|
|
|
REPORTER_ASSERT(reporter, mat.invert(NULL));
|
|
|
|
mat.invert(&inverse);
|
|
|
|
iden1.setConcat(mat, inverse);
|
|
|
|
REPORTER_ASSERT(reporter, is_identity(iden1));
|
|
|
|
iden2.setConcat(inverse, mat);
|
|
|
|
REPORTER_ASSERT(reporter, is_identity(iden2));
|
2009-06-29 16:14:41 +00:00
|
|
|
test_flatten(reporter, mat);
|
|
|
|
test_flatten(reporter, iden2);
|
2009-04-02 16:59:40 +00:00
|
|
|
|
2009-02-27 16:24:51 +00:00
|
|
|
// rectStaysRect test
|
|
|
|
{
|
|
|
|
static const struct {
|
|
|
|
SkScalar m00, m01, m10, m11;
|
|
|
|
bool mStaysRect;
|
|
|
|
}
|
|
|
|
gRectStaysRectSamples[] = {
|
|
|
|
{ 0, 0, 0, 0, false },
|
|
|
|
{ 0, 0, 0, SK_Scalar1, false },
|
|
|
|
{ 0, 0, SK_Scalar1, 0, false },
|
|
|
|
{ 0, 0, SK_Scalar1, SK_Scalar1, false },
|
|
|
|
{ 0, SK_Scalar1, 0, 0, false },
|
|
|
|
{ 0, SK_Scalar1, 0, SK_Scalar1, false },
|
|
|
|
{ 0, SK_Scalar1, SK_Scalar1, 0, true },
|
|
|
|
{ 0, SK_Scalar1, SK_Scalar1, SK_Scalar1, false },
|
|
|
|
{ SK_Scalar1, 0, 0, 0, false },
|
|
|
|
{ SK_Scalar1, 0, 0, SK_Scalar1, true },
|
|
|
|
{ SK_Scalar1, 0, SK_Scalar1, 0, false },
|
|
|
|
{ SK_Scalar1, 0, SK_Scalar1, SK_Scalar1, false },
|
|
|
|
{ SK_Scalar1, SK_Scalar1, 0, 0, false },
|
|
|
|
{ SK_Scalar1, SK_Scalar1, 0, SK_Scalar1, false },
|
|
|
|
{ SK_Scalar1, SK_Scalar1, SK_Scalar1, 0, false },
|
|
|
|
{ SK_Scalar1, SK_Scalar1, SK_Scalar1, SK_Scalar1, false }
|
|
|
|
};
|
2009-04-02 16:59:40 +00:00
|
|
|
|
2009-02-27 16:24:51 +00:00
|
|
|
for (size_t i = 0; i < SK_ARRAY_COUNT(gRectStaysRectSamples); i++) {
|
|
|
|
SkMatrix m;
|
2009-04-02 16:59:40 +00:00
|
|
|
|
2009-02-27 16:24:51 +00:00
|
|
|
m.reset();
|
|
|
|
m.set(SkMatrix::kMScaleX, gRectStaysRectSamples[i].m00);
|
|
|
|
m.set(SkMatrix::kMSkewX, gRectStaysRectSamples[i].m01);
|
|
|
|
m.set(SkMatrix::kMSkewY, gRectStaysRectSamples[i].m10);
|
|
|
|
m.set(SkMatrix::kMScaleY, gRectStaysRectSamples[i].m11);
|
|
|
|
REPORTER_ASSERT(reporter,
|
|
|
|
m.rectStaysRect() == gRectStaysRectSamples[i].mStaysRect);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-27 22:06:06 +00:00
|
|
|
#include "TestClassDef.h"
|
|
|
|
DEFINE_TESTCLASS("Matrix", MatrixTestClass, TestMatrix)
|