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