blob: 885ef4a74174e19d18f7e6367ffd6dc339d2aa19 [file] [log] [blame]
Tyler Dennistondada9602020-11-03 10:04:25 -05001/*
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"
Tyler Denniston57154992020-11-04 16:08:30 -050010#include "modules/svg/include/SkSVGAttributeParser.h"
Tyler Dennistondada9602020-11-03 10:04:25 -050011#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
Tyler Denniston57154992020-11-04 16:08:30 -050016bool 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>(
Florin Malita401321d2020-11-05 11:27:24 -050022 "baseFrequency", name, value)) ||
Tyler Denniston57154992020-11-04 16:08:30 -050023 this->setTurbulenceType(SkSVGAttributeParser::parse<SkSVGFeTurbulenceType>(
Florin Malita401321d2020-11-05 11:27:24 -050024 "type", name, value));
Tyler Denniston57154992020-11-04 16:08:30 -050025}
26
Florin Malita401321d2020-11-05 11:27:24 -050027template <>
28bool SkSVGAttributeParser::parse<SkSVGFeTurbulenceBaseFrequency>(
29 SkSVGFeTurbulenceBaseFrequency* freq) {
Tyler Denniston57154992020-11-04 16:08:30 -050030 SkSVGNumberType freqX;
Tyler Denniston4c6f57a2020-11-30 15:31:32 -050031 if (!this->parse(&freqX)) {
Tyler Denniston57154992020-11-04 16:08:30 -050032 return false;
Tyler Dennistondada9602020-11-03 10:04:25 -050033 }
Tyler Denniston57154992020-11-04 16:08:30 -050034
35 SkSVGNumberType freqY;
Florin Malita401321d2020-11-05 11:27:24 -050036 this->parseCommaWspToken();
Tyler Denniston4c6f57a2020-11-30 15:31:32 -050037 if (this->parse(&freqY)) {
Tyler Denniston57154992020-11-04 16:08:30 -050038 *freq = SkSVGFeTurbulenceBaseFrequency(freqX, freqY);
39 } else {
40 *freq = SkSVGFeTurbulenceBaseFrequency(freqX, freqX);
41 }
42
Florin Malita401321d2020-11-05 11:27:24 -050043 return this->parseEOSToken();
Tyler Denniston57154992020-11-04 16:08:30 -050044}
45
Florin Malita401321d2020-11-05 11:27:24 -050046template <>
47bool SkSVGAttributeParser::parse<SkSVGFeTurbulenceType>(SkSVGFeTurbulenceType* type) {
Tyler Denniston57154992020-11-04 16:08:30 -050048 bool parsedValue = false;
49
Florin Malita401321d2020-11-05 11:27:24 -050050 if (this->parseExpectedStringToken("fractalNoise")) {
Tyler Denniston57154992020-11-04 16:08:30 -050051 *type = SkSVGFeTurbulenceType(SkSVGFeTurbulenceType::kFractalNoise);
52 parsedValue = true;
Florin Malita401321d2020-11-05 11:27:24 -050053 } else if (this->parseExpectedStringToken("turbulence")) {
Tyler Denniston57154992020-11-04 16:08:30 -050054 *type = SkSVGFeTurbulenceType(SkSVGFeTurbulenceType::kTurbulence);
55 parsedValue = true;
56 }
57
Florin Malita401321d2020-11-05 11:27:24 -050058 return parsedValue && this->parseEOSToken();
Tyler Dennistondada9602020-11-03 10:04:25 -050059}
60
61sk_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
Tyler Denniston62a683e2020-12-11 11:47:55 -050077 return SkImageFilters::Shader(shader, this->resolveFilterSubregion(ctx, fctx));
Tyler Dennistondada9602020-11-03 10:04:25 -050078}