c37b386886
Note: in variedtext.cpp:66 changed static_assert to SkASSERT. Change-Id: I853a2e5563c90c9dde5d6ba5443cc73b664b493d Reviewed-on: https://skia-review.googlesource.com/c/skia/+/551876 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
104 lines
3.7 KiB
C++
104 lines
3.7 KiB
C++
/*
|
|
* Copyright 2021 Google LLC
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "gm/gm.h"
|
|
#include "include/core/SkCanvas.h"
|
|
#include "include/core/SkColor.h"
|
|
#include "include/core/SkColorFilter.h"
|
|
#include "include/core/SkImage.h"
|
|
#include "include/core/SkMatrix.h"
|
|
#include "include/core/SkPaint.h"
|
|
#include "include/core/SkPoint.h"
|
|
#include "include/core/SkRect.h"
|
|
#include "include/core/SkRefCnt.h"
|
|
#include "include/core/SkScalar.h"
|
|
#include "include/core/SkShader.h"
|
|
#include "include/core/SkSize.h"
|
|
#include "include/core/SkString.h"
|
|
#include "include/core/SkTileMode.h"
|
|
#include "include/core/SkTypes.h"
|
|
#include "include/effects/SkGradientShader.h"
|
|
#include "include/effects/SkLumaColorFilter.h"
|
|
#include "include/effects/SkRuntimeEffect.h"
|
|
#include "src/core/SkRuntimeEffectPriv.h"
|
|
#include "tools/Resources.h"
|
|
|
|
#include <math.h>
|
|
|
|
// A tint filter maps colors to a given range (gradient), based on the input luminance:
|
|
//
|
|
// c' = lerp(lo, hi, luma(c))
|
|
static sk_sp<SkColorFilter> MakeTintColorFilter(SkColor lo, SkColor hi, bool useSkSL) {
|
|
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 float tint_matrix[] = {
|
|
0, 0, 0, (r_hi - r_lo) / 255.0f, SkIntToScalar(r_lo) / 255.0f,
|
|
0, 0, 0, (g_hi - g_lo) / 255.0f, SkIntToScalar(g_lo) / 255.0f,
|
|
0, 0, 0, (b_hi - b_lo) / 255.0f, SkIntToScalar(b_lo) / 255.0f,
|
|
0, 0, 0, (a_hi - a_lo) / 255.0f, SkIntToScalar(a_lo) / 255.0f,
|
|
};
|
|
|
|
sk_sp<SkColorFilter> inner = SkLumaColorFilter::Make(),
|
|
outer = SkColorFilters::Matrix(tint_matrix);
|
|
|
|
// Prove that we can implement compose-color-filter using runtime effects
|
|
if (useSkSL) {
|
|
auto [effect, error] = SkRuntimeEffect::MakeForColorFilter(SkString(R"(
|
|
uniform colorFilter inner;
|
|
uniform colorFilter outer;
|
|
half4 main(half4 c) { return outer.eval(inner.eval(c)); }
|
|
)"));
|
|
SkASSERT(effect);
|
|
SkASSERT(SkRuntimeEffectPriv::SupportsConstantOutputForConstantInput(effect.get()));
|
|
sk_sp<SkColorFilter> children[] = { inner, outer };
|
|
return effect->makeColorFilter(nullptr, children, std::size(children));
|
|
} else {
|
|
return outer->makeComposed(inner);
|
|
}
|
|
}
|
|
|
|
DEF_SIMPLE_GM(composeCF, canvas, 200, 200) {
|
|
// This GM draws a simple color-filter network, using the existing "makeComposed" API, and also
|
|
// using a runtime color filter that does the same thing.
|
|
SkPaint paint;
|
|
const SkColor gradient_colors[] = {SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED};
|
|
paint.setShader(SkGradientShader::MakeSweep(
|
|
50, 50, gradient_colors, nullptr, std::size(gradient_colors)));
|
|
|
|
canvas->save();
|
|
for (bool useSkSL : {false, true}) {
|
|
auto cf0 = MakeTintColorFilter(0xff300000, 0xffa00000, useSkSL); // red tint
|
|
auto cf1 = MakeTintColorFilter(0xff003000, 0xff00a000, useSkSL); // green tint
|
|
|
|
paint.setColorFilter(cf0);
|
|
canvas->drawRect({0, 0, 100, 100}, paint);
|
|
canvas->translate(100, 0);
|
|
|
|
paint.setColorFilter(cf1);
|
|
canvas->drawRect({0, 0, 100, 100}, paint);
|
|
|
|
canvas->restore();
|
|
canvas->translate(0, 100);
|
|
}
|
|
}
|