add unittest for matrix::flatten
define constant for max value flatten/unflatten can return (so clients can put
the buffer on the stack)
git-svn-id: http://skia.googlecode.com/svn/trunk@243 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
index 9dd4fc9..741c349 100644
--- a/include/core/SkMatrix.h
+++ b/include/core/SkMatrix.h
@@ -400,6 +400,10 @@
return memcmp(a.fMat, b.fMat, sizeof(a.fMat)) != 0;
}
+ enum {
+ // flatten/unflatten will never return a value larger than this
+ kMaxFlattenSize = 9 * sizeof(SkScalar) + sizeof(uint32_t)
+ };
// return the number of bytes written, whether or not buffer is null
uint32_t flatten(void* buffer) const;
// return the number of bytes read
diff --git a/src/effects/SkGroupShape.cpp b/src/effects/SkGroupShape.cpp
index 0e7640f..b8edc82 100644
--- a/src/effects/SkGroupShape.cpp
+++ b/src/effects/SkGroupShape.cpp
@@ -80,8 +80,6 @@
return CreateProc;
}
-#define SAFE_MATRIX_STORAGE_SIZE (sizeof(SkMatrix)*2)
-
void SkGroupShape::flatten(SkFlattenableWriteBuffer& buffer) {
this->INHERITED::flatten(buffer);
@@ -92,7 +90,7 @@
while (rec < stop) {
buffer.writeFlattenable(rec->fShape);
if (rec->fMatrixRef) {
- char storage[SAFE_MATRIX_STORAGE_SIZE];
+ char storage[SkMatrix::kMaxFlattenSize];
uint32_t size = rec->fMatrixRef->flatten(storage);
buffer.write32(size);
buffer.writePad(storage, size);
@@ -110,8 +108,7 @@
SkMatrixRef* mr = NULL;
uint32_t size = buffer.readS32();
if (size) {
- char storage[SAFE_MATRIX_STORAGE_SIZE];
- SkASSERT(size <= SAFE_MATRIX_STORAGE_SIZE);
+ char storage[SkMatrix::kMaxFlattenSize];
buffer.read(storage, SkAlign4(size));
mr = SkNEW(SkMatrixRef);
mr->unflatten(storage);
diff --git a/tests/MatrixTest.cpp b/tests/MatrixTest.cpp
index 68e587b..052687d 100644
--- a/tests/MatrixTest.cpp
+++ b/tests/MatrixTest.cpp
@@ -27,6 +27,25 @@
return nearly_equal(m, identity);
}
+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);
+}
+
void TestMatrix(skiatest::Reporter* reporter) {
SkMatrix mat, inverse, iden1, iden2;
@@ -40,11 +59,13 @@
mat.invert(&inverse);
iden1.setConcat(mat, inverse);
REPORTER_ASSERT(reporter, is_identity(iden1));
+ test_flatten(reporter, mat);
mat.setScale(SK_Scalar1/2, SK_Scalar1/2);
mat.invert(&inverse);
iden1.setConcat(mat, inverse);
REPORTER_ASSERT(reporter, is_identity(iden1));
+ test_flatten(reporter, mat);
mat.setScale(SkIntToScalar(3), SkIntToScalar(5), SkIntToScalar(20), 0);
mat.postRotate(SkIntToScalar(25));
@@ -54,6 +75,8 @@
REPORTER_ASSERT(reporter, is_identity(iden1));
iden2.setConcat(inverse, mat);
REPORTER_ASSERT(reporter, is_identity(iden2));
+ test_flatten(reporter, mat);
+ test_flatten(reporter, iden2);
// rectStaysRect test
{