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 "SkCanvas.h"
15 #include "SkGradientShader.h"
16 #include "SkSurface.h"
17 
18 namespace skiagm {
19 
20 static const int kColWidth = 180;
21 static const int kNumCols = 4;
22 static const int kWidth = kColWidth * kNumCols;
23 static const int kHeight = 750;
24 
make_shader(const SkRect & bounds)25 static SkShader* make_shader(const SkRect& bounds) {
26     const SkPoint pts[] = {
27         { bounds.left(), bounds.top() },
28         { bounds.right(), bounds.bottom() },
29     };
30     const SkColor colors[] = {
31         SK_ColorRED, SK_ColorGREEN,
32     };
33     return SkGradientShader::CreateLinear(pts,
34                                           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.reset(sk_tool_utils::create_checkerboard_shader(SK_ColorBLACK,
52                                                                       SK_ColorWHITE,
53                                                                       4));
54     }
55 
onISize()56     SkISize onISize() override { return SkISize::Make(kWidth, kHeight); }
57 
onDraw(SkCanvas * canvas)58     void onDraw(SkCanvas* canvas) override {
59         SkPaint p;
60         p.setAntiAlias(false);
61         p.setStyle(SkPaint::kFill_Style);
62         p.setShader(fCheckerboard);
63         SkRect r = SkRect::MakeWH(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
64         canvas->drawRect(r, p);
65 
66         SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
67         SkAutoTUnref<SkSurface> surface(canvas->newSurface(info));
68         if (nullptr == surface) {
69             surface.reset(SkSurface::NewRaster(info));
70         }
71 
72         SkCanvas* surfCanvas = surface->getCanvas();
73         this->drawColumn(surfCanvas, SK_ColorBLACK, SK_ColorWHITE, false);
74         surfCanvas->translate(SkIntToScalar(kColWidth), 0);
75         this->drawColumn(surfCanvas, SK_ColorWHITE, SK_ColorBLACK, false);
76         surfCanvas->translate(SkIntToScalar(kColWidth), 0);
77         this->drawColumn(surfCanvas, SK_ColorGREEN, SK_ColorMAGENTA, false);
78         surfCanvas->translate(SkIntToScalar(kColWidth), 0);
79         this->drawColumn(surfCanvas, SK_ColorCYAN, SK_ColorMAGENTA, true);
80 
81         SkPaint surfPaint;
82         SkAutoTUnref<SkXfermode> xfermode(SkXfermode::Create(SkXfermode::kSrcOver_Mode));
83         surfPaint.setXfermode(xfermode);
84         surface->draw(canvas, 0, 0, &surfPaint);
85     }
86 
drawColumn(SkCanvas * canvas,SkColor backgroundColor,SkColor textColor,bool useGrad)87     void drawColumn(SkCanvas* canvas, SkColor backgroundColor, SkColor textColor, bool useGrad) {
88         const struct {
89             SkXfermode::Mode  fMode;
90             const char*       fLabel;
91         } gModes[] = {
92             { SkXfermode::kClear_Mode,        "Clear"       },
93             { SkXfermode::kSrc_Mode,          "Src"         },
94             { SkXfermode::kDst_Mode,          "Dst"         },
95             { SkXfermode::kSrcOver_Mode,      "SrcOver"     },
96             { SkXfermode::kDstOver_Mode,      "DstOver"     },
97             { SkXfermode::kSrcIn_Mode,        "SrcIn"       },
98             { SkXfermode::kDstIn_Mode,        "DstIn"       },
99             { SkXfermode::kSrcOut_Mode,       "SrcOut"      },
100             { SkXfermode::kDstOut_Mode,       "DstOut"      },
101             { SkXfermode::kSrcATop_Mode,      "SrcATop"     },
102             { SkXfermode::kDstATop_Mode,      "DstATop"     },
103             { SkXfermode::kXor_Mode,          "Xor"         },
104             { SkXfermode::kPlus_Mode,         "Plus"        },
105             { SkXfermode::kModulate_Mode,     "Modulate"    },
106             { SkXfermode::kScreen_Mode,       "Screen"      },
107             { SkXfermode::kOverlay_Mode,      "Overlay"     },
108             { SkXfermode::kDarken_Mode,       "Darken"      },
109             { SkXfermode::kLighten_Mode,      "Lighten"     },
110             { SkXfermode::kColorDodge_Mode,   "ColorDodge"  },
111             { SkXfermode::kColorBurn_Mode,    "ColorBurn"   },
112             { SkXfermode::kHardLight_Mode,    "HardLight"   },
113             { SkXfermode::kSoftLight_Mode,    "SoftLight"   },
114             { SkXfermode::kDifference_Mode,   "Difference"  },
115             { SkXfermode::kExclusion_Mode,    "Exclusion"   },
116             { SkXfermode::kMultiply_Mode,     "Multiply"    },
117             { SkXfermode::kHue_Mode,          "Hue"         },
118             { SkXfermode::kSaturation_Mode,   "Saturation"  },
119             { SkXfermode::kColor_Mode,        "Color"       },
120             { SkXfermode::kLuminosity_Mode,   "Luminosity"  },
121         };
122         // Draw background rect
123         SkPaint backgroundPaint;
124         backgroundPaint.setColor(backgroundColor);
125         canvas->drawRectCoords(0, 0, SkIntToScalar(kColWidth), SkIntToScalar(kHeight),
126                                backgroundPaint);
127         SkScalar y = fTextHeight;
128         for (size_t m = 0; m < SK_ARRAY_COUNT(gModes); m++) {
129             SkAutoTUnref<SkXfermode> xfermode(SkXfermode::Create(gModes[m].fMode));
130             SkPaint paint;
131             paint.setColor(textColor);
132             paint.setAntiAlias(true);
133             paint.setSubpixelText(true);
134             paint.setLCDRenderText(true);
135             paint.setTextSize(fTextHeight);
136             paint.setXfermode(xfermode);
137             sk_tool_utils::set_portable_typeface(&paint);
138             if (useGrad) {
139                 SkRect r;
140                 r.setXYWH(0, y - fTextHeight, SkIntToScalar(kColWidth), fTextHeight);
141                 paint.setShader(make_shader(r))->unref();
142             }
143             SkString string(gModes[m].fLabel);
144             canvas->drawText(gModes[m].fLabel, string.size(), 0, y, paint);
145             y+=fTextHeight;
146         }
147     }
148 
149 private:
150     SkScalar fTextHeight;
151     SkAutoTUnref<SkShader> fCheckerboard;
152     typedef skiagm::GM INHERITED;
153 };
154 
155 //////////////////////////////////////////////////////////////////////////////
156 
157 DEF_GM( return new LcdBlendGM; )
158 }
159