1 /* 2 * Copyright 2018 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 "sk_tool_utils.h" 10 #include "SkBitmap.h" 11 #include "SkTextUtils.h" 12 13 namespace skiagm { 14 15 // This GM recreates the blend mode images from the Android documentation 16 class AndroidBlendModesGM : public GM { 17 public: 18 AndroidBlendModesGM() { 19 this->setBGColor(SK_ColorBLACK); 20 } 21 22 protected: 23 SkString onShortName() override { 24 return SkString("androidblendmodes"); 25 } 26 27 SkISize onISize() override { 28 return SkISize::Make(kNumCols * kBitmapSize, kNumRows * kBitmapSize); 29 } 30 31 void onOnceBeforeDraw() override { 32 SkImageInfo ii = SkImageInfo::MakeN32Premul(kBitmapSize, kBitmapSize); 33 { 34 fCompositeSrc.allocPixels(ii); 35 SkCanvas tmp(fCompositeSrc); 36 tmp.clear(SK_ColorTRANSPARENT); 37 SkPaint p; 38 p.setAntiAlias(true); 39 p.setColor(sk_tool_utils::color_to_565(kBlue)); 40 tmp.drawRect(SkRect::MakeLTRB(16, 96, 160, 240), p); 41 } 42 43 { 44 fCompositeDst.allocPixels(ii); 45 SkCanvas tmp(fCompositeDst); 46 tmp.clear(SK_ColorTRANSPARENT); 47 SkPaint p; 48 p.setAntiAlias(true); 49 p.setColor(sk_tool_utils::color_to_565(kRed)); 50 tmp.drawCircle(160, 95, 80, p); 51 } 52 } 53 54 void drawTile(SkCanvas* canvas, int xOffset, int yOffset, SkBlendMode mode) { 55 canvas->translate(xOffset, yOffset); 56 57 canvas->clipRect(SkRect::MakeXYWH(0, 0, 256, 256)); 58 59 canvas->saveLayer(nullptr, nullptr); 60 61 SkPaint p; 62 canvas->drawBitmap(fCompositeDst, 0, 0, &p); 63 p.setBlendMode(mode); 64 canvas->drawBitmap(fCompositeSrc, 0, 0, &p); 65 } 66 67 void onDraw(SkCanvas* canvas) override { 68 SkFont font(sk_tool_utils::create_portable_typeface()); 69 70 sk_tool_utils::draw_checkerboard(canvas, 71 kWhite, 72 kGrey, 73 32); 74 75 int xOffset = 0, yOffset = 0; 76 77 // Android doesn't expose all the blend modes 78 // Note that the Android documentation calls: 79 // Skia's kPlus, add 80 // Skia's kModulate, multiply 81 for (SkBlendMode mode : { SkBlendMode::kPlus /* add */, SkBlendMode::kClear, 82 SkBlendMode::kDarken, SkBlendMode::kDst, 83 SkBlendMode::kDstATop, SkBlendMode::kDstIn, 84 SkBlendMode::kDstOut, SkBlendMode::kDstOver, 85 SkBlendMode::kLighten, SkBlendMode::kModulate /* multiply */, 86 SkBlendMode::kOverlay, SkBlendMode::kScreen, 87 SkBlendMode::kSrc, SkBlendMode::kSrcATop, 88 SkBlendMode::kSrcIn, SkBlendMode::kSrcOut, 89 SkBlendMode::kSrcOver, SkBlendMode::kXor } ) { 90 91 int saveCount = canvas->save(); 92 this->drawTile(canvas, xOffset, yOffset, mode); 93 canvas->restoreToCount(saveCount); 94 95 SkTextUtils::DrawString(canvas, SkBlendMode_Name(mode), 96 xOffset + kBitmapSize/2.0f, 97 yOffset + kBitmapSize, 98 font, SkPaint(), SkTextUtils::kCenter_Align); 99 100 xOffset += 256; 101 if (xOffset >= 1024) { 102 xOffset = 0; 103 yOffset += 256; 104 } 105 } 106 } 107 108 private: 109 static const int kBitmapSize = 256; 110 static const int kNumRows = 5; 111 static const int kNumCols = 4; 112 113 static const SkColor kBlue = SkColorSetARGB(255, 22, 150, 243); 114 static const SkColor kRed = SkColorSetARGB(255, 233, 30, 99); 115 static const SkColor kWhite = SkColorSetARGB(255, 243, 243, 243); 116 static const SkColor kGrey = SkColorSetARGB(255, 222, 222, 222); 117 118 SkBitmap fCompositeSrc; 119 SkBitmap fCompositeDst; 120 121 typedef GM INHERITED; 122 }; 123 124 ////////////////////////////////////////////////////////////////////////////// 125 126 DEF_GM(return new AndroidBlendModesGM;) 127 } 128