24d0c0c7988f131a813d0954830bf966fc8d5c0c
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / filters / FETurbulence.cpp
1 /*
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.
9  *
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.
14  *
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.
19  *
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.
24  */
25
26 #include "config.h"
27 #include "platform/graphics/filters/FETurbulence.h"
28
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"
35
36 namespace blink {
37
38 FETurbulence::FETurbulence(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
39     : FilterEffect(filter)
40     , m_type(type)
41     , m_baseFrequencyX(baseFrequencyX)
42     , m_baseFrequencyY(baseFrequencyY)
43     , m_numOctaves(numOctaves)
44     , m_seed(seed)
45     , m_stitchTiles(stitchTiles)
46 {
47 }
48
49 PassRefPtr<FETurbulence> FETurbulence::create(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
50 {
51     return adoptRef(new FETurbulence(filter, type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles));
52 }
53
54 TurbulenceType FETurbulence::type() const
55 {
56     return m_type;
57 }
58
59 bool FETurbulence::setType(TurbulenceType type)
60 {
61     if (m_type == type)
62         return false;
63     m_type = type;
64     return true;
65 }
66
67 float FETurbulence::baseFrequencyY() const
68 {
69     return m_baseFrequencyY;
70 }
71
72 bool FETurbulence::setBaseFrequencyY(float baseFrequencyY)
73 {
74     if (m_baseFrequencyY == baseFrequencyY)
75         return false;
76     m_baseFrequencyY = baseFrequencyY;
77     return true;
78 }
79
80 float FETurbulence::baseFrequencyX() const
81 {
82     return m_baseFrequencyX;
83 }
84
85 bool FETurbulence::setBaseFrequencyX(float baseFrequencyX)
86 {
87     if (m_baseFrequencyX == baseFrequencyX)
88         return false;
89     m_baseFrequencyX = baseFrequencyX;
90     return true;
91 }
92
93 float FETurbulence::seed() const
94 {
95     return m_seed;
96 }
97
98 bool FETurbulence::setSeed(float seed)
99 {
100     if (m_seed == seed)
101         return false;
102     m_seed = seed;
103     return true;
104 }
105
106 int FETurbulence::numOctaves() const
107 {
108     return m_numOctaves;
109 }
110
111 bool FETurbulence::setNumOctaves(int numOctaves)
112 {
113     if (m_numOctaves == numOctaves)
114         return false;
115     m_numOctaves = numOctaves;
116     return true;
117 }
118
119 bool FETurbulence::stitchTiles() const
120 {
121     return m_stitchTiles;
122 }
123
124 bool FETurbulence::setStitchTiles(bool stitch)
125 {
126     if (m_stitchTiles == stitch)
127         return false;
128     m_stitchTiles = stitch;
129     return true;
130 }
131
132 SkShader* FETurbulence::createShader()
133 {
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);
149 }
150
151 PassRefPtr<SkImageFilter> FETurbulence::createImageFilter(SkiaImageFilterBuilder* builder)
152 {
153     SkAutoTUnref<SkShader> shader(createShader());
154     SkImageFilter::CropRect rect = getCropRect(builder->cropOffset());
155     return adoptRef(SkRectShaderImageFilter::Create(shader, &rect));
156 }
157
158 static TextStream& operator<<(TextStream& ts, const TurbulenceType& type)
159 {
160     switch (type) {
161     case FETURBULENCE_TYPE_UNKNOWN:
162         ts << "UNKNOWN";
163         break;
164     case FETURBULENCE_TYPE_TURBULENCE:
165         ts << "TURBULENCE";
166         break;
167     case FETURBULENCE_TYPE_FRACTALNOISE:
168         ts << "NOISE";
169         break;
170     }
171     return ts;
172 }
173
174 TextStream& FETurbulence::externalRepresentation(TextStream& ts, int indent) const
175 {
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";
184     return ts;
185 }
186
187 } // namespace blink