Add a SkMixerColorFilter GM
Change-Id: I26382a669601f2bebb1f95e56eab2ad3718db4b9 Reviewed-on: https://skia-review.googlesource.com/c/193165 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
880b6ea52b
commit
346ce63daa
112
gm/mixercolorfilter.cpp
Normal file
112
gm/mixercolorfilter.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2019 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gm.h"
|
||||
|
||||
#include "SkCanvas.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkLumaColorFilter.h"
|
||||
#include "SkTableColorFilter.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class MixerCFGM final : public skiagm::GM {
|
||||
public:
|
||||
MixerCFGM(const SkSize& tileSize, size_t tileCount)
|
||||
: fTileSize(tileSize)
|
||||
, fTileCount(tileCount) {}
|
||||
|
||||
protected:
|
||||
SkString onShortName() override {
|
||||
return SkString("mixerCF");
|
||||
}
|
||||
|
||||
SkISize onISize() override {
|
||||
return SkISize::Make(fTileSize.width() * 1.2f * fTileCount,
|
||||
fTileSize.height() * 1.2f * 3); // 3 rows
|
||||
}
|
||||
|
||||
void onDraw(SkCanvas* canvas) override {
|
||||
SkPaint paint;
|
||||
|
||||
const SkColor gradient_colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
|
||||
paint.setShader(SkGradientShader::MakeSweep(fTileSize.width() / 2,
|
||||
fTileSize.height() / 2,
|
||||
gradient_colors, nullptr,
|
||||
SK_ARRAY_COUNT(gradient_colors)));
|
||||
|
||||
auto cf0 = MakeTintColorFilter(0xff300000, 0xffa00000); // red tint
|
||||
auto cf1 = MakeTintColorFilter(0xff003000, 0xff00a000); // green tint
|
||||
|
||||
this->mixRow(canvas, paint, nullptr, cf1);
|
||||
this->mixRow(canvas, paint, cf0, nullptr);
|
||||
this->mixRow(canvas, paint, cf0, cf1);
|
||||
}
|
||||
|
||||
private:
|
||||
const SkSize fTileSize;
|
||||
const size_t fTileCount;
|
||||
|
||||
void mixRow(SkCanvas* canvas, SkPaint& paint,
|
||||
sk_sp<SkColorFilter> cf0, sk_sp<SkColorFilter> cf1) {
|
||||
canvas->translate(0, fTileSize.height() * 0.1f);
|
||||
{
|
||||
SkAutoCanvasRestore arc(canvas, true);
|
||||
for (size_t i = 0; i < fTileCount; ++i) {
|
||||
paint.setColorFilter(
|
||||
SkColorFilter::MakeMixer(cf0, cf1, static_cast<float>(i) / (fTileCount - 1)));
|
||||
canvas->translate(fTileSize.width() * 0.1f, 0);
|
||||
canvas->drawRect(SkRect::MakeWH(fTileSize.width(), fTileSize.height()), paint);
|
||||
canvas->translate(fTileSize.width() * 1.1f, 0);
|
||||
}
|
||||
}
|
||||
canvas->translate(0, fTileSize.height() * 1.1f);
|
||||
}
|
||||
|
||||
// A tint filter maps colors to a given range (gradient), based on the input luminance:
|
||||
//
|
||||
// c' = lerp(lo, hi, luma(c))
|
||||
//
|
||||
// TODO: move to public headers/API?
|
||||
//
|
||||
static sk_sp<SkColorFilter> MakeTintColorFilter(SkColor lo, SkColor hi) {
|
||||
const auto r_lo = SkColorGetR(lo),
|
||||
g_lo = SkColorGetG(lo),
|
||||
b_lo = SkColorGetB(lo),
|
||||
a_lo = SkColorGetA(lo),
|
||||
r_hi = SkColorGetR(hi),
|
||||
g_hi = SkColorGetG(hi),
|
||||
b_hi = SkColorGetB(hi),
|
||||
a_hi = SkColorGetA(hi);
|
||||
|
||||
// We map component-wise:
|
||||
//
|
||||
// r' = lo.r + (hi.r - lo.r) * luma
|
||||
// g' = lo.g + (hi.g - lo.g) * luma
|
||||
// b' = lo.b + (hi.b - lo.b) * luma
|
||||
// a' = lo.a + (hi.a - lo.a) * luma
|
||||
//
|
||||
// The input luminance is stored in the alpha channel
|
||||
// (and RGB are cleared -- see SkLumaColorFilter). Thus:
|
||||
const SkScalar tint_matrix[] = {
|
||||
0, 0, 0, (r_hi - r_lo) / 255.0f, SkIntToScalar(r_lo),
|
||||
0, 0, 0, (g_hi - g_lo) / 255.0f, SkIntToScalar(g_lo),
|
||||
0, 0, 0, (b_hi - b_lo) / 255.0f, SkIntToScalar(b_lo),
|
||||
0, 0, 0, (a_hi - a_lo) / 255.0f, SkIntToScalar(a_lo),
|
||||
};
|
||||
|
||||
return SkColorFilter::MakeMatrixFilterRowMajor255(tint_matrix)
|
||||
->makeComposed(SkLumaColorFilter::Make());
|
||||
}
|
||||
|
||||
using INHERITED = skiagm::GM;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
DEF_GM( return new MixerCFGM(SkSize::Make(200, 250), 5); )
|
Loading…
Reference in New Issue
Block a user