• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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