2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
6 * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
7 * Copyright (C) 2011 Gabor Loki <loki@webkit.org>
8 * Copyright (C) 2013 Google Inc. All rights reserved.
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
27 #include "platform/graphics/filters/FETurbulence.h"
29 #include "SkPerlinNoiseShader.h"
30 #include "SkRectShaderImageFilter.h"
31 #include "platform/graphics/filters/Filter.h"
32 #include "platform/graphics/filters/SkiaImageFilterBuilder.h"
33 #include "platform/text/TextStream.h"
34 #include "wtf/MathExtras.h"
38 FETurbulence::FETurbulence(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
39 : FilterEffect(filter)
41 , m_baseFrequencyX(baseFrequencyX)
42 , m_baseFrequencyY(baseFrequencyY)
43 , m_numOctaves(numOctaves)
45 , m_stitchTiles(stitchTiles)
49 PassRefPtr<FETurbulence> FETurbulence::create(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
51 return adoptRef(new FETurbulence(filter, type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles));
54 TurbulenceType FETurbulence::type() const
59 bool FETurbulence::setType(TurbulenceType type)
67 float FETurbulence::baseFrequencyY() const
69 return m_baseFrequencyY;
72 bool FETurbulence::setBaseFrequencyY(float baseFrequencyY)
74 if (m_baseFrequencyY == baseFrequencyY)
76 m_baseFrequencyY = baseFrequencyY;
80 float FETurbulence::baseFrequencyX() const
82 return m_baseFrequencyX;
85 bool FETurbulence::setBaseFrequencyX(float baseFrequencyX)
87 if (m_baseFrequencyX == baseFrequencyX)
89 m_baseFrequencyX = baseFrequencyX;
93 float FETurbulence::seed() const
98 bool FETurbulence::setSeed(float seed)
106 int FETurbulence::numOctaves() const
111 bool FETurbulence::setNumOctaves(int numOctaves)
113 if (m_numOctaves == numOctaves)
115 m_numOctaves = numOctaves;
119 bool FETurbulence::stitchTiles() const
121 return m_stitchTiles;
124 bool FETurbulence::setStitchTiles(bool stitch)
126 if (m_stitchTiles == stitch)
128 m_stitchTiles = stitch;
132 SkShader* FETurbulence::createShader()
134 const SkISize size = SkISize::Make(effectBoundaries().width(), effectBoundaries().height());
135 // Frequency should be scaled by page zoom, but not by primitiveUnits.
136 // So we apply only the transform scale (as Filter::apply*Scale() do)
137 // and not the target bounding box scale (as SVGFilter::apply*Scale()
138 // would do). Note also that we divide by the scale since this is
139 // a frequency, not a period.
140 float baseFrequencyX = m_baseFrequencyX / filter()->scale();
141 float baseFrequencyY = m_baseFrequencyY / filter()->scale();
142 return (type() == FETURBULENCE_TYPE_FRACTALNOISE) ?
143 SkPerlinNoiseShader::CreateFractalNoise(SkFloatToScalar(baseFrequencyX),
144 SkFloatToScalar(baseFrequencyY), numOctaves(), SkFloatToScalar(seed()),
145 stitchTiles() ? &size : 0) :
146 SkPerlinNoiseShader::CreateTurbulence(SkFloatToScalar(baseFrequencyX),
147 SkFloatToScalar(baseFrequencyY), numOctaves(), SkFloatToScalar(seed()),
148 stitchTiles() ? &size : 0);
151 PassRefPtr<SkImageFilter> FETurbulence::createImageFilter(SkiaImageFilterBuilder* builder)
153 SkAutoTUnref<SkShader> shader(createShader());
154 SkImageFilter::CropRect rect = getCropRect(builder->cropOffset());
155 return adoptRef(SkRectShaderImageFilter::Create(shader, &rect));
158 static TextStream& operator<<(TextStream& ts, const TurbulenceType& type)
161 case FETURBULENCE_TYPE_UNKNOWN:
164 case FETURBULENCE_TYPE_TURBULENCE:
167 case FETURBULENCE_TYPE_FRACTALNOISE:
174 TextStream& FETurbulence::externalRepresentation(TextStream& ts, int indent) const
176 writeIndent(ts, indent);
177 ts << "[feTurbulence";
178 FilterEffect::externalRepresentation(ts);
179 ts << " type=\"" << type() << "\" "
180 << "baseFrequency=\"" << baseFrequencyX() << ", " << baseFrequencyY() << "\" "
181 << "seed=\"" << seed() << "\" "
182 << "numOctaves=\"" << numOctaves() << "\" "
183 << "stitchTiles=\"" << stitchTiles() << "\"]\n";