Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkSVGFilterContext.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 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 */
8
17
18namespace {
19
20sk_sp<SkImageFilter> ConvertFilterColorspace(sk_sp<SkImageFilter>&& input,
22 SkSVGColorspace dst) {
23 if (src == dst) {
24 return std::move(input);
25 } else if (src == SkSVGColorspace::kSRGB && dst == SkSVGColorspace::kLinearRGB) {
27 } else {
30 }
31}
32
33sk_sp<SkShader> paint_as_shader(const SkPaint& paint) {
34 sk_sp<SkShader> shader = paint.refShader();
35 auto color = paint.getColor4f();
36 if (shader && color.fA < 1.f) {
37 // Multiply by paint alpha
38 shader = shader->makeWithColorFilter(
39 SkColorFilters::Blend(color, /*colorSpace=*/nullptr, SkBlendMode::kDstIn));
40 } else if (!shader) {
41 shader = SkShaders::Color(color, /*colorSpace=*/nullptr);
42 }
43 if (paint.getColorFilter()) {
44 shader = shader->makeWithColorFilter(paint.refColorFilter());
45 }
46 return shader;
47}
48
49} // namespace
50
51const SkSVGFilterContext::Result* SkSVGFilterContext::findResultById(
52 const SkSVGStringType& id) const {
53 return fResults.find(id);
54}
55
57 const Result* res = nullptr;
59 res = fResults.find(input.id());
60 } else if (input.type() == SkSVGFeInputType::Type::kUnspecified) {
61 res = &fPreviousResult;
62 }
63 return res ? res->fFilterSubregion : fFilterEffectsRegion;
64}
65
68 const SkRect& subregion,
69 SkSVGColorspace resultColorspace) {
70 SkASSERT(!id.isEmpty());
71 fResults[id] = {result, subregion, resultColorspace};
72}
73
75 const SkRect& subregion,
76 SkSVGColorspace resultColorspace) {
77 fPreviousResult = {result, subregion, resultColorspace};
78}
79
81 return fPreviousResult.fImageFilter == nullptr;
82}
83
84// https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveInAttribute
85std::tuple<sk_sp<SkImageFilter>, SkSVGColorspace> SkSVGFilterContext::getInput(
86 const SkSVGRenderContext& ctx, const SkSVGFeInputType& inputType) const {
89 switch (inputType.type()) {
92 m.setScale(0, 0, 0, 1.0f);
94 break;
95 }
97 // Do nothing.
98 break;
100 const auto& fillPaint = ctx.fillPaint();
101 if (fillPaint.isValid()) {
102 auto dither = fillPaint->isDither() ? SkImageFilters::Dither::kYes
104 result = SkImageFilters::Shader(paint_as_shader(*fillPaint), dither);
105 }
106 break;
107 }
109 // The paint filter doesn't apply fill/stroke styling, but use the paint settings
110 // defined for strokes.
111 const auto& strokePaint = ctx.strokePaint();
112 if (strokePaint.isValid()) {
113 auto dither = strokePaint->isDither() ? SkImageFilters::Dither::kYes
115 result = SkImageFilters::Shader(paint_as_shader(*strokePaint), dither);
116 }
117 break;
118 }
120 const Result* res = findResultById(inputType.id());
121 if (res) {
122 result = res->fImageFilter;
123 inputCS = res->fColorspace;
124 }
125 break;
126 }
128 result = fPreviousResult.fImageFilter;
129 inputCS = fPreviousResult.fColorspace;
130 break;
131 }
132 default:
133 SkDebugf("unhandled filter input type %d\n", (int)inputType.type());
134 break;
135 }
136
137 return {result, inputCS};
138}
139
141 const SkSVGRenderContext& ctx, const SkSVGFeInputType& inputType) const {
142 return std::get<1>(this->getInput(ctx, inputType));
143}
144
146 const SkSVGFeInputType& inputType) const {
147 return std::get<0>(this->getInput(ctx, inputType));
148}
149
151 const SkSVGFeInputType& inputType,
152 SkSVGColorspace colorspace) const {
153 auto [result, inputCS] = this->getInput(ctx, inputType);
154 return ConvertFilterColorspace(std::move(result), inputCS, colorspace);
155}
SkColor4f color
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kDstIn
r = d * sa
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
SkSVGColorspace
Definition SkSVGTypes.h:719
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
static sk_sp< SkColorFilter > Matrix(const SkColorMatrix &)
static sk_sp< SkColorFilter > SRGBToLinearGamma()
static sk_sp< SkColorFilter > LinearToSRGBGamma()
static sk_sp< SkImageFilter > ColorFilter(sk_sp< SkColorFilter > cf, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
static sk_sp< SkImageFilter > Shader(sk_sp< SkShader > shader, const CropRect &cropRect={})
bool isDither() const
Definition SkPaint.h:175
const SkString & id() const
Definition SkSVGTypes.h:658
Type type() const
Definition SkSVGTypes.h:663
SkSVGColorspace resolveInputColorspace(const SkSVGRenderContext &, const SkSVGFeInputType &) const
void registerResult(const SkSVGStringType &, const sk_sp< SkImageFilter > &, const SkRect &, SkSVGColorspace)
sk_sp< SkImageFilter > resolveInput(const SkSVGRenderContext &, const SkSVGFeInputType &) const
void setPreviousResult(const sk_sp< SkImageFilter > &, const SkRect &, SkSVGColorspace)
bool previousResultIsSourceGraphic() const
const SkRect & filterPrimitiveSubregion(const SkSVGFeInputType &) const
SkTLazy< SkPaint > fillPaint() const
SkTLazy< SkPaint > strokePaint() const
const Paint & paint
GAsyncResult * result
const uintptr_t id