| Index: tests/SkImageTest.cpp
 | 
| diff --git a/tests/SkImageTest.cpp b/tests/SkImageTest.cpp
 | 
| index 3ba63b425891bcb237b8c0eb37375907ac1c75f9..a7824a52743e7f6fb4596d10a844232d08a0bca1 100644
 | 
| --- a/tests/SkImageTest.cpp
 | 
| +++ b/tests/SkImageTest.cpp
 | 
| @@ -6,6 +6,8 @@
 | 
|   */
 | 
|  
 | 
|  #include "SkBitmapDevice.h"
 | 
| +#include "SkColor.h"
 | 
| +#include "SkDrawFilter.h"
 | 
|  #include "SkImagePriv.h"
 | 
|  #include "Test.h"
 | 
|  
 | 
| @@ -47,3 +49,144 @@ DEF_TEST(SkImageFromBitmap_extractSubset, reporter) {
 | 
|      canvas.readPixels(info, &pixel, 4, gWidth - 5, gWidth - 5);
 | 
|      REPORTER_ASSERT(reporter, pixel == SK_ColorTRANSPARENT);
 | 
|  }
 | 
| +
 | 
| +namespace {
 | 
| +class TestDrawFilterImage : public SkDrawFilter {
 | 
| +public:
 | 
| +    TestDrawFilterImage()
 | 
| +            : fFilteredImage(0)
 | 
| +            , fFilteredOthers(0)
 | 
| +            , fPreventImages(true)
 | 
| +            , fPreventOthers(true) {
 | 
| +    }
 | 
| +
 | 
| +    bool filter(SkPaint*, Type type) SK_OVERRIDE {
 | 
| +        if (type == SkDrawFilter::kImage_Type) {
 | 
| +            if (fPreventImages) {
 | 
| +                fFilteredImage++;
 | 
| +                return false;
 | 
| +            }
 | 
| +            return true;
 | 
| +        }
 | 
| +
 | 
| +        if (fPreventOthers) {
 | 
| +            fFilteredOthers++;
 | 
| +            return false;
 | 
| +        }
 | 
| +        return true;
 | 
| +    }
 | 
| +    int fFilteredImage;
 | 
| +    int fFilteredOthers;
 | 
| +    bool fPreventImages;
 | 
| +    bool fPreventOthers;
 | 
| +};
 | 
| +}
 | 
| +
 | 
| +DEF_TEST(SkCanvas_test_draw_filter_image, reporter) {
 | 
| +    SkBitmap bitmap;
 | 
| +    bitmap.allocN32Pixels(1, 1);
 | 
| +    bitmap.eraseColor(SK_ColorTRANSPARENT);
 | 
| +    TestDrawFilterImage drawFilter;
 | 
| +    SkCanvas canvas(bitmap);
 | 
| +
 | 
| +    SkBitmap imageBitmap;
 | 
| +    imageBitmap.allocN32Pixels(1, 1);
 | 
| +    imageBitmap.eraseColor(SK_ColorGREEN);
 | 
| +    SkAutoTUnref<SkImage> image(SkNewImageFromBitmap(imageBitmap, true, NULL));
 | 
| +    canvas.drawImage(image, 0, 0);
 | 
| +
 | 
| +    uint32_t pixel;
 | 
| +    SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
 | 
| +    canvas.readPixels(info, &pixel, 4, 0, 0);
 | 
| +    REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
 | 
| +
 | 
| +    canvas.setDrawFilter(&drawFilter);
 | 
| +    imageBitmap.eraseColor(SK_ColorRED);
 | 
| +    image.reset(SkNewImageFromBitmap(imageBitmap, true, NULL));
 | 
| +    canvas.drawImage(image, 0, 0);
 | 
| +    canvas.readPixels(info, &pixel, 4, 0, 0);
 | 
| +    REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
 | 
| +    REPORTER_ASSERT(reporter, drawFilter.fFilteredImage == 1);
 | 
| +    REPORTER_ASSERT(reporter, drawFilter.fFilteredOthers == 0);
 | 
| +
 | 
| +    // Document a strange case: filtering everything but the images does not work as
 | 
| +    // expected. Images go through, but no pixels appear. (This due to SkCanvas::drawImage() using
 | 
| +    // SkCanvas::drawBitmap() instead of non-existing SkBaseDevice::drawImage()).
 | 
| +    drawFilter.fFilteredImage = 0;
 | 
| +    drawFilter.fPreventImages = false;
 | 
| +
 | 
| +    canvas.drawImage(image, 0, 0);
 | 
| +    canvas.readPixels(info, &pixel, 4, 0, 0);
 | 
| +    REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
 | 
| +    REPORTER_ASSERT(reporter, drawFilter.fFilteredImage == 0);
 | 
| +    REPORTER_ASSERT(reporter, drawFilter.fFilteredOthers == 1);
 | 
| +}
 | 
