| /* |
| * 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.h" |
| #include "sk_tool_utils.h" |
| #include "SkBitmap.h" |
| #include "SkTextUtils.h" |
| |
| 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(sk_tool_utils::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(sk_tool_utils::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->drawBitmap(fCompositeDst, 0, 0, &p); |
| p.setBlendMode(mode); |
| canvas->drawBitmap(fCompositeSrc, 0, 0, &p); |
| } |
| |
| void onDraw(SkCanvas* canvas) override { |
| SkFont font(sk_tool_utils::create_portable_typeface()); |
| |
| sk_tool_utils::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; |
| |
| typedef GM INHERITED; |
| }; |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| DEF_GM(return new AndroidBlendModesGM;) |
| } |