1 /*
2  * Copyright 2014 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/SkFontStyle.h"
15 #include "include/core/SkFontTypes.h"
16 #include "include/core/SkImageInfo.h"
17 #include "include/core/SkMatrix.h"
18 #include "include/core/SkPaint.h"
19 #include "include/core/SkRect.h"
20 #include "include/core/SkRefCnt.h"
21 #include "include/core/SkScalar.h"
22 #include "include/core/SkShader.h"
23 #include "include/core/SkSize.h"
24 #include "include/core/SkString.h"
25 #include "include/core/SkTileMode.h"
26 #include "include/core/SkTypeface.h"
27 #include "include/core/SkTypes.h"
28 #include "include/effects/SkGradientShader.h"
29 #include "include/utils/SkTextUtils.h"
30 #include "src/utils/SkUTF.h"
31 #include "tools/ToolUtils.h"
32 
33 #include <string.h>
34 
35 namespace {
36 
37 static uint16_t gData[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
38 
39 class ColorEmojiBlendModesGM : public skiagm::GM {
40 public:
41     const static int W = 64;
42     const static int H = 64;
ColorEmojiBlendModesGM()43     ColorEmojiBlendModesGM() {}
44 
45 protected:
onOnceBeforeDraw()46     void onOnceBeforeDraw() override {
47         const SkColor colors[] = {
48             SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
49             SK_ColorMAGENTA, SK_ColorCYAN, SK_ColorYELLOW
50         };
51         SkMatrix local;
52         local.setRotate(180);
53         SkPaint paint;
54         paint.setAntiAlias(true);
55         paint.setShader(SkGradientShader::MakeSweep(0, 0, colors, nullptr, SK_ARRAY_COUNT(colors),
56                                                     0, &local));
57 
58         sk_sp<SkTypeface> orig(ToolUtils::create_portable_typeface("serif", SkFontStyle::Bold()));
59         if (nullptr == orig) {
60             orig = SkTypeface::MakeDefault();
61         }
62         fColorType = ToolUtils::emoji_typeface();
63 
64         fBG.installPixels(SkImageInfo::Make(2, 2, kARGB_4444_SkColorType,
65                                             kOpaque_SkAlphaType), gData, 4);
66     }
67 
onShortName()68     SkString onShortName() override {
69         return SkString("coloremoji_blendmodes");
70     }
71 
onISize()72     SkISize onISize() override {
73         return {400, 640};
74     }
75 
onDraw(SkCanvas * canvas)76     void onDraw(SkCanvas* canvas) override {
77         canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
78 
79         const SkBlendMode gModes[] = {
80             SkBlendMode::kClear,
81             SkBlendMode::kSrc,
82             SkBlendMode::kDst,
83             SkBlendMode::kSrcOver,
84             SkBlendMode::kDstOver,
85             SkBlendMode::kSrcIn,
86             SkBlendMode::kDstIn,
87             SkBlendMode::kSrcOut,
88             SkBlendMode::kDstOut,
89             SkBlendMode::kSrcATop,
90             SkBlendMode::kDstATop,
91 
92             SkBlendMode::kXor,
93             SkBlendMode::kPlus,
94             SkBlendMode::kModulate,
95             SkBlendMode::kScreen,
96             SkBlendMode::kOverlay,
97             SkBlendMode::kDarken,
98             SkBlendMode::kLighten,
99             SkBlendMode::kColorDodge,
100             SkBlendMode::kColorBurn,
101             SkBlendMode::kHardLight,
102             SkBlendMode::kSoftLight,
103             SkBlendMode::kDifference,
104             SkBlendMode::kExclusion,
105             SkBlendMode::kMultiply,
106             SkBlendMode::kHue,
107             SkBlendMode::kSaturation,
108             SkBlendMode::kColor,
109             SkBlendMode::kLuminosity,
110         };
111 
112         const SkScalar w = SkIntToScalar(W);
113         const SkScalar h = SkIntToScalar(H);
114         SkMatrix m;
115         m.setScale(SkIntToScalar(6), SkIntToScalar(6));
116         auto s = fBG.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, &m);
117 
118         SkFont labelFont(ToolUtils::create_portable_typeface());
119 
120         SkPaint textP;
121         textP.setAntiAlias(true);
122         SkFont textFont(fColorType, 70);
123 
124         const int W = 5;
125 
126         SkScalar x0 = 0;
127         SkScalar y0 = 0;
128         SkScalar x = x0, y = y0;
129         for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
130             SkRect r;
131             r.setLTRB(x, y, x+w, y+h);
132 
133             SkPaint p;
134             p.setStyle(SkPaint::kFill_Style);
135             p.setShader(s);
136             canvas->drawRect(r, p);
137 
138             r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
139             p.setStyle(SkPaint::kStroke_Style);
140             p.setShader(nullptr);
141             canvas->drawRect(r, p);
142 
143             {
144                 SkAutoCanvasRestore arc(canvas, true);
145                 canvas->clipRect(r);
146                 textP.setBlendMode(gModes[i]);
147                 const char* text    = ToolUtils::emoji_sample_text();
148                 SkUnichar unichar = SkUTF::NextUTF8(&text, text + strlen(text));
149                 SkASSERT(unichar >= 0);
150                 canvas->drawSimpleText(&unichar, 4, SkTextEncoding::kUTF32,
151                                        x+ w/10.f, y + 7.f*h/8.f, textFont, textP);
152             }
153 #if 1
154             const char* label = SkBlendMode_Name(gModes[i]);
155             SkTextUtils::DrawString(canvas, label, x + w/2, y - labelFont.getSize()/2,
156                                     labelFont, SkPaint(), SkTextUtils::kCenter_Align);
157 #endif
158             x += w + SkIntToScalar(10);
159             if ((i % W) == W - 1) {
160                 x = x0;
161                 y += h + SkIntToScalar(30);
162             }
163         }
164     }
165 
166 private:
167     SkBitmap            fBG;
168     sk_sp<SkTypeface>   fColorType;
169 
170     using INHERITED = GM;
171 };
172 }  // namespace
173 
174 DEF_GM( return new ColorEmojiBlendModesGM; )
175