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