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(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 
     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.setAntiAlias(true);
    122             paint.setSubpixelText(true);
    123             paint.setLCDRenderText(true);
    124             paint.setTextSize(fTextHeight);
    125             paint.setBlendMode(gModes[m]);
    126             sk_tool_utils::set_portable_typeface(&paint);
    127             if (useGrad) {
    128                 SkRect r;
    129                 r.setXYWH(0, y - fTextHeight, SkIntToScalar(kColWidth), fTextHeight);
    130                 paint.setShader(make_shader(r));
    131             }
    132             SkString string(SkBlendMode_Name(gModes[m]));
    133             canvas->drawString(string, 0, y, paint);
    134             y+=fTextHeight;
    135         }
    136     }
    137 
    138 private:
    139     SkScalar fTextHeight;
    140     sk_sp<SkShader> fCheckerboard;
    141     typedef skiagm::GM INHERITED;
    142 };
    143 
    144 //////////////////////////////////////////////////////////////////////////////
    145 
    146 DEF_GM( return new LcdBlendGM; )
    147 }
    148