blob: d799e9bb8c600748fcb82f8d50132fd509ed96b8 [file] [log] [blame]
Robert Phillipsaea785b2018-08-03 11:15:24 -04001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "gm/gm.h"
9#include "include/core/SkBitmap.h"
Ben Wagnerd1701ba2019-04-30 13:44:26 -040010#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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "include/utils/SkTextUtils.h"
21#include "tools/ToolUtils.h"
Kevin Lubicke836c3a2023-10-20 06:55:35 -040022#include "tools/fonts/FontToolUtils.h"
Robert Phillipsaea785b2018-08-03 11:15:24 -040023
Ben Wagnerd1701ba2019-04-30 13:44:26 -040024#include <initializer_list>
25
Robert Phillipsaea785b2018-08-03 11:15:24 -040026namespace skiagm {
27
28// This GM recreates the blend mode images from the Android documentation
29class AndroidBlendModesGM : public GM {
30public:
31 AndroidBlendModesGM() {
32 this->setBGColor(SK_ColorBLACK);
33 }
34
35protected:
Leandro Lovisolo24fa2112023-08-15 19:05:17 +000036 SkString getName() const override { return SkString("androidblendmodes"); }
Robert Phillipsaea785b2018-08-03 11:15:24 -040037
Leandro Lovisolo8f023882023-08-15 21:13:52 +000038 SkISize getISize() override {
Robert Phillipsaea785b2018-08-03 11:15:24 -040039 return SkISize::Make(kNumCols * kBitmapSize, kNumRows * kBitmapSize);
40 }
41
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);
Mike Kleinea3f0142019-03-20 11:12:10 -050050 p.setColor(ToolUtils::color_to_565(kBlue));
Robert Phillipsaea785b2018-08-03 11:15:24 -040051 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);
Mike Kleinea3f0142019-03-20 11:12:10 -050060 p.setColor(ToolUtils::color_to_565(kRed));
Robert Phillipsaea785b2018-08-03 11:15:24 -040061 tmp.drawCircle(160, 95, 80, p);
62 }
63 }
64
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;
Mike Reed07c5f522021-01-23 12:23:23 -050073 canvas->drawImage(fCompositeDst.asImage(), 0, 0, SkSamplingOptions(), &p);
Robert Phillipsaea785b2018-08-03 11:15:24 -040074 p.setBlendMode(mode);
Mike Reed07c5f522021-01-23 12:23:23 -050075 canvas->drawImage(fCompositeSrc.asImage(), 0, 0, SkSamplingOptions(), &p);
Robert Phillipsaea785b2018-08-03 11:15:24 -040076 }
77
78 void onDraw(SkCanvas* canvas) override {
Kevin Lubicke836c3a2023-10-20 06:55:35 -040079 SkFont font = ToolUtils::DefaultPortableFont();
Robert Phillipsaea785b2018-08-03 11:15:24 -040080
Mike Kleinea3f0142019-03-20 11:12:10 -050081 ToolUtils::draw_checkerboard(canvas, kWhite, kGrey, 32);
Robert Phillipsaea785b2018-08-03 11:15:24 -040082
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
Mike Reed331ccfd2018-10-25 12:36:06 -0400103 SkTextUtils::DrawString(canvas, SkBlendMode_Name(mode),
Robert Phillipsaea785b2018-08-03 11:15:24 -0400104 xOffset + kBitmapSize/2.0f,
105 yOffset + kBitmapSize,
Mike Reeddc5863c2018-12-23 23:19:14 -0500106 font, SkPaint(), SkTextUtils::kCenter_Align);
Robert Phillipsaea785b2018-08-03 11:15:24 -0400107
108 xOffset += 256;
109 if (xOffset >= 1024) {
110 xOffset = 0;
111 yOffset += 256;
112 }
113 }
114 }
115
116private:
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
John Stiles7571f9e2020-09-02 22:42:33 -0400129 using INHERITED = GM;
Robert Phillipsaea785b2018-08-03 11:15:24 -0400130};
131
132//////////////////////////////////////////////////////////////////////////////
133
134DEF_GM(return new AndroidBlendModesGM;)
John Stilesa6841be2020-08-06 14:11:56 -0400135} // namespace skiagm