/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "gm/gm.h" #include "include/core/SkBitmap.h" #include "include/core/SkBlendMode.h" #include "include/core/SkCanvas.h" #include "include/core/SkColor.h" #include "include/core/SkFont.h" #include "include/core/SkImageInfo.h" #include "include/core/SkPaint.h" #include "include/core/SkRect.h" #include "include/core/SkSize.h" #include "include/core/SkString.h" #include "include/core/SkTypeface.h" #include "include/utils/SkTextUtils.h" #include "tools/ToolUtils.h" #include namespace skiagm { // This GM recreates the blend mode images from the Android documentation class AndroidBlendModesGM : public GM { public: AndroidBlendModesGM() { this->setBGColor(SK_ColorBLACK); } protected: SkString onShortName() override { return SkString("androidblendmodes"); } SkISize onISize() override { return SkISize::Make(kNumCols * kBitmapSize, kNumRows * kBitmapSize); } void onOnceBeforeDraw() override { SkImageInfo ii = SkImageInfo::MakeN32Premul(kBitmapSize, kBitmapSize); { fCompositeSrc.allocPixels(ii); SkCanvas tmp(fCompositeSrc); tmp.clear(SK_ColorTRANSPARENT); SkPaint p; p.setAntiAlias(true); p.setColor(ToolUtils::color_to_565(kBlue)); tmp.drawRect(SkRect::MakeLTRB(16, 96, 160, 240), p); } { fCompositeDst.allocPixels(ii); SkCanvas tmp(fCompositeDst); tmp.clear(SK_ColorTRANSPARENT); SkPaint p; p.setAntiAlias(true); p.setColor(ToolUtils::color_to_565(kRed)); tmp.drawCircle(160, 95, 80, p); } } void drawTile(SkCanvas* canvas, int xOffset, int yOffset, SkBlendMode mode) { canvas->translate(xOffset, yOffset); canvas->clipRect(SkRect::MakeXYWH(0, 0, 256, 256)); canvas->saveLayer(nullptr, nullptr); SkPaint p; canvas->drawImage(fCompositeDst.asImage(), 0, 0, SkSamplingOptions(), &p); p.setBlendMode(mode); canvas->drawImage(fCompositeSrc.asImage(), 0, 0, SkSamplingOptions(), &p); } void onDraw(SkCanvas* canvas) override { SkFont font(ToolUtils::create_portable_typeface()); ToolUtils::draw_checkerboard(canvas, kWhite, kGrey, 32); int xOffset = 0, yOffset = 0; // Android doesn't expose all the blend modes // Note that the Android documentation calls: // Skia's kPlus, add // Skia's kModulate, multiply for (SkBlendMode mode : { SkBlendMode::kPlus /* add */, SkBlendMode::kClear, SkBlendMode::kDarken, SkBlendMode::kDst, SkBlendMode::kDstATop, SkBlendMode::kDstIn, SkBlendMode::kDstOut, SkBlendMode::kDstOver, SkBlendMode::kLighten, SkBlendMode::kModulate /* multiply */, SkBlendMode::kOverlay, SkBlendMode::kScreen, SkBlendMode::kSrc, SkBlendMode::kSrcATop, SkBlendMode::kSrcIn, SkBlendMode::kSrcOut, SkBlendMode::kSrcOver, SkBlendMode::kXor } ) { int saveCount = canvas->save(); this->drawTile(canvas, xOffset, yOffset, mode); canvas->restoreToCount(saveCount); SkTextUtils::DrawString(canvas, SkBlendMode_Name(mode), xOffset + kBitmapSize/2.0f, yOffset + kBitmapSize, font, SkPaint(), SkTextUtils::kCenter_Align); xOffset += 256; if (xOffset >= 1024) { xOffset = 0; yOffset += 256; } } } private: static const int kBitmapSize = 256; static const int kNumRows = 5; static const int kNumCols = 4; static const SkColor kBlue = SkColorSetARGB(255, 22, 150, 243); static const SkColor kRed = SkColorSetARGB(255, 233, 30, 99); static const SkColor kWhite = SkColorSetARGB(255, 243, 243, 243); static const SkColor kGrey = SkColorSetARGB(255, 222, 222, 222); SkBitmap fCompositeSrc; SkBitmap fCompositeDst; using INHERITED = GM; }; ////////////////////////////////////////////////////////////////////////////// DEF_GM(return new AndroidBlendModesGM;) } // namespace skiagm