Modifying SkTileGrid to support arbitrary query rectangles.
Exposing SkTileGrid functionality in the public API through SkTileGridPicture.
This patch also makes TileGrid and Rtree testable in gm, which revealed errors.
TEST=gm with '--tileGrid'
BUG=http://code.google.com/p/chromium/issues/detail?id=164636
Review URL: https://codereview.appspot.com/6933044
git-svn-id: http://skia.googlecode.com/svn/trunk@6783 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tests/TileGridTest.cpp b/tests/TileGridTest.cpp
index e0c855c..d5ca52b4 100644
--- a/tests/TileGridTest.cpp
+++ b/tests/TileGridTest.cpp
@@ -8,6 +8,9 @@
#include "Test.h"
#include "SkTileGrid.h"
+#include "SkTileGridPicture.h"
+#include "SkCanvas.h"
+#include "SkDevice.h"
enum Tile {
kTopLeft_Tile = 0x1,
@@ -18,10 +21,26 @@
kAll_Tile = kTopLeft_Tile | kTopRight_Tile | kBottomLeft_Tile | kBottomRight_Tile,
};
+namespace {
+class MockCanvas : public SkCanvas {
+public:
+ MockCanvas(SkDevice* device) : SkCanvas(device)
+ {}
+
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint)
+ {
+ // This capture occurs before quick reject.
+ fRects.push(rect);
+ }
+
+ SkTDArray<SkRect> fRects;
+};
+}
+
class TileGridTest {
public:
static void verifyTileHits(skiatest::Reporter* reporter, SkIRect rect, uint32_t tileMask) {
- SkTileGrid grid(10, 10, 2, 2);
+ SkTileGrid grid(10, 10, 2, 2, NULL);
grid.insert(NULL, rect, false);
REPORTER_ASSERT(reporter, grid.tile(0,0).count() ==
((tileMask & kTopLeft_Tile)? 1 : 0));
@@ -33,6 +52,60 @@
((tileMask & kBottomRight_Tile)? 1 : 0));
}
+ static void TestUnalignedQuery(skiatest::Reporter* reporter) {
+ // Use SkTileGridPicture to generate a SkTileGrid with a helper
+ SkTileGridPicture picture(10, 10, 20, 20);
+ SkRect rect1 = SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
+ SkIntToScalar(8), SkIntToScalar(8));
+ SkRect rect2 = SkRect::MakeXYWH(SkIntToScalar(11), SkIntToScalar(11),
+ SkIntToScalar(1), SkIntToScalar(1));
+ SkCanvas* canvas = picture.beginRecording(20, 20, SkPicture::kOptimizeForClippedPlayback_RecordingFlag);
+ SkPaint paint;
+ canvas->drawRect(rect1, paint);
+ canvas->drawRect(rect2, paint);
+ picture.endRecording();
+
+ SkBitmap store;
+ store.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
+ store.allocPixels();
+
+ // Test parts of top-left tile
+ {
+ SkDevice device(store);
+ MockCanvas mockCanvas(&device);
+ picture.draw(&mockCanvas);
+ REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
+ REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
+ }
+ {
+ SkDevice device(store);
+ MockCanvas mockCanvas(&device);
+ mockCanvas.translate(SkFloatToScalar(-7.99f), SkFloatToScalar(-7.99f));
+ picture.draw(&mockCanvas);
+ REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
+ REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
+ }
+ // Corner overlap
+ {
+ SkDevice device(store);
+ MockCanvas mockCanvas(&device);
+ mockCanvas.translate(SkFloatToScalar(-9.5f), SkFloatToScalar(-9.5f));
+ picture.draw(&mockCanvas);
+ REPORTER_ASSERT(reporter, 2 == mockCanvas.fRects.count());
+ REPORTER_ASSERT(reporter, rect1 == mockCanvas.fRects[0]);
+ REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[1]);
+ }
+ // Intersect bottom right tile, but does not overlap rect 2
+ {
+ SkDevice device(store);
+ MockCanvas mockCanvas(&device);
+ mockCanvas.translate(SkFloatToScalar(-16.0f), SkFloatToScalar(-16.0f));
+ picture.draw(&mockCanvas);
+ REPORTER_ASSERT(reporter, 1 == mockCanvas.fRects.count());
+ REPORTER_ASSERT(reporter, rect2 == mockCanvas.fRects[0]);
+ }
+ }
+
static void Test(skiatest::Reporter* reporter) {
// Out of bounds
verifyTileHits(reporter, SkIRect::MakeXYWH(30, 0, 1, 1), 0);
@@ -52,6 +125,8 @@
kBottomLeft_Tile);
verifyTileHits(reporter, SkIRect::MakeXYWH(5, 5, 10, 10), kAll_Tile);
verifyTileHits(reporter, SkIRect::MakeXYWH(-10, -10, 40, 40), kAll_Tile);
+
+ TestUnalignedQuery(reporter);
}
};