1/*
2 * Copyright 2017 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#include "gm.h"
9#include "sk_tool_utils.h"
10#include "SkCanvas.h"
11#include "SkGradientShader.h"
12#include "SkHighContrastFilter.h"
13
14using InvertStyle = SkHighContrastConfig::InvertStyle;
15
16static SkScalar kSize   = 200;
17static SkColor  kColor1 = SkColorSetARGB(0xff, 0xff, 0xff, 0);
18static SkColor  kColor2 = SkColorSetARGB(0xff, 0x82, 0xff, 0);
19
20static void draw_label(SkCanvas* canvas, const SkHighContrastConfig& config) {
21    char labelBuffer[256];
22    const char* invertStr =
23        (config.fInvertStyle == InvertStyle::kInvertBrightness ?
24             "InvBrightness" :
25            (config.fInvertStyle == InvertStyle::kInvertLightness ?
26                 "InvLightness" : "NoInvert"));
27
28    snprintf(labelBuffer, sizeof(labelBuffer), "%s%s contrast=%.1f",
29             config.fGrayscale ? "Gray " : "",
30             invertStr,
31             config.fContrast);
32
33    SkPaint paint;
34    sk_tool_utils::set_portable_typeface(&paint);
35    paint.setTextSize(0.05f);
36    size_t len = strlen(labelBuffer);
37
38    SkScalar width = paint.measureText(labelBuffer, len);
39    canvas->drawText(labelBuffer, len, 0.5f - width / 2, 0.16f, paint);
40}
41
42static void draw_scene(SkCanvas* canvas, const SkHighContrastConfig& config) {
43    SkRect bounds = SkRect::MakeLTRB(0.0f, 0.0f, 1.0f, 1.0f);
44    SkPaint xferPaint;
45    xferPaint.setColorFilter(SkHighContrastFilter::Make(config));
46    canvas->saveLayer(&bounds, &xferPaint);
47
48    SkPaint paint;
49    bounds = SkRect::MakeLTRB(0.1f, 0.2f, 0.9f, 0.4f);
50    paint.setARGB(0xff, 0x66, 0x11, 0x11);
51    canvas->drawRect(bounds, paint);
52
53    paint.setARGB(0xff, 0xbb, 0x77, 0x77);
54    paint.setTextSize(0.15f);
55    canvas->drawString("A", 0.15f, 0.35f, paint);
56
57    bounds = SkRect::MakeLTRB(0.1f, 0.8f, 0.9f, 1.0f);
58    paint.setARGB(0xff, 0xcc, 0xcc, 0xff);
59    canvas->drawRect(bounds, paint);
60
61    paint.setARGB(0xff, 0x88, 0x88, 0xbb);
62    paint.setTextSize(0.15f);
63    canvas->drawString("Z", 0.75f, 0.95f, paint);
64
65    bounds = SkRect::MakeLTRB(0.1f, 0.4f, 0.9f, 0.6f);
66    SkPoint     pts[] = { { 0, 0 }, { 1, 0 } };
67    SkColor     colors[] = { SK_ColorWHITE, SK_ColorBLACK };
68    SkScalar    pos[] = { 0.2f, 0.8f };
69    paint.setShader(SkGradientShader::MakeLinear(
70        pts, colors, pos,
71        SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode));
72    canvas->drawRect(bounds, paint);
73
74    bounds = SkRect::MakeLTRB(0.1f, 0.6f, 0.9f, 0.8f);
75    SkColor colors2[] = { SK_ColorGREEN, SK_ColorWHITE };
76    paint.setShader(SkGradientShader::MakeLinear(
77        pts, colors2, pos,
78        SK_ARRAY_COUNT(colors2), SkShader::kClamp_TileMode));
79    canvas->drawRect(bounds, paint);
80
81    canvas->restore();
82}
83
84class HighContrastFilterGM : public skiagm::GM {
85public:
86    HighContrastFilterGM() {
87        SkColor  g1Colors[] = { kColor1, SkColorSetA(kColor1, 0x20) };
88        SkColor  g2Colors[] = { kColor2, SkColorSetA(kColor2, 0x20) };
89        SkPoint  g1Points[] = { { 0, 0 }, { 0,     100 } };
90        SkPoint  g2Points[] = { { 0, 0 }, { kSize, 0   } };
91        SkScalar pos[] = { 0.2f, 1.0f };
92
93        SkHighContrastConfig fConfig;
94        fFilter = SkHighContrastFilter::Make(fConfig);
95        fGr1 = SkGradientShader::MakeLinear(
96            g1Points, g1Colors, pos, SK_ARRAY_COUNT(g1Colors),
97            SkShader::kClamp_TileMode);
98        fGr2 = SkGradientShader::MakeLinear(
99            g2Points, g2Colors, pos, SK_ARRAY_COUNT(g2Colors),
100            SkShader::kClamp_TileMode);
101    }
102
103protected:
104
105    SkString onShortName() override {
106        return SkString("highcontrastfilter");
107    }
108
109    SkISize onISize() override {
110        return SkISize::Make(600, 420);
111    }
112
113    void onDraw(SkCanvas* canvas) override {
114        SkHighContrastConfig configs[] = {
115            { false, InvertStyle::kNoInvert, 0.0f },
116            { false, InvertStyle::kInvertBrightness, 0.0f },
117            { false, InvertStyle::kInvertLightness, 0.0f },
118            { false, InvertStyle::kInvertLightness, 0.2f },
119            { true, InvertStyle::kNoInvert, 0.0f },
120            { true, InvertStyle::kInvertBrightness, 0.0f },
121            { true, InvertStyle::kInvertLightness, 0.0f },
122            { true, InvertStyle::kInvertLightness, 0.2f },
123        };
124
125        for (size_t i = 0; i < SK_ARRAY_COUNT(configs); ++i) {
126            SkScalar x = kSize * (i % 4);
127            SkScalar y = kSize * (i / 4);
128            canvas->save();
129            canvas->translate(x, y);
130            canvas->scale(kSize, kSize);
131            draw_scene(canvas, configs[i]);
132            draw_label(canvas, configs[i]);
133            canvas->restore();
134        }
135    }
136
137private:
138    sk_sp<SkColorFilter>    fFilter;
139    sk_sp<SkShader>         fGr1, fGr2;
140
141    typedef skiagm::GM INHERITED;
142};
143
144DEF_GM(return new HighContrastFilterGM;)
145