Home | History | Annotate | Download | only in gm
      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 
     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:
     40     LcdBlendGM() {
     41         const int kPointSize = 25;
     42         fTextHeight = SkIntToScalar(kPointSize);
     43     }
     44 
     45 protected:
     46     SkString onShortName() override {
     47         return SkString("lcdblendmodes");
     48     }
     49 
     50     void onOnceBeforeDraw() override {
     51         fCheckerboard.reset(sk_tool_utils::create_checkerboard_shader(SK_ColorBLACK,
     52                                                                       SK_ColorWHITE,
     53                                                                       4));
     54     }
     55 
     56     SkISize onISize() override { return SkISize::Make(kWidth, kHeight); }
     57 
     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 
     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