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 "SkCanvas.h"
10 #include "SkRSXform.h"
11 #include "SkSurface.h"
12
13 // Create a square atlas of:
14 // opaque white | opaque red
15 // ------------------------------------
16 // opaque green | transparent black
17 //
make_atlas(SkCanvas * caller,int atlasSize)18 static SkImage* make_atlas(SkCanvas* caller, int atlasSize) {
19 const int kBlockSize = atlasSize/2;
20
21 SkImageInfo info = SkImageInfo::MakeN32Premul(atlasSize, atlasSize);
22 SkAutoTUnref<SkSurface> surface(caller->newSurface(info));
23 if (nullptr == surface) {
24 surface.reset(SkSurface::NewRaster(info));
25 }
26 SkCanvas* canvas = surface->getCanvas();
27
28 SkPaint paint;
29 paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode));
30
31 paint.setColor(SK_ColorWHITE);
32 SkRect r = SkRect::MakeXYWH(0, 0,
33 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
34 canvas->drawRect(r, paint);
35
36 paint.setColor(SK_ColorRED);
37 r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), 0,
38 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
39 canvas->drawRect(r, paint);
40
41 paint.setColor(SK_ColorGREEN);
42 r = SkRect::MakeXYWH(0, SkIntToScalar(kBlockSize),
43 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
44 canvas->drawRect(r, paint);
45
46 paint.setColor(SK_ColorTRANSPARENT);
47 r = SkRect::MakeXYWH(SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize),
48 SkIntToScalar(kBlockSize), SkIntToScalar(kBlockSize));
49 canvas->drawRect(r, paint);
50
51 return surface->newImageSnapshot();
52 }
53
54 // This GM tests the drawAtlas API with colors, different xfer modes
55 // and transparency in the atlas image
56 class DrawAtlasColorsGM : public skiagm::GM {
57 public:
DrawAtlasColorsGM()58 DrawAtlasColorsGM() {
59 this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC));
60 }
61
62 protected:
onShortName()63 SkString onShortName() override {
64 return SkString("draw-atlas-colors");
65 }
66
onISize()67 SkISize onISize() override {
68 return SkISize::Make(kNumXferModes * (kAtlasSize + kPad) + kPad,
69 2 * kNumColors * (kAtlasSize + kPad) + kTextPad + kPad);
70 }
71
onDraw(SkCanvas * canvas)72 void onDraw(SkCanvas* canvas) override {
73 const SkRect target = SkRect::MakeWH(SkIntToScalar(kAtlasSize), SkIntToScalar(kAtlasSize));
74
75 if (nullptr == fAtlas) {
76 fAtlas.reset(make_atlas(canvas, kAtlasSize));
77 }
78
79 const struct {
80 SkXfermode::Mode fMode;
81 const char* fLabel;
82 } gModes[] = {
83 { SkXfermode::kClear_Mode, "Clear" },
84 { SkXfermode::kSrc_Mode, "Src" },
85 { SkXfermode::kDst_Mode, "Dst" },
86 { SkXfermode::kSrcOver_Mode, "SrcOver" },
87 { SkXfermode::kDstOver_Mode, "DstOver" },
88 { SkXfermode::kSrcIn_Mode, "SrcIn" },
89 { SkXfermode::kDstIn_Mode, "DstIn" },
90 { SkXfermode::kSrcOut_Mode, "SrcOut" },
91 { SkXfermode::kDstOut_Mode, "DstOut" },
92 { SkXfermode::kSrcATop_Mode, "SrcATop" },
93 { SkXfermode::kDstATop_Mode, "DstATop" },
94 { SkXfermode::kXor_Mode, "Xor" },
95 { SkXfermode::kPlus_Mode, "Plus" },
96 { SkXfermode::kModulate_Mode, "Mod" },
97 { SkXfermode::kScreen_Mode, "Screen" },
98 { SkXfermode::kOverlay_Mode, "Overlay" },
99 { SkXfermode::kDarken_Mode, "Darken" },
100 { SkXfermode::kLighten_Mode, "Lighten" },
101 { SkXfermode::kColorDodge_Mode, "Dodge" },
102 { SkXfermode::kColorBurn_Mode, "Burn" },
103 { SkXfermode::kHardLight_Mode, "Hard" },
104 { SkXfermode::kSoftLight_Mode, "Soft" },
105 { SkXfermode::kDifference_Mode, "Diff" },
106 { SkXfermode::kExclusion_Mode, "Exclusion" },
107 { SkXfermode::kMultiply_Mode, "Multiply" },
108 { SkXfermode::kHue_Mode, "Hue" },
109 { SkXfermode::kSaturation_Mode, "Sat" },
110 { SkXfermode::kColor_Mode, "Color" },
111 { SkXfermode::kLuminosity_Mode, "Luminosity"},
112 };
113
114 SkColor gColors[] = {
115 SK_ColorWHITE,
116 SK_ColorRED,
117 0x88888888, // transparent grey
118 0x88000088 // transparent blue
119 };
120
121 const int numModes = SK_ARRAY_COUNT(gModes);
122 SkASSERT(numModes == kNumXferModes);
123 const int numColors = SK_ARRAY_COUNT(gColors);
124 SkASSERT(numColors == kNumColors);
125 SkRSXform xforms[numColors];
126 SkRect rects[numColors];
127 SkColor quadColors[numColors];
128
129 SkPaint paint;
130 paint.setAntiAlias(true);
131
132 for (int i = 0; i < numColors; ++i) {
133 xforms[i].set(1.0f, 0.0f, SkIntToScalar(kPad), i*(target.width()+kPad));
134 rects[i] = target;
135 quadColors[i] = gColors[i];
136 }
137
138 SkPaint textP;
139 textP.setTextSize(SkIntToScalar(kTextPad));
140 textP.setAntiAlias(true);
141 sk_tool_utils::set_portable_typeface(&textP, nullptr);
142
143 for (int i = 0; i < numModes; ++i) {
144 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
145 i*(target.width()+kPad)+kPad, SkIntToScalar(kTextPad),
146 textP);
147 }
148
149 for (int i = 0; i < numModes; ++i) {
150 canvas->save();
151 canvas->translate(SkIntToScalar(i*(target.height()+kPad)),
152 SkIntToScalar(kTextPad+kPad));
153 // w/o a paint
154 canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors,
155 gModes[i].fMode, nullptr, nullptr);
156 canvas->translate(0.0f, numColors*(target.height()+kPad));
157 // w a paint
158 canvas->drawAtlas(fAtlas, xforms, rects, quadColors, numColors,
159 gModes[i].fMode, nullptr, &paint);
160 canvas->restore();
161 }
162 }
163
164 private:
165 static const int kNumXferModes = 29;
166 static const int kNumColors = 4;
167 static const int kAtlasSize = 30;
168 static const int kPad = 2;
169 static const int kTextPad = 8;
170
171
172 SkAutoTUnref<SkImage> fAtlas;
173
174 typedef GM INHERITED;
175 };
176 DEF_GM( return new DrawAtlasColorsGM; )
177
178