Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2011 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 "gm.h"
      9 #include "SkCanvas.h"
     10 #include "SkColorPriv.h"
     11 #include "SkShader.h"
     12 
     13 static const struct {
     14     SkXfermode::Mode  fMode;
     15     const char*         fLabel;
     16 } gModes[] = {
     17     { SkXfermode::kClear_Mode,    "Clear"     },
     18     { SkXfermode::kSrc_Mode,      "Src"       },
     19     { SkXfermode::kDst_Mode,      "Dst"       },
     20     { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
     21     { SkXfermode::kDstOver_Mode,  "DstOver"   },
     22     { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
     23     { SkXfermode::kDstIn_Mode,    "DstIn"     },
     24     { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
     25     { SkXfermode::kDstOut_Mode,   "DstOut"    },
     26     { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
     27     { SkXfermode::kDstATop_Mode,  "DstATop"   },
     28     { SkXfermode::kXor_Mode,      "Xor"       },
     29 };
     30 
     31 const int gWidth = 64;
     32 const int gHeight = 64;
     33 const SkScalar W = SkIntToScalar(gWidth);
     34 const SkScalar H = SkIntToScalar(gHeight);
     35 
     36 static SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) {
     37 
     38     SkPaint paint;
     39     paint.setAntiAlias(true);
     40 
     41     SkRect r = SkRect::MakeWH(W, H);
     42     r.inset(W/10, H/10);
     43 
     44     paint.setColor(SK_ColorBLUE);
     45     paint.setAlpha(a0);
     46     canvas->drawOval(r, paint);
     47 
     48     paint.setColor(SK_ColorRED);
     49     paint.setAlpha(a1);
     50     paint.setXfermode(mode);
     51     for (int angle = 0; angle < 24; ++angle) {
     52         SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth;
     53         SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight;
     54         paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24);
     55         canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint);
     56     }
     57 
     58     return H;
     59 }
     60 
     61 static SkShader* make_bg_shader() {
     62     SkBitmap bm;
     63     bm.allocN32Pixels(2, 2);
     64     *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
     65     *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCE, 0xCF, 0xCE);
     66 
     67     SkMatrix m;
     68     m.setScale(SkIntToScalar(6), SkIntToScalar(6));
     69     return SkShader::CreateBitmapShader(bm,
     70                                         SkShader::kRepeat_TileMode,
     71                                         SkShader::kRepeat_TileMode,
     72                                         &m);
     73 }
     74 
     75 namespace skiagm {
     76 
     77     class HairModesGM : public GM {
     78         SkPaint fBGPaint;
     79 
     80     protected:
     81         SkString onShortName() override {
     82             return SkString("hairmodes");
     83         }
     84 
     85         virtual SkISize onISize() override { return SkISize::Make(640, 480); }
     86 
     87         void onOnceBeforeDraw() override {
     88             fBGPaint.setShader(make_bg_shader())->unref();
     89         }
     90 
     91         void onDraw(SkCanvas* canvas) override {
     92             const SkRect bounds = SkRect::MakeWH(W, H);
     93             static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
     94 
     95             canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
     96 
     97             for (int alpha = 0; alpha < 4; ++alpha) {
     98                 canvas->save();
     99                 canvas->save();
    100                 for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
    101                     if (6 == i) {
    102                         canvas->restore();
    103                         canvas->translate(W * 5, 0);
    104                         canvas->save();
    105                     }
    106                     SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
    107 
    108                     canvas->drawRect(bounds, fBGPaint);
    109                     canvas->saveLayer(&bounds, nullptr);
    110                     SkScalar dy = drawCell(canvas, mode,
    111                                            gAlphaValue[alpha & 1],
    112                                            gAlphaValue[alpha & 2]);
    113                     canvas->restore();
    114 
    115                     canvas->translate(0, dy * 5 / 4);
    116                     SkSafeUnref(mode);
    117                 }
    118                 canvas->restore();
    119                 canvas->restore();
    120                 canvas->translate(W * 5 / 4, 0);
    121             }
    122         }
    123 
    124     private:
    125         typedef GM INHERITED;
    126     };
    127 
    128     //////////////////////////////////////////////////////////////////////////////
    129 
    130     static GM* MyFactory(void*) { return new HairModesGM; }
    131     static GMRegistry reg(MyFactory);
    132 
    133 }
    134