| +
 | 
| +namespace {
 | 
| +/*
 | 
| + *  Subclass of looper that just draws once with one pixel offset.
 | 
| + */
 | 
| +class OnceTestLooper : public SkDrawLooper {
 | 
| +public:
 | 
| +    OnceTestLooper() { }
 | 
| +
 | 
| +    SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE {
 | 
| +        return SkNEW_PLACEMENT(storage, OnceTestLooperContext());
 | 
| +    }
 | 
| +
 | 
| +    size_t contextSize() const SK_OVERRIDE { return sizeof(OnceTestLooperContext); }
 | 
| +
 | 
| +#ifndef SK_IGNORE_TO_STRING
 | 
| +    void toString(SkString* str) const SK_OVERRIDE {
 | 
| +        str->append("OnceTestLooper:");
 | 
| +    }
 | 
| +#endif
 | 
| +
 | 
| +    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(OnceTestLooper);
 | 
| +
 | 
| +private:
 | 
| +    class OnceTestLooperContext : public SkDrawLooper::Context {
 | 
| +    public:
 | 
| +        OnceTestLooperContext() : fCount(0) {}
 | 
| +        virtual ~OnceTestLooperContext() {}
 | 
| +
 | 
| +        bool next(SkCanvas* canvas, SkPaint*) SK_OVERRIDE {
 | 
| +            SkASSERT(fCount <= 1);
 | 
| +            canvas->translate(0, 1);
 | 
| +            return fCount++ < 1;
 | 
| +        }
 | 
| +    private:
 | 
| +        unsigned fCount;
 | 
| +    };
 | 
| +};
 | 
| +
 | 
| +SkFlattenable* OnceTestLooper::CreateProc(SkReadBuffer&) { return SkNEW(OnceTestLooper); }
 | 
| +}
 | 
| +
 | 
| +DEF_TEST(SkCanvas_test_draw_looper_image, reporter) {
 | 
| +    // Test that drawImage loops with the looper the correct way. At the time of writing, this was
 | 
| +    // tricky because drawImage was implemented with drawBitmap.
 | 
| +    SkBitmap bitmap;
 | 
| +    bitmap.allocN32Pixels(10, 10);
 | 
| +    bitmap.eraseColor(SK_ColorRED);
 | 
| +    OnceTestLooper drawLooper;
 | 
| +    SkCanvas canvas(bitmap);
 | 
| +
 | 
| +    SkBitmap imageBitmap;
 | 
| +    imageBitmap.allocN32Pixels(1, 1);
 | 
| +    imageBitmap.eraseColor(SK_ColorGREEN);
 | 
| +    SkAutoTUnref<SkImage> image(SkNewImageFromBitmap(imageBitmap, true, NULL));
 | 
| +    SkPaint p;
 | 
| +    p.setLooper(&drawLooper);
 | 
| +    canvas.drawImage(image, 0, 0, &p);
 | 
| +
 | 
| +    uint32_t pixel;
 | 
| +    SkImageInfo info = SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType);
 | 
| +    canvas.readPixels(info, &pixel, 4, 0, 1);
 | 
| +    REPORTER_ASSERT(reporter, pixel == SK_ColorGREEN);
 | 
| +    canvas.readPixels(info, &pixel, 4, 0, 0);
 | 
| +    REPORTER_ASSERT(reporter, pixel == SK_ColorRED);
 | 
| +    canvas.readPixels(info, &pixel, 4, 0, 2);
 | 
| +    REPORTER_ASSERT(reporter, pixel == SK_ColorRED);
 | 
| +}
 | 
| +
 | 
| 
 |