xref: /aosp_15_r20/external/skia/gm/drawatlascolor.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2015 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/SkBlendMode.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkColor.h"
12 #include "include/core/SkFont.h"
13 #include "include/core/SkImage.h"
14 #include "include/core/SkImageInfo.h"
15 #include "include/core/SkPaint.h"
16 #include "include/core/SkRSXform.h"
17 #include "include/core/SkRect.h"
18 #include "include/core/SkRefCnt.h"
19 #include "include/core/SkScalar.h"
20 #include "include/core/SkSize.h"
21 #include "include/core/SkString.h"
22 #include "include/core/SkSurface.h"
23 #include "include/core/SkTypeface.h"
24 #include "include/core/SkTypes.h"
25 #include "tools/ToolUtils.h"
26 #include "tools/fonts/FontToolUtils.h"
27 
28 // Create a square atlas of:
29 //   opaque white  |     opaque red
30 //  ------------------------------------
31 //   opaque green  |  transparent black
32 //
make_atlas(SkCanvas * caller,int atlasSize)33 static sk_sp<SkImage> make_atlas(SkCanvas* caller, int atlasSize) {
34     const int kBlockSize = atlasSize/2;
35 
36     SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
37     auto        surface(ToolUtils::makeSurface(caller, info));
38     SkCanvas* canvas = surface->getCanvas();
39 
40     SkPaint paint;
41     paint.setBlendMode(SkBlendMode::kSrc);
42 
43     paint.setColor(SK_ColorWHITE);
44     SkRect r = SkRect::MakeXYWH(0, 0,
45                                 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
46     canvas->drawRect(r, paint);
47 
48     paint.setColor(SK_ColorRED);
49     r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0,
50                          SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
51     canvas->drawRect(r, paint);
52 
53     paint.setColor(SK_ColorGREEN);
54     r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize),
55                          SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
56     canvas->drawRect(r, paint);
57 
58     paint.setColor(SK_ColorTRANSPARENT);
59     r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize),
60                          SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
61     canvas->drawRect(r, paint);
62 
63     return surface->makeImageSnapshot();
64 }
65 
66 // This GM tests the drawAtlas API with colors, different xfer modes
67 // and transparency in the atlas image
68 class DrawAtlasColorsGM : public skiagm::GM {
69 public:
DrawAtlasColorsGM()70     DrawAtlasColorsGM() {
71         this->setBGColor(0xFFCCCCCC);
72     }
73 
74 protected:
getName() const75     SkString getName() const override { return SkString("draw-atlas-colors"); }
76 
getISize()77     SkISize getISize() override {
78         return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad,
79                              2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad);
80     }
81 
onDraw(SkCanvas * canvas)82     void onDraw(SkCanvas* canvas) override {
83         const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize));
84 
85         auto atlas = make_atlas(canvas, kAtlasSize);
86 
87         const SkBlendMode gModes[] = {
88             SkBlendMode::kClear,
89             SkBlendMode::kSrc,
90             SkBlendMode::kDst,
91             SkBlendMode::kSrcOver,
92             SkBlendMode::kDstOver,
93             SkBlendMode::kSrcIn,
94             SkBlendMode::kDstIn,
95             SkBlendMode::kSrcOut,
96             SkBlendMode::kDstOut,
97             SkBlendMode::kSrcATop,
98             SkBlendMode::kDstATop,
99             SkBlendMode::kXor,
100             SkBlendMode::kPlus,
101             SkBlendMode::kModulate,
102             SkBlendMode::kScreen,
103             SkBlendMode::kOverlay,
104             SkBlendMode::kDarken,
105             SkBlendMode::kLighten,
106             SkBlendMode::kColorDodge,
107             SkBlendMode::kColorBurn,
108             SkBlendMode::kHardLight,
109             SkBlendMode::kSoftLight,
110             SkBlendMode::kDifference,
111             SkBlendMode::kExclusion,
112             SkBlendMode::kMultiply,
113             SkBlendMode::kHue,
114             SkBlendMode::kSaturation,
115             SkBlendMode::kColor,
116             SkBlendMode::kLuminosity,
117         };
118 
119         SkColor gColors[] = {
120             SK_ColorWHITE,
121             SK_ColorRED,
122             0x88888888,         // transparent grey
123             0x88000088          // transparent blue
124         };
125 
126         const int numModes = std::size(gModes);
127         SkASSERT(numModes == kNumXferModes);
128         const int numColors = std::size(gColors);
129         SkASSERT(numColors == kNumColors);
130         SkRSXform xforms[numColors];
131         SkRect rects[numColors];
132         SkColor quadColors[numColors];
133 
134         SkPaint paint;
135         paint.setAntiAlias(true);
136 
137         for (int i = 0; i < numColors; ++i) {
138             xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad));
139             rects[i] = target;
140             quadColors[i] = gColors[i];
141         }
142 
143         SkFont font(ToolUtils::DefaultPortableTypeface(), kTextPad);
144 
145         for (int i = 0; i < numModes; ++i) {
146             const char* label = SkBlendMode_Name(gModes[i]);
147             canvas->drawString(label, i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad),
148                                font, paint);
149         }
150 
151         for (int i = 0; i < numModes; ++i) {
152             canvas->save();
153             canvas->translate(SkIntToScalar(i*(target.height()+kPad)),
154                               SkIntToScalar(kTextPad+kPad));
155             // w/o a paint
156             canvas->drawAtlas(atlas.get(), xforms, rects, quadColors, numColors,
157                               gModes[i], SkSamplingOptions(), nullptr, nullptr);
158             canvas->translate(0.0f, numColors*(target.height()+kPad));
159             // w a paint
160             canvas->drawAtlas(atlas.get(), xforms, rects, quadColors, numColors,
161                               gModes[i], SkSamplingOptions(), nullptr, &paint);
162             canvas->restore();
163         }
164     }
165 
166 private:
167     inline static constexpr int kNumXferModes = 29;
168     inline static constexpr int kNumColors = 4;
169     inline static constexpr int kAtlasSize = 30;
170     inline static constexpr int kPad = 2;
171     inline static constexpr int kTextPad = 8;
172 
173     using INHERITED = GM;
174 };
175 DEF_GM( return new DrawAtlasColorsGM; )
176