Flutter Engine
The Flutter Engine
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) {
73 if (!buffer.isVersionLT(SkPicturePriv::Version::kDropShadowImageFilterComposition)) {
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}
@ 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
DlColor color
float SkScalar
Definition: extension.cpp:12
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
void offset(float dx, float dy)
Definition: SkRect.h:1016
Definition: SkSize.h:52
SkScalar fHeight
Definition: SkSize.h:54
SkScalar fWidth
Definition: SkSize.h:53