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 13constexpr SkBlendMode gModes[] = { 14 SkBlendMode::kClear, 15 SkBlendMode::kSrc, 16 SkBlendMode::kDst, 17 SkBlendMode::kSrcOver, 18 SkBlendMode::kDstOver, 19 SkBlendMode::kSrcIn, 20 SkBlendMode::kDstIn, 21 SkBlendMode::kSrcOut, 22 SkBlendMode::kDstOut, 23 SkBlendMode::kSrcATop, 24 SkBlendMode::kDstATop, 25 SkBlendMode::kXor, 26}; 27 28const int gWidth = 64; 29const int gHeight = 64; 30const SkScalar W = SkIntToScalar(gWidth); 31const SkScalar H = SkIntToScalar(gHeight); 32 33static SkScalar drawCell(SkCanvas* canvas, SkBlendMode mode, SkAlpha a0, SkAlpha a1) { 34 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 58static 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, 0xCE, 0xCF, 0xCE); 63 64 SkMatrix m; 65 m.setScale(SkIntToScalar(6), SkIntToScalar(6)); 66 return SkShader::MakeBitmapShader(bm, 67 SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &m); 68} 69 70namespace skiagm { 71 72 class HairModesGM : public GM { 73 SkPaint fBGPaint; 74 75 protected: 76 SkString onShortName() override { 77 return SkString("hairmodes"); 78 } 79 80 virtual SkISize onISize() override { return SkISize::Make(640, 480); } 81 82 void onOnceBeforeDraw() override { 83 fBGPaint.setShader(make_bg_shader()); 84 } 85 86 void onDraw(SkCanvas* canvas) override { 87 const SkRect bounds = SkRect::MakeWH(W, H); 88 constexpr SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 }; 89 90 canvas->translate(SkIntToScalar(4), SkIntToScalar(4)); 91 92 for (int alpha = 0; alpha < 4; ++alpha) { 93 canvas->save(); 94 canvas->save(); 95 for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) { 96 if (6 == i) { 97 canvas->restore(); 98 canvas->translate(W * 5, 0); 99 canvas->save(); 100 } 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 GM INHERITED; 119 }; 120 121 ////////////////////////////////////////////////////////////////////////////// 122 123 static GM* MyFactory(void*) { return new HairModesGM; } 124 static GMRegistry reg(MyFactory); 125 126} 127