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 "Sample.h" 9 #include "SkBitmap.h" 10 #include "SkCanvas.h" 11 #include "SkColorPriv.h" 12 #include "SkShader.h" 13 14 static const SkBlendMode gModes[] = { 15 SkBlendMode::kClear, 16 SkBlendMode::kSrc, 17 SkBlendMode::kDst, 18 SkBlendMode::kSrcOver, 19 SkBlendMode::kDstOver, 20 SkBlendMode::kSrcIn, 21 SkBlendMode::kDstIn, 22 SkBlendMode::kSrcOut, 23 SkBlendMode::kDstOut, 24 SkBlendMode::kSrcATop, 25 SkBlendMode::kDstATop, 26 SkBlendMode::kXor, 27 }; 28 29 const int gWidth = 64; 30 const int gHeight = 64; 31 const SkScalar W = SkIntToScalar(gWidth); 32 const SkScalar H = SkIntToScalar(gHeight); 33 34 static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha a1) { 35 SkPaint paint; 36 paint.setAntiAlias(true); 37 38 SkRect r = SkRect::MakeWH(W, H); 39 r.inset(W/10, H/10); 40 41 paint.setColor(SK_ColorBLUE); 42 paint.setAlpha(a0); 43 canvas->drawOval(r, paint); 44 45 paint.setColor(SK_ColorRED); 46 paint.setAlpha(a1); 47 paint.setBlendMode(mode); 48 for (int angle = 0; angle < 24; ++angle) { 49 SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth; 50 SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight; 51 paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24); 52 canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint); 53 } 54 55 return H; 56 } 57 58 static sk_sp<SkShader> make_bg_shader() { 59 SkBitmap bm; 60 bm.allocN32Pixels(2, 2); 61 *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF; 62 *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC); 63 64 SkMatrix m; 65 m.setScale(SkIntToScalar(6), SkIntToScalar(6)); 66 67 return SkShader::MakeBitmapShader(bm, SkShader::kRepeat_TileMode, 68 SkShader::kRepeat_TileMode, &m); 69 } 70 71 class HairModesView : public Sample { 72 SkPaint fBGPaint; 73 public: 74 HairModesView() { 75 fBGPaint.setShader(make_bg_shader()); 76 } 77 78 protected: 79 virtual bool onQuery(Sample::Event* evt) { 80 if (Sample::TitleQ(*evt)) { 81 Sample::TitleR(evt, "HairlineModes"); 82 return true; 83 } 84 return this->INHERITED::onQuery(evt); 85 } 86 87 virtual void onDrawContent(SkCanvas* canvas) { 88 const SkRect bounds = SkRect::MakeWH(W, H); 89 static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 }; 90 91 canvas->translate(SkIntToScalar(4), SkIntToScalar(4)); 92 93 for (int alpha = 0; alpha < 4; ++alpha) { 94 canvas->save(); 95 canvas->save(); 96 for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) { 97 if (6 == i) { 98 canvas->restore(); 99 canvas->translate(W * 5, 0); 100 canvas->save(); 101 } 102 canvas->drawRect(bounds, fBGPaint); 103 canvas->saveLayer(&bounds, nullptr); 104 SkScalar dy = drawCell(canvas, gModes[i], 105 gAlphaValue[alpha & 1], 106 gAlphaValue[alpha & 2]); 107 canvas->restore(); 108 109 canvas->translate(0, dy * 5 / 4); 110 } 111 canvas->restore(); 112 canvas->restore(); 113 canvas->translate(W * 5 / 4, 0); 114 } 115 } 116 117 private: 118 typedef Sample INHERITED; 119 }; 120 121 /////////////////////////////////////////////////////////////////////////////// 122 123 DEF_SAMPLE( return new HairModesView(); ) 124