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