Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
mixercolorfilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2019 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/gm.h"
16#include "include/core/SkRect.h"
20#include "include/core/SkSize.h"
26#include "tools/Resources.h"
27
28#include <math.h>
29
30// A tint filter maps colors to a given range (gradient), based on the input luminance:
31//
32// c' = lerp(lo, hi, luma(c))
33//
34// TODO: move to public headers/API?
35//
37 const auto r_lo = SkColorGetR(lo),
38 g_lo = SkColorGetG(lo),
39 b_lo = SkColorGetB(lo),
40 a_lo = SkColorGetA(lo),
41 r_hi = SkColorGetR(hi),
42 g_hi = SkColorGetG(hi),
43 b_hi = SkColorGetB(hi),
44 a_hi = SkColorGetA(hi);
45
46 // We map component-wise:
47 //
48 // r' = lo.r + (hi.r - lo.r) * luma
49 // g' = lo.g + (hi.g - lo.g) * luma
50 // b' = lo.b + (hi.b - lo.b) * luma
51 // a' = lo.a + (hi.a - lo.a) * luma
52 //
53 // The input luminance is stored in the alpha channel
54 // (and RGB are cleared -- see SkLumaColorFilter). Thus:
55 const float tint_matrix[] = {
56 0, 0, 0, (r_hi - r_lo) / 255.0f, SkIntToScalar(r_lo) / 255.0f,
57 0, 0, 0, (g_hi - g_lo) / 255.0f, SkIntToScalar(g_lo) / 255.0f,
58 0, 0, 0, (b_hi - b_lo) / 255.0f, SkIntToScalar(b_lo) / 255.0f,
59 0, 0, 0, (a_hi - a_lo) / 255.0f, SkIntToScalar(a_lo) / 255.0f,
60 };
61
63}
64
65namespace {
66
67class MixerCFGM final : public skiagm::GM {
68public:
69 MixerCFGM(const SkSize& tileSize, size_t tileCount)
70 : fTileSize(tileSize)
71 , fTileCount(tileCount) {}
72
73protected:
74 SkString getName() const override { return SkString("mixerCF"); }
75
76 SkISize getISize() override {
77 return SkISize::Make(fTileSize.width() * 1.2f * fTileCount,
78 fTileSize.height() * 1.2f * 3); // 3 rows
79 }
80
81 void onDraw(SkCanvas* canvas) override {
83
84 const SkColor gradient_colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
85 paint.setShader(SkGradientShader::MakeSweep(fTileSize.width() / 2,
86 fTileSize.height() / 2,
87 gradient_colors, nullptr,
88 std::size(gradient_colors)));
89
90 auto cf0 = MakeTintColorFilter(0xff300000, 0xffa00000); // red tint
91 auto cf1 = MakeTintColorFilter(0xff003000, 0xff00a000); // green tint
92
93 this->mixRow(canvas, paint, nullptr, cf1);
94 this->mixRow(canvas, paint, cf0, nullptr);
95 this->mixRow(canvas, paint, cf0, cf1);
96 }
97
98private:
99 const SkSize fTileSize;
100 const size_t fTileCount;
101
102 void mixRow(SkCanvas* canvas, SkPaint& paint,
104 // We cycle through paint colors on each row, to test how the paint color flows through
105 // the color-filter network
106 const SkColor4f paintColors[] = {
107 { 1.0f, 1.0f, 1.0f, 1.0f }, // Opaque white
108 { 1.0f, 1.0f, 1.0f, 0.5f }, // Translucent white
109 { 0.5f, 0.5f, 1.0f, 1.0f }, // Opaque pale blue
110 { 0.5f, 0.5f, 1.0f, 0.5f }, // Translucent pale blue
111 };
112
113 canvas->translate(0, fTileSize.height() * 0.1f);
114 {
115 SkAutoCanvasRestore arc(canvas, true);
116 for (size_t i = 0; i < fTileCount; ++i) {
117 paint.setColor4f(paintColors[i % std::size(paintColors)]);
118 float t = static_cast<float>(i) / (fTileCount - 1);
119 paint.setColorFilter(SkColorFilters::Lerp(t, cf0, cf1));
120 canvas->translate(fTileSize.width() * 0.1f, 0);
121 canvas->drawRect(SkRect::MakeWH(fTileSize.width(), fTileSize.height()), paint);
122 canvas->translate(fTileSize.width() * 1.1f, 0);
123 }
124 }
125 canvas->translate(0, fTileSize.height() * 1.1f);
126 }
127
128 using INHERITED = skiagm::GM;
129};
130
131} // namespace
132
133DEF_GM( return new MixerCFGM(SkSize::Make(200, 250), 5); )
#define SkColorGetR(color)
Definition SkColor.h:65
#define SkColorGetG(color)
Definition SkColor.h:69
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
#define SkColorGetA(color)
Definition SkColor.h:61
#define SkColorGetB(color)
Definition SkColor.h:73
#define INHERITED(method,...)
#define SkIntToScalar(x)
Definition SkScalar.h:57
void drawRect(const SkRect &rect, const SkPaint &paint)
void translate(SkScalar dx, SkScalar dy)
sk_sp< SkColorFilter > makeComposed(sk_sp< SkColorFilter > inner) const
static sk_sp< SkColorFilter > Matrix(const SkColorMatrix &)
static sk_sp< SkColorFilter > Lerp(float t, sk_sp< SkColorFilter > dst, sk_sp< SkColorFilter > src)
static sk_sp< SkShader > MakeSweep(SkScalar cx, SkScalar cy, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, SkScalar startAngle, SkScalar endAngle, uint32_t flags, const SkMatrix *localMatrix)
virtual SkISize getISize()=0
virtual SkString getName() const =0
virtual DrawResult onDraw(SkCanvas *, SkString *errorMsg)
Definition gm.cpp:139
const Paint & paint
static sk_sp< SkColorFilter > MakeTintColorFilter(SkColor lo, SkColor hi, bool useSkSL)
#define DEF_GM(CODE)
Definition gm.h:40
static sk_sp< SkColorFilter > MakeTintColorFilter(SkColor lo, SkColor hi)
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static sk_sp< SkColorFilter > Make()
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
static constexpr SkSize Make(SkScalar w, SkScalar h)
Definition SkSize.h:56
SkScalar width() const
Definition SkSize.h:76
SkScalar height() const
Definition SkSize.h:77