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.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
     64     bm.allocPixels();
     65     *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
     66     *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC);
     67 
     68     SkShader* s = SkShader::CreateBitmapShader(bm,
     69                                                SkShader::kRepeat_TileMode,
     70                                                SkShader::kRepeat_TileMode);
     71 
     72     SkMatrix m;
     73     m.setScale(SkIntToScalar(6), SkIntToScalar(6));
     74     s->setLocalMatrix(m);
     75     return s;
     76 }
     77 
     78 namespace skiagm {
     79 
     80     class HairModesGM : public GM {
     81         SkPaint fBGPaint;
     82 
     83     protected:
     84 
     85         virtual SkString onShortName() SK_OVERRIDE {
     86             return SkString("hairmodes");
     87         }
     88 
     89         virtual SkISize onISize() { return make_isize(640, 480); }
     90 
     91         virtual void onOnceBeforeDraw() SK_OVERRIDE {
     92             fBGPaint.setShader(make_bg_shader())->unref();
     93         }
     94 
     95         virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
     96             const SkRect bounds = SkRect::MakeWH(W, H);
     97             static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
     98 
     99             canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
    100 
    101             for (int alpha = 0; alpha < 4; ++alpha) {
    102                 canvas->save();
    103                 canvas->save();
    104                 for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
    105                     if (6 == i) {
    106                         canvas->restore();
    107                         canvas->translate(W * 5, 0);
    108                         canvas->save();
    109                     }
    110                     SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
    111 
    112                     canvas->drawRect(bounds, fBGPaint);
    113                     canvas->saveLayer(&bounds, NULL);
    114                     SkScalar dy = drawCell(canvas, mode,
    115                                            gAlphaValue[alpha & 1],
    116                                            gAlphaValue[alpha & 2]);
    117                     canvas->restore();
    118 
    119                     canvas->translate(0, dy * 5 / 4);
    120                     SkSafeUnref(mode);
    121                 }
    122                 canvas->restore();
    123                 canvas->restore();
    124                 canvas->translate(W * 5 / 4, 0);
    125             }
    126         }
    127 
    128         // disable pdf for now, since it crashes on mac
    129         virtual uint32_t onGetFlags() const { return kSkipPDF_Flag; }
    130 
    131     private:
    132         typedef GM INHERITED;
    133     };
    134 
    135     //////////////////////////////////////////////////////////////////////////////
    136 
    137     static GM* MyFactory(void*) { return new HairModesGM; }
    138     static GMRegistry reg(MyFactory);
    139 
    140 }
    141