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