Fix Paint == comparison on Android.
The == operator was incorrect because of Androids use of
fGenerationID. This change moves the ID to the end of the
paint struct and omits it from the == comparison.
Review URL: http://codereview.appspot.com/5437098
git-svn-id: http://skia.googlecode.com/svn/trunk@2780 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h
index db11b33..3823481 100644
--- a/include/core/SkPaint.h
+++ b/include/core/SkPaint.h
@@ -877,9 +877,6 @@
unsigned fStyle : 2;
unsigned fTextEncoding : 2; // 3 values
unsigned fHinting : 2;
-#ifdef SK_BUILD_FOR_ANDROID
- uint32_t fGenerationID;
-#endif
SkDrawCacheProc getDrawCacheProc() const;
SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir,
@@ -905,6 +902,12 @@
friend class SkDraw;
friend class SkPDFDevice;
friend class SkTextToPathIter;
+
+#ifdef SK_BUILD_FOR_ANDROID
+ // In order for the == operator to work properly this must be the last field
+ // in the struct so that we can do a memcmp to this field's offset.
+ uint32_t fGenerationID;
+#endif
};
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 5ed22fd..ba99348 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -137,7 +137,12 @@
}
bool operator==(const SkPaint& a, const SkPaint& b) {
+#ifdef SK_BUILD_FOR_ANDROID
+ //assumes that fGenerationID is the last field in the struct
+ return !memcmp(&a, &b, SK_OFFSETOF(SkPaint, fGenerationID));
+#else
return !memcmp(&a, &b, sizeof(a));
+#endif
}
void SkPaint::reset() {
diff --git a/tests/PaintTest.cpp b/tests/PaintTest.cpp
index 361da74..6350eb5 100644
--- a/tests/PaintTest.cpp
+++ b/tests/PaintTest.cpp
@@ -8,6 +8,60 @@
#include "Test.h"
#include "SkPath.h"
#include "SkPaint.h"
+#include "SkLayerDrawLooper.h"
+#include "SkBlurMaskFilter.h"
+
+static void test_copy(skiatest::Reporter* reporter) {
+ SkPaint paint;
+ // set a few member variables
+ paint.setStyle(SkPaint::kStrokeAndFill_Style);
+ paint.setTextAlign(SkPaint::kLeft_Align);
+ paint.setStrokeWidth(SkIntToScalar(2));
+ // set a few pointers
+ SkLayerDrawLooper* looper = new SkLayerDrawLooper();
+ paint.setLooper(looper)->unref();
+ SkMaskFilter* mask = SkBlurMaskFilter::Create(1, SkBlurMaskFilter::kNormal_BlurStyle);
+ paint.setMaskFilter(mask)->unref();
+
+ // copy the paint using the copy constructor and check they are the same
+ SkPaint copiedPaint = paint;
+ REPORTER_ASSERT(reporter, paint == copiedPaint);
+
+#ifdef SK_BUILD_FOR_ANDROID
+ // the copy constructor should preserve the Generation ID
+ int32_t paintGenID = paint.getGenerationID();
+ int32_t copiedPaintGenID = copiedPaint.getGenerationID();
+ REPORTER_ASSERT(reporter, paintGenID == copiedPaintGenID);
+ REPORTER_ASSERT(reporter, !memcmp(&paint, &copiedPaint, sizeof(paint)));
+#endif
+
+ // copy the paint using the equal operator and check they are the same
+ copiedPaint = paint;
+ REPORTER_ASSERT(reporter, paint == copiedPaint);
+
+#ifdef SK_BUILD_FOR_ANDROID
+ // the equals operator should increment the Generation ID
+ REPORTER_ASSERT(reporter, paint.getGenerationID() == paintGenID);
+ REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
+ copiedPaintGenID = copiedPaint.getGenerationID(); // reset to the new value
+ REPORTER_ASSERT(reporter, memcmp(&paint, &copiedPaint, sizeof(paint)));
+#endif
+
+ // clean the paint and check they are back to their initial states
+ SkPaint cleanPaint;
+ paint.reset();
+ copiedPaint.reset();
+ REPORTER_ASSERT(reporter, cleanPaint == paint);
+ REPORTER_ASSERT(reporter, cleanPaint == copiedPaint);
+
+#ifdef SK_BUILD_FOR_ANDROID
+ // the reset function should increment the Generation ID
+ REPORTER_ASSERT(reporter, paint.getGenerationID() != paintGenID);
+ REPORTER_ASSERT(reporter, copiedPaint.getGenerationID() != copiedPaintGenID);
+ REPORTER_ASSERT(reporter, memcmp(&cleanPaint, &paint, sizeof(cleanPaint)));
+ REPORTER_ASSERT(reporter, memcmp(&cleanPaint, &copiedPaint, sizeof(cleanPaint)));
+#endif
+}
// found and fixed for webkit: mishandling when we hit recursion limit on
// mostly degenerate cubic flatness test
@@ -45,6 +99,7 @@
static void TestPaint(skiatest::Reporter* reporter) {
// TODO add general paint tests
+ test_copy(reporter);
// regression tests
regression_cubic(reporter);