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/SkImageInfo.h" 14#include "include/core/SkPaint.h" 15#include "include/core/SkPoint.h" 16#include "include/core/SkRect.h" 17#include "include/core/SkRefCnt.h" 18#include "include/core/SkScalar.h" 19#include "include/core/SkShader.h" 20#include "include/core/SkSize.h" 21#include "include/core/SkString.h" 22#include "include/core/SkSurface.h" 23#include "include/core/SkTileMode.h" 24#include "include/core/SkTypeface.h" 25#include "include/core/SkTypes.h" 26#include "include/effects/SkGradientShader.h" 27#include "tools/ToolUtils.h" 28 29namespace skiagm { 30 31constexpr int kColWidth = 180; 32constexpr int kNumCols = 4; 33constexpr int kWidth = kColWidth * kNumCols; 34constexpr int kHeight = 750; 35 36static sk_sp<SkShader> make_shader(const SkRect& bounds) { 37 const SkPoint pts[] = { 38 { bounds.left(), bounds.top() }, 39 { bounds.right(), bounds.bottom() }, 40 }; 41 const SkColor colors[] = { 42 SK_ColorRED, SK_ColorGREEN, 43 }; 44 return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors), 45 SkTileMode::kRepeat); 46} 47 48class LcdBlendGM : public skiagm::GM { 49public: 50 LcdBlendGM() { 51 const int kPointSize = 25; 52 fTextHeight = SkIntToScalar(kPointSize); 53 } 54 55protected: 56 SkString onShortName() override { 57 return SkString("lcdblendmodes"); 58 } 59 60 void onOnceBeforeDraw() override { 61 fCheckerboard = ToolUtils::create_checkerboard_shader(SK_ColorBLACK, SK_ColorWHITE, 4); 62 } 63 64 SkISize onISize() override { return SkISize::Make(kWidth, kHeight); } 65 66 void onDraw(SkCanvas* canvas) override { 67 SkPaint p; 68 p.setAntiAlias(false); 69 p.setStyle(SkPaint::kFill_Style); 70 p.setShader(fCheckerboard); 71 SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); 72 canvas->drawRect(r, p); 73 74 SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight); 75 SkSurfaceProps props = SkSurfaceProps(0, kRGB_H_SkPixelGeometry); 76 auto surface(ToolUtils::makeSurface(canvas, info, &props)); 77 78 SkCanvas* surfCanvas = surface->getCanvas(); 79 this->drawColumn(surfCanvas, SK_ColorBLACK, SK_ColorWHITE, false); 80 surfCanvas->translate(SkIntToScalar(kColWidth), 0); 81 this->drawColumn(surfCanvas, SK_ColorWHITE, SK_ColorBLACK, false); 82 surfCanvas->translate(SkIntToScalar(kColWidth), 0); 83 this->drawColumn(surfCanvas, SK_ColorGREEN, SK_ColorMAGENTA, false); 84 surfCanvas->translate(SkIntToScalar(kColWidth), 0); 85 this->drawColumn(surfCanvas, SK_ColorCYAN, SK_ColorMAGENTA, true); 86 87 SkPaint surfPaint; 88 surfPaint.setBlendMode(SkBlendMode::kSrcOver); 89 surface->draw(canvas, 0, 0, SkSamplingOptions(), &surfPaint); 90 } 91 92 void drawColumn(SkCanvas* canvas, SkColor backgroundColor, SkColor textColor, bool useGrad) { 93 const SkBlendMode gModes[] = { 94 SkBlendMode::kClear, 95 SkBlendMode::kSrc, 96 SkBlendMode::kDst, 97 SkBlendMode::kSrcOver, 98 SkBlendMode::kDstOver, 99 SkBlendMode::kSrcIn, 100 SkBlendMode::kDstIn, 101 SkBlendMode::kSrcOut, 102 SkBlendMode::kDstOut, 103 SkBlendMode::kSrcATop, 104 SkBlendMode::kDstATop, 105 SkBlendMode::kXor, 106 SkBlendMode::kPlus, 107 SkBlendMode::kModulate, 108 SkBlendMode::kScreen, 109 SkBlendMode::kOverlay, 110 SkBlendMode::kDarken, 111 SkBlendMode::kLighten, 112 SkBlendMode::kColorDodge, 113 SkBlendMode::kColorBurn, 114 SkBlendMode::kHardLight, 115 SkBlendMode::kSoftLight, 116 SkBlendMode::kDifference, 117 SkBlendMode::kExclusion, 118 SkBlendMode::kMultiply, 119 SkBlendMode::kHue, 120 SkBlendMode::kSaturation, 121 SkBlendMode::kColor, 122 SkBlendMode::kLuminosity, 123 }; 124 // Draw background rect 125 SkPaint backgroundPaint; 126 backgroundPaint.setColor(backgroundColor); 127 canvas->drawRect(SkRect::MakeIWH(kColWidth, kHeight), backgroundPaint); 128 SkScalar y = fTextHeight; 129 for (size_t m = 0; m < SK_ARRAY_COUNT(gModes); m++) { 130 SkPaint paint; 131 paint.setColor(textColor); 132 paint.setBlendMode(gModes[m]); 133 SkFont font(ToolUtils::create_portable_typeface(), fTextHeight); 134 font.setSubpixel(true); 135 font.setEdging(SkFont::Edging::kSubpixelAntiAlias); 136 if (useGrad) { 137 SkRect r; 138 r.setXYWH(0, y - fTextHeight, SkIntToScalar(kColWidth), fTextHeight); 139 paint.setShader(make_shader(r)); 140 } 141 SkString string(SkBlendMode_Name(gModes[m])); 142 canvas->drawString(string, 0, y, font, paint); 143 y+=fTextHeight; 144 } 145 } 146 147private: 148 SkScalar fTextHeight; 149 sk_sp<SkShader> fCheckerboard; 150 using INHERITED = skiagm::GM; 151}; 152 153////////////////////////////////////////////////////////////////////////////// 154 155DEF_GM( return new LcdBlendGM; ) 156} // namespace skiagm 157