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/base/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, std::size(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, SkSamplingOptions(), 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 kWrap = 5; 125 126 SkScalar x0 = 0; 127 SkScalar y0 = 0; 128 SkScalar x = x0, y = y0; 129 for (size_t i = 0; i < std::size(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 % kWrap) == kWrap - 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