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