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