xref: /aosp_15_r20/external/skia/modules/svg/src/SkSVGFeTurbulence.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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  */
7 
8 #include "modules/svg/include/SkSVGFeTurbulence.h"
9 
10 #include "include/core/SkShader.h"
11 #include "include/effects/SkImageFilters.h"
12 #include "include/effects/SkPerlinNoiseShader.h"
13 #include "modules/svg/include/SkSVGAttributeParser.h"
14 
15 class SkImageFilter;
16 class SkSVGFilterContext;
17 class SkSVGRenderContext;
18 struct SkISize;
19 
parseAndSetAttribute(const char * name,const char * value)20 bool SkSVGFeTurbulence::parseAndSetAttribute(const char* name, const char* value) {
21     return INHERITED::parseAndSetAttribute(name, value) ||
22            this->setNumOctaves(
23                    SkSVGAttributeParser::parse<SkSVGIntegerType>("numOctaves", name, value)) ||
24            this->setSeed(SkSVGAttributeParser::parse<SkSVGNumberType>("seed", name, value)) ||
25            this->setBaseFrequency(SkSVGAttributeParser::parse<SkSVGFeTurbulenceBaseFrequency>(
26                    "baseFrequency", name, value)) ||
27            this->setTurbulenceType(SkSVGAttributeParser::parse<SkSVGFeTurbulenceType>(
28                    "type", name, value));
29 }
30 
31 template <>
parse(SkSVGFeTurbulenceBaseFrequency * freq)32 bool SkSVGAttributeParser::parse<SkSVGFeTurbulenceBaseFrequency>(
33         SkSVGFeTurbulenceBaseFrequency* freq) {
34     SkSVGNumberType freqX;
35     if (!this->parse(&freqX)) {
36         return false;
37     }
38 
39     SkSVGNumberType freqY;
40     this->parseCommaWspToken();
41     if (this->parse(&freqY)) {
42         *freq = SkSVGFeTurbulenceBaseFrequency(freqX, freqY);
43     } else {
44         *freq = SkSVGFeTurbulenceBaseFrequency(freqX, freqX);
45     }
46 
47     return this->parseEOSToken();
48 }
49 
50 template <>
parse(SkSVGFeTurbulenceType * type)51 bool SkSVGAttributeParser::parse<SkSVGFeTurbulenceType>(SkSVGFeTurbulenceType* type) {
52     bool parsedValue = false;
53 
54     if (this->parseExpectedStringToken("fractalNoise")) {
55         *type = SkSVGFeTurbulenceType(SkSVGFeTurbulenceType::kFractalNoise);
56         parsedValue = true;
57     } else if (this->parseExpectedStringToken("turbulence")) {
58         *type = SkSVGFeTurbulenceType(SkSVGFeTurbulenceType::kTurbulence);
59         parsedValue = true;
60     }
61 
62     return parsedValue && this->parseEOSToken();
63 }
64 
onMakeImageFilter(const SkSVGRenderContext & ctx,const SkSVGFilterContext & fctx) const65 sk_sp<SkImageFilter> SkSVGFeTurbulence::onMakeImageFilter(const SkSVGRenderContext& ctx,
66                                                           const SkSVGFilterContext& fctx) const {
67     const SkISize* tileSize = nullptr;  // TODO: needs filter element subregion properties
68 
69     sk_sp<SkShader> shader;
70     switch (fTurbulenceType.fType) {
71         case SkSVGFeTurbulenceType::Type::kTurbulence:
72             shader = SkShaders::MakeTurbulence(
73                     fBaseFrequency.freqX(), fBaseFrequency.freqY(), fNumOctaves, fSeed, tileSize);
74             break;
75         case SkSVGFeTurbulenceType::Type::kFractalNoise:
76             shader = SkShaders::MakeFractalNoise(
77                     fBaseFrequency.freqX(), fBaseFrequency.freqY(), fNumOctaves, fSeed, tileSize);
78             break;
79     }
80 
81     return SkImageFilters::Shader(shader, this->resolveFilterSubregion(ctx, fctx));
82 }
83