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 "include/effects/SkHighContrastFilter.h"
9
10 #include "include/core/SkAlphaType.h"
11 #include "include/core/SkColorFilter.h"
12 #include "include/core/SkColorSpace.h"
13 #include "include/core/SkData.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkTypes.h"
16 #include "include/effects/SkRuntimeEffect.h"
17 #include "include/private/base/SkTPin.h"
18 #include "src/core/SkColorFilterPriv.h"
19 #include "src/core/SkKnownRuntimeEffects.h"
20
21 #include <cfloat>
22
Make(const SkHighContrastConfig & config)23 sk_sp<SkColorFilter> SkHighContrastFilter::Make(const SkHighContrastConfig& config) {
24 if (!config.isValid()) {
25 return nullptr;
26 }
27
28 struct Uniforms { float grayscale, invertStyle, contrast; };
29
30 // A contrast setting of exactly +1 would divide by zero (1+c)/(1-c), so pull in to +1-ε.
31 // I'm not exactly sure why we've historically pinned -1 up to -1+ε, maybe just symmetry?
32 float c = SkTPin(config.fContrast,
33 -1.0f + FLT_EPSILON,
34 +1.0f - FLT_EPSILON);
35
36 Uniforms uniforms = {
37 config.fGrayscale ? 1.0f : 0.0f,
38 (float)config.fInvertStyle, // 0.0f for none, 1.0f for brightness, 2.0f for lightness
39 (1+c)/(1-c),
40 };
41
42 const SkRuntimeEffect* highContrastEffect =
43 GetKnownRuntimeEffect(SkKnownRuntimeEffects::StableKey::kHighContrast);
44
45 const SkAlphaType kUnpremul = kUnpremul_SkAlphaType;
46 return SkColorFilterPriv::WithWorkingFormat(
47 highContrastEffect->makeColorFilter(SkData::MakeWithCopy(&uniforms,sizeof(uniforms))),
48 &SkNamedTransferFn::kLinear,
49 /* gamut= */ nullptr, // use the dst gamut
50 &kUnpremul);
51 }
52