| /* |
| * Copyright 2013 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| #include "Test.h" |
| #include "SkBitmap.h" |
| #include "SkCanvas.h" |
| #include "SkDraw.h" |
| #include "SkDevice.h" |
| #include "SkLayerDrawLooper.h" |
| #include "SkMatrix.h" |
| #include "SkPaint.h" |
| #include "SkRect.h" |
| #include "SkRefCnt.h" |
| #include "SkScalar.h" |
| #include "SkXfermode.h" |
| |
| namespace { |
| |
| class FakeDevice : public SkDevice { |
| public: |
| FakeDevice() : SkDevice(SkBitmap::kARGB_8888_Config, 100, 100) { } |
| |
| virtual void drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) { |
| fLastMatrix = *draw.fMatrix; |
| SkDevice::drawRect(draw, r, paint); |
| } |
| |
| SkMatrix fLastMatrix; |
| }; |
| |
| } // namespace |
| |
| static void test_frontToBack(skiatest::Reporter* reporter) { |
| SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper)); |
| SkLayerDrawLooper::LayerInfo layerInfo; |
| |
| // Add the front layer, with the defaults. |
| (void)looper->addLayer(layerInfo); |
| |
| // Add the back layer, with some layer info set. |
| layerInfo.fOffset.set(SkFloatToScalar(10.0f), SkFloatToScalar(20.0f)); |
| layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; |
| SkPaint* layerPaint = looper->addLayer(layerInfo); |
| layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); |
| |
| FakeDevice device; |
| SkCanvas canvas(&device); |
| SkPaint paint; |
| looper->init(&canvas); |
| |
| // The back layer should come first. |
| REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); |
| REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); |
| canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(10.0f) == device.fLastMatrix.getTranslateX()); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(20.0f) == device.fLastMatrix.getTranslateY()); |
| paint.reset(); |
| |
| // Then the front layer. |
| REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); |
| REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); |
| canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateX()); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateY()); |
| |
| // Only two layers were added, so that should be the end. |
| REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint)); |
| } |
| |
| static void test_backToFront(skiatest::Reporter* reporter) { |
| SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper)); |
| SkLayerDrawLooper::LayerInfo layerInfo; |
| |
| // Add the back layer, with the defaults. |
| (void)looper->addLayerOnTop(layerInfo); |
| |
| // Add the front layer, with some layer info set. |
| layerInfo.fOffset.set(SkFloatToScalar(10.0f), SkFloatToScalar(20.0f)); |
| layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; |
| SkPaint* layerPaint = looper->addLayerOnTop(layerInfo); |
| layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); |
| |
| FakeDevice device; |
| SkCanvas canvas(&device); |
| SkPaint paint; |
| looper->init(&canvas); |
| |
| // The back layer should come first. |
| REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); |
| REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); |
| canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateX()); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateY()); |
| paint.reset(); |
| |
| // Then the front layer. |
| REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); |
| REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); |
| canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(10.0f) == device.fLastMatrix.getTranslateX()); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(20.0f) == device.fLastMatrix.getTranslateY()); |
| |
| // Only two layers were added, so that should be the end. |
| REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint)); |
| } |
| |
| static void test_mixed(skiatest::Reporter* reporter) { |
| SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper)); |
| SkLayerDrawLooper::LayerInfo layerInfo; |
| |
| // Add the back layer, with the defaults. |
| (void)looper->addLayer(layerInfo); |
| |
| // Add the front layer, with some layer info set. |
| layerInfo.fOffset.set(SkFloatToScalar(10.0f), SkFloatToScalar(20.0f)); |
| layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit; |
| SkPaint* layerPaint = looper->addLayerOnTop(layerInfo); |
| layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode); |
| |
| FakeDevice device; |
| SkCanvas canvas(&device); |
| SkPaint paint; |
| looper->init(&canvas); |
| |
| // The back layer should come first. |
| REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); |
| REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)); |
| canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateX()); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(0.0f) == device.fLastMatrix.getTranslateY()); |
| paint.reset(); |
| |
| // Then the front layer. |
| REPORTER_ASSERT(reporter, looper->next(&canvas, &paint)); |
| REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode)); |
| canvas.drawRect(SkRect::MakeWH(SkFloatToScalar(50.0f), SkFloatToScalar(50.0f)), paint); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(10.0f) == device.fLastMatrix.getTranslateX()); |
| REPORTER_ASSERT(reporter, SkFloatToScalar(20.0f) == device.fLastMatrix.getTranslateY()); |
| |
| // Only two layers were added, so that should be the end. |
| REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint)); |
| } |
| |
| static void TestLayerDrawLooper(skiatest::Reporter* reporter) { |
| test_frontToBack(reporter); |
| test_backToFront(reporter); |
| test_mixed(reporter); |
| } |
| |
| #include "TestClassDef.h" |
| DEFINE_TESTCLASS("LayerDrawLooper", TestLayerDrawLooperClass, TestLayerDrawLooper) |