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(canvas->makeSurface(info));
66 if (nullptr == surface) {
67 surface = SkSurface::MakeRaster(info);
68 }
69
70 SkCanvas* surfCanvas = surface->getCanvas();
71 this->drawColumn(surfCanvas, SK_ColorBLACK, SK_ColorWHITE, false);
72 surfCanvas->translate(SkIntToScalar(kColWidth), 0);
73 this->drawColumn(surfCanvas, SK_ColorWHITE, SK_ColorBLACK, false);
74 surfCanvas->translate(SkIntToScalar(kColWidth), 0);
75 this->drawColumn(surfCanvas, SK_ColorGREEN, SK_ColorMAGENTA, false);
76 surfCanvas->translate(SkIntToScalar(kColWidth), 0);
77 this->drawColumn(surfCanvas, SK_ColorCYAN, SK_ColorMAGENTA, true);
78
79 SkPaint surfPaint;
80 surfPaint.setBlendMode(SkBlendMode::kSrcOver);
81 surface->draw(canvas, 0, 0, &surfPaint);
82 }
83
drawColumn(SkCanvas * canvas,SkColor backgroundColor,SkColor textColor,bool useGrad)84 void drawColumn(SkCanvas* canvas, SkColor backgroundColor, SkColor textColor, bool useGrad) {
85 const SkBlendMode gModes[] = {
86 SkBlendMode::kClear,
87 SkBlendMode::kSrc,
88 SkBlendMode::kDst,
89 SkBlendMode::kSrcOver,
90 SkBlendMode::kDstOver,
91 SkBlendMode::kSrcIn,
92 SkBlendMode::kDstIn,
93 SkBlendMode::kSrcOut,
94 SkBlendMode::kDstOut,
95 SkBlendMode::kSrcATop,
96 SkBlendMode::kDstATop,
97 SkBlendMode::kXor,
98 SkBlendMode::kPlus,
99 SkBlendMode::kModulate,
100 SkBlendMode::kScreen,
101 SkBlendMode::kOverlay,
102 SkBlendMode::kDarken,
103 SkBlendMode::kLighten,
104 SkBlendMode::kColorDodge,
105 SkBlendMode::kColorBurn,
106 SkBlendMode::kHardLight,
107 SkBlendMode::kSoftLight,
108 SkBlendMode::kDifference,
109 SkBlendMode::kExclusion,
110 SkBlendMode::kMultiply,
111 SkBlendMode::kHue,
112 SkBlendMode::kSaturation,
113 SkBlendMode::kColor,
114 SkBlendMode::kLuminosity,
115 };
116 // Draw background rect
117 SkPaint backgroundPaint;
118 backgroundPaint.setColor(backgroundColor);
119 canvas->drawRect(SkRect::MakeIWH(kColWidth, kHeight), backgroundPaint);
120 SkScalar y = fTextHeight;
121 for (size_t m = 0; m < SK_ARRAY_COUNT(gModes); m++) {
122 SkPaint paint;
123 paint.setColor(textColor);
124 paint.setAntiAlias(true);
125 paint.setSubpixelText(true);
126 paint.setLCDRenderText(true);
127 paint.setTextSize(fTextHeight);
128 paint.setBlendMode(gModes[m]);
129 sk_tool_utils::set_portable_typeface(&paint);
130 if (useGrad) {
131 SkRect r;
132 r.setXYWH(0, y - fTextHeight, SkIntToScalar(kColWidth), fTextHeight);
133 paint.setShader(make_shader(r));
134 }
135 SkString string(SkBlendMode_Name(gModes[m]));
136 canvas->drawString(string, 0, y, paint);
137 y+=fTextHeight;
138 }
139 }
140
141 private:
142 SkScalar fTextHeight;
143 sk_sp<SkShader> fCheckerboard;
144 typedef skiagm::GM INHERITED;
145 };
146
147 //////////////////////////////////////////////////////////////////////////////
148
149 DEF_GM( return new LcdBlendGM; )
150 }
151