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