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 "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 
     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:
     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 = sk_tool_utils::create_checkerboard_shader(SK_ColorBLACK, SK_ColorWHITE, 4);
     52     }
     53 
     54     SkISize onISize() override { return SkISize::Make(kWidth, kHeight); }
     55 
     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 
     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->drawText(string.c_str(), string.size(), 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