Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "Test.h"
      9 #include "TestClassDef.h"
     10 #include "SkBitmap.h"
     11 #include "SkBitmapDevice.h"
     12 #include "SkCanvas.h"
     13 #include "SkDraw.h"
     14 #include "SkLayerDrawLooper.h"
     15 #include "SkMatrix.h"
     16 #include "SkPaint.h"
     17 #include "SkRect.h"
     18 #include "SkRefCnt.h"
     19 #include "SkScalar.h"
     20 #include "SkXfermode.h"
     21 
     22 class FakeDevice : public SkBitmapDevice {
     23 public:
     24     FakeDevice() : SkBitmapDevice(SkBitmap::kARGB_8888_Config, 100, 100, false) { }
     25 
     26     virtual void drawRect(const SkDraw& draw, const SkRect& r,
     27                           const SkPaint& paint) SK_OVERRIDE {
     28         fLastMatrix = *draw.fMatrix;
     29         INHERITED::drawRect(draw, r, paint);
     30     }
     31 
     32     SkMatrix fLastMatrix;
     33 
     34 private:
     35     typedef SkBitmapDevice INHERITED;
     36 };
     37 
     38 static void test_frontToBack(skiatest::Reporter* reporter) {
     39     SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
     40     SkLayerDrawLooper::LayerInfo layerInfo;
     41 
     42     // Add the front layer, with the defaults.
     43     (void)looper->addLayer(layerInfo);
     44 
     45     // Add the back layer, with some layer info set.
     46     layerInfo.fOffset.set(10.0f, 20.0f);
     47     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
     48     SkPaint* layerPaint = looper->addLayer(layerInfo);
     49     layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
     50 
     51     FakeDevice device;
     52     SkCanvas canvas(&device);
     53     SkPaint paint;
     54     looper->init(&canvas);
     55 
     56     // The back layer should come first.
     57     REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
     58     REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
     59     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     60     REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
     61     REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
     62     paint.reset();
     63 
     64     // Then the front layer.
     65     REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
     66     REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
     67     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     68     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
     69     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
     70 
     71     // Only two layers were added, so that should be the end.
     72     REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
     73 }
     74 
     75 static void test_backToFront(skiatest::Reporter* reporter) {
     76     SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
     77     SkLayerDrawLooper::LayerInfo layerInfo;
     78 
     79     // Add the back layer, with the defaults.
     80     (void)looper->addLayerOnTop(layerInfo);
     81 
     82     // Add the front layer, with some layer info set.
     83     layerInfo.fOffset.set(10.0f, 20.0f);
     84     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
     85     SkPaint* layerPaint = looper->addLayerOnTop(layerInfo);
     86     layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
     87 
     88     FakeDevice device;
     89     SkCanvas canvas(&device);
     90     SkPaint paint;
     91     looper->init(&canvas);
     92 
     93     // The back layer should come first.
     94     REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
     95     REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
     96     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
     97     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
     98     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
     99     paint.reset();
    100 
    101     // Then the front layer.
    102     REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
    103     REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
    104     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
    105     REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
    106     REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
    107 
    108     // Only two layers were added, so that should be the end.
    109     REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
    110 }
    111 
    112 static void test_mixed(skiatest::Reporter* reporter) {
    113     SkAutoTUnref<SkLayerDrawLooper> looper(SkNEW(SkLayerDrawLooper));
    114     SkLayerDrawLooper::LayerInfo layerInfo;
    115 
    116     // Add the back layer, with the defaults.
    117     (void)looper->addLayer(layerInfo);
    118 
    119     // Add the front layer, with some layer info set.
    120     layerInfo.fOffset.set(10.0f, 20.0f);
    121     layerInfo.fPaintBits |= SkLayerDrawLooper::kXfermode_Bit;
    122     SkPaint* layerPaint = looper->addLayerOnTop(layerInfo);
    123     layerPaint->setXfermodeMode(SkXfermode::kSrc_Mode);
    124 
    125     FakeDevice device;
    126     SkCanvas canvas(&device);
    127     SkPaint paint;
    128     looper->init(&canvas);
    129 
    130     // The back layer should come first.
    131     REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
    132     REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode));
    133     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
    134     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateX());
    135     REPORTER_ASSERT(reporter, 0.0f == device.fLastMatrix.getTranslateY());
    136     paint.reset();
    137 
    138     // Then the front layer.
    139     REPORTER_ASSERT(reporter, looper->next(&canvas, &paint));
    140     REPORTER_ASSERT(reporter, SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrc_Mode));
    141     canvas.drawRect(SkRect::MakeWH(50.0f, 50.0f), paint);
    142     REPORTER_ASSERT(reporter, 10.0f == device.fLastMatrix.getTranslateX());
    143     REPORTER_ASSERT(reporter, 20.0f == device.fLastMatrix.getTranslateY());
    144 
    145     // Only two layers were added, so that should be the end.
    146     REPORTER_ASSERT(reporter, !looper->next(&canvas, &paint));
    147 }
    148 
    149 DEF_TEST(LayerDrawLooper, reporter) {
    150     test_frontToBack(reporter);
    151     test_backToFront(reporter);
    152     test_mixed(reporter);
    153 }
    154