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