• 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(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