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