Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkDropShadowImageFilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2013 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
9
20#include "include/core/SkSize.h"
26
27#include <optional>
28#include <utility>
29
30struct SkRect;
31
32namespace {
33
34static sk_sp<SkImageFilter> make_drop_shadow_graph(SkVector offset,
35 SkSize sigma,
37 bool shadowOnly,
39 const std::optional<SkRect>& crop) {
40 // A drop shadow blurs the input, filters it to be the solid color + blurred
41 // alpha, and then offsets it. If it's not shadow-only, the input is then
42 // src-over blended on top. Finally it's cropped to the optional 'crop'.
43 sk_sp<SkImageFilter> filter = input;
44 filter = SkImageFilters::Blur(sigma.fWidth, sigma.fHeight, std::move(filter));
47 std::move(filter));
48 // TODO: Offset should take SkSamplingOptions too, but kLinear filtering is needed to hide
49 // nearest-neighbor sampling artifacts from fractional offsets applied post-blur.
52 std::move(filter));
53 if (!shadowOnly) {
54#if defined(SK_LEGACY_BLEND_FOR_DROP_SHADOWS)
55 filter = SkImageFilters::Blend(
56 SkBlendMode::kSrcOver, std::move(filter), std::move(input));
57#else
58 // Merge is visually equivalent to Blend(kSrcOver) but draws each child independently,
59 // whereas Blend() fills the union of the child bounds with a single shader evaluation.
60 // Since we know the original and the offset blur will have somewhat disjoint bounds, a
61 // Blend() shader would force evaluating tile edge conditions for each, while merge lets us
62 // avoid that.
63 filter = SkImageFilters::Merge(std::move(filter), std::move(input));
64#endif
65 }
66 if (crop) {
67 filter = SkImageFilters::Crop(*crop, std::move(filter));
68 }
69 return filter;
70}
71
72sk_sp<SkFlattenable> legacy_drop_shadow_create_proc(SkReadBuffer& buffer) {
74 // SKPs created with this version or newer just serialize the image filter composition that
75 // is equivalent to a drop-shadow, instead of a single dedicated flattenable for the effect.
76 return nullptr;
77 }
78
79 auto [child, cropRect] = SkImageFilter_Base::Unflatten(buffer);
80
81 SkScalar dx = buffer.readScalar();
82 SkScalar dy = buffer.readScalar();
83 SkScalar sigmaX = buffer.readScalar();
84 SkScalar sigmaY = buffer.readScalar();
85 SkColor color = buffer.readColor();
86
87 // For backwards compatibility, the shadow mode had been saved as an enum cast to a 32LE int,
88 // where shadow-and-foreground was 0 and shadow-only was 1. Other than the number of bits, this
89 // is equivalent to the bool that SkDropShadowImageFilter now uses.
90 bool shadowOnly = SkToBool(buffer.read32LE(1));
91 return make_drop_shadow_graph({dx, dy}, {sigmaX, sigmaY}, color, shadowOnly,
92 std::move(child), cropRect);
93}
94
95} // anonymous namespace
96
98 SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color,
99 sk_sp<SkImageFilter> input, const CropRect& cropRect) {
100 return make_drop_shadow_graph({dx, dy}, {sigmaX, sigmaY}, color, /*shadowOnly=*/false,
101 std::move(input), cropRect);
102}
103
105 SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color,
106 sk_sp<SkImageFilter> input, const CropRect& cropRect) {
107 return make_drop_shadow_graph({dx, dy}, {sigmaX, sigmaY}, color, /*shadowOnly=*/true,
108 std::move(input), cropRect);
109}
110
111// TODO (michaelludwig) - Remove after grace period for SKPs to stop using old create proc
113 SkFlattenable::Register("SkDropShadowImageFilter", legacy_drop_shadow_create_proc);
114 SkFlattenable::Register("SkDropShadowImageFilterImpl", legacy_drop_shadow_create_proc);
115}
SkColor4f color
@ kSrcOver
r = s + (1-sa)*d
@ kSrcIn
r = s * da
uint32_t SkColor
Definition SkColor.h:37
void SkRegisterLegacyDropShadowImageFilterFlattenable()
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
static void Register(const char name[], Factory)
static std::pair< sk_sp< SkImageFilter >, std::optional< SkRect > > Unflatten(SkReadBuffer &buffer)
static sk_sp< SkImageFilter > ColorFilter(sk_sp< SkColorFilter > cf, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > DropShadow(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Merge(sk_sp< SkImageFilter > *const filters, int count, const CropRect &cropRect={})
static sk_sp< SkImageFilter > DropShadowOnly(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor color, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > MatrixTransform(const SkMatrix &matrix, const SkSamplingOptions &sampling, sk_sp< SkImageFilter > input)
static sk_sp< SkImageFilter > Crop(const SkRect &rect, SkTileMode tileMode, sk_sp< SkImageFilter > input)
static sk_sp< SkImageFilter > Blend(SkBlendMode mode, sk_sp< SkImageFilter > background, sk_sp< SkImageFilter > foreground=nullptr, const CropRect &cropRect={})
static SkMatrix Translate(SkScalar dx, SkScalar dy)
Definition SkMatrix.h:91
@ kDropShadowImageFilterComposition
float SkScalar
Definition extension.cpp:12
static const uint8_t buffer[]
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition SkRecords.h:208
Point offset
SkScalar fHeight
Definition SkSize.h:54
SkScalar fWidth
Definition SkSize.h:53